diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 64962ab..ebd7637 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -80,20 +80,7 @@
 
         <!-- Top-level settings -->
 
-        <activity android:name=".wifi.WifiSettings" android:label="@string/wifi_settings"
-                android:clearTaskOnLaunch="true"
-                >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <action android:name="android.settings.WIFI_SETTINGS" />
-                <action android:name="android.net.wifi.PICK_WIFI_NETWORK" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.VOICE_LAUNCH" />
-                <category android:name="com.android.settings.SHORTCUT" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".wifi.WifiSettings2"
+        <activity android:name=".wifi.WifiSettings"
                 android:label="@string/wifi_settings"
                 android:configChanges="orientation|keyboardHidden"
                 android:clearTaskOnLaunch="true"
@@ -181,6 +168,16 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".TetherSettings"
+                android:configChanges="orientation|keyboardHidden"
+                android:launchMode="singleTask">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE_LAUNCH" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".vpn.VpnSettings"
                 android:configChanges="orientation|keyboardHidden"
                 android:launchMode="singleTask">
diff --git a/res/layout/wifi_ap_configure.xml b/res/layout/wifi_ap_configure.xml
deleted file mode 100644
index 3f8fbba..0000000
--- a/res/layout/wifi_ap_configure.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-        
-    <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:padding="8dip"
-            android:orientation="vertical"> 
-    
-            <LinearLayout
-                android:id="@+id/table"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="vertical">
-            </LinearLayout>
-
-    
-        <!-- SSID -->
-    
-        <TextView android:id="@+id/ssid_text"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/wifi_type_ssid" />
-
-        <EditText android:id="@+id/ssid_edit"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:singleLine="true"
-                android:inputType="textNoSuggestions" />
-    
-        <!-- Security -->
-        
-        <TextView android:id="@+id/security_text"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="8dip"
-                android:text="@string/wifi_security" />
-            
-        <!-- The entries will be set programmatically -->
-        <Spinner android:id="@+id/security_spinner"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
-
-        <!-- Enterprise Fields -->
-        <LinearLayout android:id="@+id/enterprise_wrapper"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:padding="0dip"
-            android:orientation="vertical">
-                <TextView android:id="@+id/eap_text"
-                        style="?android:attr/textAppearanceSmallInverse"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="8dip"
-                        android:text="@string/please_select_eap" />
-                <Spinner android:id="@+id/eap_spinner"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content" />
-                <TextView android:id="@+id/phase2_text"
-                        style="?android:attr/textAppearanceSmallInverse"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="8dip"
-                        android:text="@string/please_select_phase2" />
-                <Spinner android:id="@+id/phase2_spinner"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content" />
-
-                <TextView android:id="@+id/ca_certificate_text"
-                        style="?android:attr/textAppearanceSmallInverse"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="8dip"
-                        android:text="@string/please_select_ca_certificate" />
-                <Spinner android:id="@+id/ca_certificate_spinner"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content" />
-                <TextView android:id="@+id/client_certificate_text"
-                        style="?android:attr/textAppearanceSmallInverse"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="8dip"
-                        android:text="@string/please_select_client_certificate" />
-                <Spinner android:id="@+id/client_certificate_spinner"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content" />
-                <TextView android:id="@+id/identity_text"
-                        style="?android:attr/textAppearanceSmallInverse"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="8dip"
-                        android:text="@string/please_type_identity" />
-                <EditText android:id="@+id/identity_edit"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="2dip"
-                        android:singleLine="true"
-                        android:inputType="textNoSuggestions" />
-                <TextView android:id="@+id/anonymous_identity_text"
-                        style="?android:attr/textAppearanceSmallInverse"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="8dip"
-                        android:text="@string/please_type_anonymous_identity" />
-                <EditText android:id="@+id/anonymous_identity_edit"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="2dip"
-                        android:singleLine="true" />
-        </LinearLayout>
-
-        <!-- Password -->
-        
-        <TextView android:id="@+id/password_text"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="8dip"
-                android:text="@string/please_type_passphrase" />
-            
-        <EditText android:id="@+id/password_edit"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:singleLine="true"
-                android:password="true" />
-    
-        <CheckBox android:id="@+id/show_password_checkbox"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:text="@string/wifi_show_password" />
-                
-        <Spinner android:id="@+id/wep_type_spinner"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:entries="@array/wifi_wep_type" />
-            
-    </LinearLayout>
-
-</ScrollView>    
diff --git a/res/layout/wifi_ap_info.xml b/res/layout/wifi_ap_info.xml
deleted file mode 100644
index d38a831..0000000
--- a/res/layout/wifi_ap_info.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-        
-    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:padding="8dip"
-            android:orientation="vertical"> 
-    
-        <LinearLayout
-                android:id="@+id/table"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="vertical">
-        
-        <!-- Info dynamically added here. -->
-        
-        </LinearLayout>
-    
-        <!-- Password -->
-        <TextView android:id="@+id/password_text"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="8dip"
-                android:text="@string/please_type_passphrase" />
-            
-        <EditText android:id="@+id/password_edit"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:singleLine="true"
-                android:password="true" />
-    
-        <CheckBox android:id="@+id/show_password_checkbox"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:text="@string/wifi_show_password" />
-                
-    </LinearLayout>
-
-</ScrollView>    
diff --git a/res/layout/wifi_ap_info_row.xml b/res/layout/wifi_ap_info_row.xml
deleted file mode 100644
index dfc4ca8..0000000
--- a/res/layout/wifi_ap_info_row.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-    <TextView
-            android:id="@+id/name"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginRight="8dip"
-            android:textAppearance="?android:attr/textAppearanceSmallInverse" />
-    <TextView
-            android:id="@+id/value"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceSmallInverse"
-            android:textStyle="bold" />
-</LinearLayout>
diff --git a/res/layout/wifi_ap_retry_password.xml b/res/layout/wifi_ap_retry_password.xml
deleted file mode 100644
index d460d8e..0000000
--- a/res/layout/wifi_ap_retry_password.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-        
-    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:padding="8dip"
-            android:orientation="vertical"> 
-    
-        <TextView
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/wifi_password_incorrect_error" />
-                    
-        <!-- Password -->
-        <TextView android:id="@+id/password_text"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="8dip"
-                android:text="@string/please_type_passphrase" />
-            
-        <EditText android:id="@+id/password_edit"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:singleLine="true"
-                android:password="true" />
-    
-        <CheckBox android:id="@+id/show_password_checkbox"
-                style="?android:attr/textAppearanceSmallInverse"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:text="@string/wifi_show_password" />
-                
-    </LinearLayout>
-
-</ScrollView>    
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index d7be2ae..4ac663b 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -263,45 +263,6 @@
         <item>Excellent</item>
     </string-array>
 
-    <!-- Match this with code. --> <skip />
-    <!-- Wi-Fi settings.  The type of security a Wi-Fi network has.  The user can choose this when he adds a manual network, or configures an existing network. -->
-    <string-array name="wifi_security_entries">
-        <!-- Let the phone figure out the security type auutomatically. -->
-        <item>Auto</item>
-        <!-- The Wi-Fi network does not have any security. -->
-        <item>None</item>
-        <!-- Do not translate. The Wi-Fi network has WEP security. -->
-        <item>WEP</item>
-        <!-- The Wi-Fi network has WPA personal security. WPA Personal is a tech term, and might be better left untranslated? -->
-        <item>WPA/WPA2 PSK</item>
-        <!-- The Wi-Fi network has WPA EAP extensible authentication protocol. -->
-        <item>802.1x Enterprise</item>
-    </string-array>
-
-    <!-- Match this with code. --> <skip />
-    <!-- Wi-Fi settings.  The type of security a Wi-Fi network has.  The user can choose this when he adds a manual network, or configures an existing network. -->
-    <string-array name="wifi_security_without_auto_entries">
-        <!-- The Wi-Fi network does not have any security. -->
-        <item>None</item>
-        <!-- Do not translate. The Wi-Fi network has WEP security. -->
-        <item>WEP</item>
-        <!-- The Wi-Fi network has WPA personal security. WPA Personal is a tech term, and might be better left untranslated? -->
-        <item>WPA/WPA2 PSK</item>
-        <!-- The Wi-Fi network has WPA enterprise security. WPA Enterprise is a tech term, and might be better left untranslated? -->
-        <item>802.1x Enterprise</item>
-    </string-array>
-
-    <!-- Match this with code. --> <skip />
-    <!-- Wi-Fi settings.  Presented as a list dialog to the user.  He chooses the type of WEP key he entered. -->
-    <string-array name="wifi_wep_type">
-        <!-- This means the phone should figure out the type automatically the best it can. -->
-        <item>Auto</item>
-        <!-- Do not translate. -->
-        <item>WEP ASCII</item>
-        <!-- WEP key that is in hexadecimal. -->
-        <item>WEP hexadecimal</item>
-    </string-array>
-
     <!-- Wi-Fi settings. Presented as a list dialog to the user to choose the Wi-Fi sleep policy. -->
     <string-array name="wifi_sleep_policy_entries">
         <!-- Wi-Fi should go to sleep when the screen turns off. -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9c38934..d145841 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -790,133 +790,6 @@
     <!-- Label for the netmask of the network -->
     <string name="wifi_netmask">Netmask</string>
 
-    <!-- Button caption to forget a wifi network -->
-    <string name="forget_network">Forget</string>
-    <!-- Label for link speed (wifi) -->
-    <string name="wifi_link_speed">Speed</string>
-    <!-- Verbose wifi signal strength.  This is the best out of 4 levels. -->
-    <string name="wifi_signal_3">Excellent</string>
-    <!-- Verbose wifi signal strength.  This is the 2nd best out of 4 levels. -->
-    <string name="wifi_signal_2">Good</string>
-    <!-- Verbose wifi signal strength.  This is the 3rd best out of 4 levels. -->
-    <string name="wifi_signal_1">Fair</string>
-    <!-- Verbose wifi signal strength.  This is the worst out of 4 levels. -->
-    <string name="wifi_signal_0">Poor</string>
-    <!-- Label for the security of a wifi network -->
-    <string name="security">Security</string>
-    <!-- Value for the wifi security.  This means no encryption. -->
-    <string name="wifi_security_open">Open</string>
-    <!-- Value for the wifi security -->
-    <string name="wifi_security_wep">WEP</string>
-    <!-- Value for the wifi security -->
-    <string name="wifi_security_psk">WPA/WPA2 PSK</string>
-    <!-- Value for the wifi security -->
-    <string name="wifi_security_eap">Enterprise(802.1x)</string>
-    <!-- Value for the wifi security -->
-
-    <!-- Value for the wifi security when it is unknown -->
-    <string name="wifi_security_unknown">Unknown</string>
-    <!-- Verbose security type of a wifi network.  Open means no security. Capitalized by app. -->
-    <string name="wifi_security_verbose_open">open network</string>
-    <!-- Verbose security type of a wifi network.  Capitalized by app. -->
-    <string name="wifi_security_verbose_wep">secured with WEP</string>
-    <!-- Verbose security type of a wifi network.  Capitalized by app. -->
-    <string name="wifi_security_verbose_psk">secured with WPA/WPA2 PSK</string>
-    <!-- Verbose security type of a wifi network.  Capitalized by app. -->
-    <string name="wifi_security_verbose_eap">secured with 802.1x EAP</string>
-    <!-- Label for the signal strength -->
-    <string name="signal">Signal strength</string>
-    <!-- Error message when Wi-Fi can't start -->
-    <string name="error_starting">Unable to start Wi-Fi</string>
-    <!-- Error message when Wi-Fi can't stop -->
-    <string name="error_stopping">Unable to stop Wi-Fi</string>
-    <!-- Error message when Wi-Fi can't scan for networks -->
-    <string name="error_scanning">Unable to scan for networks</string>
-    <!-- Error message when Wi-Fi can't connect -->
-    <string name="error_connecting">Unable to connect to the network</string>
-    <!-- Error message when Wi-Fi can't save the network -->
-    <string name="error_saving">Unable to save the network</string>
-    <!-- Button label to connect to a wifi network-->
-    <string name="connect">Connect</string>
-    <!-- Dialog title for when the user is trying to connect to a particular network-->
-    <string name="connect_to_blank"><xliff:g id="network_name">%1$s</xliff:g></string>
-    <!-- Caption for the eap method -->
-    <string name="please_select_eap">EAP method</string>
-    <!-- Caption for the phase2 -->
-    <string name="please_select_phase2">Phase 2 authentication</string>
-    <!-- Caption for the identity -->
-    <string name="please_type_identity">Identity</string>
-    <!-- Caption for the anonymous_identity -->
-    <string name="please_type_anonymous_identity">Anonymous identity</string>
-    <!-- Caption for the client_certificate -->
-    <string name="please_select_client_certificate">Client certificate</string>
-    <!-- Caption for the ca certificate -->
-    <string name="please_select_ca_certificate">CA certificate</string>
-    <!-- Caption for the wireless password -->
-    <string name="please_type_passphrase">Wireless password</string>
-    <!--Wi-Fi settings screen, connect to network dialog box, field label and hint text -->
-    <string name="please_type_hex_key">WEP hex key (0-9, A-F)</string>
-    <!--Wi-Fi settings screen menu option -->
-    <string name="scan_wifi">Scan</string>
-    <!-- Wifi network summary when not in nearby. -->
-    <string name="summary_not_in_range">Not in range</string>
-    <!-- Wifi network summary when the network is configured previously, capitalized by app -->
-    <string name="summary_remembered">remembered</string>
-    <!-- Wifi network summary when there was an error connecting -->
-    <string name="summary_connection_failed">Connection unsuccessful, touch to try again</string>
-    <!-- Caption for entering the SSID of a wifi network -->
-    <string name="wifi_type_ssid">Network SSID</string>
-    <!-- Button caption to save a configuration wifi -->
-    <string name="wifi_save_config">Save</string>
-    <!-- An edit field's grayed out value when it has not been modified -->
-    <string name="wifi_password_unchanged">(unchanged)</string>
-    <!-- Action message to add a wifi network -->
-    <string name="wifi_add_other_network">Add Wi-Fi network</string>
-    <!-- This dialog will use the error_title as the title. -->
-    <string name="wifi_password_incorrect_error">The network password you typed is not correct. Please try again.</string>
-    <!-- Generic error message -->
-    <string name="wifi_generic_connection_error">There is a problem connecting to the network. Please try again.</string>
-    <!--Wi-Fi settings screen, network context menu item -->
-    <string name="wifi_context_menu_connect">Connect to network</string>
-    <!--Wi-Fi settings screen, network context menu item -->
-    <string name="wifi_context_menu_forget">Forget network</string>
-    <!--Wi-Fi settings screen, network context menu item -->
-    <string name="wifi_context_menu_change_password">Change password</string>
-
-    <!-- Status message of Wi-Fi when it is scanning -->
-    <string name="fragment_status_scanning">Scanning\u2026</string>
-    <!-- Status message of Wi-Fi when it is connecting to a particular network -->
-    <string name="fragment_status_connecting">Connecting to <xliff:g id="network_name">%1$s</xliff:g>\u2026</string>
-    <!-- Status message of Wi-Fi when it is authenticating with a network -->
-    <string name="fragment_status_authenticating">Authenticating with <xliff:g id="network_name">%1$s</xliff:g>\u2026</string>
-    <!-- Status message of Wi-Fi when it is obtaining the IP address from a netwrok -->
-    <string name="fragment_status_obtaining_ip">Obtaining IP address from <xliff:g id="network_name">%1$s</xliff:g>\u2026</string>
-    <!-- Status message of Wi-Fi when it is connect to a network -->
-    <string name="fragment_status_connected">Connected to <xliff:g id="network_name">%1$s</xliff:g></string>
-    <!-- Status message of Wi-Fi when it is disconnecting from a network -->
-    <string name="fragment_status_disconnecting">Disconnecting from <xliff:g id="network_name">%1$s</xliff:g>\u2026</string>
-    <!-- Status message of Wi-Fi when it is disconnected from a network-->
-    <string name="fragment_status_disconnected">Disconnected</string>
-    <!-- Status message of Wi-Fi when it is a failure (connection) -->
-    <string name="fragment_status_failed">Unsuccessful</string>
-
-    <!-- Status message of Wi-Fi when it is scanning -->
-    <string name="status_scanning">Scanning\u2026</string>
-    <!-- Status message of Wi-Fi when it is connecting (but the network is not known right now) -->
-    <string name="status_connecting">Connecting\u2026</string>
-    <!-- Status message of Wi-Fi when it is authenticating (but the network is not known right now) -->
-    <string name="status_authenticating">Authenticating\u2026</string>
-    <!--Wi-Fi settings screen, summary text for network when connecting -->
-    <string name="status_obtaining_ip">Obtaining address\u2026</string>
-    <!--Wi-Fi settings screen, summary text for network when connected -->
-    <string name="status_connected">Connected</string>
-    <!-- Status message of Wi-Fi when it is disconnecting (but the network is not known right now) -->
-    <string name="status_disconnecting">Disconnecting\u2026</string>
-    <!-- Status message of Wi-Fi when it is disconnected (but the network is not known right now) -->
-    <string name="status_disconnected">Disconnected</string>
-    <!-- Status message of Wi-Fi when it is a failure (but the network is not known right now) -->
-    <string name="status_failed">Unsuccessful</string>
-
     <!-- Do not translate. Used for diagnostic screens, precise translation is not necessary
          Wi-Fi Testing on the diagnostic screen-->
     <string name="testing_wifi_info" translatable="false">Wifi information</string>
@@ -1383,6 +1256,27 @@
     <!-- Main settings screen, Call settings summary for item to go into call settings -->
     <string name="call_settings_summary">Set up voicemail, call forwarding, call waiting, caller ID</string>
 
+    <!-- Tethering controls, item title to go into the tethering settings -->
+    <string name="tether_settings_title">Tethering settings</string>
+    <!-- Tethering controls, the item summary for the user to go into the tethering settings -->
+    <string name="tether_settings_summary">Set up and manage tethering</string>
+
+    <!-- Title of the screen for adjusting tethering settings -->
+    <string name="tether_screen_title">Tethering settings</string>
+
+    <!-- Tethering notification toggle - controls whether a notification will appear when a tetherable connection becomes available -->
+    <string name="enable_tether_notice_checkbox">Notifications</string>
+    <!-- Tethering notification summary explains the notification toggle -->
+    <string name="enable_tether_notice_checkbox_summary">Show a notification when USB tethering is available</string>
+    <!-- USB Tethering options -->
+    <string name="usb_tethering_button_text">USB tethering</string>
+    <!-- USB available subtext - shown when USB is connected but not currently being tethered -->
+    <string name="usb_tethering_available_subtext">USB connected, select to tether</string>
+    <!-- USB tethered subtext - shown when USB is connected and being tethered -->
+    <string name="usb_tethering_active_subtext">Connected, select to disconnect</string>
+    <!-- USB unavailable subtext - shown when USB is not connected -->
+    <string name="usb_tethering_unavailable_subtext">USB not connected</string>
+
     <!-- Wireless controls, item title to go into the network settings -->
     <string name="network_settings_title">Mobile networks</string>
     <!-- Wireless controls, the item summary for the user to go into the network settings -->
@@ -2378,16 +2272,23 @@
     <string name="privacy_settings_title">Privacy settings</string>
     <!-- Location settings section title -->
     <string name="location_section_title">Location</string>
-    <!-- Settings section title -->
-    <string name="settings_section_title">Settings</string>
+    <!-- Backup section title -->
+    <string name="backup_section_title">Backup and Restore</string>
     <!-- Personal data section title -->
     <string name="personal_data_section_title">Personal data</string>
     <!-- Backup settings menu title -->
     <string name="backup_settings_title">Back up my settings</string>
+    <!-- Auto-restore menu title -->
+    <string name="auto_restore_title">Automatic restore</string>
+    <!-- Summary text of the "automatic restore" setting -->
+    <string name="auto_restore_summary">Restore applications\' data from backup when they are installed</string>
     <!-- Dialog title for confirmation to erase backup data from server -->
-    <string name="backup_erase_dialog_title">Settings backup</string>
+    <string name="backup_erase_dialog_title">Backup</string>
     <!-- Dialog title for confirmation to erase backup data from server -->
-    <string name="backup_erase_dialog_message">Are you sure you want to stop backing up your settings and erase all copies on Google servers?</string>
+    <string name="backup_erase_dialog_message">Are you sure you want to stop backing up your settings and application data and erase all copies on Google servers?</string>
+
+    <!-- Do not translate. Obsolete Settings section title - STOPSHIP remove before shipping -->
+    <string name="settings_section_title">Settings</string>
 
     <!-- Device admin settings screen --><skip/>
     <!-- Device admin settings activity title -->
diff --git a/res/xml/privacy_settings.xml b/res/xml/privacy_settings.xml
index 92955a5..9a440cc 100644
--- a/res/xml/privacy_settings.xml
+++ b/res/xml/privacy_settings.xml
@@ -26,13 +26,18 @@
                 android:summary="@string/use_location_summary"/>
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="settings_category"
-            android:title="@string/settings_section_title">
+    <PreferenceCategory android:key="backup_category"
+            android:title="@string/backup_section_title">
         <!-- Backup settings -->
         <CheckBoxPreference
                 android:key="backup_settings"
                 android:title="@string/backup_settings_title"
                 android:persistent="false" />
+        <CheckBoxPreference
+                android:key="auto_restore"
+                android:title="@string/auto_restore_title"
+                android:summary="@string/auto_restore_summary"
+                android:persistent="false" />
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/res/xml/tether_prefs.xml b/res/xml/tether_prefs.xml
new file mode 100644
index 0000000..321129f
--- /dev/null
+++ b/res/xml/tether_prefs.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+        android:title="@string/tether_screen_title">
+
+    <PreferenceScreen
+        android:key="usb_tether_settings"
+        android:title="@string/usb_tethering_button_text"
+        android:widgetLayout="@*android:layout/preference_dialog" >
+        <intent
+            android:action="android.intent.action.MAIN"
+            android:targetPackage="android"
+            android:targetClass="com.android.internal.app.TetherActivity" />
+    </PreferenceScreen>
+
+    <CheckBoxPreference
+        android:key="enable_tether_notice"
+        android:title="@string/enable_tether_notice_checkbox"
+        android:summary="@string/enable_tether_notice_checkbox_summary"/>
+
+</PreferenceScreen>
diff --git a/res/xml/wifi_access_points.xml b/res/xml/wifi_access_points.xml
index 281093c..48104dd 100644
--- a/res/xml/wifi_access_points.xml
+++ b/res/xml/wifi_access_points.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -23,8 +23,8 @@
             android:persistent="false" />
 
     <Preference
-            android:key="add_other_network"
-            android:title="@string/wifi_add_other_network"
+            android:key="add_network"
+            android:title="@string/wifi_add_network"
             android:persistent="false" />
 
 </PreferenceScreen>
diff --git a/res/xml/wifi_access_points2.xml b/res/xml/wifi_access_points2.xml
deleted file mode 100644
index 48104dd..0000000
--- a/res/xml/wifi_access_points2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        android:title="@string/wifi_settings_category">
-
-    <com.android.settings.ProgressCategory
-            android:key="access_points"
-            android:title="@string/wifi_access_points"
-            android:persistent="false" />
-
-    <Preference
-            android:key="add_network"
-            android:title="@string/wifi_add_network"
-            android:persistent="false" />
-
-</PreferenceScreen>
diff --git a/res/xml/wifi_settings.xml b/res/xml/wifi_settings.xml
index 8a76674..35f1173 100644
--- a/res/xml/wifi_settings.xml
+++ b/res/xml/wifi_settings.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -18,28 +18,28 @@
         android:title="@string/wifi_settings_category">
 
     <CheckBoxPreference
-            android:key="wifi_enabled"
+            android:key="enable_wifi"
             android:title="@string/wifi"
             android:summary="@string/wifi_quick_toggle_summary"
             android:persistent="false" />
 
     <CheckBoxPreference
-            android:key="open_network_notifications_enabled"
-            android:dependency="wifi_enabled"
+            android:key="notify_open_networks"
+            android:dependency="enable_wifi"
             android:title="@string/wifi_notify_open_networks"
             android:summary="@string/wifi_notify_open_networks_summary"
             android:persistent="false" />
 
     <com.android.settings.ProgressCategory
             android:key="access_points"
-            android:dependency="wifi_enabled"
+            android:dependency="enable_wifi"
             android:title="@string/wifi_access_points"
             android:persistent="false" />
 
     <Preference
-            android:key="add_other_network"
-            android:dependency="wifi_enabled"
-            android:title="@string/wifi_add_other_network"
+            android:key="add_network"
+            android:dependency="enable_wifi"
+            android:title="@string/wifi_add_network"
             android:persistent="false" />
 
 </PreferenceScreen>
diff --git a/res/xml/wifi_settings2.xml b/res/xml/wifi_settings2.xml
deleted file mode 100644
index 35f1173..0000000
--- a/res/xml/wifi_settings2.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        android:title="@string/wifi_settings_category">
-
-    <CheckBoxPreference
-            android:key="enable_wifi"
-            android:title="@string/wifi"
-            android:summary="@string/wifi_quick_toggle_summary"
-            android:persistent="false" />
-
-    <CheckBoxPreference
-            android:key="notify_open_networks"
-            android:dependency="enable_wifi"
-            android:title="@string/wifi_notify_open_networks"
-            android:summary="@string/wifi_notify_open_networks_summary"
-            android:persistent="false" />
-
-    <com.android.settings.ProgressCategory
-            android:key="access_points"
-            android:dependency="enable_wifi"
-            android:title="@string/wifi_access_points"
-            android:persistent="false" />
-
-    <Preference
-            android:key="add_network"
-            android:dependency="enable_wifi"
-            android:title="@string/wifi_add_network"
-            android:persistent="false" />
-
-</PreferenceScreen>
diff --git a/res/xml/wireless_settings.xml b/res/xml/wireless_settings.xml
index d3c593f..9977505 100644
--- a/res/xml/wireless_settings.xml
+++ b/res/xml/wireless_settings.xml
@@ -37,7 +37,7 @@
         <intent
             android:action="android.intent.action.MAIN"
             android:targetPackage="com.android.settings"
-            android:targetClass="com.android.settings.wifi.WifiSettings2" />
+            android:targetClass="com.android.settings.wifi.WifiSettings" />
     </PreferenceScreen>
 
     <CheckBoxPreference
@@ -57,6 +57,15 @@
     </PreferenceScreen>
 
     <PreferenceScreen
+        android:title="@string/tether_settings_title"
+        android:summary="@string/tether_settings_summary">
+        <intent
+            android:action="android.intent.action.MAIN"
+            android:targetPackage="com.android.settings"
+            android:targetClass="com.android.settings.TetherSettings" />
+    </PreferenceScreen>
+
+    <PreferenceScreen
         android:key="vpn_settings"
         android:title="@string/vpn_settings_title"
         android:summary="@string/vpn_settings_summary" >
diff --git a/src/com/android/settings/ManageApplications.java b/src/com/android/settings/ManageApplications.java
index 96459c1..0525dab 100644
--- a/src/com/android/settings/ManageApplications.java
+++ b/src/com/android/settings/ManageApplications.java
@@ -1557,17 +1557,39 @@
              filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
              filter.addDataScheme("package");
              ManageApplications.this.registerReceiver(this, filter);
+             // Register for events related to sdcard installation.
+             IntentFilter sdFilter = new IntentFilter();
+             sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_AVAILABLE);
+             sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE);
+             ManageApplications.this.registerReceiver(this, sdFilter);
          }
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String actionStr = intent.getAction();
-            Uri data = intent.getData();
-            String pkgName = data.getEncodedSchemeSpecificPart();
-            if (localLOGV) Log.i(TAG, "action:"+actionStr+", for package:"+pkgName);
-            updatePackageList(actionStr, pkgName);
-        }
+         @Override
+         public void onReceive(Context context, Intent intent) {
+             // technically we dont have to invoke handler since onReceive is invoked on
+             // the main thread but doing it here for better clarity
+             String actionStr = intent.getAction();
+             if (Intent.ACTION_PACKAGE_ADDED.equals(actionStr) ||
+                     Intent.ACTION_PACKAGE_REMOVED.equals(actionStr)) {
+                 Uri data = intent.getData();
+                 String pkgName = data.getEncodedSchemeSpecificPart();
+                 updatePackageList(actionStr, pkgName);
+             } else if (Intent.ACTION_MEDIA_RESOURCES_AVAILABLE.equals(actionStr) ||
+                     Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE.equals(actionStr)) {
+                 boolean available = Intent.ACTION_MEDIA_RESOURCES_AVAILABLE.equals(actionStr);
+                 String pkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                 if (pkgList == null || pkgList.length == 0) {
+                     // Ignore
+                     return;
+                 }
+                 String msg = available ? Intent.ACTION_PACKAGE_ADDED :
+                     Intent.ACTION_PACKAGE_REMOVED;
+                 for (String pkgName : pkgList) {
+                     updatePackageList(msg, pkgName);
+                 }
+             }
+         }
     }
-    
+
     private void updatePackageList(String actionStr, String pkgName) {
         // technically we dont have to invoke handler since onReceive is invoked on
         // the main thread but doing it here for better clarity
diff --git a/src/com/android/settings/PrivacySettings.java b/src/com/android/settings/PrivacySettings.java
index 611af04..a92f09b 100644
--- a/src/com/android/settings/PrivacySettings.java
+++ b/src/com/android/settings/PrivacySettings.java
@@ -47,12 +47,14 @@
     // Vendor specific
     private static final String GSETTINGS_PROVIDER = "com.google.settings";
     private static final String LOCATION_CATEGORY = "location_category";
-    private static final String SETTINGS_CATEGORY = "settings_category";
+    private static final String BACKUP_CATEGORY = "backup_category";
     private static final String USE_LOCATION = "use_location";
     private static final String BACKUP_SETTINGS = "backup_settings";
+    private static final String AUTO_RESTORE = "auto_restore";
     private static final String KEY_DONE_USE_LOCATION = "doneLocation";
     private CheckBoxPreference mUseLocation;
     private CheckBoxPreference mBackup;
+    private CheckBoxPreference mAutoRestore;
     private boolean mOkClicked;
     private Dialog mConfirmDialog;
 
@@ -64,14 +66,16 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.privacy_settings);
+        final PreferenceScreen screen = getPreferenceScreen();
 
-        mUseLocation = (CheckBoxPreference) getPreferenceScreen().findPreference(USE_LOCATION);
-        mBackup = (CheckBoxPreference) getPreferenceScreen().findPreference(BACKUP_SETTINGS);
+        mUseLocation = (CheckBoxPreference) screen.findPreference(USE_LOCATION);
+        mBackup = (CheckBoxPreference) screen.findPreference(BACKUP_SETTINGS);
+        mAutoRestore = (CheckBoxPreference) screen.findPreference(AUTO_RESTORE);
 
         // Vendor specific
         if (getPackageManager().resolveContentProvider(GSETTINGS_PROVIDER, 0) == null) {
-            getPreferenceScreen().removePreference(findPreference(LOCATION_CATEGORY));
-            getPreferenceScreen().removePreference(findPreference(SETTINGS_CATEGORY));
+            screen.removePreference(findPreference(LOCATION_CATEGORY));
+            screen.removePreference(findPreference(BACKUP_CATEGORY));
         }
         updateToggles();
 
@@ -118,6 +122,18 @@
             } else {
                 setBackupEnabled(true);
             }
+        } else if (preference == mAutoRestore) {
+            IBackupManager bm = IBackupManager.Stub.asInterface(
+                    ServiceManager.getService(Context.BACKUP_SERVICE));
+            if (bm != null) {
+                // TODO: disable via the backup manager interface
+                boolean curState = mAutoRestore.isChecked();
+                try {
+                    bm.setAutoRestore(curState);
+                } catch (RemoteException e) {
+                    mAutoRestore.setChecked(!curState);
+                }
+            }
         }
 
         return false;
@@ -171,8 +187,14 @@
         ContentResolver res = getContentResolver();
         mUseLocation.setChecked(Settings.Secure.getInt(res,
                 Settings.Secure.USE_LOCATION_FOR_SERVICES, 2) == 1);
-        mBackup.setChecked(Settings.Secure.getInt(res,
-                Settings.Secure.BACKUP_ENABLED, 0) == 1);
+
+        final boolean backupEnabled = Settings.Secure.getInt(res,
+                Settings.Secure.BACKUP_ENABLED, 0) == 1;
+        mBackup.setChecked(backupEnabled);
+
+        mAutoRestore.setChecked(Settings.Secure.getInt(res,
+                Settings.Secure.BACKUP_AUTO_RESTORE, 0) == 1);
+        mAutoRestore.setEnabled(backupEnabled);
     }
 
     private void updateUseLocation() {
@@ -196,6 +218,7 @@
                 mUseLocation.setChecked(false);
             } else if (mDialogType == DIALOG_ERASE_BACKUP) {
                 mBackup.setChecked(true);
+                mAutoRestore.setEnabled(true);
             }
         }
         updateUseLocation();
@@ -248,9 +271,11 @@
                 bm.setBackupEnabled(enable);
             } catch (RemoteException e) {
                 mBackup.setChecked(!enable);
+                mAutoRestore.setEnabled(!enable);
                 return;
             }
         }
         mBackup.setChecked(enable);
+        mAutoRestore.setEnabled(enable);
     }
 }
diff --git a/src/com/android/settings/RingerVolumePreference.java b/src/com/android/settings/RingerVolumePreference.java
index a546818..ddadbb6 100644
--- a/src/com/android/settings/RingerVolumePreference.java
+++ b/src/com/android/settings/RingerVolumePreference.java
@@ -66,14 +66,7 @@
     @Override
     protected void onBindDialogView(View view) {
         super.onBindDialogView(view);
-     
-        mNotificationsUseRingVolumeCheckbox =
-                (CheckBox) view.findViewById(R.id.same_notification_volume);
-        mNotificationsUseRingVolumeCheckbox.setOnCheckedChangeListener(this);
-        mNotificationsUseRingVolumeCheckbox.setChecked(Settings.System.getInt(
-                getContext().getContentResolver(),
-                Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1);
-      
+
         for (int i = 0; i < SEEKBAR_ID.length; i++) {
             SeekBar seekBar = (SeekBar) view.findViewById(SEEKBAR_ID[i]);
             mSeekBarVolumizer[i] = new SeekBarVolumizer(getContext(), seekBar,
@@ -81,6 +74,12 @@
         }
 
         mNotificationVolumeTitle = (TextView) view.findViewById(R.id.notification_volume_title);
+        mNotificationsUseRingVolumeCheckbox =
+                (CheckBox) view.findViewById(R.id.same_notification_volume);
+        mNotificationsUseRingVolumeCheckbox.setOnCheckedChangeListener(this);
+        mNotificationsUseRingVolumeCheckbox.setChecked(Settings.System.getInt(
+                getContext().getContentResolver(),
+                Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1);
         setNotificationVolumeVisibility(!mNotificationsUseRingVolumeCheckbox.isChecked());
     }
 
diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java
new file mode 100644
index 0000000..0a63de3
--- /dev/null
+++ b/src/com/android/settings/TetherSettings.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings;
+
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.util.Log;
+
+/*
+ * Displays preferences for Tethering.
+ */
+public class TetherSettings extends PreferenceActivity {
+
+    private static final String ENABLE_TETHER_NOTICE = "enable_tether_notice";
+    private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
+
+    private CheckBoxPreference mEnableTetherNotice;
+    private PreferenceScreen mUsbTether;
+
+    private BroadcastReceiver mTetherChangeReceiver;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.tether_prefs);
+
+        mEnableTetherNotice = (CheckBoxPreference) findPreference(ENABLE_TETHER_NOTICE);
+        mUsbTether = (PreferenceScreen) findPreference(USB_TETHER_SETTINGS);
+    }
+
+    private class TetherChangeReceiver extends BroadcastReceiver {
+        public void onReceive(Context content, Intent intent) {
+            updateState(intent.getIntExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER_COUNT,0)>0,
+                    intent.getIntExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER_COUNT,0)>0);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mEnableTetherNotice.setChecked(Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.TETHER_NOTIFY, 0) != 0);
+
+        IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
+        mTetherChangeReceiver = new TetherChangeReceiver();
+        registerReceiver(mTetherChangeReceiver, filter);
+
+        ConnectivityManager cm =
+                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+        updateState(cm.getTetherableIfaces().length>0, cm.getTetheredIfaces().length>0);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        unregisterReceiver(mTetherChangeReceiver);
+        mTetherChangeReceiver = null;
+    }
+
+    private void updateState(boolean isAvailable, boolean isTethered) {
+        if (isTethered) {
+            mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
+            mUsbTether.setEnabled(true);
+        } else if (isAvailable) {
+            mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
+            mUsbTether.setEnabled(true);
+        } else {
+            mUsbTether.setSummary(R.string.usb_tethering_unavailable_subtext);
+            mUsbTether.setEnabled(false);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+
+        if (preference == mEnableTetherNotice) {
+            boolean newState = mEnableTetherNotice.isChecked();
+            Settings.Secure.putInt(getContentResolver(),
+                    Settings.Secure.TETHER_NOTIFY, newState ? 1 : 0);
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/src/com/android/settings/TextToSpeechSettings.java b/src/com/android/settings/TextToSpeechSettings.java
index 838d978..1a97fbf 100644
--- a/src/com/android/settings/TextToSpeechSettings.java
+++ b/src/com/android/settings/TextToSpeechSettings.java
@@ -425,7 +425,9 @@
         // update the demo string
         mDemoStringIndex = mDefaultLocPref.findIndexOfValue(mDefaultLanguage + LOCALE_DELIMITER
                 + mDefaultCountry);
-        mDefaultLocPref.setValueIndex(mDemoStringIndex);
+        if (mDemoStringIndex > -1){
+            mDefaultLocPref.setValueIndex(mDemoStringIndex);
+        }
     }
 
     /**
diff --git a/src/com/android/settings/wifi/AccessPointDialog.java b/src/com/android/settings/wifi/AccessPointDialog.java
deleted file mode 100644
index bf9a471..0000000
--- a/src/com/android/settings/wifi/AccessPointDialog.java
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi;
-
-import com.android.settings.R;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.security.Credentials;
-import android.security.KeyStore;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.format.Formatter;
-import android.text.method.PasswordTransformationMethod;
-import android.text.method.TransformationMethod;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.TableLayout;
-import android.widget.TextView;
-
-public class AccessPointDialog extends AlertDialog implements DialogInterface.OnClickListener,
-        AdapterView.OnItemSelectedListener, View.OnClickListener {
-
-    private static final String TAG = "AccessPointDialog";
-    private static final String INSTANCE_KEY_ACCESS_POINT_STATE =
-            "com.android.settings.wifi.AccessPointDialog:accessPointState";
-    private static final String INSTANCE_KEY_MODE =
-            "com.android.settings.wifi.AccessPointDialog:mode";
-    private static final String INSTANCE_KEY_CUSTOM_TITLE =
-            "com.android.settings.wifi.AccessPointDialog:customTitle";
-    private static final String INSTANCE_KEY_AUTO_SECURITY_ALLOWED =
-            "com.android.settings.wifi.AccessPointDialog:autoSecurityAllowed";
-    
-    private static final int POSITIVE_BUTTON = BUTTON1;
-    private static final int NEGATIVE_BUTTON = BUTTON2;
-    private static final int NEUTRAL_BUTTON = BUTTON3;
-    
-    /** The dialog should show info connectivity functionality */
-    public static final int MODE_INFO = 0;
-    /** The dialog should configure the detailed AP properties */
-    public static final int MODE_CONFIGURE = 1;
-    /** The dialog should have the password field and connect/cancel */
-    public static final int MODE_RETRY_PASSWORD = 2;
-    
-    // These should be matched with the XML. Both arrays in XML depend on this
-    // ordering!
-    private static final int SECURITY_AUTO = 0;
-    private static final int SECURITY_NONE = 1;
-    private static final int SECURITY_WEP = 2;
-    private static final int SECURITY_PSK = 3;
-    private static final int SECURITY_EAP = 4;
-
-    private static final int[] WEP_TYPE_VALUES = {
-            AccessPointState.WEP_PASSWORD_AUTO, AccessPointState.WEP_PASSWORD_ASCII,
-            AccessPointState.WEP_PASSWORD_HEX
-    };
-    private static final String NOT_APPLICABLE = "N/A";
-    private static final String KEYSTORE_HEADER = "keystore://";
-
-    // Button positions, default to impossible values
-    private int mConnectButtonPos = Integer.MAX_VALUE; 
-    private int mForgetButtonPos = Integer.MAX_VALUE;
-    private int mSaveButtonPos = Integer.MAX_VALUE;
-
-    // Client configurable items. Generally, these should be saved in instance state
-    private int mMode = MODE_INFO;
-    private boolean mAutoSecurityAllowed = true;
-    private CharSequence mCustomTitle;
-    // This does not need to be saved in instance state.
-    private WifiLayer mWifiLayer;
-    private AccessPointState mState;
-    
-    // General views
-    private View mView;
-    private View mEnterpriseView;
-    private TextView mPasswordText;
-    private EditText mPasswordEdit;
-    private CheckBox mShowPasswordCheckBox;
-
-    // Enterprise fields
-    private TextView mEapText;
-    private Spinner mEapSpinner;
-    private TextView mPhase2Text;
-    private Spinner mPhase2Spinner;
-    private TextView mIdentityText;
-    private EditText mIdentityEdit;
-    private TextView mAnonymousIdentityText;
-    private EditText mAnonymousIdentityEdit;
-    private TextView mCaCertText;
-    private Spinner mCaCertSpinner;
-    private TextView mClientCertText;
-    private Spinner mClientCertSpinner;
-    private EditText[] mEnterpriseTextFields;
-
-    
-    // Info-specific views
-    private ViewGroup mTable;
-    
-    // Configure-specific views
-    private EditText mSsidEdit;
-    private TextView mSsidText;
-    private TextView mSecurityText;
-    private Spinner mSecuritySpinner;
-    private Spinner mWepTypeSpinner;
-    private KeyStore mKeyStore;
-
-    public AccessPointDialog(Context context, WifiLayer wifiLayer) {
-        super(context);
-
-        mWifiLayer = wifiLayer;
-        mKeyStore = KeyStore.getInstance();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        onLayout();
-        onFill();
-
-        super.onCreate(savedInstanceState);
-
-        if (mMode == MODE_CONFIGURE) {
-            Button saveButton = getButton(mSaveButtonPos);
-            saveButton.setEnabled(false);
-            saveButton.setFocusable(false);
-        }
-    }
-
-    private final TextWatcher mSsidEditorWatcher = new TextWatcher() {
-        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-        }
-        public void onTextChanged(CharSequence s, int start, int before, int count) {
-            if (mSaveButtonPos != Integer.MAX_VALUE) {
-                boolean enable = true;
-                if (s.length() == 0) {
-                    enable = false;
-                }
-                Button saveButton = getButton(mSaveButtonPos);
-                saveButton.setEnabled(enable);
-                saveButton.setFocusable(enable);
-            }
-        }
-        public void afterTextChanged(Editable s) {
-        }
-    };
-
-    @Override
-    public void onRestoreInstanceState(Bundle savedInstanceState) {
-        // Set to a class loader that can find AccessPointState
-        savedInstanceState.setClassLoader(getClass().getClassLoader());
-        
-        mState = savedInstanceState.getParcelable(INSTANCE_KEY_ACCESS_POINT_STATE);
-        mState.setContext(getContext());
-        
-        mMode = savedInstanceState.getInt(INSTANCE_KEY_MODE, mMode);
-        mAutoSecurityAllowed = savedInstanceState.getBoolean(INSTANCE_KEY_AUTO_SECURITY_ALLOWED,
-                mAutoSecurityAllowed);
-        mCustomTitle = savedInstanceState.getCharSequence(INSTANCE_KEY_CUSTOM_TITLE);
-        if (mCustomTitle != null) {
-            setTitle(mCustomTitle);
-        }
-
-        // This is called last since it depends on the above values 
-        super.onRestoreInstanceState(savedInstanceState);
-        
-        if (mShowPasswordCheckBox != null) {
-            // Restore the show-password-state on the edit text
-            setShowPassword(mShowPasswordCheckBox.isChecked());
-        }
-    }
-
-    @Override
-    public Bundle onSaveInstanceState() {
-        Bundle bundle = super.onSaveInstanceState();
-        bundle.putParcelable(INSTANCE_KEY_ACCESS_POINT_STATE, mState);
-        bundle.putInt(INSTANCE_KEY_MODE, mMode);
-        bundle.putBoolean(INSTANCE_KEY_AUTO_SECURITY_ALLOWED, mAutoSecurityAllowed);
-        bundle.putCharSequence(INSTANCE_KEY_CUSTOM_TITLE, mCustomTitle);
-        return bundle;
-    }
-
-    /**
-     * Sets state to show in this dialog.
-     * 
-     * @param state The state.
-     */
-    public void setState(AccessPointState state) {
-        mState = state;
-    }
-
-    /**
-     * Sets the dialog mode.
-     * @param mode One of {@link #MODE_CONFIGURE} or {@link #MODE_INFO}
-     */
-    public void setMode(int mode) {
-        mMode = mode;
-    }
-
-    public void setAutoSecurityAllowed(boolean autoSecurityAllowed) {
-        mAutoSecurityAllowed = autoSecurityAllowed;
-    }
-
-    @Override
-    public void setTitle(CharSequence title) {
-        super.setTitle(title);
-        mCustomTitle = title;
-    }
-
-    @Override
-    public void setTitle(int titleId) {
-        setTitle(getContext().getString(titleId));
-    }
-
-    public void enableEnterpriseFields() {
-        setEnterpriseFieldsVisible(true);
-        updateCertificateSelection();
-        setGenericPasswordVisible(true);
-        // Both WPA and WPA2 show the same caption, so either is ok
-        updatePasswordCaption(AccessPointState.PSK);
-    }
-
-    /** Called after flags are set, the dialog's layout/etc should be set up here */
-    private void onLayout() {
-        final Context context = getContext();
-        final String ssid = mState.ssid;
-        
-        int positiveButtonResId = 0;
-        int negativeButtonResId = R.string.cancel;
-        int neutralButtonResId = 0;
-
-        if (mCustomTitle == null) {
-            // Generic title is the SSID
-            // We don't want to trigger this as a custom title, so call super's
-            super.setTitle(ssid);
-        }
-        setInverseBackgroundForced(true);
-
-        boolean defaultPasswordVisibility = true;
-
-        if (mMode == MODE_CONFIGURE) {
-            setLayout(R.layout.wifi_ap_configure);
-
-            positiveButtonResId = R.string.wifi_save_config;
-            mSaveButtonPos = POSITIVE_BUTTON;
-
-            setEnterpriseFieldsVisible(false);
-
-        } else if (mMode == MODE_INFO) {
-            if (mState.isEnterprise() && !mState.configured) {
-                setLayout(R.layout.wifi_ap_configure);
-                setEnterpriseFieldsVisible(true);
-            } else {
-                setLayout(R.layout.wifi_ap_info);
-            }
-
-            if (mState.isConnectable()) {
-                if (mCustomTitle == null) {
-                    // We don't want to trigger this as a custom title, so call super's
-                    super.setTitle(context.getString(R.string.connect_to_blank, ssid));
-                }
-                positiveButtonResId = R.string.connect;
-                mConnectButtonPos = POSITIVE_BUTTON;
-            }
-
-            if (mState.isForgetable()) {
-                if (positiveButtonResId == 0) {
-                    positiveButtonResId = R.string.forget_network;
-                    mForgetButtonPos = POSITIVE_BUTTON;
-                } else {
-                    neutralButtonResId = R.string.forget_network;
-                    mForgetButtonPos = NEUTRAL_BUTTON;
-                }
-            }
-        } else if (mMode == MODE_RETRY_PASSWORD) {
-            setLayout(R.layout.wifi_ap_retry_password);
-
-            positiveButtonResId = R.string.connect;
-            mConnectButtonPos = POSITIVE_BUTTON;
-
-            setGenericPasswordVisible(true);
-            defaultPasswordVisibility = false;
-        }
-
-        if (defaultPasswordVisibility) {
-            if (!mState.configured && mState.seen && mState.hasSecurity()) {
-                setGenericPasswordVisible(true);
-            } else {
-                setGenericPasswordVisible(false);
-            }
-        }
-
-        setButtons(positiveButtonResId, negativeButtonResId, neutralButtonResId);
-
-    }
-
-    /** Called when we need to set our member variables to point to the views. */
-    private void onReferenceViews(View view) {
-        mPasswordText = (TextView) view.findViewById(R.id.password_text);
-        mPasswordEdit = (EditText) view.findViewById(R.id.password_edit);
-        mSsidText = (TextView) view.findViewById(R.id.ssid_text);
-        mSsidEdit = (EditText) view.findViewById(R.id.ssid_edit);
-        if (mSsidEdit != null) {
-            mSsidEdit.addTextChangedListener(mSsidEditorWatcher);
-        }
-        mSecurityText = (TextView) view.findViewById(R.id.security_text);
-        mSecuritySpinner = (Spinner) view.findViewById(R.id.security_spinner);
-        mWepTypeSpinner = (Spinner) view.findViewById(R.id.wep_type_spinner);
-        mEnterpriseView = mView.findViewById(R.id.enterprise_wrapper);
-
-        mShowPasswordCheckBox = (CheckBox) view.findViewById(R.id.show_password_checkbox);
-        if (mShowPasswordCheckBox != null) {
-            mShowPasswordCheckBox.setOnClickListener(this);
-        }
-        if (mMode == MODE_CONFIGURE) {
-            mSecuritySpinner.setOnItemSelectedListener(this);
-            mSecuritySpinner.setPromptId(R.string.security);
-            setSpinnerAdapter(mSecuritySpinner, mAutoSecurityAllowed ?
-                R.array.wifi_security_entries
-                : R.array.wifi_security_without_auto_entries);
-        } else if (mMode == MODE_INFO) {
-            mTable = (ViewGroup) view.findViewById(R.id.table);
-        }
-        /* for enterprise one */
-        if (mMode == MODE_CONFIGURE ||
-                (mState.isEnterprise() && !mState.configured)) {
-            setEnterpriseFields(view);
-            updateCertificateSelection();
-        }
-    }
-
-    private void updateCertificateSelection() {
-        setSpinnerAdapter(mClientCertSpinner, getAllUserCertificateKeys());
-        setSpinnerAdapter(mCaCertSpinner, getAllCaCertificateKeys());
-
-        mPhase2Spinner.setSelection(getSelectionIndex(
-                R.array.wifi_phase2_entries, mState.getPhase2()));
-        mEapSpinner.setSelection(getSelectionIndex(
-                R.array.wifi_eap_entries, mState.getEap()));
-        mClientCertSpinner.setSelection(getSelectionIndex(
-                getAllUserCertificateKeys(), mState.getEnterpriseField(
-                AccessPointState.CLIENT_CERT)));
-        mCaCertSpinner.setSelection(getSelectionIndex(
-                getAllCaCertificateKeys(), mState.getEnterpriseField(
-                AccessPointState.CA_CERT)));
-    }
-
-    private String[] getAllCaCertificateKeys() {
-        return appendEmptyInSelection(mKeyStore.saw(Credentials.CA_CERTIFICATE));
-    }
-
-    private String[] getAllUserCertificateKeys() {
-        return appendEmptyInSelection(mKeyStore.saw(Credentials.USER_CERTIFICATE));
-    }
-
-    private String[] appendEmptyInSelection(String[] keys) {
-        if (keys == null) {
-            return new String[] {NOT_APPLICABLE};
-        } else {
-            String[] selections = new String[keys.length + 1];
-            System.arraycopy(keys, 0, selections, 0, keys.length);
-            selections[keys.length] = NOT_APPLICABLE;
-            return selections;
-        }
-    }
-
-    private void setEnterpriseFields(View view) {
-        mIdentityText = (TextView) view.findViewById(R.id.identity_text);
-        mIdentityEdit = (EditText) view.findViewById(R.id.identity_edit);
-        mAnonymousIdentityText =
-                (TextView) view.findViewById(R.id.anonymous_identity_text);
-        mAnonymousIdentityEdit =
-                (EditText) view.findViewById(R.id.anonymous_identity_edit);
-        mClientCertText =
-                (TextView) view.findViewById(R.id.client_certificate_text);
-        mCaCertText = (TextView) view.findViewById(R.id.ca_certificate_text);
-        mEapText = (TextView) view.findViewById(R.id.eap_text);
-        mEapSpinner = (Spinner) view.findViewById(R.id.eap_spinner);
-        mEapSpinner.setOnItemSelectedListener(this);
-        mEapSpinner.setPromptId(R.string.please_select_eap);
-        setSpinnerAdapter(mEapSpinner, R.array.wifi_eap_entries);
-
-        mPhase2Text = (TextView) view.findViewById(R.id.phase2_text);
-        mPhase2Spinner = (Spinner) view.findViewById(R.id.phase2_spinner);
-        mPhase2Spinner.setOnItemSelectedListener(this);
-        mPhase2Spinner.setPromptId(R.string.please_select_phase2);
-        setSpinnerAdapter(mPhase2Spinner, R.array.wifi_phase2_entries);
-
-        mClientCertSpinner =
-                (Spinner) view.findViewById(R.id.client_certificate_spinner);
-        mClientCertSpinner.setOnItemSelectedListener(this);
-        mClientCertSpinner.setPromptId(
-                R.string.please_select_client_certificate);
-        setSpinnerAdapter(mClientCertSpinner, getAllUserCertificateKeys());
-
-        mCaCertSpinner =
-                (Spinner) view.findViewById(R.id.ca_certificate_spinner);
-        mCaCertSpinner.setOnItemSelectedListener(this);
-        mCaCertSpinner.setPromptId(R.string.please_select_ca_certificate);
-        setSpinnerAdapter(mCaCertSpinner, getAllCaCertificateKeys());
-
-        mEnterpriseTextFields = new EditText[] {
-            mIdentityEdit, mAnonymousIdentityEdit
-        };
-
-    }
-
-    private void setSpinnerAdapter(Spinner spinner, String[] items) {
-        if (items != null) {
-            ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
-                    getContext(), android.R.layout.simple_spinner_item, items);
-            adapter.setDropDownViewResource(
-                    android.R.layout.simple_spinner_dropdown_item);
-            spinner.setAdapter(adapter);
-        }
-    }
-
-    private void setSpinnerAdapter(Spinner spinner, int arrayResId) {
-        setSpinnerAdapter(spinner,
-            getContext().getResources().getStringArray(arrayResId));
-    }
-
-    /** Called when the widgets are in-place waiting to be filled with data */
-    private void onFill() {
-
-        // Appears in the order added
-        if (mMode == MODE_INFO) {
-            if (mState.primary) {
-                addInfoRow(R.string.wifi_status, mState.getSummarizedStatus());
-                addInfoRow(R.string.wifi_link_speed, mState.linkSpeed + WifiInfo.LINK_SPEED_UNITS);
-            }
-    
-            if (mState.seen) {
-                addInfoRow(R.string.signal, getSignalResId(mState.signal));
-            }
-            
-            if (mState.security != null) {
-                addInfoRow(R.string.security, mState.getHumanReadableSecurity());
-            }
-    
-            if (mState.primary && mState.ipAddress != 0) {
-                addInfoRow(R.string.ip_address, Formatter.formatIpAddress(mState.ipAddress));
-            }
-            
-        } else if (mMode == MODE_CONFIGURE) {
-            String ssid = mState.ssid;
-            if (!TextUtils.isEmpty(ssid)) {
-                mSsidEdit.setText(ssid);
-            }
-            if (mState.configured) {
-                mPasswordEdit.setHint(R.string.wifi_password_unchanged);
-            }
-        }
-
-        updatePasswordCaption(mState.security);
-    }
-
-    private void updatePasswordCaption(String security) {
-        if (mPasswordText != null) {
-            if (security != null && security.equals(AccessPointState.WEP)) {
-                mPasswordText.setText(R.string.please_type_hex_key);
-            } else {
-                mPasswordText.setText(R.string.please_type_passphrase);
-            }
-        }
-    }
-    
-    private void addInfoRow(int nameResId, String value) {
-        View rowView = getLayoutInflater().inflate(R.layout.wifi_ap_info_row, mTable, false);
-        ((TextView) rowView.findViewById(R.id.name)).setText(nameResId);
-        ((TextView) rowView.findViewById(R.id.value)).setText(value);
-        mTable.addView(rowView);
-    }
-        
-    private void addInfoRow(int nameResId, int valueResId) {
-        addInfoRow(nameResId, getContext().getString(valueResId));
-    }
-    
-    private void setButtons(int positiveResId, int negativeResId, int neutralResId) {
-        final Context context = getContext();
-        
-        if (positiveResId > 0) {
-            setButton(context.getString(positiveResId), this);
-        }
-        
-        if (negativeResId > 0) {
-            setButton2(context.getString(negativeResId), this);
-        }
-
-        if (neutralResId > 0) {
-            setButton3(context.getString(neutralResId), this);
-        }
-    }
-    
-    private void setLayout(int layoutResId) {
-        setView(mView = getLayoutInflater().inflate(layoutResId, null));
-        onReferenceViews(mView);
-    }
-    
-    public void onClick(DialogInterface dialog, int which) {
-        if (which == mForgetButtonPos) {
-            handleForget();
-        } else if (which == mConnectButtonPos) {
-            handleConnect();
-        } else if (which == mSaveButtonPos) {
-            handleSave();
-        }
-    }
-    
-    private void handleForget() {
-        if (!replaceStateWithWifiLayerInstance()) return;
-        mWifiLayer.forgetNetwork(mState);
-    }
-    
-    private void handleConnect() {
-        if (!replaceStateWithWifiLayerInstance()) {
-            Log.w(TAG, "Assuming connecting to a new network.");
-        }
-
-        if (mState.isEnterprise()) {
-            if(!mState.configured) {
-                updateEnterpriseFields();
-            }
-        }
-        updatePasswordField();
-
-        mWifiLayer.connectToNetwork(mState);
-    }
-
-    /*
-     * If the network is secured and they haven't entered a password, popup an
-     * error. Allow empty passwords if the state already has a password set
-     * (since in that scenario, an empty password means keep the old password).
-     */
-    private void updatePasswordField() {
-
-      String password = getEnteredPassword();
-      boolean passwordIsEmpty = TextUtils.isEmpty(password);
-      /*
-       * When 'retry password', they can not enter a blank password. In any
-       * other mode, we let them enter a blank password if the state already
-       * has a password.
-       */
-      if (passwordIsEmpty && (!mState.hasPassword() ||
-              mMode == MODE_RETRY_PASSWORD) &&
-              (mState.security != null) &&
-              !mState.security.equals(AccessPointState.OPEN) &&
-              !mState.isEnterprise()) {
-          new AlertDialog.Builder(getContext())
-                  .setTitle(R.string.error_title)
-                  .setIcon(android.R.drawable.ic_dialog_alert)
-                  .setMessage(R.string.wifi_password_incorrect_error)
-                  .setPositiveButton(android.R.string.ok, null)
-                  .show();
-          return;
-      }
-
-      if (!passwordIsEmpty) {
-          mState.setPassword(password);
-      }
-    }
-
-    private void handleSave() {
-        replaceStateWithWifiLayerInstance();
-
-        String ssid = mSsidEdit.getText().toString();
-        String password = mPasswordEdit.getText().toString();
-        
-        mState.setSsid(ssid);
-        
-        int securityType = getSecurityTypeFromSpinner();
-
-        if (!TextUtils.isEmpty(password) && (securityType != SECURITY_WEP)) {
-            mState.setPassword(password);
-        }
-
-        switch (securityType) {
-            case SECURITY_PSK: {
-                mState.setSecurity(AccessPointState.PSK);
-                break;
-            }
-
-            case SECURITY_AUTO: {
-                break;
-            }
-
-            case SECURITY_WEP: {
-                mState.setSecurity(AccessPointState.WEP);
-                mState.setPassword(password, WEP_TYPE_VALUES[
-                        mWepTypeSpinner.getSelectedItemPosition()]);
-                    break;
-            }
-
-            case SECURITY_EAP:
-                mState.setSecurity(AccessPointState.EAP);
-                break;
-
-            case SECURITY_NONE:
-            default:
-                mState.setSecurity(AccessPointState.OPEN);
-                break;
-        }
-
-        if (mState.isEnterprise() && !mState.configured) {
-            updateEnterpriseFields();
-        }
-
-        /**
-         * AP state on the current scan list needs update to enable "Forget" capability.
-         * This is not required for newly added APs.
-         */
-        AccessPointState ap = mWifiLayer.getWifiLayerApInstance(mState);
-        if(ap != null) {
-            ap.setConfigured(true);
-        }
-
-        if (!mWifiLayer.saveNetwork(mState)) {
-            return;
-        }
-
-        // Connect right away if they've touched it
-        if (!mWifiLayer.connectToNetwork(mState)) {
-            return;
-        }
-
-    }
-    
-    private int getSelectionIndex(String[] array, String selection) {
-        if(selection != null) {
-            for (int i = 0 ; i < array.length ; i++) {
-                if (selection.contains(array[i])) return i;
-            }
-        }
-        return 0;
-    }
-
-    private int getSelectionIndex(int arrayResId, String selection) {
-        return getSelectionIndex(
-            getContext().getResources().getStringArray(arrayResId), selection);
-    }
-
-    private void updateEnterpriseFields() {
-        int i;
-        String value;
-        for (i = AccessPointState.IDENTITY ;
-                i <= AccessPointState.ANONYMOUS_IDENTITY ; i++) {
-            value = mEnterpriseTextFields[i].getText().toString();
-            if (!TextUtils.isEmpty(value)) {
-                mState.setEnterpriseField(i, value);
-            }
-        }
-        Spinner spinner = mClientCertSpinner;
-        int index = spinner.getSelectedItemPosition();
-        if (index != (spinner.getCount() - 1)) {
-            String key = (String) spinner.getSelectedItem();
-            mState.setEnterpriseField(AccessPointState.CLIENT_CERT,
-                    KEYSTORE_HEADER + Credentials.USER_CERTIFICATE + key);
-            mState.setEnterpriseField(AccessPointState.PRIVATE_KEY,
-                    KEYSTORE_HEADER + Credentials.USER_PRIVATE_KEY + key);
-        }
-        spinner = mCaCertSpinner;
-        index = spinner.getSelectedItemPosition();
-        if (index != (spinner.getCount() - 1)) {
-            String key = (String) spinner.getSelectedItem();
-            mState.setEnterpriseField(AccessPointState.CA_CERT,
-                    KEYSTORE_HEADER + Credentials.CA_CERTIFICATE + key);
-        }
-        mState.setSecurity(AccessPointState.EAP);
-        mState.setEap(mEapSpinner.getSelectedItemPosition());
-        mState.setPhase2((String) mPhase2Spinner.getSelectedItem());
-    }
-
-    /**
-     * Replaces our {@link #mState} with the equal WifiLayer instance.  This is useful after
-     * we unparceled the state previously and before we are calling methods on {@link #mWifiLayer}.
-     * 
-     * @return Whether WifiLayer was able to find an equal state in its set.
-     */
-    private boolean replaceStateWithWifiLayerInstance() {
-        AccessPointState state = mWifiLayer.getWifiLayerApInstance(mState);
-        if (state == null) {
-            return false;
-        }
-        
-        mState = state;
-        return true;
-    }
-    
-    private int getSecurityTypeFromSpinner() {
-        int position = mSecuritySpinner.getSelectedItemPosition();
-        // If there is no AUTO choice, the position needs 1 added to get
-        // to the proper spinner position -> security constants mapping
-        return mAutoSecurityAllowed ? position : position + 1;
-    }
-    
-    private String getEnteredPassword() {
-        return mPasswordEdit != null ? mPasswordEdit.getText().toString() : null;
-    }
-    
-    /**
-     * Call the one you want to hide first.
-     */
-    private void setWepVisible(boolean visible) {
-        setGenericPasswordVisible(visible);
-        int visibility = visible ? View.VISIBLE : View.GONE;
-        mWepTypeSpinner.setVisibility(visibility);
-    }
-    
-    /**
-     * @see #setWepVisible(boolean)
-     */
-    private void setGenericPasswordVisible(boolean visible) {
-        int visibility = visible ? View.VISIBLE : View.GONE;
-        mPasswordText.setVisibility(visibility);
-        mPasswordEdit.setVisibility(visibility);
-        mShowPasswordCheckBox.setVisibility(visibility);
-    }
-
-    private void setEnterpriseFieldsVisible(boolean visible) {
-        int visibility = visible ? View.VISIBLE : View.GONE;
-        mEnterpriseView.setVisibility(visibility);
-        if (visible) {
-            setWepVisible(false);
-        }
-        if (mMode != MODE_CONFIGURE) {
-            mSsidText.setVisibility(View.GONE);
-            mSsidEdit.setVisibility(View.GONE);
-            mSecurityText.setVisibility(View.GONE);
-            mSecuritySpinner.setVisibility(View.GONE);
-        }
-    }
-
-    public void onItemSelected(AdapterView parent, View view, int position, long id) {
-        if (parent == mSecuritySpinner) {
-            handleSecurityChange(getSecurityTypeFromSpinner());
-        }
-    }
-
-    public void onNothingSelected(AdapterView parent) {
-    }
-
-    private void handleSecurityChange(int security) {
-        setEnterpriseFieldsVisible(false);
-        switch (security) {
-            
-            case SECURITY_NONE: {
-                setWepVisible(false);
-                setGenericPasswordVisible(false);
-                break;
-            }
-            
-            case SECURITY_WEP: {
-                setGenericPasswordVisible(false);
-                setWepVisible(true);
-                updatePasswordCaption(AccessPointState.WEP);
-                break;
-            }
-            
-            case SECURITY_AUTO: {
-                setWepVisible(false);
-                setGenericPasswordVisible(mState.hasSecurity());
-                // Shows the generic 'wireless password'
-                updatePasswordCaption(AccessPointState.PSK);
-                break;
-            }
-
-            case SECURITY_PSK: {
-                setWepVisible(false);
-                setGenericPasswordVisible(true);
-                // Both WPA and WPA2 show the same caption, so either is ok
-                updatePasswordCaption(AccessPointState.PSK);
-                break;
-            }
-            case SECURITY_EAP: {
-                // Unlock the keystore if it is not unlocked yet.
-                if (mKeyStore.test() != KeyStore.NO_ERROR) {
-                    Credentials.getInstance().unlock(getContext());
-                    return;
-                }
-                enableEnterpriseFields();
-                break;
-            }
-        }
-    }
-
-    private static int getSignalResId(int signal) {
-        switch (WifiManager.calculateSignalLevel(signal, 4)) {
-            case 0: {
-                return R.string.wifi_signal_0;
-            }
-            case 1: {
-                return R.string.wifi_signal_1;
-            }
-            case 2: {
-                return R.string.wifi_signal_2;
-            }
-            case 3: {
-                return R.string.wifi_signal_3;
-            }
-        }
-        
-        return 0;
-    }
-    
-
-    public void onClick(View v) {
-        if (v == mShowPasswordCheckBox) {
-            setShowPassword(mShowPasswordCheckBox.isChecked());
-        }
-    }
-    
-    private void setShowPassword(boolean showPassword) {
-        if (mPasswordEdit != null) {
-            mPasswordEdit.setInputType(InputType.TYPE_CLASS_TEXT |
-                    (showPassword ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
-                            : InputType.TYPE_TEXT_VARIATION_PASSWORD));
-        }
-    }
-    
-}
diff --git a/src/com/android/settings/wifi/AccessPointPreference.java b/src/com/android/settings/wifi/AccessPointPreference.java
deleted file mode 100644
index 0c5d6df..0000000
--- a/src/com/android/settings/wifi/AccessPointPreference.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi;
-
-import com.android.settings.R;
-
-import android.net.wifi.WifiManager;
-import android.preference.Preference;
-import android.view.View;
-import android.widget.ImageView;
-
-public class AccessPointPreference extends Preference implements
-        AccessPointState.AccessPointStateCallback {
-    
-    // UI states
-    private static final int[] STATE_ENCRYPTED = { R.attr.state_encrypted };
-    private static final int[] STATE_EMPTY = { };
-    
-    // Signal strength indicator
-    private static final int UI_SIGNAL_LEVELS = 4;
-
-    private AccessPointState mState;
-
-    public AccessPointPreference(WifiSettings wifiSettings, AccessPointState state) {
-        super(wifiSettings, null);
-        
-        mState = state;
-        
-        setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
-        
-        state.setCallback(this);
-        
-        refresh();
-    }
-    
-    public void refresh() {
-        setTitle(mState.ssid);
-        setSummary(mState.getSummarizedStatus());
-
-        notifyChanged();
-    }
-    
-    public void refreshAccessPointState() {
-        refresh();
-        
-        // The ordering of access points could have changed due to the state change, so
-        // re-evaluate ordering
-        notifyHierarchyChanged();
-    }
-
-    @Override
-    protected void onBindView(View view) {
-        super.onBindView(view);
-
-        ImageView signal = (ImageView) view.findViewById(R.id.signal);
-        if (mState.seen) {
-            signal.setImageResource(R.drawable.wifi_signal);
-            signal.setImageState(mState.hasSecurity() ? STATE_ENCRYPTED : STATE_EMPTY, true);
-            signal.setImageLevel(getUiSignalLevel());
-        } else {
-            signal.setImageDrawable(null);
-        }
-    }
-
-    private int getUiSignalLevel() {
-        return mState != null ? WifiManager.calculateSignalLevel(mState.signal, UI_SIGNAL_LEVELS)
-                : 0; 
-    }
-
-    /**
-     * Returns the {@link AccessPointState} associated with this preference.
-     * @return The {@link AccessPointState}.
-     */
-    public AccessPointState getAccessPointState() {
-        return mState;
-    }
-    
-    @Override
-    public int compareTo(Preference another) {
-        if (!(another instanceof AccessPointPreference)) {
-            // Let normal preferences go before us.
-            // NOTE: we should only be compared to Preference in our
-            //       category.
-            return 1;
-        }
-        
-        return mState.compareTo(((AccessPointPreference) another).mState);
-    }
-    
-}
-
diff --git a/src/com/android/settings/wifi/AccessPointState.java b/src/com/android/settings/wifi/AccessPointState.java
deleted file mode 100644
index 1c3ef95..0000000
--- a/src/com/android/settings/wifi/AccessPointState.java
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi;
-
-import com.android.settings.R;
-
-import android.content.Context;
-import android.net.NetworkInfo;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiConfiguration.AuthAlgorithm;
-import android.net.wifi.WifiConfiguration.GroupCipher;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.PairwiseCipher;
-import android.net.wifi.WifiConfiguration.Protocol;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-public final class AccessPointState implements Comparable<AccessPointState>, Parcelable {
-
-    private static final String TAG = "AccessPointState";
-    
-    // Constants used for different security types
-    public static final String PSK = "PSK";
-    public static final String WEP = "WEP";
-    public static final String EAP = "EAP";
-    public static final String OPEN = "Open";
-
-    public static final String[] EAP_METHOD = { "PEAP", "TLS", "TTLS" };
-
-    /** String present in capabilities if the scan result is ad-hoc */
-    private static final String ADHOC_CAPABILITY = "[IBSS]";
-    /** String present in capabilities if the scan result is enterprise secured */
-    private static final String ENTERPRISE_CAPABILITY = "-EAP-";
-
-    public static final String BSSID_ANY = "any";
-    public static final int NETWORK_ID_NOT_SET = -1;
-    /** This should be used with care! */
-    static final int NETWORK_ID_ANY = -2;
-    
-    public static final int MATCH_NONE = 0;
-    public static final int MATCH_WEAK = 1;
-    public static final int MATCH_STRONG = 2;
-    public static final int MATCH_EXACT = 3;
-    
-    // Don't set these directly, use the setters.
-    public int networkId;
-    public int priority;
-    public boolean hiddenSsid;
-    public int linkSpeed;
-    public int ipAddress;
-    public String bssid;
-    public String ssid;
-    public int signal;
-    public boolean primary;
-    public boolean seen;
-    public boolean configured;
-    public NetworkInfo.DetailedState status;
-    public String security;
-    public boolean disabled;
-    
-    /**
-     * Use this for sorting based on signal strength. It is a heavily-damped
-     * time-averaged weighted signal.
-     */
-    private float signalForSorting = Float.MIN_VALUE;
-    
-    private static final float DAMPING_FACTOR = 0.2f;
-    
-    /**
-     * This will be a user entered password, and NOT taken from wpa_supplicant
-     * (since it would give us *)
-     */
-    private String mPassword; 
-    private boolean mConfigHadPassword;
-    
-    public static final int WEP_PASSWORD_AUTO = 0;
-    public static final int WEP_PASSWORD_ASCII = 1;
-    public static final int WEP_PASSWORD_HEX = 2;
-    private int mWepPasswordType;
-
-    /* Enterprise Fields */
-    public static final int IDENTITY = 0;
-    public static final int ANONYMOUS_IDENTITY = 1;
-    public static final int CLIENT_CERT = 2;
-    public static final int CA_CERT = 3;
-    public static final int PRIVATE_KEY = 4;
-    public static final int MAX_ENTRPRISE_FIELD = 5;
-    private String mEnterpriseFields[] = new String[MAX_ENTRPRISE_FIELD];
-    private String mEap;
-    private String mPhase2;
-
-    private Context mContext;
-
-    /**
-     * If > 0, don't refresh (changes are being batched), use
-     * {@link #blockRefresh()} and {@link #unblockRefresh()} only.
-     */
-    private int mBlockRefresh;
-    /**
-     * This will be set by {@link #requestRefresh} and shouldn't be written to
-     * elsewhere.
-     */
-    private boolean mNeedsRefresh;    
-    
-    private AccessPointStateCallback mCallback;
-    
-    private StringBuilder mSummaryBuilder = new StringBuilder();
-    
-    interface AccessPointStateCallback {
-        void refreshAccessPointState();
-    }
-    
-    public AccessPointState(Context context) {
-        this();
-        
-        setContext(context);
-    }
-
-    private AccessPointState() {
-        bssid = BSSID_ANY;
-        ssid = "";
-        networkId = NETWORK_ID_NOT_SET;
-        hiddenSsid = false;
-    }
-
-    void setContext(Context context) {
-        mContext = context;
-    }
-
-    public void setNetworkId(int networkId) {
-        this.networkId = networkId;
-    }
-    
-    public void setBssid(String bssid) {
-        if (bssid != null) {
-            // If the BSSID is a wildcard, do NOT let a specific BSSID replace it
-            if (!this.bssid.equals(BSSID_ANY)) {
-                this.bssid = bssid;
-            }
-        }
-    }
-
-    private String getWpaSupplicantBssid() {
-        return bssid.equals(BSSID_ANY) ? null : bssid;
-    }
-    
-    public static String convertToQuotedString(String string) {
-        if (TextUtils.isEmpty(string)) {
-            return "";
-        }
-        return "\"" + string + "\"";
-    }
-    
-    public void setPrimary(boolean primary) {
-        if (this.primary != primary) {
-            this.primary = primary;
-            requestRefresh();
-        }
-    }
-    
-    public void setSeen(boolean seen) {
-        if (this.seen != seen) {
-            this.seen = seen;
-            requestRefresh();
-        }
-    }
-    
-    public void setDisabled(boolean disabled) {
-        if (this.disabled != disabled) {
-            this.disabled = disabled;
-            requestRefresh();
-        }
-    }
-    
-    public void setSignal(int signal) {
-
-        if (signalForSorting == Float.MIN_VALUE) {
-            signalForSorting = signal;
-        } else {
-            signalForSorting = (DAMPING_FACTOR * signal) + ((1-DAMPING_FACTOR) * signalForSorting);
-        }
-
-        if (this.signal != signal) {
-            this.signal = signal;
-            requestRefresh();
-        }
-    }
-   
-    public void setSsid(String ssid) {
-        if (ssid != null) {
-            this.ssid = ssid;
-            requestRefresh();
-        }
-    }
-    
-    public void setPriority(int priority) {
-        if (this.priority != priority) {
-            this.priority = priority;
-            requestRefresh();
-        }
-    }
-
-    public void setHiddenSsid(boolean hiddenSsid) {
-        if (this.hiddenSsid != hiddenSsid) {
-            this.hiddenSsid = hiddenSsid;
-            requestRefresh();
-        }
-    }
-
-    public void setLinkSpeed(int linkSpeed) {
-        if (this.linkSpeed != linkSpeed) {
-            this.linkSpeed = linkSpeed;
-            requestRefresh();
-        }
-    }
-    
-    public void setIpAddress(int address) {
-        if (ipAddress != address) {
-            ipAddress = address;
-            requestRefresh();
-        }
-    }
-    
-    public void setConfigured(boolean configured) {
-        if (this.configured != configured) {
-            this.configured = configured;
-            requestRefresh();
-        }
-    }
-    
-    public void setStatus(NetworkInfo.DetailedState status) {
-        if (this.status != status) {
-            this.status = status;
-            requestRefresh();
-        }
-    }
-
-    public boolean isEnterprise() {
-        return (AccessPointState.EAP.equals(security));
-    }
-
-    public void setSecurity(String security) {
-        if (TextUtils.isEmpty(this.security) || !this.security.equals(security)) {
-            this.security = security;
-            requestRefresh();
-        }
-    }
-
-    public boolean hasSecurity() {
-        return security != null && !security.contains(OPEN);
-    }
-    
-    public String getHumanReadableSecurity() {
-        if (security.equals(OPEN)) return mContext.getString(R.string.wifi_security_open);
-        else if (security.equals(WEP)) return mContext.getString(R.string.wifi_security_wep);
-        else if (security.equals(PSK)) return mContext.getString(R.string.wifi_security_psk);
-        else if (security.equals(EAP)) return mContext.getString(R.string.wifi_security_eap);
-
-        return mContext.getString(R.string.wifi_security_unknown);
-    }
-    
-    public void updateFromScanResult(ScanResult scanResult) {
-        blockRefresh();
-        
-        // We don't keep specific AP BSSIDs and instead leave that as wildcard
-        
-        setSeen(true);
-        setSsid(scanResult.SSID);
-        if (networkId == NETWORK_ID_NOT_SET) {
-            // Since ScanResults don't cross-reference network ID, we set it as a wildcard
-            setNetworkId(NETWORK_ID_ANY);
-        }
-        setSignal(scanResult.level);
-        setSecurity(getScanResultSecurity(scanResult));
-        unblockRefresh();
-    }
-    
-    /**
-     * @return The security of a given {@link ScanResult}.
-     */
-    public static String getScanResultSecurity(ScanResult scanResult) {
-        final String cap = scanResult.capabilities;
-        final String[] securityModes = { WEP, PSK, EAP };
-        for (int i = securityModes.length - 1; i >= 0; i--) {
-            if (cap.contains(securityModes[i])) {
-                return securityModes[i];
-            }
-        }
-        
-        return OPEN;
-    }
-    
-    /**
-     * @return Whether the given ScanResult represents an adhoc network.
-     */
-    public static boolean isAdhoc(ScanResult scanResult) {
-        return scanResult.capabilities.contains(ADHOC_CAPABILITY);
-    }
-    
-    /**
-     * @return Whether the given ScanResult has enterprise security.
-     */
-    public static boolean isEnterprise(ScanResult scanResult) {
-        return scanResult.capabilities.contains(ENTERPRISE_CAPABILITY);
-    }
-    
-    public void updateFromWifiConfiguration(WifiConfiguration wifiConfig) {
-        if (wifiConfig != null) {
-            blockRefresh();
-            setBssid(wifiConfig.BSSID);
-            setNetworkId(wifiConfig.networkId);
-            setPriority(wifiConfig.priority);
-            setHiddenSsid(wifiConfig.hiddenSSID);
-            setSsid(wifiConfig.SSID);
-            setConfigured(true);
-            setDisabled(wifiConfig.status == WifiConfiguration.Status.DISABLED);
-            parseWifiConfigurationSecurity(wifiConfig);
-            unblockRefresh();
-        }
-    }
-    
-    public void setPassword(String password) {
-        setPassword(password, WEP_PASSWORD_AUTO);
-    }
-    
-    public void setPassword(String password, int wepPasswordType) {
-        mPassword = password;
-        mWepPasswordType = wepPasswordType;
-    }
-
-    /* For Enterprise Fields */
-    public void setEnterpriseField(int field, String value) {
-        if ((value != null) && (field >= 0) && (field < MAX_ENTRPRISE_FIELD)) {
-            this.mEnterpriseFields[field] = value;
-            requestRefresh();
-        }
-    }
-
-    public void setPhase2(String phase2) {
-        if (!TextUtils.isEmpty(phase2) && (!phase2.equals("None"))) {
-            mPhase2 = phase2;
-        }
-    }
-
-    public String getPhase2() {
-        return mPhase2;
-    }
-
-    public void setEap(int method) {
-        mEap =  EAP_METHOD[method];
-        requestRefresh();
-    }
-
-    public String getEap() {
-        return mEap;
-    }
-    public String getEnterpriseField(int field) {
-        if(field >=0 && field < MAX_ENTRPRISE_FIELD) {
-            return mEnterpriseFields[field];
-        }
-        return null;
-    }
-
-    public boolean hasPassword() {
-        return !TextUtils.isEmpty(mPassword) || mConfigHadPassword; 
-    }
-    
-    private static boolean hasPassword(WifiConfiguration wifiConfig) {
-        return !TextUtils.isEmpty(wifiConfig.preSharedKey)
-                || !TextUtils.isEmpty(wifiConfig.wepKeys[0])
-                || !TextUtils.isEmpty(wifiConfig.wepKeys[1])
-                || !TextUtils.isEmpty(wifiConfig.wepKeys[2])
-                || !TextUtils.isEmpty(wifiConfig.wepKeys[3]);        
-    }
-    
-    private void parseWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
-        setSecurity(getWifiConfigurationSecurity(wifiConfig));
-        mConfigHadPassword = hasPassword(wifiConfig);
-    }
-    
-    /**
-     * @return The security of a given {@link WifiConfiguration}.
-     */
-    public static String getWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
-        if (!TextUtils.isEmpty(wifiConfig.eap.value())) {
-            return EAP;
-        } else if (!TextUtils.isEmpty(wifiConfig.preSharedKey)) {
-            return PSK;
-        } else if (!TextUtils.isEmpty(wifiConfig.wepKeys[0])) {
-            return WEP;
-        }
-        return OPEN;
-    }
-    
-    public void updateFromWifiInfo(WifiInfo wifiInfo, NetworkInfo.DetailedState state) {
-        if (wifiInfo != null) {
-            blockRefresh();
-            setBssid(wifiInfo.getBSSID());
-            setLinkSpeed(wifiInfo.getLinkSpeed());
-            setNetworkId(wifiInfo.getNetworkId());
-            setIpAddress(wifiInfo.getIpAddress());
-            setSsid(wifiInfo.getSSID());
-            if (state != null) {
-                setStatus(state);
-            }
-            setHiddenSsid(wifiInfo.getHiddenSSID());
-            unblockRefresh();
-        }
-    }
-    
-    /**
-     * @return Whether this AP can be connected to at the moment.
-     */
-    public boolean isConnectable() {
-        return !primary && seen;
-    }
-
-    /**
-     * @return Whether this AP can be forgotten at the moment.
-     */
-    public boolean isForgetable() {
-        return configured;
-    }
-    
-    /**
-     * Updates the state as if it were never configured.
-     * <p>
-     * Note: This will not pass the forget call to the Wi-Fi API.
-     */
-    public void forget() {
-        blockRefresh();
-        setConfigured(false);
-        setNetworkId(NETWORK_ID_NOT_SET);
-        setPrimary(false);
-        setStatus(null);
-        setDisabled(false);
-        unblockRefresh();
-    }
-    
-    public void updateWifiConfiguration(WifiConfiguration config) {
-        config.BSSID = getWpaSupplicantBssid();
-        config.priority = priority;
-        config.hiddenSSID = hiddenSsid;
-        config.SSID = ssid;
-        config.eap.setValue(mEap);
-
-        if (!TextUtils.isEmpty(mPhase2)) {
-            config.phase2.setValue("auth=" + mPhase2);
-        } else {
-            config.phase2.setValue(null);
-        }
-        if (!TextUtils.isEmpty(mEnterpriseFields[IDENTITY])) {
-            config.identity.setValue(mEnterpriseFields[IDENTITY]);
-        } else {
-            config.identity.setValue(null);
-        }
-        if (!TextUtils.isEmpty(mEnterpriseFields[ANONYMOUS_IDENTITY])) {
-            config.anonymous_identity.setValue(
-                    mEnterpriseFields[ANONYMOUS_IDENTITY]);
-        } else {
-            config.anonymous_identity.setValue(null);
-        }
-        if (!TextUtils.isEmpty(mEnterpriseFields[CLIENT_CERT])) {
-            config.client_cert.setValue(
-                    mEnterpriseFields[CLIENT_CERT]);
-        } else {
-            config.client_cert.setValue(null);
-        }
-        if (!TextUtils.isEmpty(mEnterpriseFields[CA_CERT])) {
-            config.ca_cert.setValue(
-                    mEnterpriseFields[CA_CERT]);
-        } else {
-            config.ca_cert.setValue(null);
-        }
-        if (!TextUtils.isEmpty(mEnterpriseFields[PRIVATE_KEY])) {
-            config.private_key.setValue(
-                    mEnterpriseFields[PRIVATE_KEY]);
-        } else {
-            config.private_key.setValue(null);
-        }
-        setupSecurity(config);
-    }
-    
-    private void setupSecurity(WifiConfiguration config) {
-        config.allowedAuthAlgorithms.clear();
-        config.allowedGroupCiphers.clear();
-        config.allowedKeyManagement.clear();
-        config.allowedPairwiseCiphers.clear();
-        config.allowedProtocols.clear();
-        
-        if (TextUtils.isEmpty(security)) {
-            security = OPEN;
-            Log.w(TAG, "Empty security, assuming open");
-        }
-        
-        if (security.equals(WEP)) {
-            // If password is empty, it should be left untouched
-            if (!TextUtils.isEmpty(mPassword)) {
-                if (mWepPasswordType == WEP_PASSWORD_AUTO) {
-                    if (isHexWepKey(mPassword)) {
-                        config.wepKeys[0] = mPassword;
-                    } else {
-                        config.wepKeys[0] = convertToQuotedString(mPassword);
-                    }
-                } else {
-                    config.wepKeys[0] = mWepPasswordType == WEP_PASSWORD_ASCII
-                            ? convertToQuotedString(mPassword)
-                            : mPassword;
-                }
-            }
-            config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
-            config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
-            config.allowedKeyManagement.set(KeyMgmt.NONE);
-            config.wepTxKeyIndex = 0;
-        } else if (security.equals(PSK)){
-            // If password is empty, it should be left untouched
-            if (!TextUtils.isEmpty(mPassword)) {
-                if (mPassword.length() == 64 && isHex(mPassword)) {
-                    // Goes unquoted as hex
-                    config.preSharedKey = mPassword;
-                } else {
-                    // Goes quoted as ASCII
-                    config.preSharedKey = convertToQuotedString(mPassword);
-                }
-            }
-        } else if (security.equals(EAP)) {
-            config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
-            config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
-            if (!TextUtils.isEmpty(mPassword)) {
-                config.password.setValue(mPassword);
-            }
-        } else if (security.equals(OPEN)) {
-            config.allowedKeyManagement.set(KeyMgmt.NONE);
-        }
-    }
-    
-    private static boolean isHexWepKey(String wepKey) {
-        final int len = wepKey.length();
-        
-        // WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
-        if (len != 10 && len != 26 && len != 58) {
-            return false;
-        }
-        
-        return isHex(wepKey);
-    }
-    
-    private static boolean isHex(String key) {
-        for (int i = key.length() - 1; i >= 0; i--) {
-            final char c = key.charAt(i);
-            if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) {
-                return false;
-            }
-        }
-        
-        return true;
-    }
-    
-    public void setCallback(AccessPointStateCallback callback) {
-        mCallback = callback;
-    }
-    
-    void blockRefresh() {
-        mBlockRefresh++;
-    }
-    
-    void unblockRefresh() {
-        if (--mBlockRefresh == 0 && mNeedsRefresh) {
-            requestRefresh();
-        }
-    }
-    
-    private void requestRefresh() {
-        if (mBlockRefresh > 0) {
-            mNeedsRefresh = true;
-            return;
-        }
-        
-        if (mCallback != null) {
-            mCallback.refreshAccessPointState();
-        }
-        
-        mNeedsRefresh = false;
-    }
-    
-    /**
-     * {@inheritDoc}
-     * @see #hashCode()
-     * @see #equals(Object)
-     */
-    public int matches(int otherNetworkId, String otherBssid, String otherSsid,
-            String otherSecurity) {
-        
-        // Whenever this method is touched, please ensure #equals and #hashCode
-        // still work with the changes here!
-        
-        if (otherSsid == null) {
-            if (WifiLayer.LOGV) {
-                Log.w(TAG, "BSSID: " + otherBssid + ", SSID: " + otherSsid);
-            }
-            return MATCH_NONE;
-        }
-
-        /*
-         * If we both have 'security' set, it must match (an open network still
-         * has 'security' set to OPEN)
-         */
-        if (security != null && otherSecurity != null) {
-            if (!security.equals(otherSecurity)) {
-                return MATCH_NONE;
-            }
-        }
-        
-        // WifiConfiguration gives an empty bssid as a BSSID wildcard
-        if (TextUtils.isEmpty(otherBssid)) {
-            otherBssid = AccessPointState.BSSID_ANY;
-        }
-
-        final boolean networkIdMatches = networkId == otherNetworkId;
-        if (!networkIdMatches && networkId != NETWORK_ID_ANY && otherNetworkId != NETWORK_ID_ANY) {
-            // Network IDs don't match (e.g., 1 & 2 or unset & 1) and neither is a wildcard
-            return MATCH_NONE;
-        }
-        
-        if (networkIdMatches && otherNetworkId != NETWORK_ID_NOT_SET
-                && otherNetworkId != NETWORK_ID_ANY) {
-            // Network ID matches (they're set to the same ID)
-            return MATCH_EXACT;
-        }
-        
-        // So now, network IDs aren't set or at least one is a wildcard 
-        
-        final boolean bssidMatches = bssid.equals(otherBssid);
-        final boolean otherBssidIsWildcard = otherBssid.equals(BSSID_ANY);
-        if (bssidMatches && !otherBssidIsWildcard) {
-            // BSSID matches (and neither is a wildcard)
-            return MATCH_STRONG;
-        }
-
-        if (!bssidMatches && !bssid.equals(BSSID_ANY) && !otherBssidIsWildcard) {
-            // BSSIDs don't match (e.g., 00:24:21:21:42:12 & 42:12:44:21:22:52)
-            // and neither is a wildcard
-            return MATCH_NONE;
-        }
-        
-        // So now, BSSIDs are both wildcards
-        
-        final boolean ssidMatches = ssid.equals(otherSsid); 
-        if (ssidMatches) {
-            // SSID matches
-            return MATCH_WEAK;
-        }
-
-        return MATCH_NONE;
-    }
-    
-    /**
-     * {@inheritDoc}
-     * @see #matches(int, String, String)
-     * @see #equals(Object)
-     */
-    @Override
-    public int hashCode() {
-        // Two equal() objects must have same hashCode.
-        // With Wi-Fi, the broadest match is if two SSIDs are the same.  The finer-grained matches
-        // imply this (for example, the same network IDs means the same WifiConfiguration which
-        // means the same SSID).
-        // See #matches for the exact matching algorithm we use.
-        return ssid != null ? ssid.hashCode() : 0;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @see #matches(int, String, String)
-     * @see #hashCode()
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (!o.getClass().equals(getClass())) {
-            return false;
-        }
-        
-        final AccessPointState other = (AccessPointState) o;
-
-        // To see which conditions cause two AccessPointStates to be equal, see
-        // where #matches returns MATCH_WEAK or greater.
-        
-        return matches(other.networkId, other.bssid, other.ssid, other.security) >= MATCH_WEAK;
-    }
-
-    public int matchesWifiConfiguration(WifiConfiguration wifiConfig) {
-        String security = getWifiConfigurationSecurity(wifiConfig);
-        return matches(wifiConfig.networkId, wifiConfig.BSSID, wifiConfig.SSID, security);
-    }
-    
-    String getSummarizedStatus() {
-        StringBuilder sb = mSummaryBuilder;
-        sb.delete(0, sb.length());
-        
-        if (primary && status != null) {
-            buildSummary(sb, WifiStatus.getPrintable(mContext, status), true);
-            
-        } else if (!seen) {
-            buildSummary(sb, mContext.getString(R.string.summary_not_in_range), true);
-
-            // Remembered comes second in this case
-            if (!primary && configured) {
-                buildSummary(sb, mContext.getString(R.string.summary_remembered), true);
-            }
-            
-        } else {
-            if (configured && disabled) {
-                // The connection failure overrides all in this case
-                return mContext.getString(R.string.summary_connection_failed);
-            }
-
-            // Remembered comes first in this case
-            if (!primary && configured) {
-                buildSummary(sb, mContext.getString(R.string.summary_remembered), true);
-            }
-            
-            // If it is seen (and not the primary), show the security type
-            String verboseSecurity = getVerboseSecurity();
-            if (verboseSecurity != null) {
-                buildSummary(sb, verboseSecurity, true);
-            }
-        }
-        
-        return sb.toString();
-    }
-    
-    private String getVerboseSecurity() {
-        if (WEP.equals(security)) {
-            return mContext.getString(R.string.wifi_security_verbose_wep);
-        } else if (PSK.equals(security)) {
-            return mContext.getString(R.string.wifi_security_verbose_psk);
-        } else if (EAP.equals(security)) {
-            return mContext.getString(R.string.wifi_security_verbose_eap);
-        } else {
-            return null;
-        }
-    }
-
-    private void buildSummary(StringBuilder sb, String string, boolean autoUpperCaseFirstLetter) {
-        if (sb.length() == 0) {
-            if (autoUpperCaseFirstLetter && string.length() > 1
-                    && Character.isLowerCase(string.charAt(0))
-                    && !Character.isUpperCase(string.charAt(1))) {
-                sb.append(Character.toUpperCase(string.charAt(0))).append(string, 1,
-                        string.length());
-            } else {
-                sb.append(string);
-            }
-        } else {
-            sb.append(", ");
-            sb.append(string);
-        }
-    }
-
-    public int compareTo(AccessPointState other) {
-        // This ranks the states for displaying in the AP list, not for
-        // connecting to (wpa_supplicant does that using the WifiConfiguration's
-        // priority field).
-        
-        // Clarity > efficiency, of this logic:
-        int comparison;
-        
-        // Primary
-        comparison = (other.primary ? 1 : 0) - (primary ? 1 : 0);
-        if (comparison != 0) return comparison;
-        
-        // Currently seen (similar to, but not always the same as within range)
-        comparison = (other.seen ? 1 : 0) - (seen ? 1 : 0);
-        if (comparison != 0) return comparison;
-
-        // Configured
-        comparison = (other.configured ? 1 : 0) - (configured ? 1 : 0);
-        if (comparison != 0) return comparison;
-
-        if (!configured) {
-            // Neither are configured
-
-            // Open network
-            comparison = (hasSecurity() ? 1 : 0) - (other.hasSecurity() ? 1 : 0);
-            if (comparison != 0) return comparison;
-        }
-
-        // Signal strength
-        comparison = (int) (other.signalForSorting - signalForSorting);
-        if (comparison != 0) return comparison;
-
-        // Alphabetical
-        return ssid.compareToIgnoreCase(other.ssid);
-    }
-
-    public String toString() {
-        return ssid + " (" + bssid + ", " + networkId + ", " + super.toString() + ")";
-    }
-    
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(bssid);
-        dest.writeInt(configured ? 1 : 0);
-        dest.writeInt(ipAddress);
-        dest.writeInt(linkSpeed);
-        dest.writeInt(networkId);
-        dest.writeInt(primary ? 1 : 0);
-        dest.writeInt(priority);
-        dest.writeInt(hiddenSsid ? 1 : 0);
-        dest.writeString(security);
-        dest.writeInt(seen ? 1 : 0);
-        dest.writeInt(disabled ? 1 : 0);
-        dest.writeInt(signal);
-        dest.writeString(ssid);
-        dest.writeString(status != null ? status.toString() : null);
-        dest.writeString(mPassword);
-        dest.writeInt(mConfigHadPassword ? 1 : 0);
-        dest.writeInt(mWepPasswordType);
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    public static final Creator<AccessPointState> CREATOR =
-        new Creator<AccessPointState>() {
-            public AccessPointState createFromParcel(Parcel in) {
-                AccessPointState state = new AccessPointState();
-                state.bssid = in.readString();
-                state.configured = in.readInt() == 1;
-                state.ipAddress = in.readInt();
-                state.linkSpeed = in.readInt();
-                state.networkId = in.readInt();
-                state.primary = in.readInt() == 1;
-                state.priority = in.readInt();
-                state.hiddenSsid = in.readInt() == 1;
-                state.security = in.readString();
-                state.seen = in.readInt() == 1;
-                state.disabled = in.readInt() == 1;
-                state.signal = in.readInt();
-                state.ssid = in.readString();
-                String statusStr = in.readString();
-                if (statusStr != null) {
-                    state.status = NetworkInfo.DetailedState.valueOf(statusStr);
-                }
-                state.mPassword = in.readString();
-                state.mConfigHadPassword = in.readInt() == 1;
-                state.mWepPasswordType = in.readInt();
-                return state;
-            }
-
-            public AccessPointState[] newArray(int size) {
-                return new AccessPointState[size];
-            }
-        };
-
-        
-}
diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java
index 7ede80d..6c55136 100644
--- a/src/com/android/settings/wifi/WifiEnabler.java
+++ b/src/com/android/settings/wifi/WifiEnabler.java
@@ -58,18 +58,12 @@
     };
 
     public WifiEnabler(Context context, CheckBoxPreference checkBox) {
-        this(context, (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
-                checkBox);
-    }
-    
-    public WifiEnabler(Context context, WifiManager wifiManager,
-            CheckBoxPreference checkBox) {
         mContext = context;
         mCheckBox = checkBox;
-        mWifiManager = wifiManager;
         mOriginalSummary = checkBox.getSummary();
         checkBox.setPersistent(false);
-        
+
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
         mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
         // The order matters! We really should not depend on this. :(
         mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
diff --git a/src/com/android/settings/wifi/WifiLayer.java b/src/com/android/settings/wifi/WifiLayer.java
deleted file mode 100644
index 0281cb0..0000000
--- a/src/com/android/settings/wifi/WifiLayer.java
+++ /dev/null
@@ -1,1315 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi;
-
-import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
-import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
-
-import com.android.settings.R;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkInfo.State;
-import android.net.wifi.ScanResult;
-import android.net.wifi.SupplicantState;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Helper class for abstracting Wi-Fi.
- * <p>
- * Client must call {@link #onCreate()}, {@link #onCreatedCallback()},
- * {@link #onPause()}, {@link #onResume()}.
- */
-public class WifiLayer {
-    
-    private static final String TAG = "SettingsWifiLayer";
-    static final boolean LOGV = false || Config.LOGV;
-    
-    //============================
-    // Other member variables
-    //============================
-    
-    private Context mContext;
-    private Callback mCallback;
-
-    static final int MESSAGE_ATTEMPT_SCAN = 1;
-    private Handler mHandler = new MyHandler();
-    
-    //============================
-    // Wifi member variables
-    //============================
-    
-    private WifiManager mWifiManager;
-    private IntentFilter mIntentFilter;
-    private List<AccessPointState> mApScanList = new ArrayList<AccessPointState>();
-    private List<AccessPointState> mApOtherList = new ArrayList<AccessPointState>();
-    private AccessPointState mCurrentPrimaryAp;
-    
-    /** The last access point that we were authenticating with. */
-    private AccessPointState mLastAuthenticatingAp;
-    
-    /** The delay between scans when we're continually scanning. */
-    private static final int CONTINUOUS_SCAN_DELAY_MS = 6000; 
-    /** On failure, the maximum retries for scanning. */
-    private static final int SCAN_MAX_RETRY = 5;
-    /** On failure, the delay between each scan retry. */
-    private static final int SCAN_RETRY_DELAY_MS = 1000;
-    /** On failure, the number of retries so far. */
-    private int mScanRetryCount = 0;
-    /**
-     * Whether we're currently obtaining an address. Continuous scanning will be
-     * disabled in this state.
-     */
-    private boolean mIsObtainingAddress;
-
-    /**
-     * See {@link android.provider.Settings.Secure#WIFI_NUM_OPEN_NETWORKS_KEPT}.
-     */
-    private int WIFI_NUM_OPEN_NETWORKS_KEPT;
-    /**
-     * Once the highest priority exceeds this value, all networks will be
-     * wrapped around starting at 0. This is so another client of the Wi-Fi
-     * API can have access points that aren't managed by us. (If the other
-     * client wants lower-priority access points than ours, it can use negative
-     * priority.)
-     */
-    private static final int HIGHEST_PRIORITY_MAX_VALUE = 99999;
-    /**
-     * Never access directly, only the related methods should.
-     */
-    private int mNextHighestPriority;
-    
-    /**
-     * This is used to track when the user wants to connect to a specific AP. We
-     * disable all other APs, set this to true, and let wpa_supplicant connect.
-     * Once we get a network state change, we re-enable the rest of them.
-     */
-    private boolean mReenableApsOnNetworkStateChange = false;
-
-    /**
-     * The current supplicant state, as broadcasted.
-     */
-    private SupplicantState mCurrentSupplicantState;
-    
-    //============================
-    // Inner classes
-    //============================
-    
-    interface Callback {
-        void onError(int messageResId);
-        
-        /**
-         * Called when an AP is added or removed.
-         * 
-         * @param ap The AP.
-         * @param added {@code true} if added, {@code false} if removed.
-         */
-        void onAccessPointSetChanged(AccessPointState ap, boolean added);
-        
-        /**
-         * Called when the scanning status changes.
-         * 
-         * @param started {@code true} if the scanning just started,
-         *            {@code false} if it just ended.
-         */
-        void onScanningStatusChanged(boolean started);
-
-        /**
-         * Called when the access points should be enabled or disabled. This is
-         * called from both wpa_supplicant being connected/disconnected and Wi-Fi
-         * being enabled/disabled.
-         * 
-         * @param enabled {@code true} if they should be enabled, {@code false}
-         *            if they should be disabled.
-         */
-        void onAccessPointsStateChanged(boolean enabled);   
-        
-        /**
-         * Called when there is trouble authenticating and the retry-password
-         * dialog should be shown.
-         * 
-         * @param ap The access point.
-         */
-        void onRetryPassword(AccessPointState ap);
-    }
-    
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                handleNetworkStateChanged(
-                        (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
-                        intent.getStringExtra(WifiManager.EXTRA_BSSID));
-            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-                handleScanResultsAvailable();
-            } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
-                handleSupplicantConnectionChanged(
-                        intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false));
-            } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
-                handleSupplicantStateChanged(
-                        (SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE),
-                        intent.hasExtra(WifiManager.EXTRA_SUPPLICANT_ERROR),
-                        intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0));
-            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                        WifiManager.WIFI_STATE_UNKNOWN));
-            } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
-                handleSignalChanged(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, 0));
-            } else if (action.equals(WifiManager.NETWORK_IDS_CHANGED_ACTION)) {
-                handleNetworkIdsChanged();
-            }
-        }
-    };
-    
-    /**
-     * If using this class, make sure to call the callbacks of this class, such
-     * as {@link #onCreate()}, {@link #onCreatedCallback()},
-     * {@link #onPause()}, {@link #onResume()}.
-     * 
-     * @param context The context.
-     * @param callback The interface that will be invoked when events from this
-     *            class are generated.
-     */
-    public WifiLayer(Context context, Callback callback) {
-        mContext = context;
-        mCallback = callback;
-    }
-    
-    //============================
-    // Lifecycle
-    //============================
-
-    /**
-     * The client MUST call this.
-     * <p>
-     * This shouldn't have any dependency on the callback.
-     */
-    public void onCreate() {
-        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-        
-        mIntentFilter = new IntentFilter();
-        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
-        mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
-        
-        WIFI_NUM_OPEN_NETWORKS_KEPT = Settings.Secure.getInt(mContext.getContentResolver(),
-            Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, 10);
-    }
-    
-    /**
-     * The client MUST call this.
-     * <p>
-     * Callback is ready, this can do whatever it wants with it.
-     */
-    public void onCreatedCallback() {
-        if (isWifiEnabled()) {
-            refreshAll(false);
-        }
-    }
-    
-    /**
-     * The client MUST call this.
-     * 
-     * @see android.app.Activity#onResume
-     */
-    public void onResume() {
-        mContext.registerReceiver(mReceiver, mIntentFilter);
-        
-        if (isWifiEnabled()) {
-            // Kick start the continual scan
-            queueContinuousScan();
-        }
-    }
-
-    /**
-     * The client MUST call this.
-     * 
-     * @see android.app.Activity#onPause
-     */
-    public void onPause() {
-        mContext.unregisterReceiver(mReceiver);
-        
-        attemptReenableAllAps();
-        
-        removeFutureScans();
-    }
-    
-    //============================
-    // "Public" API
-    //============================
-
-    /**
-     * Returns an AccessPointState instance (that we track locally in WifiLayer)
-     * for the given state. First, we check if we track the given instance. If
-     * not, we find an equal AccessPointState instance that we track.
-     * 
-     * @param state An AccessPointState instance that does not necessarily have
-     *            to be one that this WifiLayer class tracks. For example, it
-     *            could be the result of unparceling.
-     * @return An AccessPointState instance that this WifiLayer class tracks.
-     */
-    public AccessPointState getWifiLayerApInstance(AccessPointState state) {
-        synchronized (this) {
-            
-            if (hasApInstanceLocked(state)) {
-                return state;
-            }
-            
-            return findApLocked(state.networkId, state.bssid, state.ssid, state.security);
-        }
-    }
-    
-    /**
-     * Connects to the network, and creates the Wi-Fi API config if necessary.
-     * 
-     * @param state The state of the network to connect to. This MUST be an
-     *            instance that was given to you by this class. If you
-     *            constructed the instance yourself (for example, after
-     *            unparceling it), you should use
-     *            {@link #getWifiLayerApInstance(AccessPointState)}.
-     * @return Whether the operation was successful.
-     */
-    public boolean connectToNetwork(AccessPointState state) {
-        if (LOGV) {
-            Log.v(TAG, "Connecting to " + state);
-        }
-        
-        // Need WifiConfiguration for the AP
-        WifiConfiguration config = findConfiguredNetwork(state);
-
-        if (LOGV) {
-            Log.v(TAG, " Found configured network " + config);
-        }
-        
-        if (config == null) {
-            /*
-             * Connecting for the first time, need to create it. We will enable
-             * and save it below (when we set priority).
-             */
-            config = addConfiguration(state, 0);
-
-            if (config == null) {
-                Log.e(TAG, "Config is still null, even after attempting to add it.");
-                error(R.string.error_connecting);
-                return false;
-            }
-
-            /*
-             * We could reload the configured networks, but instead just
-             * shortcut and add this state to our list in memory.
-             */
-            ensureTrackingState(state);
-        } else {
-            // Make sure the configuration has the latest from the state
-            state.updateWifiConfiguration(config);
-        }
-
-        // Enable this network before we save to storage
-        if (!managerEnableNetwork(state, false)) {
-            Log.e(TAG, "Could not enable network ID " + state.networkId);
-            error(R.string.error_connecting);
-            return false;
-        }
-        
-        /*
-         * Give it highest priority, this could cause a network ID change, so do
-         * it after any modifications to the network we're connecting to
-         */
-        setHighestPriorityStateAndSave(state, config);
-        
-        /*
-         * We force supplicant to connect to this network by disabling the
-         * others. We do this AFTER we save above so this disabled flag isn't
-         * persisted.
-         */
-        mReenableApsOnNetworkStateChange = true;
-        if (!managerEnableNetwork(state, true)) {
-            Log.e(TAG, "Could not enable network ID " + state.networkId);
-            error(R.string.error_connecting);
-            return false;
-        }
-
-        if (LOGV) {
-            Log.v(TAG, " Enabled network " + state.networkId);
-        }
-
-        if (mCurrentSupplicantState == SupplicantState.DISCONNECTED ||
-                mCurrentSupplicantState == SupplicantState.SCANNING) {
-            mWifiManager.reconnect();
-        }
-        
-        // Check for too many configured open networks
-        if (!state.hasSecurity()) {
-            checkForExcessOpenNetworks();
-        }
-        
-        return true;
-    }
-    
-    /**
-     * Saves a network, and creates the Wi-Fi API config if necessary.
-     * 
-     * @param state The state of the network to save. If you constructed the
-     *            instance yourself (for example, after unparceling it), you
-     *            should use {@link #getWifiLayerApInstance(AccessPointState)}.
-     * @return Whether the operation was successful.
-     */
-    public boolean saveNetwork(AccessPointState state) {
-        WifiConfiguration config = findConfiguredNetwork(state);
-        
-        if (config == null) {
-            // if the user is adding a new network, assume that it is hidden
-            state.setHiddenSsid(true);
-
-            config = addConfiguration(state, ADD_CONFIGURATION_ENABLE);
-
-            if (config == null) {
-                Log.e(TAG, "Could not save configuration, call to addConfiguration failed.");
-                error(R.string.error_saving);
-                return false;
-            }
-            
-        } else {
-            state.updateWifiConfiguration(config);
-            if (mWifiManager.updateNetwork(config) == -1) {
-                Log.e(TAG, "Could not update configuration, call to WifiManager failed.");
-                error(R.string.error_saving);
-                return false;
-            }
-        }
-        
-        // Successfully added network, go ahead and persist
-        if (!managerSaveConfiguration()) {
-            Log.e(TAG, "Could not save configuration, call to WifiManager failed.");
-            error(R.string.error_saving);
-            return false;
-        }
-        
-        /*
-         * It's necessary to update the network id of this state because the network id
-         * could have changed after the configuration is saved. For example, if there are
-         * more than 10 saved open-networks, some older open-networks will have been be forgotten.
-         */
-        state.setNetworkId(AccessPointState.NETWORK_ID_ANY);
-        config = findConfiguredNetwork(state);
-        if (config != null) {
-            state.setNetworkId(config.networkId);
-        }
-
-        /*
-         * We could reload the configured networks, but instead just shortcut
-         * and add this state to our list in memory
-         */
-        ensureTrackingState(state);
-        
-        return true;
-    }
-    
-    /**
-     * Forgets a network.
-     * 
-     * @param state The state of the network to forget. If you constructed the
-     *            instance yourself (for example, after unparceling it), you
-     *            should use {@link #getWifiLayerApInstance(AccessPointState)}.
-     * @return Whether the operation was succesful.
-     */
-    public boolean forgetNetwork(AccessPointState state) {
-        if (!state.configured) {
-            Log.w(TAG, "Inconsistent state:  Forgetting a network that is not configured.");
-            return true;
-        }
-        
-        int oldNetworkId = state.networkId;
-        state.forget();
-        
-        if (!state.seen) {
-            // If it is not seen, it should be removed from the UI
-            removeApFromUi(state);
-        }
-                    
-        synchronized (this) {
-            mApOtherList.remove(state);
-            // It should not be removed from the scan list, since if it was
-            // there that means it's still seen
-        }
-
-        if (!mWifiManager.removeNetwork(oldNetworkId)) {
-            Log.e(TAG, "Removing network " + state.ssid + " (network ID " + oldNetworkId +
-                    ") failed.");
-            return false;
-        }
-        
-        if (!managerSaveConfiguration()) {
-            error(R.string.error_saving);
-            return false;
-        }
-
-        return true;
-    }
-    
-    /**
-     * This ensures this class is tracking the given state. This means it is in
-     * our list of access points, either in the scanned list or in the
-     * remembered list.
-     * 
-     * @param state The state that will be checked for tracking, and if not
-     *            tracking will be added to the remembered list in memory.
-     */
-    private void ensureTrackingState(AccessPointState state) {
-        synchronized (this) {
-            if (hasApInstanceLocked(state)) {
-                return;
-            }
-            
-            mApOtherList.add(state);
-        }
-    }
-    
-    /**
-     * Attempts to scan networks.  This has a retry mechanism.
-     */
-    public void attemptScan() {
-        
-        // Remove any future scans since we're scanning right now
-        removeFutureScans();
-        
-        if (!mWifiManager.isWifiEnabled()) return;
-        
-        if (!mWifiManager.startScanActive()) {
-            postAttemptScan();
-        } else {
-            mScanRetryCount = 0;
-        }
-    }
-
-    private void queueContinuousScan() {
-        mHandler.removeMessages(MESSAGE_ATTEMPT_SCAN);
-        
-        if (!mIsObtainingAddress) {
-            // Don't do continuous scan while in obtaining IP state
-            mHandler.sendEmptyMessageDelayed(MESSAGE_ATTEMPT_SCAN, CONTINUOUS_SCAN_DELAY_MS);
-        }
-    }
-    
-    private void removeFutureScans() {
-        mHandler.removeMessages(MESSAGE_ATTEMPT_SCAN);
-    }
-    
-    public boolean isWifiEnabled() {
-        return mWifiManager.isWifiEnabled();
-    }
-    
-    public void error(int messageResId) {
-        Log.e(TAG, mContext.getResources().getString(messageResId));
-        
-        if (mCallback != null) {
-            mCallback.onError(messageResId);
-        }
-    }
-    
-    //============================
-    // Wifi logic
-    //============================
-
-    private void refreshAll(boolean attemptScan) {
-        loadConfiguredAccessPoints();
-        refreshStatus();
-        
-        if (attemptScan) {
-            attemptScan();
-        }
-    }
-    
-    private void postAttemptScan() {
-        onScanningStarted();
-
-        if (++mScanRetryCount < SCAN_MAX_RETRY) {
-            // Just in case, remove previous ones first
-            removeFutureScans();
-            mHandler.sendEmptyMessageDelayed(MESSAGE_ATTEMPT_SCAN, SCAN_RETRY_DELAY_MS);
-        } else {
-            // Show an error once we run out of attempts
-            error(R.string.error_scanning);
-            onScanningEnded();
-        }
-    }
-    
-    private void onScanningStarted() {
-        if (mCallback != null) {
-            mCallback.onScanningStatusChanged(true);
-        }
-    }
-    
-    private void onScanningEnded() {
-        queueContinuousScan();
-        
-        if (mCallback != null) {
-            mCallback.onScanningStatusChanged(false);
-        }
-    }
-    
-    private void clearApLists() {
-        List<AccessPointState> accessPoints = new ArrayList<AccessPointState>();
-        
-        synchronized(this) {
-            // Clear the logic's list of access points
-            accessPoints.addAll(mApScanList);
-            accessPoints.addAll(mApOtherList);
-            mApScanList.clear();
-            mApOtherList.clear();
-        }
-        
-        for (int i = accessPoints.size() - 1; i >= 0; i--) {
-            removeApFromUi(accessPoints.get(i));
-        }
-    }
-    
-    private boolean managerSaveConfiguration() {
-        boolean retValue = mWifiManager.saveConfiguration();
-        
-        /*
-         * We need to assume the network IDs have changed, so handle this. Note:
-         * we also have a receiver on the broadcast intent in case another wifi
-         * framework client caused the change. In this case, we will handle the
-         * possible network ID change twice (but it's not too costly).
-         */
-        handleNetworkIdsChanged();
-        
-        return retValue;
-    }
-    
-    private boolean managerEnableNetwork(AccessPointState state, boolean disableOthers) {
-        if (!mWifiManager.enableNetwork(state.networkId, disableOthers)) {
-            return false;
-        }
-        
-        // Enabling was successful, make sure the state is not disabled
-        state.setDisabled(false);
-        
-        return true;
-    }
-    
-    private static final int ADD_CONFIGURATION_ENABLE = 1;
-    private static final int ADD_CONFIGURATION_SAVE = 2;
-    private WifiConfiguration addConfiguration(AccessPointState state, int flags) {
-        // Create and add
-        WifiConfiguration config = new WifiConfiguration();
-        
-        state.updateWifiConfiguration(config);
-        
-        final int networkId = mWifiManager.addNetwork(config);
-        if (networkId == -1) {
-            return null;
-        }
-        
-        state.setNetworkId(networkId);
-        state.setConfigured(true);
-        
-        // If we should, then enable it, since it comes disabled by default
-        if ((flags & ADD_CONFIGURATION_ENABLE) != 0
-                && !managerEnableNetwork(state, false)) {
-            return null;
-        }
-
-        // If we should, then save it
-        if ((flags & ADD_CONFIGURATION_SAVE) != 0 && !managerSaveConfiguration()) {
-            return null;
-        }
-
-        if (mCallback != null) {
-            mCallback.onAccessPointSetChanged(state, true);
-        }
-
-        return config;
-    }
-    
-    private WifiConfiguration findConfiguredNetwork(AccessPointState state) {
-        final List<WifiConfiguration> wifiConfigs = getConfiguredNetworks();
-        
-        for (int i = wifiConfigs.size() - 1; i >= 0; i--) {
-            final WifiConfiguration wifiConfig = wifiConfigs.get(i); 
-            if (state.matchesWifiConfiguration(wifiConfig) >= AccessPointState.MATCH_WEAK) {
-                return wifiConfig;
-            }
-        }
-        
-        return null;
-    }
-    
-    private List<WifiConfiguration> getConfiguredNetworks() {
-        final List<WifiConfiguration> wifiConfigs = mWifiManager.getConfiguredNetworks();
-        return wifiConfigs;
-    }
-    
-    /**
-     * Must call while holding the lock for the list, which is usually the
-     * WifiLayer instance.
-     */
-    private static AccessPointState findApLocked(List<AccessPointState> list, int networkId,
-            String bssid, String ssid, String security) {
-        AccessPointState ap;
-        for (int i = list.size() - 1; i >= 0; i--) {
-            ap = list.get(i);
-            if (ap.matches(networkId, bssid, ssid, security) >= AccessPointState.MATCH_WEAK) {
-                return ap;
-            }
-        }
-
-        return null;
-    }
-    
-    /**
-     * Must call while holding the lock for the lists, which is usually this
-     * WifiLayer instance.
-     */
-    private AccessPointState findApLocked(int networkId, String bssid, String ssid,
-            String security) {
-        AccessPointState ap = findApLocked(mApScanList, networkId, bssid, ssid, security);
-        if (ap == null) {
-            ap = findApLocked(mApOtherList, networkId, bssid, ssid, security);
-        }
-        return ap;
-    }
-
-    /**
-     * Returns whether we have the exact instance of the access point state
-     * given. This is useful in cases where an AccessPointState has been
-     * parceled by the client and the client is attempting to use it to
-     * connect/forget/save.
-     * <p>
-     * Must call while holding the lock for the lists, which is usually this
-     * WifiLayer instance.
-     */
-    private boolean hasApInstanceLocked(AccessPointState state) {
-        
-        for (int i = mApScanList.size() - 1; i >= 0; i--) {
-            if (mApScanList.get(i) == state) {
-                return true;
-            }
-        }
-
-        for (int i = mApOtherList.size() - 1; i >= 0; i--) {
-            if (mApOtherList.get(i) == state) {
-                return true;
-            }
-        }
-        
-        return false;
-    }
-    
-    private void loadConfiguredAccessPoints() {
-        final List<WifiConfiguration> configs = getConfiguredNetworks();
-        
-        for (int i = configs.size() - 1; i >= 0; i--) {
-            final WifiConfiguration config = configs.get(i);
-            
-            AccessPointState ap;
-            synchronized(this) {
-                ap = findApLocked(config.networkId, config.BSSID, config.SSID,
-                        AccessPointState.getWifiConfigurationSecurity(config));
-                
-                if (ap != null) {
-                    // We already know about this one
-                    continue;
-                }
-                ap = new AccessPointState(mContext);
-                ap.updateFromWifiConfiguration(config);
-                if (LOGV) Log.v(TAG, "Created " + ap + " in loadConfiguredAccessPoints");
-                mApOtherList.add(ap);
-            }
-
-            // Make sure our next highest priority is greater than this
-            checkNextHighestPriority(ap.priority);
-            
-            if (mCallback != null) {
-                mCallback.onAccessPointSetChanged(ap, true);
-            }
-        }
-    }
-
-    private AccessPointState getCurrentAp() {
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        
-        String ssid = wifiInfo.getSSID();
-        if (ssid != null) {
-            /*
-             * We pass null for security since we have a network ID (i.e., it's
-             * not a wildcard), and rely on it matching.
-             */
-            synchronized (this) {
-                return findApLocked(wifiInfo.getNetworkId(), wifiInfo.getBSSID(), ssid, null);
-            }
-        } else {
-            return null;
-        }
-    }
-    
-    private void setPrimaryAp(AccessPointState ap) {
-        synchronized (this) {
-            // Unset other
-            if (mCurrentPrimaryAp != null) {
-                mCurrentPrimaryAp.setPrimary(false);
-            }
-
-            mCurrentPrimaryAp = ap;
-        }
-
-        if (ap != null) {
-            ap.setPrimary(true);
-        }
-    }
-
-    private void attemptReenableAllAps() {
-        if (mReenableApsOnNetworkStateChange) {
-            mReenableApsOnNetworkStateChange = false;
-            enableAllAps();
-        }
-    }
-    
-    private void enableAllAps() {
-        synchronized(this) {
-            if (LOGV) {
-                Log.v(TAG, " Enabling all APs");
-            }
-            
-            enableApsLocked(mApOtherList);
-            enableApsLocked(mApScanList);
-        }
-    }
-    
-    private void enableApsLocked(List<AccessPointState> apList) {
-        for (int i = apList.size() - 1; i >= 0; i--) {
-            AccessPointState state = apList.get(i);
-            int networkId = state.networkId;
-            if (networkId != AccessPointState.NETWORK_ID_NOT_SET &&
-                    networkId != AccessPointState.NETWORK_ID_ANY) {
-                managerEnableNetwork(state, false);
-            }
-        }
-    }
-    
-    private void removeApFromUi(AccessPointState ap) {
-        if (mCallback != null) {
-            mCallback.onAccessPointSetChanged(ap, false);
-        }
-    }
-    
-    /**
-     * Sets the access point state to the highest priority.
-     * <p>
-     * If you have a list of configured networks from WifiManager, you probably
-     * shouldn't call this until you're done traversing the list.
-     * 
-     * @param state The state to set as the highest priority.
-     * @param reusableConfiguration An optional WifiConfiguration that will be
-     *            given to the WifiManager as updated data for the network ID.
-     *            This will be filled with the new priority.
-     * @return Whether the operation was successful.
-     */
-    private boolean setHighestPriorityStateAndSave(AccessPointState state,
-            WifiConfiguration reusableConfiguration) {
-
-        if (!isConsideredForHighestPriority(state)) {
-            Log.e(TAG,
-                    "Could not set highest priority on state because state is not being considered.");
-            return false;
-        }
-        
-        if (reusableConfiguration == null) {
-            reusableConfiguration = new WifiConfiguration();
-        }
-        
-        int oldPriority = reusableConfiguration.priority;
-        reusableConfiguration.priority = getNextHighestPriority();
-        reusableConfiguration.networkId = state.networkId;
-        
-        if (mWifiManager.updateNetwork(reusableConfiguration) == -1) {
-            // Rollback priority
-            reusableConfiguration.priority = oldPriority;
-            Log.e(TAG,
-                    "Could not set highest priority on state because updating the supplicant network failed.");
-            return false;
-        }
-
-        if (!managerSaveConfiguration()) {
-            reusableConfiguration.priority = oldPriority;
-            Log.e(TAG,
-                    "Could not set highest priority on state because saving config failed.");
-            return false;
-        }
-        
-        state.priority = reusableConfiguration.priority;
-        
-        if (LOGV) {
-            Log.v(TAG, " Set highest priority to "
-                    + state.priority + " from " + oldPriority);
-        }
-        
-        return true;
-    }
-
-    /**
-     * Makes sure the next highest priority is larger than the given priority.
-     */
-    private void checkNextHighestPriority(int priority) {
-        if (priority > HIGHEST_PRIORITY_MAX_VALUE || priority < 0) {
-            // This is a priority that we aren't managing
-            return;
-        }
-        
-        if (mNextHighestPriority <= priority) {
-            mNextHighestPriority = priority + 1;
-        }
-    }
-
-    /**
-     * Checks if there are too many open networks, and removes the excess ones.
-     */
-    private void checkForExcessOpenNetworks() {
-        synchronized(this) {
-            ArrayList<AccessPointState> allAps = getApsSortedByPriorityLocked();
-
-            // Walk from highest to lowest priority
-            int openConfiguredCount = 0;
-            for (int i = allAps.size() - 1; i >= 0; i--) {
-                AccessPointState state = allAps.get(i);
-                if (state.configured && !state.hasSecurity()) {
-                    openConfiguredCount++;
-                    if (openConfiguredCount > WIFI_NUM_OPEN_NETWORKS_KEPT) {
-                        // Remove this network
-                        forgetNetwork(state);
-                    }
-                }
-            }
-        }
-    }
-    
-    private boolean isConsideredForHighestPriority(AccessPointState state) {
-        return state.configured && state.networkId != AccessPointState.NETWORK_ID_ANY &&
-                state.networkId != AccessPointState.NETWORK_ID_NOT_SET;
-    }
-    
-    /**
-     * Gets the next highest priority. If this value is larger than the max,
-     * shift all the priorities so the lowest starts at 0.
-     * <p>
-     * Only
-     * {@link #setHighestPriorityStateAndSave(AccessPointState, WifiConfiguration)}
-     * should call this.
-     * 
-     * @return The next highest priority to use.
-     */
-    private int getNextHighestPriority() {
-        if (mNextHighestPriority > HIGHEST_PRIORITY_MAX_VALUE) {
-            shiftPriorities();
-        }
-        
-        return mNextHighestPriority++;
-    }
-
-    /**
-     * Shift all the priorities so the lowest starts at 0.
-     * 
-     * @return Whether the operation was successful.
-     */
-    private boolean shiftPriorities() {
-        synchronized(this) {
-
-            ArrayList<AccessPointState> allAps = getApsSortedByPriorityLocked();
-
-            // Re-usable WifiConfiguration for setting priority
-            WifiConfiguration updatePriorityConfig = new WifiConfiguration();
-            
-            // Set new priorities
-            mNextHighestPriority = 0;
-            int size = allAps.size();
-            for (int i = 0; i < size; i++) {
-                AccessPointState state = allAps.get(i);
-                
-                if (!isConsideredForHighestPriority(state)) {
-                    continue;
-                }
-                
-                if (!setHighestPriorityStateAndSave(state, updatePriorityConfig)) {
-                    Log.e(TAG,
-                            "Could not shift priorities because setting the new priority failed.");
-                    return false;
-                }
-            }
-            
-            return true;
-        }
-    }
-
-    private ArrayList<AccessPointState> getApsSortedByPriorityLocked() {
-        // Get all of the access points we have
-        ArrayList<AccessPointState> allAps = new ArrayList<AccessPointState>(mApScanList.size()
-                + mApOtherList.size());
-        allAps.addAll(mApScanList);
-        allAps.addAll(mApOtherList);
-        
-        // Sort them based on priority
-        Collections.sort(allAps, new Comparator<AccessPointState>() {
-            public int compare(AccessPointState object1, AccessPointState object2) {
-                return object1.priority - object2.priority;
-            }
-        });
-
-        return allAps;
-    }
-    
-    //============================
-    // Status related
-    //============================
-
-    private void refreshStatus() {
-        refreshStatus(null, null);
-    }
-    
-    private void refreshStatus(AccessPointState ap, NetworkInfo.DetailedState detailedState) {
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        if (detailedState == null) {
-            detailedState = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState());
-        }
-
-        if (ap == null && WifiStatus.isLiveConnection(detailedState)) {
-            /*
-             * We pass null for security since we have a network ID (i.e., it's
-             * not a wildcard), and rely on it matching.
-             */
-            synchronized (this) {
-                ap = findApLocked(wifiInfo.getNetworkId(), wifiInfo.getBSSID(), wifiInfo
-                        .getSSID(), null);
-            }
-        }
-
-        if (ap != null) {
-            ap.blockRefresh();
-
-            // Let the AP get the latest info from the WifiInfo 
-            ap.updateFromWifiInfo(wifiInfo, detailedState);
-
-            // The detailed state from the Intent has more states than the WifiInfo's detailed
-            // state can have (for example, DHCP completion).  Set the status using
-            // the Intent's detailed state.
-            ap.setStatus(detailedState);
-            ap.unblockRefresh();
-        }
-    }
-    
-    //============================
-    // Wifi callbacks
-    //============================
-    
-    private void handleNetworkStateChanged(NetworkInfo info, String bssid) {
-        final AccessPointState ap = getCurrentAp();
-        NetworkInfo.DetailedState detailedState = info.getDetailedState(); 
-
-        if (LOGV) {
-            Log.v(TAG, "State change received " + info.toString() + ", or "
-                    + detailedState + " on " + bssid + " matched to " + ap);
-        }
-
-        handleDisablingScanWhileObtainingAddress(detailedState);
-        
-        // This will update the AP with its new info
-        refreshStatus(ap, detailedState);
-        
-        boolean isDisconnected = info.getState().equals(State.DISCONNECTED);
-        if (ap != null && info.isConnectedOrConnecting()) {
-            setPrimaryAp(ap);
-
-            if (LOGV) {
-                Log.v(TAG, " Updated " + ap + " to be primary");
-            }
-            
-        } else if (isDisconnected) {
-            
-            /*
-             * When we drop off a network (for example, the router is powered
-             * down when we were connected), we received a DISCONNECT event
-             * without a BSSID. We should not have a primary AP anymore.
-             */
-            setPrimaryAp(null);
-            
-            if (LOGV) {
-                Log.v(TAG, " Cleared primary");
-            }
-            
-        } else if (detailedState.equals(DetailedState.FAILED)) {
-
-            /*
-             * Doh, failed for whatever reason. Unset the primary AP, but set
-             * failed status on the AP that failed.
-             */
-            setPrimaryAp(null);
-            ap.setStatus(DetailedState.FAILED);
-            
-            // Bring up error dialog
-            error(R.string.wifi_generic_connection_error);
-            
-        } else if (LOGV) {
-            Log.v(TAG, " Did not update any AP to primary, could have updated "
-                    + ap + " but we aren't connected or connecting");
-        }
-
-        if ((ap != null) && (info.isConnected()
-                    || (detailedState == DetailedState.OBTAINING_IPADDR))) {
-            /*
-             * Sometimes the scan results do not contain the AP even though it's
-             * clearly connected. This may be because we do passive background
-             * scanning that isn't as 'strong' as active scanning, so even
-             * though a network is nearby, it won't be seen by the passive
-             * scanning. If we are connected (or obtaining IP) then we know it
-             * is seen.
-             */
-            ap.setSeen(true);
-        }
-
-        attemptReenableAllAps();
-    }
-
-    private void handleDisablingScanWhileObtainingAddress(DetailedState detailedState) {
-        
-        if (detailedState == DetailedState.OBTAINING_IPADDR) {
-            mIsObtainingAddress = true;
-
-            // We will not scan while obtaining an IP address
-            removeFutureScans();
-            
-        } else {
-            mIsObtainingAddress = false;
-            
-            // Start continuous scan
-            queueContinuousScan();
-        }
-    }
-    
-    private void handleScanResultsAvailable() {
-        synchronized(this) {
-            // In the end, we'll moved the ones no longer seen into the mApOtherList
-            List<AccessPointState> oldScanList = mApScanList;
-            List<AccessPointState> newScanList =
-                    new ArrayList<AccessPointState>(oldScanList.size());
-
-            List<ScanResult> list = mWifiManager.getScanResults();
-            if (list != null) {
-                for (int i = list.size() - 1; i >= 0; i--) {
-                    final ScanResult scanResult = list.get(i);
-                    
-                    if (LOGV) {
-//                        Log.v(TAG, "    " + scanResult);
-                    }
-                    
-                    if (scanResult == null) {
-                        continue;
-                    }
-                    
-                    /*
-                     * Ignore adhoc, enterprise-secured, or hidden networks.
-                     * Hidden networks show up with empty SSID.
-                     */
-                    if (AccessPointState.isAdhoc(scanResult)
-                            || TextUtils.isEmpty(scanResult.SSID)) {
-                        continue;
-                    }
-                    
-                    final String ssid = scanResult.SSID;
-                    String security = AccessPointState.getScanResultSecurity(scanResult);
-                    
-                    // See if this AP is part of a group of APs (e.g., any large
-                    // wifi network has many APs, we'll only show one) that we've
-                    // seen in this scan
-                    AccessPointState ap = findApLocked(newScanList, AccessPointState.NETWORK_ID_ANY,
-                                                 AccessPointState.BSSID_ANY, ssid, security);
-
-                    // Yup, we've seen this network.
-                    if (ap != null) {
-                        // Use the better signal
-                        if (WifiManager.compareSignalLevel(scanResult.level, ap.signal) > 0) {
-                            ap.setSignal(scanResult.level);
-                        }
-                        
-                        if (LOGV) {
-//                            Log.v(TAG, "         Already seen, continuing..");
-                        }
-                        
-                        continue;
-                    }
-
-                    // Find the AP in either our old scan list, or our non-seen
-                    // configured networks list
-                    ap = findApLocked(AccessPointState.NETWORK_ID_ANY, AccessPointState.BSSID_ANY,
-                                ssid, security);
-
-                    if (ap != null) {
-                        // Remove the AP from both (no harm if one doesn't contain it)
-                        oldScanList.remove(ap);
-                        mApOtherList.remove(ap);
-                    } else {
-                        ap = new AccessPointState(mContext);
-//                        if (LOGV) Log.v(TAG, "Created " + ap);
-                    }
-
-                    // Give it the latest state
-                    ap.updateFromScanResult(scanResult);
-
-                    if (mCallback != null) {
-                        mCallback.onAccessPointSetChanged(ap, true);
-                    }
-
-                    newScanList.add(ap);
-                }
-            }
-            
-            // oldScanList contains the ones no longer seen
-            List<AccessPointState> otherList = mApOtherList;
-            for (int i = oldScanList.size() - 1; i >= 0; i--) {
-                final AccessPointState ap = oldScanList.get(i);
-                
-                if (ap.configured) {
-                    
-                    // Keep it around, since it is configured
-                    ap.setSeen(false);
-                    otherList.add(ap);
-                    
-                } else {
-                    
-                    // Remove it since it is not configured and not seen
-                    removeApFromUi(ap);
-                }
-            }
-            
-            mApScanList = newScanList;
-        }
-
-        onScanningEnded();
-    }
-    
-    private void handleSupplicantConnectionChanged(boolean connected) {
-        if (mCallback != null) {
-            mCallback.onAccessPointsStateChanged(connected);
-        }
-        
-        if (connected) {
-            refreshAll(true);
-        }
-    }
-
-    private void handleWifiStateChanged(int wifiState) {
-        
-        if (wifiState == WIFI_STATE_ENABLED) {
-            loadConfiguredAccessPoints();
-            attemptScan();
-
-        } else if (wifiState == WIFI_STATE_DISABLED) {
-            removeFutureScans();
-            if (LOGV) Log.v(TAG, "Clearing AP lists because wifi is disabled");
-            clearApLists();
-        }
-        
-        if (mCallback != null) {
-            mCallback.onAccessPointsStateChanged(wifiState == WIFI_STATE_ENABLED);
-        }
-    }
-    
-    private void handleSignalChanged(int rssi) {
-        
-        if (mCurrentPrimaryAp != null) {
-            mCurrentPrimaryAp.setSignal(rssi);
-        }
-    }
-
-    private void handleSupplicantStateChanged(SupplicantState state, boolean hasError, int error) {
-        mCurrentSupplicantState = state;
-        
-        if (SupplicantState.FOUR_WAY_HANDSHAKE.equals(state)) {
-            mLastAuthenticatingAp = getCurrentAp();
-        }
-        
-        if (hasError) {
-            handleSupplicantStateError(error);
-        }
-    }
-    
-    private void handleSupplicantStateError(int supplicantError) {
-        if (supplicantError == WifiManager.ERROR_AUTHENTICATING) {
-            if (mCallback != null) {
-                if (mLastAuthenticatingAp != null) {
-                    mCallback.onRetryPassword(mLastAuthenticatingAp);
-                }
-            }
-        }
-    }
-    
-    private void handleNetworkIdsChanged() {
-        synchronized (this) {
-            final List<WifiConfiguration> configs = getConfiguredNetworks();
-            
-            for (int i = configs.size() - 1; i >= 0; i--) {
-                final WifiConfiguration config = configs.get(i);
-                
-                AccessPointState ap;
-                // Since network IDs have changed, we can't use it to find our previous AP state
-                ap = findApLocked(AccessPointState.NETWORK_ID_ANY, config.BSSID, config.SSID,
-                        AccessPointState.getWifiConfigurationSecurity(config));
-                
-                if (ap == null) {
-                    continue;
-                }
-
-                ap.setNetworkId(config.networkId);
-            }
-        }
-    }
-    
-    private class MyHandler extends Handler {
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MESSAGE_ATTEMPT_SCAN:
-                    attemptScan();
-                    break;
-            }
-        }
-    }
-    
-}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 04f6aa4..e06dcd4 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,465 +19,472 @@
 import com.android.settings.ProgressCategory;
 import com.android.settings.R;
 
-import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.DetailedState;
+import android.net.wifi.ScanResult;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiConfiguration.Status;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 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.preference.CheckBoxPreference;
-import android.provider.Settings;
+import android.provider.Settings.Secure;
 import android.security.Credentials;
 import android.security.KeyStore;
-import android.util.Log;
+import android.text.TextUtils;
 import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.AdapterView;
-import android.widget.Toast;
 import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.Toast;
 
-import java.util.Set;
-import java.util.WeakHashMap;
+import java.util.ArrayList;
+import java.util.List;
 
-/**
- * Settings screen for WiFi. This will be launched from the main system settings.
- */
-public class WifiSettings extends PreferenceActivity implements WifiLayer.Callback,
-        DialogInterface.OnDismissListener {
-
-    private static final String TAG = "WifiSettings";
-
-    //============================
-    // Preference/activity member variables
-    //============================
-
-    private static final String INSTANCE_KEY_DIALOG_BUNDLE =
-            "com.android.settings.wifi.WifiSettings:dialogBundle";
-    /*
-     * We don't use Activity's dialog management because AlertDialog isn't fully
-     * able to change many of its features after it's been created, and the
-     * dialog management only creates once.
-     */
-    private Dialog mDialog;
-
-    private static final String KEY_ONLY_ACCESS_POINTS = "only_access_points";
-    private static final String KEY_ADD_OTHER_NETWORK = "add_other_network";
-
-    private static final int CONTEXT_MENU_ID_CONNECT = Menu.FIRST;
-    private static final int CONTEXT_MENU_ID_FORGET = Menu.FIRST + 1;
-    private static final int CONTEXT_MENU_ID_CHANGE_PASSWORD = Menu.FIRST + 2;
-
+public class WifiSettings extends PreferenceActivity implements DialogInterface.OnClickListener {
     private static final int MENU_ID_SCAN = Menu.FIRST;
     private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
+    private static final int MENU_ID_CONNECT = Menu.FIRST + 2;
+    private static final int MENU_ID_FORGET = Menu.FIRST + 3;
+    private static final int MENU_ID_MODIFY = Menu.FIRST + 4;
 
-    private static final String KEY_WIFI_ENABLED = "wifi_enabled";
-    private static final String KEY_OPEN_NETWORK_NOTIFICATIONS_ENABLED =
-            "open_network_notifications_enabled";
-    private static final String KEY_ACCESS_POINTS = "access_points";
+    private final IntentFilter mFilter;
+    private final BroadcastReceiver mReceiver;
+    private final Scanner mScanner;
 
-    private ProgressCategory mApCategory;
-    private CheckBoxPreference mWifiEnabled;
+    private WifiManager mWifiManager;
     private WifiEnabler mWifiEnabler;
-    private CheckBoxPreference mOpenNetworkNotificationsEnabled;
-    private Preference mAddOtherNetwork;
+    private CheckBoxPreference mNotifyOpenNetworks;
+    private ProgressCategory mAccessPoints;
+    private Preference mAddNetwork;
 
-    private WeakHashMap<AccessPointState, AccessPointPreference> mAps;
+    private DetailedState mLastState;
+    private WifiInfo mLastInfo;
+    private int mLastPriority;
 
-    private KeyStore mKeyStore = KeyStore.getInstance();
-    private AccessPointState mResumeState = null;
-    private int mResumeMode;
+    private boolean mResetNetworks = false;
+    private int mKeyStoreNetworkId = -1;
 
-    //============================
-    // Wifi member variables
-    //============================
-
-    private WifiLayer mWifiLayer;
-
-    //============================
-    // Activity lifecycle
-    //============================
+    private AccessPoint mSelected;
+    private WifiDialog mDialog;
 
     public WifiSettings() {
-        mAps = new WeakHashMap<AccessPointState, AccessPointPreference>();
-        mWifiLayer = new WifiLayer(this, this);
+        mFilter = new IntentFilter();
+        mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
+        mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
+        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
+
+        mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                handleEvent(intent);
+            }
+        };
+
+        mScanner = new Scanner();
     }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        onCreatePreferences();
-        mWifiLayer.onCreate();
+        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
 
-        onCreatedWifi();
-        mWifiLayer.onCreatedCallback();
-    }
-
-    private int getPreferenceResource() {
-        if (getIntent().getBooleanExtra(KEY_ONLY_ACCESS_POINTS, false)) {
-            return R.xml.wifi_access_points;
+        if (getIntent().getBooleanExtra("only_access_points", false)) {
+            addPreferencesFromResource(R.xml.wifi_access_points);
         } else {
-            return R.xml.wifi_settings;
-        }
-    }
-
-    /**
-     * Shouldn't have any dependency on the wifi layer.
-     */
-    private void onCreatePreferences() {
-        addPreferencesFromResource(getPreferenceResource());
-
-        final PreferenceScreen preferenceScreen = getPreferenceScreen();
-
-        mApCategory = (ProgressCategory) preferenceScreen.findPreference(KEY_ACCESS_POINTS);
-        // We don't want the ordering to be the order preferences are added,
-        // instead we want*:
-        //   1) preferred, visible APs
-        //   2) visible APs
-        //   3) preferred, APs out of range
-        //   * this ordering logic is in AccessPointPreference's compareTo
-        mApCategory.setOrderingAsAdded(false);
-
-        if (!getIntent().getBooleanExtra(KEY_ONLY_ACCESS_POINTS, false)) {
-            mWifiEnabled = (CheckBoxPreference) preferenceScreen.findPreference(KEY_WIFI_ENABLED);
-            mWifiEnabler = new WifiEnabler(this, (WifiManager) getSystemService(WIFI_SERVICE),
-                    mWifiEnabled);
-
-            mOpenNetworkNotificationsEnabled = (CheckBoxPreference) preferenceScreen
-                    .findPreference(KEY_OPEN_NETWORK_NOTIFICATIONS_ENABLED);
-            mOpenNetworkNotificationsEnabled.setChecked(Settings.Secure.getInt(getContentResolver(),
-                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);
+            addPreferencesFromResource(R.xml.wifi_settings);
+            mWifiEnabler = new WifiEnabler(this,
+                    (CheckBoxPreference) findPreference("enable_wifi"));
+            mNotifyOpenNetworks =
+                    (CheckBoxPreference) findPreference("notify_open_networks");
+            mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(),
+                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);
         }
 
-        mAddOtherNetwork = preferenceScreen.findPreference(KEY_ADD_OTHER_NETWORK);
+        mAccessPoints = (ProgressCategory) findPreference("access_points");
+        mAccessPoints.setOrderingAsAdded(false);
+        mAddNetwork = findPreference("add_network");
 
         registerForContextMenu(getListView());
     }
 
-    private void onCreatedWifi() {
-    }
-
     @Override
     protected void onResume() {
         super.onResume();
-        mWifiLayer.onResume();
         if (mWifiEnabler != null) {
             mWifiEnabler.resume();
         }
-        // do what we should have after keystore is unlocked.
-        if (mResumeState != null) {
-            if (mKeyStore.test() == KeyStore.NO_ERROR) {
-                showAccessPointDialog(mResumeState, mResumeMode);
-            }
-            mResumeMode = -1;
-            mResumeState = null;
-        } else {
-            if (mResumeMode == AccessPointDialog.MODE_CONFIGURE) {
-                if (mKeyStore.test() == KeyStore.NO_ERROR) {
-                    ((AccessPointDialog) mDialog).enableEnterpriseFields();
+        registerReceiver(mReceiver, mFilter);
+        if (mKeyStoreNetworkId != -1 && KeyStore.getInstance().test() == KeyStore.NO_ERROR) {
+            connect(mKeyStoreNetworkId);
+        }
+        mKeyStoreNetworkId = -1;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (mWifiEnabler != null) {
+            mWifiEnabler.pause();
+        }
+        unregisterReceiver(mReceiver);
+        mScanner.pause();
+        if (mDialog != null) {
+            mDialog.dismiss();
+            mDialog = null;
+        }
+        if (mResetNetworks) {
+            enableNetworks();
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)
+                .setIcon(R.drawable.ic_menu_scan_network);
+        menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)
+                .setIcon(android.R.drawable.ic_menu_manage);
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_ID_SCAN:
+                mScanner.resume();
+                return true;
+            case MENU_ID_ADVANCED:
+                startActivity(new Intent(this, AdvancedSettings.class));
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) {
+        if (info instanceof AdapterContextMenuInfo) {
+            Preference preference = (Preference) getListView().getItemAtPosition(
+                    ((AdapterContextMenuInfo) info).position);
+
+            if (preference instanceof AccessPoint) {
+                mSelected = (AccessPoint) preference;
+                menu.setHeaderTitle(mSelected.ssid);
+                if (mSelected.getLevel() != -1 && mSelected.getState() == null) {
+                    menu.add(Menu.NONE, MENU_ID_CONNECT, 0, R.string.wifi_menu_connect);
+                }
+                if (mSelected.networkId != -1) {
+                    menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget);
+                    if (mSelected.security != AccessPoint.SECURITY_NONE) {
+                        menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
+                    }
                 }
             }
         }
     }
 
     @Override
-    protected void onPause() {
-        super.onPause();
-        mWifiLayer.onPause();
-        if (mWifiEnabler != null) {
-            mWifiEnabler.pause();
+    public boolean onContextItemSelected(MenuItem item) {
+        if (mSelected == null) {
+            return super.onContextItemSelected(item);
         }
-        if (mDialog != null) {
-            mDialog.dismiss();
+        switch (item.getItemId()) {
+            case MENU_ID_CONNECT:
+                if (mSelected.networkId != -1) {
+                    if (!requireKeyStore(mSelected.getConfig())) {
+                        connect(mSelected.networkId);
+                    }
+                } else if (mSelected.security == AccessPoint.SECURITY_NONE) {
+                    // Shortcut for open networks.
+                    WifiConfiguration config = new WifiConfiguration();
+                    config.SSID = mSelected.ssid;
+                    config.allowedKeyManagement.set(KeyMgmt.NONE);
+                    int networkId = mWifiManager.addNetwork(config);
+                    mWifiManager.enableNetwork(networkId, false);
+                    connect(networkId);
+                } else {
+                    showDialog(mSelected, false);
+                }
+                return true;
+            case MENU_ID_FORGET:
+                forget(mSelected.networkId);
+                return true;
+            case MENU_ID_MODIFY:
+                showDialog(mSelected, true);
+                return true;
         }
+        return super.onContextItemSelected(item);
     }
 
     @Override
-    protected void onDestroy() {
-        super.onDestroy();
-
-        if (mDialog != null) {
-            mDialog.dismiss();
+    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
+        if (preference instanceof AccessPoint) {
+            mSelected = (AccessPoint) preference;
+            showDialog(mSelected, false);
+        } else if (preference == mAddNetwork) {
+            mSelected = null;
+            showDialog(null, true);
+        } else if (preference == mNotifyOpenNetworks) {
+            Secure.putInt(getContentResolver(),
+                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
+                    mNotifyOpenNetworks.isChecked() ? 1 : 0);
+        } else {
+            return super.onPreferenceTreeClick(screen, preference);
         }
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
-
-        menu.add(0, MENU_ID_SCAN, 0, R.string.scan_wifi)
-            .setIcon(R.drawable.ic_menu_scan_network);
-
-        menu.add(0, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)
-            .setIcon(android.R.drawable.ic_menu_manage);
-
         return true;
     }
 
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        super.onOptionsItemSelected(item);
+    public void onClick(DialogInterface dialogInterface, int button) {
+        if (button == WifiDialog.BUTTON_FORGET && mSelected != null) {
+            forget(mSelected.networkId);
+        } else if (button == WifiDialog.BUTTON_SUBMIT) {
+            WifiConfiguration config = mDialog.getConfig();
 
-        switch (item.getItemId()) {
-
-            case MENU_ID_SCAN:
-                mWifiLayer.attemptScan();
-                return true;
-
-            case MENU_ID_ADVANCED:
-                Intent intent = new Intent(this, AdvancedSettings.class);
-                startActivity(intent);
-                return true;
-
-            default:
-                return false;
-        }
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-
-        if (mDialog != null) {
-            Bundle dialogBundle = mDialog.onSaveInstanceState();
-            outState.putBundle(INSTANCE_KEY_DIALOG_BUNDLE, dialogBundle);
-        }
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-
-        Bundle dialogBundle = state.getBundle(INSTANCE_KEY_DIALOG_BUNDLE);
-        if (dialogBundle != null) {
-            mDialog = new AccessPointDialog(this, mWifiLayer);
-            mDialog.onRestoreInstanceState(dialogBundle);
-            showDialog(mDialog);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void onDismiss(DialogInterface dialog) {
-        if (dialog == mDialog) {
-            mDialog = null;
-            mResumeMode = -1;
-        }
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-        super.onCreateContextMenu(menu, v, menuInfo);
-
-        AccessPointState state = getStateFromMenuInfo(menuInfo);
-        if (state == null) {
-            return;
-        }
-        menu.setHeaderTitle(state.ssid);
-
-        if (state.isConnectable()) {
-            menu.add(0, CONTEXT_MENU_ID_CONNECT, 0, R.string.wifi_context_menu_connect);
-        }
-
-        if (state.isForgetable()) {
-            menu.add(0, CONTEXT_MENU_ID_FORGET, 1, R.string.wifi_context_menu_forget);
-
-            if (state.hasPassword()) {
-                menu.add(0, CONTEXT_MENU_ID_CHANGE_PASSWORD, 2,
-                        R.string.wifi_context_menu_change_password);
+            if (config == null) {
+                if (mSelected != null && !requireKeyStore(mSelected.getConfig())) {
+                    connect(mSelected.networkId);
+                }
+            } else if (config.networkId != -1) {
+                if (mSelected != null) {
+                    mWifiManager.updateNetwork(config);
+                    saveNetworks();
+                }
+            } else {
+                int networkId = mWifiManager.addNetwork(config);
+                if (networkId != -1) {
+                    mWifiManager.enableNetwork(networkId, false);
+                    config.networkId = networkId;
+                    if (mDialog.edit || requireKeyStore(config)) {
+                        saveNetworks();
+                    } else {
+                        connect(networkId);
+                    }
+                }
             }
         }
     }
 
-    @Override
-    public boolean onContextItemSelected(MenuItem item) {
-
-        AccessPointState state = getStateFromMenuInfo(item.getMenuInfo());
-        if (state == null) {
-            return false;
-        }
-
-        switch (item.getItemId()) {
-
-            case CONTEXT_MENU_ID_CONNECT:
-                connectToNetwork(state);
-                return true;
-
-            case CONTEXT_MENU_ID_FORGET:
-                mWifiLayer.forgetNetwork(state);
-                return true;
-
-            case CONTEXT_MENU_ID_CHANGE_PASSWORD:
-                showAccessPointDialog(state, AccessPointDialog.MODE_CONFIGURE);
-                return true;
-
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Decides what needs to happen to connect to a particular access point. If
-     * it is secured and doesn't already have a password, it will bring up a
-     * password box. Otherwise it will just connect.
-     */
-    private void connectToNetwork(AccessPointState state) {
-        if (state.hasSecurity() && !state.hasPassword()) {
-            showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
-        } else {
-            mWifiLayer.connectToNetwork(state);
-        }
-    }
-
-    private AccessPointState getStateFromMenuInfo(ContextMenuInfo menuInfo) {
-        if ((menuInfo == null) || !(menuInfo instanceof AdapterContextMenuInfo)) {
-            return null;
-        }
-
-        AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
-        Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(
-                adapterMenuInfo.position);
-        if (pref == null || !(pref instanceof AccessPointPreference)) {
-            return null;
-        }
-
-        return ((AccessPointPreference) pref).getAccessPointState();
-    }
-
-    //============================
-    // Preference callbacks
-    //============================
-
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        super.onPreferenceTreeClick(preferenceScreen, preference);
-
-        if (preference == mAddOtherNetwork) {
-            showAddOtherNetworkDialog();
-        } else if (preference == mOpenNetworkNotificationsEnabled) {
-            Settings.Secure.putInt(getContentResolver(),
-                Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
-                mOpenNetworkNotificationsEnabled.isChecked() ? 1 : 0);
-        } else if (preference instanceof AccessPointPreference) {
-            AccessPointState state = ((AccessPointPreference) preference).getAccessPointState();
-            showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
-        }
-
-        return false;
-    }
-
-    //============================
-    // Wifi-related
-    //============================
-
-    public WifiLayer getWifiLayer() {
-        return mWifiLayer;
-    }
-
-    private void showAddOtherNetworkDialog() {
-        AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer);
-        dialog.setState(new AccessPointState(this));
-        dialog.setMode(AccessPointDialog.MODE_CONFIGURE);
-        dialog.setTitle(R.string.wifi_add_other_network);
-        dialog.setAutoSecurityAllowed(false);
-        mResumeMode = AccessPointDialog.MODE_CONFIGURE;
-        showDialog(dialog);
-    }
-
-    public void showAccessPointDialog(AccessPointState state, int mode) {
-        if (state.isEnterprise() && mKeyStore.test() != KeyStore.NO_ERROR) {
-            Credentials.getInstance().unlock(this);
-            mResumeState = state;
-            mResumeMode = mode;
-            return;
-        }
-        AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer);
-        dialog.setMode(mode);
-        dialog.setState(state);
-        showDialog(dialog);
-    }
-
-    private void showDialog(Dialog dialog) {
-        // Have only one dialog open at a time
+    private void showDialog(AccessPoint accessPoint, boolean edit) {
         if (mDialog != null) {
             mDialog.dismiss();
         }
+        mDialog = new WifiDialog(this, this, accessPoint, edit);
+        mDialog.show();
+    }
 
-        mDialog = dialog;
-        if (dialog != null) {
-            dialog.setOnDismissListener(this);
-            dialog.show();
+    private boolean requireKeyStore(WifiConfiguration config) {
+        if (WifiDialog.requireKeyStore(config) &&
+                KeyStore.getInstance().test() != KeyStore.NO_ERROR) {
+            mKeyStoreNetworkId = config.networkId;
+            Credentials.getInstance().unlock(this);
+            return true;
         }
+        return false;
     }
 
-    //============================
-    // Wifi callbacks
-    //============================
-
-    public void onError(int messageResId) {
-        Toast.makeText(this, messageResId, Toast.LENGTH_LONG).show();
+    private void forget(int networkId) {
+        mWifiManager.removeNetwork(networkId);
+        saveNetworks();
     }
 
-    public void onScanningStatusChanged(boolean started) {
-        mApCategory.setProgress(started);
-    }
-
-    public void onAccessPointSetChanged(AccessPointState ap, boolean added) {
-
-        AccessPointPreference pref = mAps.get(ap);
-
-        if (WifiLayer.LOGV) {
-            Log.v(TAG, "onAccessPointSetChanged with " + ap + " and "
-                    + (added ? "added" : "removed") + ", found pref " + pref);
-        }
-
-        if (added) {
-
-            if (pref == null) {
-                pref = new AccessPointPreference(this, ap);
-                mAps.put(ap, pref);
-            } else {
-                pref.setEnabled(true);
-            }
-
-            mApCategory.addPreference(pref);
-
-        } else {
-
-            mAps.remove(ap);
-
-            if (pref != null) {
-                mApCategory.removePreference(pref);
-            }
-
-        }
-    }
-
-    public void onAccessPointsStateChanged(boolean enabled) {
-        if (enabled) {
-            mApCategory.setEnabled(true);
-        } else {
-            mApCategory.removeAll();
-            mAps.clear();
-        }
-
-        mAddOtherNetwork.setEnabled(enabled);
-    }
-
-    public void onRetryPassword(AccessPointState ap) {
-
-        if ((mDialog != null) && mDialog.isShowing()) {
-            // If we're already showing a dialog, ignore this request
+    private void connect(int networkId) {
+        if (networkId == -1) {
             return;
         }
 
-        showAccessPointDialog(ap, AccessPointDialog.MODE_RETRY_PASSWORD);
+        // Reset the priority of each network if it goes too high.
+        if (mLastPriority > 1000000) {
+            for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) {
+                AccessPoint accessPoint = (AccessPoint) mAccessPoints.getPreference(i);
+                if (accessPoint.networkId != -1) {
+                    WifiConfiguration config = new WifiConfiguration();
+                    config.networkId = accessPoint.networkId;
+                    config.priority = 0;
+                    mWifiManager.updateNetwork(config);
+                }
+            }
+            mLastPriority = 0;
+        }
+
+        // Set to the highest priority and save the configuration.
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        config.priority = ++mLastPriority;
+        mWifiManager.updateNetwork(config);
+        saveNetworks();
+
+        // Connect to network by disabling others.
+        mWifiManager.enableNetwork(networkId, true);
+        mWifiManager.reconnect();
+        mResetNetworks = true;
     }
 
+    private void enableNetworks() {
+        for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) {
+            WifiConfiguration config = ((AccessPoint) mAccessPoints.getPreference(i)).getConfig();
+            if (config != null && config.status != Status.ENABLED) {
+                mWifiManager.enableNetwork(config.networkId, false);
+            }
+        }
+        mResetNetworks = false;
+    }
+
+    private void saveNetworks() {
+        // Always save the configuration with all networks enabled.
+        enableNetworks();
+        mWifiManager.saveConfiguration();
+        updateAccessPoints();
+    }
+
+    private void updateAccessPoints() {
+        List<AccessPoint> accessPoints = new ArrayList<AccessPoint>();
+
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        if (configs != null) {
+            mLastPriority = 0;
+            for (WifiConfiguration config : configs) {
+                if (config.priority > mLastPriority) {
+                    mLastPriority = config.priority;
+                }
+
+                // Shift the status to make enableNetworks() more efficient.
+                if (config.status == Status.CURRENT) {
+                    config.status = Status.ENABLED;
+                } else if (mResetNetworks && config.status == Status.DISABLED) {
+                    config.status = Status.CURRENT;
+                }
+
+                AccessPoint accessPoint = new AccessPoint(this, config);
+                accessPoint.update(mLastInfo, mLastState);
+                accessPoints.add(accessPoint);
+            }
+        }
+
+        List<ScanResult> results = mWifiManager.getScanResults();
+        if (results != null) {
+            for (ScanResult result : results) {
+                // Ignore hidden and ad-hoc networks.
+                if (result.SSID == null || result.SSID.length() == 0 ||
+                        result.capabilities.contains("[IBSS]")) {
+                    continue;
+                }
+
+                boolean found = false;
+                for (AccessPoint accessPoint : accessPoints) {
+                    if (accessPoint.update(result)) {
+                        found = true;
+                    }
+                }
+                if (!found) {
+                    accessPoints.add(new AccessPoint(this, result));
+                }
+            }
+        }
+
+        mAccessPoints.removeAll();
+        for (AccessPoint accessPoint : accessPoints) {
+            mAccessPoints.addPreference(accessPoint);
+        }
+    }
+
+    private void handleEvent(Intent intent) {
+        String action = intent.getAction();
+        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
+            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                    WifiManager.WIFI_STATE_UNKNOWN));
+        } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
+            updateAccessPoints();
+        } else if (WifiManager.NETWORK_IDS_CHANGED_ACTION.equals(action)) {
+            if (mSelected != null && mSelected.networkId != -1) {
+                mSelected = null;
+            }
+            updateAccessPoints();
+        } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
+            updateConnectionState(WifiInfo.getDetailedStateOf((SupplicantState)
+                    intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
+        } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
+            updateConnectionState(((NetworkInfo) intent.getParcelableExtra(
+                    WifiManager.EXTRA_NETWORK_INFO)).getDetailedState());
+        } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
+            updateConnectionState(null);
+        }
+    }
+
+    private void updateConnectionState(DetailedState state) {
+        if (state == DetailedState.OBTAINING_IPADDR) {
+            mScanner.pause();
+        } else {
+            mScanner.resume();
+        }
+
+        mLastInfo = mWifiManager.getConnectionInfo();
+        if (state != null) {
+            mLastState = state;
+        }
+
+        for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) {
+            ((AccessPoint) mAccessPoints.getPreference(i)).update(mLastInfo, mLastState);
+        }
+
+        if (mResetNetworks && (state == DetailedState.CONNECTED ||
+                state == DetailedState.DISCONNECTED || state == DetailedState.FAILED)) {
+            enableNetworks();
+        }
+    }
+
+    private void updateWifiState(int state) {
+        if (state == WifiManager.WIFI_STATE_ENABLED) {
+            mScanner.resume();
+            updateAccessPoints();
+        } else {
+            mScanner.pause();
+            mAccessPoints.removeAll();
+        }
+    }
+
+    private class Scanner extends Handler {
+        private int mRetry = 0;
+
+        void resume() {
+            if (!hasMessages(0)) {
+                sendEmptyMessage(0);
+            }
+        }
+
+        void pause() {
+            mRetry = 0;
+            mAccessPoints.setProgress(false);
+            removeMessages(0);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            if (mWifiManager.startScanActive()) {
+                mRetry = 0;
+            } else if (++mRetry >= 3) {
+                mRetry = 0;
+                Toast.makeText(WifiSettings.this, R.string.wifi_fail_to_scan,
+                        Toast.LENGTH_LONG).show();
+            }
+            mAccessPoints.setProgress(mRetry != 0);
+            sendEmptyMessageDelayed(0, 6000);
+        }
+    }
 }
diff --git a/src/com/android/settings/wifi/WifiSettings2.java b/src/com/android/settings/wifi/WifiSettings2.java
deleted file mode 100644
index 0c177b1..0000000
--- a/src/com/android/settings/wifi/WifiSettings2.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi;
-
-import com.android.settings.ProgressCategory;
-import com.android.settings.R;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.NetworkInfo;
-import android.net.wifi.ScanResult;
-import android.net.wifi.SupplicantState;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.Status;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-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.Settings.Secure;
-import android.security.Credentials;
-import android.security.KeyStore;
-import android.text.TextUtils;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.Toast;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class WifiSettings2 extends PreferenceActivity implements DialogInterface.OnClickListener {
-    private static final int MENU_ID_SCAN = Menu.FIRST;
-    private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
-    private static final int MENU_ID_CONNECT = Menu.FIRST + 2;
-    private static final int MENU_ID_FORGET = Menu.FIRST + 3;
-    private static final int MENU_ID_MODIFY = Menu.FIRST + 4;
-
-    private final IntentFilter mFilter;
-    private final BroadcastReceiver mReceiver;
-    private final Scanner mScanner;
-
-    private WifiManager mWifiManager;
-    private WifiEnabler mWifiEnabler;
-    private CheckBoxPreference mNotifyOpenNetworks;
-    private ProgressCategory mAccessPoints;
-    private Preference mAddNetwork;
-
-    private NetworkInfo.DetailedState mLastState;
-    private WifiInfo mLastInfo;
-    private int mLastPriority;
-
-    private boolean mResetNetworks = false;
-    private int mKeyStoreNetworkId = -1;
-
-    private AccessPoint mSelected;
-    private WifiDialog mDialog;
-
-    public WifiSettings2() {
-        mFilter = new IntentFilter();
-        mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
-        mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
-        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
-
-        mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                handleEvent(intent);
-            }
-        };
-
-        mScanner = new Scanner();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
-
-        if (getIntent().getBooleanExtra("only_access_points", false)) {
-            addPreferencesFromResource(R.xml.wifi_access_points2);
-        } else {
-            addPreferencesFromResource(R.xml.wifi_settings2);
-            mWifiEnabler = new WifiEnabler(this, mWifiManager,
-                    (CheckBoxPreference) findPreference("enable_wifi"));
-            mNotifyOpenNetworks =
-                    (CheckBoxPreference) findPreference("notify_open_networks");
-            mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(),
-                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);
-        }
-
-        mAccessPoints = (ProgressCategory) findPreference("access_points");
-        mAccessPoints.setOrderingAsAdded(false);
-        mAddNetwork = findPreference("add_network");
-
-        registerForContextMenu(getListView());
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        registerReceiver(mReceiver, mFilter);
-        if (mWifiEnabler != null) {
-            mWifiEnabler.resume();
-        }
-        if (mKeyStoreNetworkId != -1 && KeyStore.getInstance().test() == KeyStore.NO_ERROR) {
-            connect(mKeyStoreNetworkId);
-        }
-        mKeyStoreNetworkId = -1;
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        unregisterReceiver(mReceiver);
-        if (mWifiEnabler != null) {
-            mWifiEnabler.pause();
-        }
-        mScanner.pause();
-        if (mDialog != null) {
-            mDialog.dismiss();
-            mDialog = null;
-        }
-        if (mResetNetworks) {
-            enableNetworks();
-        }
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)
-                .setIcon(R.drawable.ic_menu_scan_network);
-        menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)
-                .setIcon(android.R.drawable.ic_menu_manage);
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case MENU_ID_SCAN:
-                mScanner.resume();
-                return true;
-            case MENU_ID_ADVANCED:
-                startActivity(new Intent(this, AdvancedSettings.class));
-                return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) {
-        if (info instanceof AdapterContextMenuInfo) {
-            Preference preference = (Preference) getListView().getItemAtPosition(
-                    ((AdapterContextMenuInfo) info).position);
-
-            if (preference instanceof AccessPoint) {
-                mSelected = (AccessPoint) preference;
-                menu.setHeaderTitle(mSelected.ssid);
-                if (mSelected.getLevel() != -1 && mSelected.getState() == null) {
-                    menu.add(Menu.NONE, MENU_ID_CONNECT, 0, R.string.wifi_menu_connect);
-                }
-                if (mSelected.networkId != -1) {
-                    menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget);
-                    if (mSelected.security != AccessPoint.SECURITY_NONE) {
-                        menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean onContextItemSelected(MenuItem item) {
-        if (mSelected == null) {
-            return super.onContextItemSelected(item);
-        }
-        switch (item.getItemId()) {
-            case MENU_ID_CONNECT:
-                if (mSelected.networkId != -1) {
-                    if (!requireKeyStore(mSelected.getConfig())) {
-                        connect(mSelected.networkId);
-                    }
-                } else if (mSelected.security == AccessPoint.SECURITY_NONE) {
-                    // Shortcut for open networks.
-                    WifiConfiguration config = new WifiConfiguration();
-                    config.SSID = mSelected.ssid;
-                    config.allowedKeyManagement.set(KeyMgmt.NONE);
-                    int networkId = mWifiManager.addNetwork(config);
-                    mWifiManager.enableNetwork(networkId, false);
-                    connect(networkId);
-                } else {
-                    showDialog(mSelected, false);
-                }
-                return true;
-            case MENU_ID_FORGET:
-                forget(mSelected.networkId);
-                return true;
-            case MENU_ID_MODIFY:
-                showDialog(mSelected, true);
-                return true;
-        }
-        return super.onContextItemSelected(item);
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
-        if (preference instanceof AccessPoint) {
-            mSelected = (AccessPoint) preference;
-            showDialog(mSelected, false);
-        } else if (preference == mAddNetwork) {
-            mSelected = null;
-            showDialog(null, true);
-        } else if (preference == mNotifyOpenNetworks) {
-            Secure.putInt(getContentResolver(),
-                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
-                    mNotifyOpenNetworks.isChecked() ? 1 : 0);
-        } else {
-            return super.onPreferenceTreeClick(screen, preference);
-        }
-        return true;
-    }
-
-    public void onClick(DialogInterface dialogInterface, int button) {
-        if (button == WifiDialog.BUTTON_FORGET && mSelected != null) {
-            forget(mSelected.networkId);
-        } else if (button == WifiDialog.BUTTON_SUBMIT) {
-            WifiConfiguration config = mDialog.getConfig();
-
-            if (config == null) {
-                if (mSelected != null && !requireKeyStore(mSelected.getConfig())) {
-                    connect(mSelected.networkId);
-                }
-            } else if (config.networkId != -1) {
-                if (mSelected != null) {
-                    mWifiManager.updateNetwork(config);
-                    saveNetworks();
-                }
-            } else {
-                int networkId = mWifiManager.addNetwork(config);
-                if (networkId != -1) {
-                    mWifiManager.enableNetwork(networkId, false);
-                    config.networkId = networkId;
-                    if (mDialog.edit || requireKeyStore(config)) {
-                        saveNetworks();
-                    } else {
-                        connect(networkId);
-                    }
-                }
-            }
-        }
-    }
-
-    private void showDialog(AccessPoint accessPoint, boolean edit) {
-        if (mDialog != null) {
-            mDialog.dismiss();
-        }
-        mDialog = new WifiDialog(this, this, accessPoint, edit);
-        mDialog.show();
-    }
-
-    private boolean requireKeyStore(WifiConfiguration config) {
-        if (WifiDialog.requireKeyStore(config) &&
-                KeyStore.getInstance().test() != KeyStore.NO_ERROR) {
-            mKeyStoreNetworkId = config.networkId;
-            Credentials.getInstance().unlock(this);
-            return true;
-        }
-        return false;
-    }
-
-    private void forget(int networkId) {
-        mWifiManager.removeNetwork(networkId);
-        saveNetworks();
-    }
-
-    private void connect(int networkId) {
-        if (networkId == -1) {
-            return;
-        }
-
-        // Reset the priority of each network if it goes too high.
-        if (mLastPriority > 1000000) {
-            for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) {
-                AccessPoint accessPoint = (AccessPoint) mAccessPoints.getPreference(i);
-                if (accessPoint.networkId != -1) {
-                    WifiConfiguration config = new WifiConfiguration();
-                    config.networkId = accessPoint.networkId;
-                    config.priority = 0;
-                    mWifiManager.updateNetwork(config);
-                }
-            }
-            mLastPriority = 0;
-        }
-
-        // Set to the highest priority and save the configuration.
-        WifiConfiguration config = new WifiConfiguration();
-        config.networkId = networkId;
-        config.priority = ++mLastPriority;
-        mWifiManager.updateNetwork(config);
-        saveNetworks();
-
-        // Connect to network by disabling others.
-        mWifiManager.enableNetwork(networkId, true);
-        mWifiManager.reconnect();
-        mResetNetworks = true;
-    }
-
-    private void enableNetworks() {
-        for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) {
-            WifiConfiguration config = ((AccessPoint) mAccessPoints.getPreference(i)).getConfig();
-            if (config != null && config.status != Status.ENABLED) {
-                mWifiManager.enableNetwork(config.networkId, false);
-            }
-        }
-        mResetNetworks = false;
-    }
-
-    private void saveNetworks() {
-        // Always save the configuration with all networks enabled.
-        enableNetworks();
-        mWifiManager.saveConfiguration();
-        updateAccessPoints();
-    }
-
-    private void updateAccessPoints() {
-        List<AccessPoint> accessPoints = new ArrayList<AccessPoint>();
-
-        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
-        if (configs != null) {
-            mLastPriority = 0;
-            for (WifiConfiguration config : configs) {
-                if (config.priority > mLastPriority) {
-                    mLastPriority = config.priority;
-                }
-
-                // Shift the status to make enableNetworks() more efficient.
-                if (config.status == Status.CURRENT) {
-                    config.status = Status.ENABLED;
-                } else if (mResetNetworks && config.status == Status.DISABLED) {
-                    config.status = Status.CURRENT;
-                }
-
-                AccessPoint accessPoint = new AccessPoint(this, config);
-                accessPoint.update(mLastInfo, mLastState);
-                accessPoints.add(accessPoint);
-            }
-        }
-
-        List<ScanResult> results = mWifiManager.getScanResults();
-        if (results != null) {
-            for (ScanResult result : results) {
-                // Ignore hidden and ad-hoc networks.
-                if (result.SSID == null || result.SSID.length() == 0 ||
-                        result.capabilities.contains("[IBSS]")) {
-                    continue;
-                }
-
-                boolean found = false;
-                for (AccessPoint accessPoint : accessPoints) {
-                    if (accessPoint.update(result)) {
-                        found = true;
-                    }
-                }
-                if (!found) {
-                    accessPoints.add(new AccessPoint(this, result));
-                }
-            }
-        }
-
-        mAccessPoints.removeAll();
-        for (AccessPoint accessPoint : accessPoints) {
-            mAccessPoints.addPreference(accessPoint);
-        }
-    }
-
-    private void handleEvent(Intent intent) {
-        String action = intent.getAction();
-        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
-            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                    WifiManager.WIFI_STATE_UNKNOWN));
-        } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
-            updateAccessPoints();
-        } else if (WifiManager.NETWORK_IDS_CHANGED_ACTION.equals(action)) {
-            if (mSelected != null && mSelected.networkId != -1) {
-                mSelected = null;
-            }
-            updateAccessPoints();
-        } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
-            updateConnectionState(WifiInfo.getDetailedStateOf((SupplicantState)
-                    intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
-        } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
-            updateConnectionState(((NetworkInfo) intent.getParcelableExtra(
-                    WifiManager.EXTRA_NETWORK_INFO)).getDetailedState());
-        } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
-            updateConnectionState(null);
-        }
-    }
-
-    private void updateConnectionState(NetworkInfo.DetailedState state) {
-        if (state == NetworkInfo.DetailedState.OBTAINING_IPADDR) {
-            mScanner.pause();
-        } else {
-            mScanner.resume();
-        }
-
-        mLastInfo = mWifiManager.getConnectionInfo();
-        if (state != null) {
-            mLastState = state;
-        }
-
-        for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) {
-            ((AccessPoint) mAccessPoints.getPreference(i)).update(mLastInfo, mLastState);
-        }
-    }
-
-    private void updateWifiState(int state) {
-        if (state == WifiManager.WIFI_STATE_ENABLED) {
-            mScanner.resume();
-            updateAccessPoints();
-        } else {
-            mScanner.pause();
-            mAccessPoints.removeAll();
-        }
-    }
-
-    private class Scanner extends Handler {
-        private int mRetry = 0;
-
-        void resume() {
-            if (!hasMessages(0)) {
-                sendEmptyMessage(0);
-            }
-        }
-
-        void pause() {
-            mRetry = 0;
-            mAccessPoints.setProgress(false);
-            removeMessages(0);
-        }
-
-        @Override
-        public void handleMessage(Message message) {
-            if (mWifiManager.startScanActive()) {
-                mRetry = 0;
-            } else if (++mRetry >= 3) {
-                mRetry = 0;
-                Toast.makeText(WifiSettings2.this, R.string.wifi_fail_to_scan,
-                        Toast.LENGTH_LONG).show();
-            }
-            mAccessPoints.setProgress(mRetry != 0);
-            sendEmptyMessageDelayed(0, 6000);
-        }
-    }
-}
diff --git a/src/com/android/settings/wifi/WifiStatus.java b/src/com/android/settings/wifi/WifiStatus.java
deleted file mode 100644
index e10ab8d..0000000
--- a/src/com/android/settings/wifi/WifiStatus.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi;
-
-import com.android.settings.R;
-
-import android.content.Context;
-import android.net.NetworkInfo;
-import android.text.TextUtils;
-
-public class WifiStatus {
-    public static String getStatus(Context context, String ssid,
-            NetworkInfo.DetailedState detailedState) {
-        
-        if (!TextUtils.isEmpty(ssid) && isLiveConnection(detailedState)) {
-            return getPrintableFragment(context, detailedState, ssid);
-        } else {
-            return getPrintable(context, detailedState);
-        }
-    }
-    
-    public static boolean isLiveConnection(NetworkInfo.DetailedState detailedState) {
-        return detailedState != NetworkInfo.DetailedState.DISCONNECTED
-                && detailedState != NetworkInfo.DetailedState.FAILED
-                && detailedState != NetworkInfo.DetailedState.IDLE
-                && detailedState != NetworkInfo.DetailedState.SCANNING;
-    }
-    
-    public static String getPrintable(Context context,
-            NetworkInfo.DetailedState detailedState) {
-        
-        switch (detailedState) {
-            case AUTHENTICATING:
-                return context.getString(R.string.status_authenticating);
-            case CONNECTED:
-                return context.getString(R.string.status_connected);
-            case CONNECTING:
-                return context.getString(R.string.status_connecting);
-            case DISCONNECTED:
-                return context.getString(R.string.status_disconnected);
-            case DISCONNECTING:
-                return context.getString(R.string.status_disconnecting);
-            case FAILED:
-                return context.getString(R.string.status_failed);
-            case OBTAINING_IPADDR:
-                return context.getString(R.string.status_obtaining_ip);
-            case SCANNING:
-                return context.getString(R.string.status_scanning);
-            default:
-                return null;
-        }
-    }
-    
-    public static String getPrintableFragment(Context context,
-            NetworkInfo.DetailedState detailedState, String apName) {
-        
-        String fragment = null;
-        switch (detailedState) {
-            case AUTHENTICATING:
-                fragment = context.getString(R.string.fragment_status_authenticating);
-                break;
-            case CONNECTED:
-                fragment = context.getString(R.string.fragment_status_connected);
-                break;
-            case CONNECTING:
-                fragment = context.getString(R.string.fragment_status_connecting);
-                break;
-            case DISCONNECTED:
-                fragment = context.getString(R.string.fragment_status_disconnected);
-                break;
-            case DISCONNECTING:
-                fragment = context.getString(R.string.fragment_status_disconnecting);
-                break;
-            case FAILED:
-                fragment = context.getString(R.string.fragment_status_failed);
-                break;
-            case OBTAINING_IPADDR:
-                fragment = context.getString(R.string.fragment_status_obtaining_ip);
-                break;
-            case SCANNING:
-                fragment = context.getString(R.string.fragment_status_scanning);
-                break;
-        }
-        
-        return String.format(fragment, apName);
-    }
-    
-}
diff --git a/src/com/android/settings/wifi/WifiStatusTest.java b/src/com/android/settings/wifi/WifiStatusTest.java
index e440a33..1b23834 100644
--- a/src/com/android/settings/wifi/WifiStatusTest.java
+++ b/src/com/android/settings/wifi/WifiStatusTest.java
@@ -17,7 +17,6 @@
 package com.android.settings.wifi;
 
 import com.android.settings.R;
-import com.android.settings.wifi.WifiStatus;
 import android.net.wifi.ScanResult;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
@@ -295,8 +294,8 @@
 
     private void handleNetworkStateChanged(NetworkInfo networkInfo) {
         if (mWifiManager.isWifiEnabled()) {
-            String summary = WifiStatus.getStatus(this,
-                    mWifiManager.getConnectionInfo().getSSID(), networkInfo.getDetailedState());
+            String summary = Summary.get(this, mWifiManager.getConnectionInfo().getSSID(),
+                    networkInfo.getDetailedState());
             mNetworkState.setText(summary);
         }
     }
