Merge "fix add wifi network dialog"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 42c076b..caf1b18 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -105,8 +105,9 @@
                   android:screenOrientation="landscape"
                   android:exported="true" />
 
-        <activity android:name=".wifi.AdvancedSettings"
+        <activity-alias android:name=".wifi.AdvancedSettings"
                 android:label="@string/wifi_ip_settings_titlebar"
+                android:targetActivity="Settings"
                 >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -114,7 +115,7 @@
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
-        </activity>
+        </activity-alias>
 
         <activity android:name=".wifi.WifiInfo">
             <intent-filter>
@@ -197,10 +198,10 @@
             </intent-filter>
         </activity-alias>
 
-        <activity android:name=".vpn.VpnSettings"
-                android:label="@string/vpn_settings_title"
+        <activity-alias android:name=".vpn.VpnSettings"
                 android:configChanges="orientation|keyboardHidden"
-                android:clearTaskOnLaunch="true">
+                android:clearTaskOnLaunch="true"
+                android:targetActivity="Settings">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <action android:name="android.net.vpn.SETTINGS" />
@@ -208,14 +209,7 @@
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
-        </activity>
-
-        <activity android:name=".vpn.VpnTypeSelection"
-                android:configChanges="orientation|keyboardHidden">
-        </activity>
-        <activity android:name=".vpn.VpnEditor"
-                android:configChanges="orientation|keyboardHidden">
-        </activity>
+        </activity-alias>
 
         <activity-alias android:name="DateTimeSettings"
                 android:label="@string/date_and_time"
@@ -836,6 +830,17 @@
             </intent-filter>
         </activity>
 
+        <activity-alias
+            android:name="ManageAccountsSettings"
+            android:label="@string/sync_settings"
+            android:targetActivity="Settings">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.settings.SYNC_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity-alias>
+
         <receiver android:name=".widget.SettingsAppWidgetProvider" android:label="@string/gadget_title">
             <intent-filter>
                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
diff --git a/res/drawable-hdpi/ic_list_sync_anim0.png b/res/drawable-hdpi/ic_list_sync_anim0.png
new file mode 100755
index 0000000..dc78905
--- /dev/null
+++ b/res/drawable-hdpi/ic_list_sync_anim0.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_list_sync_anim1.png b/res/drawable-hdpi/ic_list_sync_anim1.png
new file mode 100755
index 0000000..5fe6b4f
--- /dev/null
+++ b/res/drawable-hdpi/ic_list_sync_anim1.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_list_sync_anim2.png b/res/drawable-hdpi/ic_list_sync_anim2.png
new file mode 100755
index 0000000..d9d68ed
--- /dev/null
+++ b/res/drawable-hdpi/ic_list_sync_anim2.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_list_sync_anim3.png b/res/drawable-hdpi/ic_list_sync_anim3.png
new file mode 100755
index 0000000..7275c29
--- /dev/null
+++ b/res/drawable-hdpi/ic_list_sync_anim3.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_sync_green.png b/res/drawable-hdpi/ic_sync_green.png
new file mode 100644
index 0000000..6956088
--- /dev/null
+++ b/res/drawable-hdpi/ic_sync_green.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_sync_grey.png b/res/drawable-hdpi/ic_sync_grey.png
new file mode 100644
index 0000000..3e9995a
--- /dev/null
+++ b/res/drawable-hdpi/ic_sync_grey.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_sync_red.png b/res/drawable-hdpi/ic_sync_red.png
new file mode 100644
index 0000000..5abb707
--- /dev/null
+++ b/res/drawable-hdpi/ic_sync_red.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_list_sync_anim0.png b/res/drawable-mdpi/ic_list_sync_anim0.png
new file mode 100644
index 0000000..981a72e
--- /dev/null
+++ b/res/drawable-mdpi/ic_list_sync_anim0.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_list_sync_anim1.png b/res/drawable-mdpi/ic_list_sync_anim1.png
new file mode 100644
index 0000000..4581ba2
--- /dev/null
+++ b/res/drawable-mdpi/ic_list_sync_anim1.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_list_sync_anim2.png b/res/drawable-mdpi/ic_list_sync_anim2.png
new file mode 100644
index 0000000..b745916
--- /dev/null
+++ b/res/drawable-mdpi/ic_list_sync_anim2.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_list_sync_anim3.png b/res/drawable-mdpi/ic_list_sync_anim3.png
new file mode 100644
index 0000000..43e453d
--- /dev/null
+++ b/res/drawable-mdpi/ic_list_sync_anim3.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_list_syncerror.png b/res/drawable-mdpi/ic_list_syncerror.png
new file mode 100644
index 0000000..328b6a7
--- /dev/null
+++ b/res/drawable-mdpi/ic_list_syncerror.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_sync_green.png b/res/drawable-mdpi/ic_sync_green.png
new file mode 100644
index 0000000..177a024
--- /dev/null
+++ b/res/drawable-mdpi/ic_sync_green.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_sync_grey.png b/res/drawable-mdpi/ic_sync_grey.png
new file mode 100644
index 0000000..8f168d4
--- /dev/null
+++ b/res/drawable-mdpi/ic_sync_grey.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_sync_red.png b/res/drawable-mdpi/ic_sync_red.png
new file mode 100644
index 0000000..5e38136
--- /dev/null
+++ b/res/drawable-mdpi/ic_sync_red.png
Binary files differ
diff --git a/res/drawable/ic_list_sync_anim.xml b/res/drawable/ic_list_sync_anim.xml
new file mode 100644
index 0000000..b6965c5
--- /dev/null
+++ b/res/drawable/ic_list_sync_anim.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/status_icon_background.xml
+**
+** Copyright 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.
+*/
+-->
+<animation-list
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:oneshot="false">
+    <item android:drawable="@drawable/ic_list_sync_anim0" android:duration="150" />
+    <item android:drawable="@drawable/ic_list_sync_anim1" android:duration="150" />
+    <item android:drawable="@drawable/ic_list_sync_anim2" android:duration="150" />
+    <item android:drawable="@drawable/ic_list_sync_anim3" android:duration="150" />
+</animation-list>
+
diff --git a/res/layout-xlarge/date_time_settings_setupwizard.xml b/res/layout-xlarge/date_time_settings_setupwizard.xml
index 3985217..3c05089 100644
--- a/res/layout-xlarge/date_time_settings_setupwizard.xml
+++ b/res/layout-xlarge/date_time_settings_setupwizard.xml
@@ -19,7 +19,7 @@
               android:layout_width="fill_parent"
               android:layout_height="fill_parent"
               android:paddingTop="70dip"
-              android:paddingBottom="40dip"
+              android:paddingBottom="100dip"
               android:paddingLeft="60dip"
               android:paddingRight="60dip">
 
@@ -29,7 +29,7 @@
               android:layout_height="wrap_content"
               android:layout_weight="0"
               android:gravity="center"
-              android:layout_marginBottom="10dip"
+              android:layout_marginBottom="30dip"
               android:layout_alignParentTop="true"
               android:textSize="64dip"
               android:textColor="#FF30FF30"
@@ -41,69 +41,98 @@
                   android:layout_height="fill_parent"
                   android:layout_weight="1">
         <!-- Left side: time zone setting -->
-        <LinearLayout android:orientation="vertical"
-                      android:layout_width="0px"
-                      android:layout_weight="1"
-                      android:layout_height="fill_parent">
-            <!-- TODO: replace with appropratie UI component -->
-            <CheckBox android:id="@+id/time_zone_auto"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content"
-                      android:gravity="right|center_horizontal"
-                      android:layout_marginBottom="5dip"
-                      android:textSize="32dip"
-                      android:text="@string/time_zone_auto_stub"/>
-
-            <!-- text should manually be set. -->
-            <Button android:id="@+id/current_time_zone"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:textSize="24dip"
-                    android:layout_alignParentTop="true" />
-            <LinearLayout android:id="@+id/zone_picker"
+        <RelativeLayout android:layout_width="0px"
+                        android:layout_weight="1"
+                        android:layout_height="fill_parent"
+                        android:layout_marginRight="50dip">
+            <LinearLayout android:id="@+id/timezone"
                           android:orientation="vertical"
                           android:layout_width="fill_parent"
-                          android:layout_height="fill_parent"
-                          android:paddingLeft="10dip"
-                          android:paddingBottom="20dip"
-                          android:gravity="center"
-                          android:visibility="gone"
-                          android:clickable="true">
-                <fragment android:id="@+id/zone_picker_fragment"
-                          class="com.android.settings.ZonePicker"
-                          android:layout_width="fill_parent"
-                          android:layout_height="wrap_content" />
+                          android:layout_height="wrap_content"
+                          android:layout_weight="1"
+                          android:layout_alignParentTop="true">
+
+                <CheckBox android:id="@+id/time_zone_auto"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:gravity="right|center_horizontal"
+                          android:layout_marginBottom="5dip"
+                          android:textSize="32dip"
+                          android:text="@string/time_zone_auto_stub"/>
+
+                <!-- text should manually be set. -->
+                <Button android:id="@+id/current_time_zone"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:textSize="24dip"
+                        android:layout_alignParentTop="true" />
+                <LinearLayout android:id="@+id/zone_picker"
+                              android:orientation="vertical"
+                              android:layout_width="fill_parent"
+                              android:layout_height="350dip"
+                              android:paddingLeft="10dip"
+                              android:paddingBottom="20dip"
+                              android:gravity="center"
+                              android:visibility="gone"
+                              android:clickable="true">
+                    <fragment android:id="@+id/zone_picker_fragment"
+                              class="com.android.settings.ZonePicker"
+                              android:layout_width="fill_parent"
+                              android:layout_height="wrap_content" />
+                </LinearLayout>
             </LinearLayout>
-        </LinearLayout>
+            <Button android:id="@+id/skip_button"
+                    android:layout_width="300dip"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:layout_alignParentBottom="true"
+                    android:layout_centerHorizontal="true"
+                    android:textSize="32dip"
+                    android:text="@string/skip_label"/>
+        </RelativeLayout>
 
         <!-- Right side: date & time setting -->
-        <LinearLayout android:orientation="vertical"
-                      android:layout_width="0px"
-                      android:layout_weight="1"
-                      android:layout_height="fill_parent">
-
-            <!-- TODO: replace with appropratie UI component -->
-            <CheckBox android:id="@+id/date_time_auto"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content"
-                      android:gravity="right|center_horizontal"
-                      android:textSize="32dip"
-                      android:text="@string/date_time_auto" />
-
-            <LinearLayout android:orientation="horizontal"
+        <RelativeLayout android:layout_width="0px"
+                        android:layout_weight="1"
+                        android:layout_height="fill_parent"
+                        android:layout_marginLeft="50dip">
+            <LinearLayout android:id="@+id/datetime"
+                          android:orientation="vertical"
                           android:layout_width="fill_parent"
-                          android:layout_height="wrap_content">
-                <TimePicker android:id="@+id/time_picker"
-                            android:layout_width="0px"
-                            android:layout_weight=".5"
-                            android:layout_height="wrap_content"
-                            android:visibility="visible"/>
-                <DatePicker android:id="@+id/date_picker"
-                            android:layout_width="0px"
-                            android:layout_weight=".5"
-                            android:layout_height="wrap_content"/>
+                          android:layout_height="wrap_content"
+                          android:layout_weight="1"
+                          android:layout_alignParentTop="true">
+
+                <CheckBox android:id="@+id/date_time_auto"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:gravity="right|center_horizontal"
+                          android:textSize="32dip"
+                          android:text="@string/date_time_auto" />
+
+                <LinearLayout android:orientation="horizontal"
+                              android:layout_width="fill_parent"
+                              android:layout_height="wrap_content">
+                    <TimePicker android:id="@+id/time_picker"
+                                android:layout_width="0px"
+                                android:layout_weight=".5"
+                                android:layout_height="wrap_content"
+                                android:visibility="visible"/>
+                    <DatePicker android:id="@+id/date_picker"
+                                android:layout_width="0px"
+                                android:layout_weight=".5"
+                                android:layout_height="wrap_content"/>
+                </LinearLayout>
             </LinearLayout>
-        </LinearLayout>
+            <Button android:id="@+id/next_button"
+                    android:layout_width="300dip"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:layout_alignParentBottom="true"
+                    android:layout_centerHorizontal="true"
+                    android:textSize="32dip"
+                    android:text="@string/next_label" />
+        </RelativeLayout>
     </LinearLayout>
 
     <LinearLayout android:id="@+id/bottom"
@@ -112,22 +141,6 @@
                   android:gravity="center"
                   android:layout_height="wrap_content"
                   android:layout_weight="0">
-        <Button android:id="@+id/skip_button"
-                android:layout_width="300dip"
-                android:layout_height="wrap_content"
-                android:layout_alignParentBottom="true"
-                android:layout_alignParentLeft="true"
-                android:layout_marginRight="50dip"
-                android:textSize="32dip"
-                android:text="@string/skip_label"/>
 
-        <Button android:id="@+id/next_button"
-                android:layout_width="300dip"
-                android:layout_height="wrap_content"
-                android:layout_alignParentBottom="true"
-                android:layout_alignParentRight="true"
-                android:layout_marginLeft="50dip"
-                android:textSize="32dip"
-                android:text="@string/next_label" />
     </LinearLayout>
 </LinearLayout>
diff --git a/res/layout/account_preference.xml b/res/layout/account_preference.xml
new file mode 100644
index 0000000..810c57a
--- /dev/null
+++ b/res/layout/account_preference.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:gravity="center_vertical"
+    android:paddingLeft="16dip"
+    android:paddingRight="?android:attr/scrollbarSize">
+
+    <ImageView
+        android:id="@+id/providerIcon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="5dip"
+        android:layout_gravity="center" />
+
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="6dip"
+        android:layout_marginTop="6dip"
+        android:layout_marginBottom="6dip"
+        android:layout_weight="1">
+
+        <TextView android:id="@+android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+
+        <TextView android:id="@+android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/title"
+            android:layout_alignLeft="@android:id/title"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:maxLines="2" />
+
+    </RelativeLayout>
+
+    <ImageView
+        android:id="@+id/syncStatusIcon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="5dip"
+        android:layout_marginRight="7dip"
+        android:layout_gravity="center" />
+
+</LinearLayout>
diff --git a/res/layout/manage_accounts_screen.xml b/res/layout/manage_accounts_screen.xml
new file mode 100644
index 0000000..2150ddf
--- /dev/null
+++ b/res/layout/manage_accounts_screen.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/layout/list_content.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:drawSelectorOnTop="false"
+        android:scrollbarAlwaysDrawVerticalTrack="true"
+    />
+
+    <TextView android:id="@+id/sync_settings_error_info"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/sync_is_failing" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:background="@android:drawable/bottom_bar">
+
+        <View
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"/>
+
+        <Button android:id="@+id/add_account_button"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="2"
+            android:layout_marginTop="5dip"
+            android:text="@string/add_account_label" />
+
+        <View
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"/>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/wifi_config_preference.xml b/res/layout/wifi_config_preference.xml
index c510abf..b7f183f 100644
--- a/res/layout/wifi_config_preference.xml
+++ b/res/layout/wifi_config_preference.xml
@@ -142,4 +142,84 @@
                   android:layout_height="wrap_content"
                   android:text="@string/wifi_show_password" />
     </LinearLayout>  <!-- android:id="@+id/fields" -->
+
+    <LinearLayout android:id="@+id/ipfields"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical"
+                  android:visibility="gone">
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/wifi_ip_settings" />
+
+        <Spinner android:id="@+id/ipsettings"
+                 android:layout_width="fill_parent"
+                 android:layout_height="wrap_content"
+                 android:prompt="@string/wifi_ip_settings"
+                 android:entries="@array/wifi_ip_settings" />
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/staticip"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical"
+                  android:visibility="gone">
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/wifi_ip_address" />
+
+        <EditText android:id="@+id/ipaddress"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:inputType="textNoSuggestions" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/wifi_gateway" />
+
+        <EditText android:id="@+id/gateway"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:inputType="textNoSuggestions" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/wifi_netmask" />
+
+        <EditText android:id="@+id/netmask"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:inputType="textNoSuggestions" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/wifi_dns1" />
+
+        <EditText android:id="@+id/dns1"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:inputType="textNoSuggestions" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/wifi_dns2" />
+
+        <EditText android:id="@+id/dns2"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:inputType="textNoSuggestions" />
+    </LinearLayout>
+
 </LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 84bc6cc..9408544 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2122,10 +2122,21 @@
         </string>
     <!-- Message for the prompt that lets users know that they have no accessibility related apps
          installed and that they can install TalkBack from Market. -->
-    <string name="accessibility_service_no_apps_message">You do not have any accessibility related
+    <string name="accessibility_service_no_apps_message">You do not have any accessibility-related
         applications installed.\n\nYou can download a screen reader for your device from Android
         Market.\n\nClick "OK" to install the screen reader.</string>
 
+    <!-- Accessibility settings: Webpage accessibility scripts category [CHAR LIMIT=25] -->
+    <string name="accessibility_script_injection_category">Accessibility scripts</string>
+    <!-- Accessibility settings: Checkbox title for enabling download of accessibility scripts [CHAR LIMIT=40] -->
+    <string name="accessibility_script_injection_enabled">Download accessibility scripts</string>
+    <!-- Accessibility settings: Checkbox summary for enabling download of accessibility scripts [CHAR LIMIT=65] -->
+    <string name="accessibility_script_injection_enabled_summary">Allow applications to download accessibility scripts from Google</string>
+    <!-- Warning message about security implications of downloading accessibility scripts,
+         displayed as a dialog message when the user selects to enable script downloading. [CHAR LIMIT="NONE"] -->
+    <string name="accessibility_script_injection_security_warning">Some applications can ask Google
+        to download scripts to your phone that make their content more accessible. Are you sure you
+        want to allow Google to install accessibility scripts on your phone?</string>
     <!-- Accessibility settings: Power button category -->
     <string name="accessibility_power_button_category">Power button</string>
     <!-- Accessibility settings: checkbox title for power button behavior -->
@@ -2689,4 +2700,38 @@
 
     <!-- Do not translate. This is a stub which will be removed soon. -->
     <string name="time_zone_auto_stub" translatable="false">Select Time Zone</string>
+
+
+
+    <!-- Message when sync is currently failing [CHAR LIMIT=100] -->
+    <string name="sync_is_failing">Sync is currently experiencing problems. It will be back shortly.</string>
+    <!-- Button label to add an account [CHAR LIMIT=20] -->
+    <string name="add_account_label">Add account</string>
+    <!-- Header title for those settings relating to general syncing.
+         [CHAR LIMIT=30] -->
+    <string name="header_general_sync_settings">General sync settings</string>
+    <!-- Data synchronization settings screen, title of setting that controls whether background data should be used [CHAR LIMIT=30] -->
+    <string name="background_data">Background data</string>
+    <!-- Data synchronization settings screen, summary of setting that controls whether background data should be used [CHAR LIMIT=60] -->
+    <string name="background_data_summary">Applications can sync, send, and receive data at any time</string>
+    <!-- Data synchronization settings screen, title of dialog that confirms the user's unchecking of background data [CHAR LIMIT=20] -->
+    <string name="background_data_dialog_title">Attention</string>
+    <!-- Data synchronization settings screen, message of dialog that confirms the user's unchecking of background data [CHAR LIMIT=200] -->
+    <string name="background_data_dialog_message">Disabling background data extends battery life and lowers data use. Some applications may still use the background data connection.</string>
+    <!-- Data synchronization settings screen, setting option name
+         [CHAR LIMIT=30] -->
+    <string name="sync_automatically">Auto-sync</string>
+    <!-- Data synchronization settings screen, setting option summary text when check box is selected [CHAR LIMIT=60] -->
+    <string name="sync_automatically_summary">Applications sync data automatically</string>
+    <!-- Header title for list of accounts on Accounts & Synchronization settings [CHAR LIMIT=30] -->
+    <string name="header_manage_accounts">Manage accounts</string>
+
+    <!-- Sync status messages on Accounts & Synchronization settings --><skip/>
+    <!-- Sync status shown when sync is enabled [CHAR LIMIT=20] -->
+    <string name="sync_enabled">Sync is ON</string>
+    <!-- Sync status shown when sync is disabled [CHAR LIMIT=20] -->
+    <string name="sync_disabled">Sync is OFF</string>
+    <!-- Sync status shown when last sync resulted in an error [CHAR LIMIT=20] -->
+    <string name="sync_error">Sync error</string>
+
 </resources>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index f82af85..f2efb27 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -26,6 +26,15 @@
     <PreferenceCategory android:key="accessibility_services_category"
             android:title="@string/accessibility_services_category" />
 
+    <PreferenceCategory android:key="accessibility_script_injection_category"
+            android:title="@string/accessibility_script_injection_category">
+        <CheckBoxPreference
+                android:key="toggle_accessibility_script_injection_checkbox"
+                android:title="@string/accessibility_script_injection_enabled"
+                android:summary="@string/accessibility_script_injection_enabled_summary"
+                android:persistent="false" />
+    </PreferenceCategory>
+
     <PreferenceCategory android:key="power_button_category"
             android:title="@string/accessibility_power_button_category">
         <CheckBoxPreference
diff --git a/res/xml/manage_accounts_settings.xml b/res/xml/manage_accounts_settings.xml
new file mode 100644
index 0000000..8ddd7e7
--- /dev/null
+++ b/res/xml/manage_accounts_settings.xml
@@ -0,0 +1,36 @@
+<?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">
+
+    <PreferenceCategory
+            android:title="@string/header_general_sync_settings" />
+
+    <CheckBoxPreference android:key="backgroundDataCheckBox"
+        android:persistent="false"
+        android:title="@string/background_data"
+        android:summary="@string/background_data_summary"/>
+
+    <CheckBoxPreference android:key="syncAutomaticallyCheckBox"
+        android:persistent="false"
+        android:dependency="backgroundDataCheckBox"
+        android:title="@string/sync_automatically"
+        android:summary="@string/sync_automatically_summary"/>
+
+    <PreferenceCategory android:key="manageAccountsCategory"
+            android:title="@string/header_manage_accounts" />
+
+</PreferenceScreen>
diff --git a/res/xml/settings.xml b/res/xml/settings.xml
index a91d279..5b6691e 100644
--- a/res/xml/settings.xml
+++ b/res/xml/settings.xml
@@ -93,10 +93,10 @@
              preference. -->
 
         <com.android.settings.IconPreferenceScreen
+            android:fragment="com.android.settings.ManageAccountsSettings"
             settings:icon="@drawable/ic_settings_sync"
             android:title="@string/sync_settings"
             android:key="sync_settings">
-            <intent android:action="android.settings.SYNC_SETTINGS" />
         </com.android.settings.IconPreferenceScreen>
 
         <!-- Privacy -->
diff --git a/res/xml/voice_input_output_settings.xml b/res/xml/voice_input_output_settings.xml
index 5781a5c..1645d88 100644
--- a/res/xml/voice_input_output_settings.xml
+++ b/res/xml/voice_input_output_settings.xml
@@ -35,10 +35,7 @@
             android:title="@string/voice_output_category" />
 
     <PreferenceScreen android:key="tts_settings"
-            android:title="@string/tts_settings_title">
-        <intent android:action="android.intent.action.MAIN"
-                android:targetPackage="com.android.settings"
-                android:targetClass="com.android.settings.TextToSpeechSettings" />
-    </PreferenceScreen>
+            android:fragment="com.android.settings.TextToSpeechSettings"
+            android:title="@string/tts_settings_title" />
 
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
diff --git a/res/xml/wireless_settings.xml b/res/xml/wireless_settings.xml
index 8e05e60..f6d0012 100644
--- a/res/xml/wireless_settings.xml
+++ b/res/xml/wireless_settings.xml
@@ -59,13 +59,10 @@
     </PreferenceScreen>
 
     <PreferenceScreen
+        android:fragment="com.android.settings.vpn.VpnSettings"
         android:key="vpn_settings"
         android:title="@string/vpn_settings_title"
         android:summary="@string/vpn_settings_summary" >
-        <intent
-            android:action="android.intent.action.MAIN"
-            android:targetPackage="com.android.settings"
-            android:targetClass="com.android.settings.vpn.VpnSettings" />
     </PreferenceScreen>
 
     <PreferenceScreen
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index 321e956..104ee9e 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -56,6 +56,9 @@
     private static final String ACCESSIBILITY_SERVICES_CATEGORY =
         "accessibility_services_category";
 
+    private static final String TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX =
+        "toggle_accessibility_script_injection_checkbox";
+
     private static final String POWER_BUTTON_CATEGORY =
         "power_button_category";
 
@@ -64,6 +67,8 @@
 
     private CheckBoxPreference mToggleCheckBox;
 
+    private CheckBoxPreference mToggleScriptInjectionCheckBox;
+
     private PreferenceCategory mPowerButtonCategory;
     private CheckBoxPreference mPowerButtonEndsCallCheckBox;
 
@@ -81,18 +86,16 @@
         addPreferencesFromResource(R.xml.accessibility_settings);
 
         mToggleCheckBox = (CheckBoxPreference) findPreference(
-            TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX);
+                TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX);
+
+        mToggleScriptInjectionCheckBox = (CheckBoxPreference) findPreference(
+                TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX);
 
         mPowerButtonCategory = (PreferenceCategory) findPreference(POWER_BUTTON_CATEGORY);
         mPowerButtonEndsCallCheckBox = (CheckBoxPreference) findPreference(
-            POWER_BUTTON_ENDS_CALL_CHECKBOX);
+                POWER_BUTTON_ENDS_CALL_CHECKBOX);
 
         addAccessibilitServicePreferences();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
 
         final HashSet<String> enabled = new HashSet<String>();
         String settingValue = Settings.Secure.getString(getContentResolver(),
@@ -136,6 +139,12 @@
             displayNoAppsAlert();
         }
 
+        // set the accessibility script injection category
+        boolean scriptInjectionEnabled = (Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);
+        mToggleScriptInjectionCheckBox.setChecked(scriptInjectionEnabled);
+        mToggleScriptInjectionCheckBox.setEnabled(true);
+
         if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
                 && Utils.isVoiceCapable(getActivity())) {
             int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
@@ -185,7 +194,6 @@
         final String key = preference.getKey();
 
         if (TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX.equals(key)) {
-            boolean isChecked = ((CheckBoxPreference) preference).isChecked();
             handleEnableAccessibilityStateChange((CheckBoxPreference) preference);
         } else if (POWER_BUTTON_ENDS_CALL_CHECKBOX.equals(key)) {
             boolean isChecked = ((CheckBoxPreference) preference).isChecked();
@@ -196,6 +204,8 @@
                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
                     (isChecked ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
                             : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
+        } else if (TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX.equals(key)) {
+            handleToggleAccessibilityScriptInjection((CheckBoxPreference) preference);
         } else if (preference instanceof CheckBoxPreference) {
             handleEnableAccessibilityServiceStateChange((CheckBoxPreference) preference);
         }
@@ -242,6 +252,42 @@
     }
 
     /**
+     * Handles the change of the accessibility script injection setting state.
+     *
+     * @param preference The preference for enabling/disabling accessibility script injection.
+     */
+    private void handleToggleAccessibilityScriptInjection(CheckBoxPreference preference) {
+        if (preference.isChecked()) {
+            final CheckBoxPreference checkBoxPreference = preference;
+            // TODO: DialogFragment?
+            AlertDialog dialog = (new AlertDialog.Builder(getActivity()))
+                .setTitle(android.R.string.dialog_alert_title)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setMessage(getActivity().getString(
+                        R.string.accessibility_script_injection_security_warning))
+                .setCancelable(true)
+                .setPositiveButton(android.R.string.ok,
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            Settings.Secure.putInt(getContentResolver(),
+                            Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1);
+                        }
+                })
+                .setNegativeButton(android.R.string.cancel,
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            checkBoxPreference.setChecked(false);
+                        }
+                    })
+                .create();
+                dialog.show();
+        } else {
+            Settings.Secure.putInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0);
+        }
+    }
+
+    /**
      * Handles the change of the preference for enabling/disabling an AccessibilityService.
      *
      * @param preference The preference.
diff --git a/src/com/android/settings/AccountPreference.java b/src/com/android/settings/AccountPreference.java
new file mode 100644
index 0000000..a860d1a
--- /dev/null
+++ b/src/com/android/settings/AccountPreference.java
@@ -0,0 +1,142 @@
+/*
+ * 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 java.util.ArrayList;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.preference.Preference;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * AccountPreference is used to display a username, status and provider icon for an account on
+ * the device.
+ */
+public class AccountPreference extends Preference {
+    private static final String TAG = "AccountPreference";
+    public static final int SYNC_ENABLED = 0; // all know sync adapters are enabled and OK
+    public static final int SYNC_DISABLED = 1; // no sync adapters are enabled
+    public static final int SYNC_ERROR = 2; // one or more sync adapters have a problem
+    private int mStatus;
+    private Account mAccount;
+    private ArrayList<String> mAuthorities;
+    private Drawable mProviderIcon;
+    private ImageView mSyncStatusIcon;
+    private ImageView mProviderIconView;
+
+    public AccountPreference(Context context, Account account, Drawable icon,
+            ArrayList<String> authorities) {
+        super(context);
+        mAccount = account;
+        mAuthorities = authorities;
+        mProviderIcon = icon;
+        setLayoutResource(R.layout.account_preference);
+        setTitle(mAccount.name);
+        setSummary("");
+        // Add account info to the intent for AccountSyncSettings
+        Intent intent = new Intent("android.settings.ACCOUNT_SYNC_SETTINGS");
+        intent.putExtra("account", mAccount);
+        setIntent(intent);
+        setPersistent(false);
+        setSyncStatus(SYNC_DISABLED);
+    }
+
+    public Account getAccount() {
+        return mAccount;
+    }
+
+    public ArrayList<String> getAuthorities() {
+        return mAuthorities;
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        setSummary(getSyncStatusMessage(mStatus));
+        mProviderIconView = (ImageView) view.findViewById(R.id.providerIcon);
+        mProviderIconView.setImageDrawable(mProviderIcon);
+        mSyncStatusIcon = (ImageView) view.findViewById(R.id.syncStatusIcon);
+        mSyncStatusIcon.setImageResource(getSyncStatusIcon(mStatus));
+    }
+
+    public void setProviderIcon(Drawable icon) {
+        mProviderIcon = icon;
+        if (mProviderIconView != null) {
+            mProviderIconView.setImageDrawable(icon);
+        }
+    }
+
+    public void setSyncStatus(int status) {
+        mStatus = status;
+        if (mSyncStatusIcon != null) {
+            mSyncStatusIcon.setImageResource(getSyncStatusIcon(status));
+        }
+        setSummary(getSyncStatusMessage(status));
+    }
+
+    private int getSyncStatusMessage(int status) {
+        int res;
+        switch (status) {
+            case SYNC_ENABLED:
+                res = R.string.sync_enabled;
+                break;
+            case SYNC_DISABLED:
+                res = R.string.sync_disabled;
+                break;
+            case SYNC_ERROR:
+                res = R.string.sync_error;
+                break;
+            default:
+                res = R.string.sync_error;
+                Log.e(TAG, "Unknown sync status: " + status);
+        }
+        return res;
+    }
+
+    private int getSyncStatusIcon(int status) {
+        int res;
+        switch (status) {
+            case SYNC_ENABLED:
+                res = R.drawable.ic_sync_green;
+                break;
+            case SYNC_DISABLED:
+                res = R.drawable.ic_sync_grey;
+                break;
+            case SYNC_ERROR:
+                res = R.drawable.ic_sync_red;
+                break;
+            default:
+                res = R.drawable.ic_sync_red;
+                Log.e(TAG, "Unknown sync status: " + status);
+        }
+        return res;
+    }
+
+    @Override
+    public int compareTo(Preference other) {
+        if (!(other instanceof AccountPreference)) {
+            // Put other preference types above us
+            return 1;
+        }
+        return mAccount.name.compareTo(((AccountPreference) other).mAccount.name);
+    }
+}
diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java
index ecf8520..5a8f148 100644
--- a/src/com/android/settings/DateTimeSettings.java
+++ b/src/com/android/settings/DateTimeSettings.java
@@ -16,6 +16,7 @@
 
 package com.android.settings;
 
+import android.app.Activity;
 import android.app.DatePickerDialog;
 import android.app.Dialog;
 import android.app.TimePickerDialog;
@@ -133,8 +134,8 @@
         filter.addAction(Intent.ACTION_TIME_CHANGED);
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
         getActivity().registerReceiver(mIntentReceiver, filter, null, null);
-        
-        updateTimeAndDateDisplay();
+
+        updateTimeAndDateDisplay(getActivity());
     }
 
     @Override 
@@ -144,8 +145,8 @@
         getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
     }
     
-    private void updateTimeAndDateDisplay() {
-        java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(getActivity());
+    private void updateTimeAndDateDisplay(Context context) {
+        java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context);
         final Calendar now = Calendar.getInstance();
         Date dummyDate = mDummyDate.getTime();
         mTimePref.setSummary(DateFormat.getTimeFormat(getActivity()).format(now.getTime()));
@@ -157,13 +158,19 @@
     @Override
     public void onDateSet(DatePicker view, int year, int month, int day) {
         setDate(year, month, day);
-        updateTimeAndDateDisplay();
+        final Activity activity = getActivity();
+        if (activity != null) {
+            updateTimeAndDateDisplay(activity);
+        }
     }
 
     @Override
     public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
         setTime(hourOfDay, minute);
-        updateTimeAndDateDisplay();
+        final Activity activity = getActivity();
+        if (activity != null) {
+            updateTimeAndDateDisplay(activity);
+        }
 
         // We don't need to call timeUpdated() here because the TIME_CHANGED
         // broadcast is sent by the AlarmManager as a side effect of setting the
@@ -177,7 +184,7 @@
                     getResources().getString(R.string.default_date_format));
             Settings.System.putString(getContentResolver(), 
                     Settings.System.DATE_FORMAT, format);
-            updateTimeAndDateDisplay();
+            updateTimeAndDateDisplay(getActivity());
         } else if (key.equals(KEY_AUTO_TIME)) {
             boolean autoEnabled = preferences.getBoolean(key, true);
             Settings.System.putInt(getContentResolver(), 
@@ -260,7 +267,7 @@
             showDialog(DIALOG_TIMEPICKER);
         } else if (preference == mTime24Pref) {
             set24Hour(((CheckBoxPreference)mTime24Pref).isChecked());
-            updateTimeAndDateDisplay();
+            updateTimeAndDateDisplay(getActivity());
             timeUpdated();
         }
         return super.onPreferenceTreeClick(preferenceScreen, preference);
@@ -269,7 +276,7 @@
     @Override
     public void onActivityResult(int requestCode, int resultCode,
             Intent data) {
-        updateTimeAndDateDisplay();
+        updateTimeAndDateDisplay(getActivity());
     }
     
     private void timeUpdated() {
@@ -374,7 +381,10 @@
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            updateTimeAndDateDisplay();
+            final Activity activity = getActivity();
+            if (activity != null) {
+                updateTimeAndDateDisplay(activity);
+            }
         }
     };
 }
diff --git a/src/com/android/settings/DateTimeSettingsSetupWizard.java b/src/com/android/settings/DateTimeSettingsSetupWizard.java
index 5da17da..016a7f2 100644
--- a/src/com/android/settings/DateTimeSettingsSetupWizard.java
+++ b/src/com/android/settings/DateTimeSettingsSetupWizard.java
@@ -19,6 +19,7 @@
 import com.android.settings.ZonePicker.ZoneSelectionListener;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -26,6 +27,7 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.Button;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
@@ -44,6 +46,7 @@
     private Button mTimeZone;
     private TimePicker mTimePicker;
     private DatePicker mDatePicker;
+    private InputMethodManager mInputMethodManager;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -90,6 +93,8 @@
         mDatePicker = (DatePicker)findViewById(R.id.date_picker);
         mDatePicker.setEnabled(!autoDateTimeEnabled);
 
+        mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+
         ((ZonePicker)getFragmentManager().findFragmentById(R.id.zone_picker_fragment))
                 .setZoneSelectionListener(this);
 
@@ -123,6 +128,7 @@
 
     @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        final boolean autoEnabled = isChecked;  // just for readibility.
         Settings.System.putInt(getContentResolver(),
                 Settings.System.AUTO_TIME,
                 isChecked ? 1 : 0);
@@ -130,9 +136,16 @@
             findViewById(R.id.current_time_zone).setVisibility(View.VISIBLE);
             findViewById(R.id.zone_picker).setVisibility(View.GONE);
         }
-        mTimeZone.setEnabled(!isChecked);
-        mTimePicker.setEnabled(!isChecked);
-        mDatePicker.setEnabled(!isChecked);
+        mTimeZone.setEnabled(!autoEnabled);
+        mTimePicker.setEnabled(!autoEnabled);
+        mDatePicker.setEnabled(!autoEnabled);
+        if (autoEnabled) {
+            final View focusedView = getCurrentFocus();
+            if (focusedView != null) {
+                mInputMethodManager.hideSoftInputFromWindow(focusedView.getWindowToken(), 0);
+                focusedView.clearFocus();
+            }
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/LocalePicker.java b/src/com/android/settings/LocalePicker.java
index 2030e95..8b94ccb 100644
--- a/src/com/android/settings/LocalePicker.java
+++ b/src/com/android/settings/LocalePicker.java
@@ -16,6 +16,8 @@
 
 package com.android.settings;
 
+import java.util.Locale;
+
 public class LocalePicker extends com.android.internal.app.LocalePicker
         implements com.android.internal.app.LocalePicker.LocaleSelectionListener {
     public LocalePicker() {
@@ -24,7 +26,8 @@
     }
 
     @Override
-    public void onLocaleSelected() {
+    public void onLocaleSelected(Locale locale) {
         getActivity().onBackPressed();
+        LocalePicker.updateLocale(locale);
     }
 }
diff --git a/src/com/android/settings/ManageAccountsSettings.java b/src/com/android/settings/ManageAccountsSettings.java
new file mode 100644
index 0000000..f138674
--- /dev/null
+++ b/src/com/android/settings/ManageAccountsSettings.java
@@ -0,0 +1,373 @@
+/*
+ * 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 com.google.android.collect.Maps;
+
+import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorDescription;
+import android.accounts.OnAccountsUpdateListener;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SyncAdapterType;
+import android.content.SyncInfo;
+import android.content.SyncStatusInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.net.ConnectivityManager;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+public class ManageAccountsSettings extends PreferenceFragment
+        implements View.OnClickListener, OnAccountsUpdateListener, DialogCreatable {
+    private static final String TAG = ManageAccountsSettings.class.getSimpleName();
+
+    private static final String AUTHORITIES_FILTER_KEY = "authorities";
+    private static final boolean LDEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final String AUTO_SYNC_CHECKBOX_KEY = "syncAutomaticallyCheckBox";
+    private static final String MANAGE_ACCOUNTS_CATEGORY_KEY = "manageAccountsCategory";
+    private static final String BACKGROUND_DATA_CHECKBOX_KEY = "backgroundDataCheckBox";
+    private static final int DIALOG_DISABLE_BACKGROUND_DATA = 1;
+
+    private CheckBoxPreference mBackgroundDataCheckBox;
+    private PreferenceCategory mManageAccountsCategory;
+    private String[] mAuthorities;
+    private TextView mErrorInfoView;
+    private Button mAddAccountButton;
+    private CheckBoxPreference mAutoSyncCheckbox;
+
+    private SettingsDialogFragment mDialogFragment;
+
+    private AuthenticatorDescription[] mAuthDescs;
+    private Map<String, AuthenticatorDescription> mTypeToAuthDescription
+            = new HashMap<String, AuthenticatorDescription>();
+    private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        final View view = inflater.inflate(R.layout.manage_accounts_screen, container, false);
+        return view;
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        final Activity activity = getActivity();
+        addPreferencesFromResource(R.xml.manage_accounts_settings);
+        final View view = getView();
+
+        mErrorInfoView = (TextView)view.findViewById(R.id.sync_settings_error_info);
+        mErrorInfoView.setVisibility(View.GONE);
+        mErrorInfoView.setCompoundDrawablesWithIntrinsicBounds(
+                activity.getResources().getDrawable(R.drawable.ic_list_syncerror),
+                null, null, null);
+
+        mBackgroundDataCheckBox = (CheckBoxPreference) findPreference(BACKGROUND_DATA_CHECKBOX_KEY);
+        mAutoSyncCheckbox = (CheckBoxPreference) findPreference(AUTO_SYNC_CHECKBOX_KEY);
+
+        mManageAccountsCategory = (PreferenceCategory)findPreference(MANAGE_ACCOUNTS_CATEGORY_KEY);
+        mAuthorities = activity.getIntent().getStringArrayExtra(AUTHORITIES_FILTER_KEY);
+        mAddAccountButton = (Button)view.findViewById(R.id.add_account_button);
+        mAddAccountButton.setOnClickListener(this);
+
+        AccountManager.get(activity).addOnAccountsUpdatedListener(this, null, true);
+        updateAuthDescriptions(activity);
+    }
+
+    @Override
+    public void onDestroy() {
+        AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
+        super.onDestroy();
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferences, Preference preference) {
+        if (preference == mBackgroundDataCheckBox) {
+            final ConnectivityManager connManager = (ConnectivityManager)
+                    getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+            final boolean oldBackgroundDataSetting = connManager.getBackgroundDataSetting();
+            final boolean backgroundDataSetting = mBackgroundDataCheckBox.isChecked();
+            if (oldBackgroundDataSetting != backgroundDataSetting) {
+                if (backgroundDataSetting) {
+                    setBackgroundDataInt(true);
+                    onSyncStateUpdated();
+                } else {
+                    // This will get unchecked only if the user hits "Ok"
+                    mBackgroundDataCheckBox.setChecked(true);
+                    showDialog(DIALOG_DISABLE_BACKGROUND_DATA);
+                }
+            }
+        } else if (preference == mAutoSyncCheckbox) {
+            ContentResolver.setMasterSyncAutomatically(mAutoSyncCheckbox.isChecked());
+            onSyncStateUpdated();
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public Dialog onCreateDialog(int id) {
+        switch (id) {
+            case DIALOG_DISABLE_BACKGROUND_DATA:
+                final CheckBoxPreference pref =
+                    (CheckBoxPreference) findPreference(BACKGROUND_DATA_CHECKBOX_KEY);
+                return new AlertDialog.Builder(getActivity())
+                        .setTitle(R.string.background_data_dialog_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.background_data_dialog_message)
+                        .setPositiveButton(android.R.string.ok,
+                                    new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int which) {
+                                    setBackgroundDataInt(false);
+                                    pref.setChecked(false);
+                                    onSyncStateUpdated();
+                                }
+                            })
+                        .setNegativeButton(android.R.string.cancel, null)
+                        .create();
+        }
+
+        return null;
+    }
+
+    void showDialog(int dialogId) {
+        if (mDialogFragment != null) {
+            Log.e(TAG, "Old dialog fragment not null!");
+        }
+        mDialogFragment = new SettingsDialogFragment(this, dialogId);
+        mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
+    }
+
+    private void setBackgroundDataInt(boolean enabled) {
+        final ConnectivityManager connManager = (ConnectivityManager)
+                getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+        connManager.setBackgroundDataSetting(enabled);
+    }
+
+    private void onSyncStateUpdated() {
+        // Set background connection state
+        final ConnectivityManager connManager = (ConnectivityManager)
+                getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+        final boolean backgroundDataSetting = connManager.getBackgroundDataSetting();
+        mBackgroundDataCheckBox.setChecked(backgroundDataSetting);
+        boolean masterSyncAutomatically = ContentResolver.getMasterSyncAutomatically();
+        mAutoSyncCheckbox.setChecked(masterSyncAutomatically);
+
+        // iterate over all the preferences, setting the state properly for each
+        SyncInfo currentSync = ContentResolver.getCurrentSync();
+
+        boolean anySyncFailed = false; // true if sync on any account failed
+
+        // only track userfacing sync adapters when deciding if account is synced or not
+        final SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes();
+        HashSet<String> userFacing = new HashSet<String>();
+        for (int k = 0, n = syncAdapters.length; k < n; k++) {
+            final SyncAdapterType sa = syncAdapters[k];
+            if (sa.isUserVisible()) {
+                userFacing.add(sa.authority);
+            }
+        }
+        for (int i = 0, count = mManageAccountsCategory.getPreferenceCount(); i < count; i++) {
+            Preference pref = mManageAccountsCategory.getPreference(i);
+            if (! (pref instanceof AccountPreference)) {
+                continue;
+            }
+
+            AccountPreference accountPref = (AccountPreference) pref;
+            Account account = accountPref.getAccount();
+            int syncCount = 0;
+            boolean syncIsFailing = false;
+            final ArrayList<String> authorities = accountPref.getAuthorities();
+            if (authorities != null) {
+                for (String authority : authorities) {
+                    SyncStatusInfo status = ContentResolver.getSyncStatus(account, authority);
+                    boolean syncEnabled = ContentResolver.getSyncAutomatically(account, authority)
+                            && masterSyncAutomatically
+                            && backgroundDataSetting
+                            && (ContentResolver.getIsSyncable(account, authority) > 0);
+                    boolean authorityIsPending = ContentResolver.isSyncPending(account, authority);
+                    boolean activelySyncing = currentSync != null
+                            && currentSync.authority.equals(authority)
+                            && new Account(currentSync.account.name, currentSync.account.type)
+                                    .equals(account);
+                    boolean lastSyncFailed = status != null
+                            && syncEnabled
+                            && status.lastFailureTime != 0
+                            && status.getLastFailureMesgAsInt(0)
+                               != ContentResolver.SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS;
+                    if (lastSyncFailed && !activelySyncing && !authorityIsPending) {
+                        syncIsFailing = true;
+                        anySyncFailed = true;
+                    }
+                    syncCount += syncEnabled && userFacing.contains(authority) ? 1 : 0;
+                }
+            } else {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "no syncadapters found for " + account);
+                }
+            }
+            int syncStatus = AccountPreference.SYNC_DISABLED;
+            if (syncIsFailing) {
+                syncStatus = AccountPreference.SYNC_ERROR;
+            } else if (syncCount == 0) {
+                syncStatus = AccountPreference.SYNC_DISABLED;
+            } else if (syncCount > 0) {
+                syncStatus = AccountPreference.SYNC_ENABLED;
+            }
+            accountPref.setSyncStatus(syncStatus);
+        }
+
+        mErrorInfoView.setVisibility(anySyncFailed ? View.VISIBLE : View.GONE);
+    }
+
+    @Override
+    public void onAccountsUpdated(Account[] accounts) {
+        mManageAccountsCategory.removeAll();
+        for (int i = 0, n = accounts.length; i < n; i++) {
+            final Account account = accounts[i];
+            final ArrayList<String> auths = getAuthoritiesForAccountType(account.type);
+
+            boolean showAccount = true;
+            if (mAuthorities != null && auths != null) {
+                showAccount = false;
+                for (String requestedAuthority : mAuthorities) {
+                    if (auths.contains(requestedAuthority)) {
+                        showAccount = true;
+                        break;
+                    }
+                }
+            }
+
+            if (showAccount) {
+                final Drawable icon = getDrawableForType(account.type);
+                final AccountPreference preference =
+                        new AccountPreference(getActivity(), account, icon, auths);
+                mManageAccountsCategory.addPreference(preference);
+            }
+        }
+        onSyncStateUpdated();
+    }
+
+    private void onAuthDescriptionsUpdated() {
+        // Update account icons for all account preference items
+        for (int i = 0; i < mManageAccountsCategory.getPreferenceCount(); i++) {
+            AccountPreference pref = (AccountPreference) mManageAccountsCategory.getPreference(i);
+            pref.setProviderIcon(getDrawableForType(pref.getAccount().type));
+            pref.setSummary(getLabelForType(pref.getAccount().type));
+        }
+    }
+
+    public void onClick(View v) {
+        if (v == mAddAccountButton) {
+            Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
+            intent.putExtra(AUTHORITIES_FILTER_KEY, mAuthorities);
+            startActivity(intent);
+        }
+    }
+
+    /* The logic below is copied from AcountPrefernceBase */
+
+    private Drawable getDrawableForType(final String accountType) {
+        Drawable icon = null;
+        if (mTypeToAuthDescription.containsKey(accountType)) {
+            try {
+                AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+                Context authContext = getActivity().createPackageContext(desc.packageName, 0);
+                icon = authContext.getResources().getDrawable(desc.iconId);
+            } catch (PackageManager.NameNotFoundException e) {
+                // TODO: place holder icon for missing account icons?
+                Log.w(TAG, "No icon for account type " + accountType);
+            }
+        }
+        return icon;
+    }
+
+    private CharSequence getLabelForType(final String accountType) {
+        CharSequence label = null;
+        if (mTypeToAuthDescription.containsKey(accountType)) {
+             try {
+                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+                 Context authContext = getActivity().createPackageContext(desc.packageName, 0);
+                 label = authContext.getResources().getText(desc.labelId);
+             } catch (PackageManager.NameNotFoundException e) {
+                 Log.w(TAG, "No label for account type " + ", type " + accountType);
+             }
+        }
+        return label;
+    }
+
+    private ArrayList<String> getAuthoritiesForAccountType(String type) {
+        if (mAccountTypeToAuthorities == null) {
+            mAccountTypeToAuthorities = Maps.newHashMap();
+            SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes();
+            for (int i = 0, n = syncAdapters.length; i < n; i++) {
+                final SyncAdapterType sa = syncAdapters[i];
+                ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType);
+                if (authorities == null) {
+                    authorities = new ArrayList<String>();
+                    mAccountTypeToAuthorities.put(sa.accountType, authorities);
+                }
+                if (LDEBUG) {
+                    Log.d(TAG, "added authority " + sa.authority + " to accountType "
+                            + sa.accountType);
+                }
+                authorities.add(sa.authority);
+            }
+        }
+        return mAccountTypeToAuthorities.get(type);
+    }
+
+    private void updateAuthDescriptions(Context context) {
+        mAuthDescs = AccountManager.get(context).getAuthenticatorTypes();
+        for (int i = 0; i < mAuthDescs.length; i++) {
+            mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
+        }
+        onAuthDescriptionsUpdated();
+    }
+}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 50aa1df..224aa53 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -41,7 +41,8 @@
  */
 public class Settings extends Activity
         implements PreferenceFragment.OnPreferenceStartFragmentCallback,
-        SettingsPreferenceFragment.OnStateListener {
+        SettingsPreferenceFragment.OnStateListener,
+        SettingsPreferenceFragment.FragmentStarter {
 
     private static final boolean DBG = false;
 
@@ -143,7 +144,9 @@
         if (DBG) Log.d(TAG, "showFragment");
        Fragment f = Fragment.instantiate(this, fragmentClass, extras);
         if (f instanceof SettingsPreferenceFragment) {
-            ((SettingsPreferenceFragment) f).setOnStateListener(this);
+            SettingsPreferenceFragment spf = (SettingsPreferenceFragment) f;
+            spf.setOnStateListener(this);
+            spf.setFragmentStarter(this);
         }
         mBreadCrumbs.clear();
         getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
@@ -176,9 +179,17 @@
 
     public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
         if (DBG) Log.d(TAG, "onPreferenceStartFragment");
-        Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras());
+        return startFragment(caller, pref.getFragment(), -1, pref.getExtras());
+    }
+
+    public boolean startFragment(
+            Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
+        Fragment f = Fragment.instantiate(this, fragmentClass, extras);
+        caller.setTargetFragment(f, requestCode);
         if (f instanceof SettingsPreferenceFragment) {
-            ((SettingsPreferenceFragment) f).setOnStateListener(this);
+            SettingsPreferenceFragment spf = (SettingsPreferenceFragment) f;
+            spf.setOnStateListener(this);
+            spf.setFragmentStarter(this);
         }
         getFragmentManager().openTransaction().replace(R.id.prefs, f)
                 .addToBackStack(BACK_STACK_PREFS).commit();
@@ -224,8 +235,6 @@
         private void updatePreferenceList() {
             final Activity activity = getActivity();
             PreferenceGroup parent = (PreferenceGroup) findPreference(KEY_PARENT);
-            Utils.updatePreferenceToSpecificActivityOrRemove(activity, parent,
-                    KEY_SYNC_SETTINGS, 0);
             Preference dockSettings = parent.findPreference(KEY_DOCK_SETTINGS);
             if (activity.getResources().getBoolean(R.bool.has_dock_settings) == false
                     && dockSettings != null) {
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 935c72a..f41561e 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.app.Dialog;
 import android.app.DialogFragment;
+import android.app.Fragment;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -58,6 +59,10 @@
     private SettingsDialogFragment mDialogFragment;
 
     private OnStateListener mOnStateListener;
+    private FragmentStarter mFragmentStarter;
+
+    private int mResultCode = Activity.RESULT_CANCELED;
+    private Intent mResultData;
 
     private Button mNextButton;
 
@@ -74,6 +79,43 @@
         mOnStateListener = listener;
     }
 
+    /**
+     * Letting the class, assumed to be Fragment, start another Fragment object.
+     * The target Fragment object is stored in the caller Fragment using
+     * {@link Fragment#setTargetFragment(Fragment, int)}. The caller
+     * is able to obtain result code and result data via
+     * {@link SettingsPreferenceFragment#getResultCode()} and
+     * {@link SettingsPreferenceFragment#getResultData()} accordingly.
+     */
+    interface FragmentStarter {
+        public boolean startFragment(
+                Fragment caller, String fragmentClass, int requestCode, Bundle extras);
+    }
+
+    public void setFragmentStarter(FragmentStarter starter) {
+        mFragmentStarter = starter;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final Fragment f = getTargetFragment();
+        final int requestCode = getTargetRequestCode();
+
+        // TargetFragment becomes invalid when this object is resumed. Notify it to
+        // FragmentManager. Without this code, FragmentManager wrongly take the TargetFragment
+        // as live, and throws IllegalStateException.
+        setTargetFragment(null, -1);
+
+        if (f != null && (f instanceof SettingsPreferenceFragment)) {
+            final SettingsPreferenceFragment spf = (SettingsPreferenceFragment)f;
+            final int resultCode = spf.getResultCode();
+            final Intent resultData = spf.getResultData();
+            onActivityResult(requestCode, resultCode, resultData);
+        }
+    }
+
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
@@ -86,6 +128,32 @@
         setupButtonBar();
     }
 
+    public final void setResult(int resultCode) {
+        mResultCode = resultCode;
+        mResultData = null;
+    }
+
+    public final void setResult(int resultCode, Intent data) {
+        mResultCode = resultCode;
+        mResultData = data;
+    }
+
+    public final int getResultCode() {
+        return mResultCode;
+    }
+
+    public final Intent getResultData() {
+        return mResultData;
+    }
+
+    /*
+     * The name is intentionally made different from Activity#finish(), so that
+     * users won't misunderstand its meaning.
+     */
+    public final void finishFragment() {
+        getActivity().onBackPressed();
+    }
+
     @Override
     public void onDestroy() {
         super.onDestroy();
@@ -179,6 +247,16 @@
         getActivity().onBackPressed();
     }
 
+    public boolean startFragment(
+            Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
+        if (mFragmentStarter != null) {
+            return mFragmentStarter.startFragment(caller, fragmentClass, requestCode, extras);
+        } else {
+            Log.w(TAG, "FragmentStarter is not set.");
+            return false;
+        }
+    }
+
     /**
      * Sets up Button Bar possibly required in the Fragment. Probably available only in
      * phones.
diff --git a/src/com/android/settings/TextToSpeechSettings.java b/src/com/android/settings/TextToSpeechSettings.java
index 89a4641..488e117 100644
--- a/src/com/android/settings/TextToSpeechSettings.java
+++ b/src/com/android/settings/TextToSpeechSettings.java
@@ -16,29 +16,30 @@
 
 package com.android.settings;
 
-import static android.provider.Settings.Secure.TTS_USE_DEFAULTS;
-import static android.provider.Settings.Secure.TTS_DEFAULT_RATE;
-import static android.provider.Settings.Secure.TTS_DEFAULT_LANG;
 import static android.provider.Settings.Secure.TTS_DEFAULT_COUNTRY;
-import static android.provider.Settings.Secure.TTS_DEFAULT_VARIANT;
+import static android.provider.Settings.Secure.TTS_DEFAULT_LANG;
+import static android.provider.Settings.Secure.TTS_DEFAULT_RATE;
 import static android.provider.Settings.Secure.TTS_DEFAULT_SYNTH;
+import static android.provider.Settings.Secure.TTS_DEFAULT_VARIANT;
 import static android.provider.Settings.Secure.TTS_ENABLED_PLUGINS;
+import static android.provider.Settings.Secure.TTS_USE_DEFAULTS;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
+import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceActivity;
 import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
-import android.preference.CheckBoxPreference;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.speech.tts.TextToSpeech;
@@ -49,7 +50,7 @@
 import java.util.Locale;
 import java.util.StringTokenizer;
 
-public class TextToSpeechSettings extends PreferenceActivity implements
+public class TextToSpeechSettings extends SettingsPreferenceFragment implements
         Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
         TextToSpeech.OnInitListener {
 
@@ -90,8 +91,6 @@
     private String             mDefaultEng = "";
     private int                mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
 
-    // Array of strings used to demonstrate TTS in the different languages.
-    private String[] mDemoStrings;
     // Index of the current string to use for the demo.
     private int      mDemoStringIndex = 0;
 
@@ -109,16 +108,14 @@
     private static final int GET_SAMPLE_TEXT = 1983;
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
+    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-
         addPreferencesFromResource(R.xml.tts_settings);
 
-        addEngineSpecificSettings();
+        final Activity activity = getActivity();
+        addEngineSpecificSettings(activity);
 
-        mDemoStrings = getResources().getStringArray(R.array.tts_demo_strings);
-
-        setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
+        activity.setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
 
         mEnableDemo = false;
         mTtsStarted = false;
@@ -128,12 +125,12 @@
         mDefaultCountry = currentLocale.getISO3Country();
         mDefaultLocVariant = currentLocale.getVariant();
 
-        mTts = new TextToSpeech(this, this);
+        mTts = new TextToSpeech(activity, this);
     }
 
 
     @Override
-    protected void onStart() {
+    public void onStart() {
         super.onStart();
         if (mTtsStarted){
             // whenever we return to this screen, we don't know the state of the
@@ -147,7 +144,7 @@
 
 
     @Override
-    protected void onDestroy() {
+    public void onDestroy() {
         super.onDestroy();
         if (mTts != null) {
             mTts.shutdown();
@@ -155,7 +152,7 @@
     }
 
     @Override
-    protected void onPause() {
+    public void onPause() {
         super.onPause();
         if ((mDefaultRatePref != null) && (mDefaultRatePref.getDialog() != null)) {
             mDefaultRatePref.getDialog().dismiss();
@@ -168,9 +165,7 @@
         }
     }
 
-
-
-    private void addEngineSpecificSettings() {
+    private void addEngineSpecificSettings(Context context) {
         PreferenceGroup enginesCategory = (PreferenceGroup) findPreference("tts_engines_section");
         Intent intent = new Intent("android.intent.action.START_TTS_ENGINE");
         ResolveInfo[] enginesArray = new ResolveInfo[0];
@@ -180,14 +175,14 @@
             String prefKey = "";
             final String pluginPackageName = enginesArray[i].activityInfo.packageName;
             if (!enginesArray[i].activityInfo.packageName.equals(SYSTEM_TTS)) {
-                CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
+                CheckBoxPreference chkbxPref = new CheckBoxPreference(context);
                 prefKey = KEY_PLUGIN_ENABLED_PREFIX + pluginPackageName;
                 chkbxPref.setKey(prefKey);
                 chkbxPref.setTitle(enginesArray[i].loadLabel(pm));
                 enginesCategory.addPreference(chkbxPref);
             }
             if (pluginHasSettings(pluginPackageName)) {
-                Preference pref = new Preference(this);
+                Preference pref = new Preference(context);
                 prefKey = KEY_PLUGIN_SETTINGS_PREFIX + pluginPackageName;
                 pref.setKey(prefKey);
                 pref.setTitle(enginesArray[i].loadLabel(pm));
@@ -360,7 +355,7 @@
                 mDefaultLocVariant = new String();
             }
             mTts.setLanguage(new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
-            mTts.setSpeechRate((float)(mDefaultRate/100.0f));
+            mTts.setSpeechRate(mDefaultRate/100.0f);
             initDefaultSettings();
             initClickers();
             updateWidgetState();
@@ -378,7 +373,8 @@
     /**
      * Called when voice data integrity check returns
      */
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == VOICE_DATA_INTEGRITY_CHECK) {
             if (data == null){
                 // The CHECK_TTS_DATA activity for the plugin did not run properly;
@@ -402,7 +398,7 @@
             }
             if (available.size() > 0){
                 if (mTts == null) {
-                    mTts = new TextToSpeech(this, this);
+                    mTts = new TextToSpeech(getActivity(), this);
                 }
                 ListPreference ttsLanguagePref =
                         (ListPreference) findPreference("tts_default_lang");
@@ -478,7 +474,7 @@
             updateWidgetState();
         } else if (requestCode == GET_SAMPLE_TEXT) {
             if (resultCode == TextToSpeech.LANG_AVAILABLE) {
-                String sample = getString(R.string.tts_demo);
+                String sample = getActivity().getString(R.string.tts_demo);
                 if ((data != null) && (data.getStringExtra("sampleText") != null)) {
                     sample = data.getStringExtra("sampleText");
                 }
@@ -492,7 +488,6 @@
         }
     }
 
-
     public boolean onPreferenceChange(Preference preference, Object objValue) {
         if (KEY_TTS_USE_DEFAULT.equals(preference.getKey())) {
             // "Use Defaults"
@@ -507,7 +502,7 @@
                 Settings.Secure.putInt(getContentResolver(),
                         TTS_DEFAULT_RATE, mDefaultRate);
                 if (mTts != null) {
-                    mTts.setSpeechRate((float)(mDefaultRate/100.0f));
+                    mTts.setSpeechRate(mDefaultRate/100.0f);
                 }
                 Log.i(TAG, "TTS default rate is " + mDefaultRate);
             } catch (NumberFormatException e) {
@@ -575,10 +570,11 @@
             if (!chkPref.getKey().equals(KEY_TTS_USE_DEFAULT)){
                 if (chkPref.isChecked()) {
                     chkPref.setChecked(false);
-                    AlertDialog d = (new AlertDialog.Builder(this))
+                    AlertDialog d = (new AlertDialog.Builder(getActivity()))
                             .setTitle(android.R.string.dialog_alert_title)
                             .setIcon(android.R.drawable.ic_dialog_alert)
-                            .setMessage(getString(R.string.tts_engine_security_warning,
+                            .setMessage(
+                                    getActivity().getString(R.string.tts_engine_security_warning,
                                     chkPref.getTitle()))
                             .setCancelable(true)
                             .setPositiveButton(android.R.string.ok,
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 694bc1f..4c43712 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -16,14 +16,12 @@
 
 package com.android.settings;
 
-import java.util.List;
-
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.graphics.drawable.Drawable;
@@ -33,6 +31,9 @@
 import android.preference.PreferenceGroup;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.List;
 
 public class Utils {
 
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 8765dfb..af03549 100644
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -69,6 +69,7 @@
 public class InstalledAppDetails extends Activity
         implements View.OnClickListener, ApplicationsState.Callbacks {
     private static final String TAG="InstalledAppDetails";
+    static final boolean SUPPORT_DISABLE_APPS = false;
     
     private PackageManager mPm;
     private ApplicationsState mState;
@@ -259,30 +260,32 @@
         } else {
             if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                 enabled = false;
-                try {
-                    // Try to prevent the user from bricking their phone
-                    // by not allowing disabling of apps signed with the
-                    // system cert and any launcher app in the system.
-                    PackageInfo sys = mPm.getPackageInfo("android",
-                            PackageManager.GET_SIGNATURES);
-                    Intent intent = new Intent(Intent.ACTION_MAIN);
-                    intent.addCategory(Intent.CATEGORY_HOME);
-                    intent.setPackage(mAppEntry.info.packageName);
-                    List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
-                    if ((homes != null && homes.size() > 0) ||
-                            (mPackageInfo != null &&
-                                    sys.signatures[0].equals(mPackageInfo.signatures[0]))) {
-                        // Disable button for core system applications.
-                        mUninstallButton.setText(R.string.disable_text);
-                    } else if (mAppEntry.info.enabled) {
-                        mUninstallButton.setText(R.string.disable_text);
-                        enabled = true;
-                    } else {
-                        mUninstallButton.setText(R.string.enable_text);
-                        enabled = true;
+                if (SUPPORT_DISABLE_APPS) {
+                    try {
+                        // Try to prevent the user from bricking their phone
+                        // by not allowing disabling of apps signed with the
+                        // system cert and any launcher app in the system.
+                        PackageInfo sys = mPm.getPackageInfo("android",
+                                PackageManager.GET_SIGNATURES);
+                        Intent intent = new Intent(Intent.ACTION_MAIN);
+                        intent.addCategory(Intent.CATEGORY_HOME);
+                        intent.setPackage(mAppEntry.info.packageName);
+                        List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
+                        if ((homes != null && homes.size() > 0) ||
+                                (mPackageInfo != null &&
+                                        sys.signatures[0].equals(mPackageInfo.signatures[0]))) {
+                            // Disable button for core system applications.
+                            mUninstallButton.setText(R.string.disable_text);
+                        } else if (mAppEntry.info.enabled) {
+                            mUninstallButton.setText(R.string.disable_text);
+                            enabled = true;
+                        } else {
+                            mUninstallButton.setText(R.string.enable_text);
+                            enabled = true;
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                        Log.w(TAG, "Unable to get package info", e);
                     }
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "Unable to get package info", e);
                 }
             } else {
                 mUninstallButton.setText(R.string.uninstall_text);
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 772e48d..34e0e8e 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -354,7 +354,11 @@
                     holder.appIcon.setImageDrawable(entry.icon);
                 }
                 holder.updateSizeText(ManageApplications.this);
-                holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
+                if (InstalledAppDetails.SUPPORT_DISABLE_APPS) {
+                    holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
+                } else {
+                    holder.disabled.setVisibility(View.GONE);
+                }
             }
             mActive.remove(convertView);
             mActive.add(convertView);
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index 5f374a5..d655f90 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -91,10 +91,10 @@
     // See mConnectAttempted
     private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
 
-    
+
     /**
      * Describes the current device and profile for logging.
-     * 
+     *
      * @param profile Profile to describe
      * @return Description of the device and profile
      */
@@ -107,7 +107,7 @@
 
         return sb.toString();
     }
-    
+
     private String describe(Profile profile) {
         return describe(this, profile);
     }
@@ -264,7 +264,7 @@
                         .getProfileManager(mLocalManager, profile);
                 if (profileManager.isPreferred(mDevice)) {
                     ++preferredProfiles;
-                    disconnectConnected(profile);
+                    disconnectConnected(this, profile);
                     connectInt(this, profile);
                 }
             }
@@ -287,7 +287,7 @@
                 LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
                         .getProfileManager(mLocalManager, profile);
                 profileManager.setPreferred(mDevice, false);
-                disconnectConnected(profile);
+                disconnectConnected(this, profile);
                 connectInt(this, profile);
             }
         }
@@ -297,19 +297,20 @@
         mConnectAttempted = SystemClock.elapsedRealtime();
         // Reset the only-show-one-error-dialog tracking variable
         mIsConnectingErrorPossible = true;
-        disconnectConnected(profile);
+        disconnectConnected(this, profile);
         connectInt(this, profile);
     }
 
-    private void disconnectConnected(Profile profile) {
+    private void disconnectConnected(CachedBluetoothDevice device, Profile profile) {
         LocalBluetoothProfileManager profileManager =
             LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
         CachedBluetoothDeviceManager cachedDeviceManager = mLocalManager.getCachedDeviceManager();
         Set<BluetoothDevice> devices = profileManager.getConnectedDevices();
         if (devices == null) return;
-        for (BluetoothDevice device : devices) {
-            CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(device);
-            if (cachedDevice != null) {
+        for (BluetoothDevice btDevice : devices) {
+            CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(btDevice);
+
+            if (cachedDevice != null && !cachedDevice.equals(device)) {
                 disconnectInt(cachedDevice, profile);
             }
         }
diff --git a/src/com/android/settings/vpn/VpnEditor.java b/src/com/android/settings/vpn/VpnEditor.java
index 349befb..3ab0b90 100644
--- a/src/com/android/settings/vpn/VpnEditor.java
+++ b/src/com/android/settings/vpn/VpnEditor.java
@@ -17,7 +17,9 @@
 package com.android.settings.vpn;
 
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.DialogInterface;
@@ -27,22 +29,19 @@
 import android.net.vpn.L2tpProfile;
 import android.net.vpn.PptpProfile;
 import android.net.vpn.VpnProfile;
-import android.net.vpn.VpnType;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
 import android.text.TextUtils;
-import android.view.KeyEvent;
+import android.util.Log;
 import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 
 /**
  * The activity class for editing a new or existing VPN profile.
  */
-public class VpnEditor extends PreferenceActivity {
+public class VpnEditor extends SettingsPreferenceFragment {
     private static final int MENU_SAVE = Menu.FIRST;
     private static final int MENU_CANCEL = Menu.FIRST + 1;
     private static final int CONFIRM_DIALOG_ID = 0;
@@ -56,59 +55,75 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        VpnProfile p = (VpnProfile) ((savedInstanceState == null)
-                ? getIntent().getParcelableExtra(VpnSettings.KEY_VPN_PROFILE)
-                : savedInstanceState.getParcelable(KEY_PROFILE));
-        mProfileEditor = getEditor(p);
-        mAddingProfile = TextUtils.isEmpty(p.getName());
 
         // Loads the XML preferences file
         addPreferencesFromResource(R.xml.vpn_edit);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        VpnProfile p;
+        if (savedInstanceState != null) {
+            p = (VpnProfile)savedInstanceState.getParcelable(KEY_PROFILE);
+        } else {
+            p = (VpnProfile)getArguments().getParcelable(VpnSettings.KEY_VPN_PROFILE);
+            if (p == null) {
+                p = getActivity().getIntent().getParcelableExtra(VpnSettings.KEY_VPN_PROFILE);
+            }
+        }
+
+        mProfileEditor = getEditor(p);
+        mAddingProfile = TextUtils.isEmpty(p.getName());
 
         initViewFor(p);
 
         Parcel parcel = Parcel.obtain();
         p.writeToParcel(parcel, 0);
         mOriginalProfileData = parcel.marshall();
+
+        registerForContextMenu(getListView());
+        setHasOptionsMenu(true);
     }
 
     @Override
-    protected synchronized void onSaveInstanceState(Bundle outState) {
+    public synchronized void onSaveInstanceState(Bundle outState) {
         if (mProfileEditor == null) return;
 
         outState.putParcelable(KEY_PROFILE, getProfile());
     }
 
     @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
         menu.add(0, MENU_SAVE, 0, R.string.vpn_menu_done)
             .setIcon(android.R.drawable.ic_menu_save);
         menu.add(0, MENU_CANCEL, 0,
                 mAddingProfile ? R.string.vpn_menu_cancel
                                : R.string.vpn_menu_revert)
             .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
-        return true;
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case MENU_SAVE:
-                if (validateAndSetResult()) finish();
+                if (validateAndSetResult()) finishFragment();
                 return true;
 
             case MENU_CANCEL:
                 if (profileChanged()) {
                     showDialog(CONFIRM_DIALOG_ID);
                 } else {
-                    finish();
+                    finishFragment();
                 }
                 return true;
         }
         return super.onOptionsItemSelected(item);
     }
 
+    /*
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
@@ -117,7 +132,7 @@
                 return true;
         }
         return super.onKeyDown(keyCode, event);
-    }
+    }*/
 
     private void initViewFor(VpnProfile profile) {
         setTitle(profile);
@@ -125,10 +140,11 @@
     }
 
     private void setTitle(VpnProfile profile) {
+        final Activity activity = getActivity();
         String formatString = mAddingProfile
-                ? getString(R.string.vpn_edit_title_add)
-                : getString(R.string.vpn_edit_title_edit);
-        setTitle(String.format(formatString,
+                ? activity.getString(R.string.vpn_edit_title_add)
+                : activity.getString(R.string.vpn_edit_title_edit);
+        activity.setTitle(String.format(formatString,
                 profile.getType().getDisplayName()));
     }
 
@@ -140,7 +156,7 @@
         String errorMsg = mProfileEditor.validate();
 
         if (errorMsg != null) {
-            Util.showErrorMessage(this, errorMsg);
+            Util.showErrorMessage(getActivity(), errorMsg);
             return false;
         }
 
@@ -149,9 +165,9 @@
     }
 
     private void setResult(VpnProfile p) {
-        Intent intent = new Intent(this, VpnSettings.class);
+        Intent intent = new Intent(getActivity(), VpnSettings.class);
         intent.putExtra(VpnSettings.KEY_VPN_PROFILE, (Parcelable) p);
-        setResult(RESULT_OK, intent);
+        setResult(Activity.RESULT_OK, intent);
     }
 
     private VpnProfileEditor getEditor(VpnProfile p) {
@@ -175,10 +191,9 @@
 
 
     @Override
-    protected Dialog onCreateDialog(int id) {
-
+    public Dialog onCreateDialog(int id) {
         if (id == CONFIRM_DIALOG_ID) {
-            return new AlertDialog.Builder(this)
+            return new AlertDialog.Builder(getActivity())
                     .setTitle(android.R.string.dialog_alert_title)
                     .setIcon(android.R.drawable.ic_dialog_alert)
                     .setMessage(mAddingProfile
@@ -187,7 +202,7 @@
                     .setPositiveButton(R.string.vpn_yes_button,
                             new DialogInterface.OnClickListener() {
                                 public void onClick(DialogInterface dialog, int w) {
-                                    finish();
+                                    finishFragment();
                                 }
                             })
                     .setNegativeButton(R.string.vpn_mistake_button, null)
@@ -197,8 +212,9 @@
         return super.onCreateDialog(id);
     }
 
+    /*
     @Override
-    protected void onPrepareDialog(int id, Dialog dialog) {
+    public void onPrepareDialog(int id, Dialog dialog) {
         super.onPrepareDialog(id, dialog);
 
         if (id == CONFIRM_DIALOG_ID) {
@@ -206,7 +222,7 @@
                     ? getString(R.string.vpn_confirm_add_profile_cancellation)
                     : getString(R.string.vpn_confirm_edit_profile_cancellation));
         }
-    }
+    }*/
 
     private VpnProfile getProfile() {
         return mProfileEditor.getProfile();
diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java
index 7b8d433..e9a4c3d 100644
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -17,11 +17,14 @@
 package com.android.settings.vpn;
 
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.content.ComponentName;
+import android.app.Fragment;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -37,12 +40,10 @@
 import android.os.Bundle;
 import android.os.ConditionVariable;
 import android.os.IBinder;
-import android.os.Parcelable;
 import android.preference.Preference;
-import android.preference.PreferenceActivity;
+import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
-import android.preference.Preference.OnPreferenceClickListener;
 import android.security.Credentials;
 import android.security.KeyStore;
 import android.text.TextUtils;
@@ -69,8 +70,8 @@
 /**
  * The preference activity for configuring VPN settings.
  */
-public class VpnSettings extends PreferenceActivity implements
-        DialogInterface.OnClickListener {
+public class VpnSettings extends SettingsPreferenceFragment
+        implements DialogInterface.OnClickListener {
     // Key to the field exchanged for profile editing.
     static final String KEY_VPN_PROFILE = "vpn_profile";
 
@@ -122,7 +123,7 @@
 
     private KeyStore mKeyStore = KeyStore.getInstance();
 
-    private VpnManager mVpnManager = new VpnManager(this);
+    private VpnManager mVpnManager;
 
     private ConnectivityReceiver mConnectivityReceiver =
             new ConnectivityReceiver();
@@ -137,7 +138,13 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.vpn_settings);
+    }
 
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        mVpnManager = new VpnManager(getActivity());
         // restore VpnProfile list and construct VpnPreference map
         mVpnListContainer = (PreferenceCategory) findPreference(PREF_VPN_LIST);
 
@@ -168,22 +175,24 @@
         if ((mUnlockAction != null) && isKeyStoreUnlocked()) {
             Runnable action = mUnlockAction;
             mUnlockAction = null;
-            runOnUiThread(action);
+            getActivity().runOnUiThread(action);
         }
     }
 
     @Override
-    protected void onDestroy() {
-        super.onDestroy();
+    public void onDestroyView() {
         unregisterForContextMenu(getListView());
         mVpnManager.unregisterConnectivityReceiver(mConnectivityReceiver);
         if ((mShowingDialog != null) && mShowingDialog.isShowing()) {
             mShowingDialog.dismiss();
         }
+        // This should be called after the procedure above as ListView inside this Fragment
+        // will be deleted here.
+        super.onDestroyView();
     }
 
     @Override
-    protected Dialog onCreateDialog (int id) {
+    public Dialog onCreateDialog (int id) {
         switch (id) {
             case DIALOG_CONNECT:
                 return createConnectDialog();
@@ -203,13 +212,14 @@
     }
 
     private Dialog createConnectDialog() {
-        return new AlertDialog.Builder(this)
+        final Activity activity = getActivity();
+        return new AlertDialog.Builder(activity)
                 .setView(mConnectingActor.createConnectView())
-                .setTitle(String.format(getString(R.string.vpn_connect_to),
+                .setTitle(String.format(activity.getString(R.string.vpn_connect_to),
                         mActiveProfile.getName()))
-                .setPositiveButton(getString(R.string.vpn_connect_button),
+                .setPositiveButton(activity.getString(R.string.vpn_connect_button),
                         this)
-                .setNegativeButton(getString(android.R.string.cancel),
+                .setNegativeButton(activity.getString(android.R.string.cancel),
                         this)
                 .setOnCancelListener(new DialogInterface.OnCancelListener() {
                             public void onCancel(DialogInterface dialog) {
@@ -291,7 +301,7 @@
     }
 
     private AlertDialog.Builder createCommonDialogBuilder() {
-        return new AlertDialog.Builder(this)
+        return new AlertDialog.Builder(getActivity())
                 .setTitle(android.R.string.dialog_alert_title)
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setPositiveButton(R.string.vpn_yes_button,
@@ -364,9 +374,9 @@
     }
 
     @Override
-    protected void onActivityResult(final int requestCode, final int resultCode,
+    public void onActivityResult(final int requestCode, final int resultCode,
             final Intent data) {
-        if ((resultCode == RESULT_CANCELED) || (data == null)) {
+        if ((resultCode == Activity.RESULT_CANCELED) || (data == null)) {
             Log.d(TAG, "no result returned by editor");
             return;
         }
@@ -381,11 +391,12 @@
                 return;
             }
 
+            final Activity activity = getActivity();
             int index = getProfileIndexFromId(p.getId());
             if (checkDuplicateName(p, index)) {
                 final VpnProfile profile = p;
-                Util.showErrorMessage(this, String.format(
-                        getString(R.string.vpn_error_duplicate_name),
+                Util.showErrorMessage(activity, String.format(
+                        activity.getString(R.string.vpn_error_duplicate_name),
                         p.getName()),
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int w) {
@@ -407,30 +418,32 @@
             try {
                 if (index < 0) {
                     addProfile(p);
-                    Util.showShortToastMessage(this, String.format(
-                            getString(R.string.vpn_profile_added), p.getName()));
+                    Util.showShortToastMessage(activity, String.format(
+                            activity.getString(R.string.vpn_profile_added), p.getName()));
                 } else {
                     replaceProfile(index, p);
-                    Util.showShortToastMessage(this, String.format(
-                            getString(R.string.vpn_profile_replaced),
+                    Util.showShortToastMessage(activity, String.format(
+                            activity.getString(R.string.vpn_profile_replaced),
                             p.getName()));
                 }
             } catch (IOException e) {
                 final VpnProfile profile = p;
-                Util.showErrorMessage(this, e + ": " + e.getMessage(),
+                Util.showErrorMessage(activity, e + ": " + e.getMessage(),
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int w) {
                                 startVpnEditor(profile);
                             }
                         });
             }
+
+            // Remove cached VpnEditor as it is needless anymore.
         } else {
             throw new RuntimeException("unknown request code: " + requestCode);
         }
     }
 
     // Called when the buttons on the connect dialog are clicked.
-    //@Override
+    @Override
     public synchronized void onClick(DialogInterface dialog, int which) {
         if (which == CONNECT_BUTTON) {
             Dialog d = (Dialog) dialog;
@@ -440,12 +453,15 @@
                 removeDialog(DIALOG_CONNECT);
                 return;
             } else {
-                dismissDialog(DIALOG_CONNECT);
+                // dismissDialog(DIALOG_CONNECT);
+                removeDialog(DIALOG_CONNECT);
+
+                final Activity activity = getActivity();
                 // show error dialog
-                mShowingDialog = new AlertDialog.Builder(this)
+                mShowingDialog = new AlertDialog.Builder(activity)
                         .setTitle(android.R.string.dialog_alert_title)
                         .setIcon(android.R.drawable.ic_dialog_alert)
-                        .setMessage(String.format(getString(
+                        .setMessage(String.format(activity.getString(
                                 R.string.vpn_error_miss_entering), error))
                         .setPositiveButton(R.string.vpn_back_button,
                                 new DialogInterface.OnClickListener() {
@@ -513,7 +529,7 @@
                         }
                     }
                 };
-        mShowingDialog = new AlertDialog.Builder(this)
+        mShowingDialog = new AlertDialog.Builder(getActivity())
                 .setTitle(android.R.string.dialog_alert_title)
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setMessage(R.string.vpn_confirm_profile_deletion)
@@ -559,7 +575,7 @@
     // Adds a preference in mVpnListContainer
     private VpnPreference addPreferenceFor(
             VpnProfile p, boolean addToContainer) {
-        VpnPreference pref = new VpnPreference(this, p);
+        VpnPreference pref = new VpnPreference(getActivity(), p);
         mVpnPreferenceMap.put(p.getName(), pref);
         if (addToContainer) mVpnListContainer.addPreference(pref);
 
@@ -599,8 +615,8 @@
     }
 
     private void startVpnTypeSelection() {
-        Intent intent = new Intent(this, VpnTypeSelection.class);
-        startActivityForResult(intent, REQUEST_SELECT_VPN_TYPE);
+        startFragment(this, VpnTypeSelection.class.getCanonicalName(),
+                REQUEST_SELECT_VPN_TYPE, null);
     }
 
     private boolean isKeyStoreUnlocked() {
@@ -614,16 +630,14 @@
                 L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p;
                 String presharedKey = pskProfile.getPresharedKey();
                 if (!TextUtils.isEmpty(presharedKey)) return true;
-                // pass through
-
+                // $FALL-THROUGH$
             case L2TP:
                 L2tpProfile l2tpProfile = (L2tpProfile) p;
                 if (l2tpProfile.isSecretEnabled() &&
                         !TextUtils.isEmpty(l2tpProfile.getSecretString())) {
                     return true;
                 }
-                // pass through
-
+                // $FALL-THROUGH$
             default:
                 return false;
         }
@@ -648,14 +662,15 @@
     private boolean unlockKeyStore(VpnProfile p, Runnable action) {
         if (isKeyStoreUnlocked()) return true;
         mUnlockAction = action;
-        Credentials.getInstance().unlock(this);
+        Credentials.getInstance().unlock(getActivity());
         return false;
     }
 
     private void startVpnEditor(final VpnProfile profile) {
-        Intent intent = new Intent(this, VpnEditor.class);
-        intent.putExtra(KEY_VPN_PROFILE, (Parcelable) profile);
-        startActivityForResult(intent, REQUEST_ADD_OR_EDIT_PROFILE);
+        Bundle args = new Bundle();
+        args.putParcelable(KEY_VPN_PROFILE, profile);
+        startFragment(this, VpnEditor.class.getCanonicalName(),
+                REQUEST_ADD_OR_EDIT_PROFILE, args);
     }
 
     private synchronized void connect(final VpnProfile p) {
@@ -714,7 +729,7 @@
 
         case CONNECTING:
             mConnectingActor = getActor(p);
-            // pass through
+            // $FALL-THROUGH$
         case DISCONNECTING:
             mActiveProfile = p;
             disableProfilePreferencesIfOneActive();
@@ -810,11 +825,6 @@
             public int compare(VpnProfile p1, VpnProfile p2) {
                 return p1.getName().compareTo(p2.getName());
             }
-
-            public boolean equals(VpnProfile p) {
-                // not used
-                return false;
-            }
         });
         for (VpnProfile p : mVpnProfileList) {
             Preference pref = addPreferenceFor(p, false);
@@ -855,20 +865,21 @@
     }
 
     private String getProfileSummaryString(VpnProfile p) {
+        final Activity activity = getActivity();
         switch (p.getState()) {
         case CONNECTING:
-            return getString(R.string.vpn_connecting);
+            return activity.getString(R.string.vpn_connecting);
         case DISCONNECTING:
-            return getString(R.string.vpn_disconnecting);
+            return activity.getString(R.string.vpn_disconnecting);
         case CONNECTED:
-            return getString(R.string.vpn_connected);
+            return activity.getString(R.string.vpn_connected);
         default:
-            return getString(R.string.vpn_connect_hint);
+            return activity.getString(R.string.vpn_connect_hint);
         }
     }
 
     private VpnProfileActor getActor(VpnProfile p) {
-        return new AuthenticationActor(this, p);
+        return new AuthenticationActor(getActivity(), p);
     }
 
     private VpnProfile createVpnProfile(String type) {
@@ -938,8 +949,7 @@
                     Log.e(TAG, "keystore write failed: key=" + key);
                 }
                 pskProfile.setPresharedKey(key);
-                // pass through
-
+                // $FALL-THROUGH$
             case L2TP_IPSEC:
             case L2TP:
                 L2tpProfile l2tpProfile = (L2tpProfile) p;
@@ -1007,8 +1017,6 @@
 
     // managing status check in a background thread
     private class StatusChecker {
-        private List<VpnProfile> mList;
-
         synchronized void check(final List<VpnProfile> list) {
             final ConditionVariable cv = new ConditionVariable();
             cv.close();
@@ -1027,7 +1035,7 @@
                             changeState(p, VpnState.IDLE);
                         }
                     }
-                    VpnSettings.this.unbindService(this);
+                    getActivity().unbindService(this);
                     showPreferences();
                 }
 
@@ -1035,7 +1043,7 @@
                     cv.open();
 
                     setDefaultState(list);
-                    VpnSettings.this.unbindService(this);
+                    getActivity().unbindService(this);
                     showPreferences();
                 }
             };
diff --git a/src/com/android/settings/vpn/VpnTypeSelection.java b/src/com/android/settings/vpn/VpnTypeSelection.java
index aa4bc5e..5990ac0 100644
--- a/src/com/android/settings/vpn/VpnTypeSelection.java
+++ b/src/com/android/settings/vpn/VpnTypeSelection.java
@@ -17,13 +17,14 @@
 package com.android.settings.vpn;
 
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 
+import android.app.Activity;
 import android.content.Intent;
 import android.net.vpn.VpnManager;
 import android.net.vpn.VpnType;
 import android.os.Bundle;
 import android.preference.Preference;
-import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
 
 import java.util.HashMap;
@@ -32,7 +33,7 @@
 /**
  * The activity to select a VPN type.
  */
-public class VpnTypeSelection extends PreferenceActivity {
+public class VpnTypeSelection extends SettingsPreferenceFragment {
     private Map<String, VpnType> mTypeMap = new HashMap<String, VpnType>();
 
     @Override
@@ -46,19 +47,20 @@
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen ps, Preference pref) {
         setResult(mTypeMap.get(pref.getTitle().toString()));
-        finish();
+        finishFragment();
         return true;
     }
 
     private void initTypeList() {
         PreferenceScreen root = getPreferenceScreen();
+        final Activity activity = getActivity();
         for (VpnType t : VpnManager.getSupportedVpnTypes()) {
             String displayName = t.getDisplayName();
             String message = String.format(
-                    getString(R.string.vpn_edit_title_add), displayName);
+                    activity.getString(R.string.vpn_edit_title_add), displayName);
             mTypeMap.put(message, t);
 
-            Preference pref = new Preference(this);
+            Preference pref = new Preference(activity);
             pref.setTitle(message);
             pref.setSummary(t.getDescriptionId());
             root.addPreference(pref);
@@ -66,8 +68,8 @@
     }
 
     private void setResult(VpnType type) {
-        Intent intent = new Intent(this, VpnSettings.class);
+        Intent intent = new Intent(getActivity(), VpnSettings.class);
         intent.putExtra(VpnSettings.KEY_VPN_TYPE, type.toString());
-        setResult(RESULT_OK, intent);
+        setResult(Activity.RESULT_OK, intent);
     }
 }
diff --git a/src/com/android/settings/wifi/AdvancedSettings.java b/src/com/android/settings/wifi/AdvancedSettings.java
index 4b33fdc..c88073d 100644
--- a/src/com/android/settings/wifi/AdvancedSettings.java
+++ b/src/com/android/settings/wifi/AdvancedSettings.java
@@ -17,35 +17,40 @@
 package com.android.settings.wifi;
 
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 
+import android.app.Activity;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
+import android.os.SystemProperties;
 import android.preference.ListPreference;
 import android.preference.Preference;
-import android.preference.PreferenceActivity;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.widget.Toast;
-import android.os.SystemProperties;
 
-public class AdvancedSettings extends PreferenceActivity
+public class AdvancedSettings extends SettingsPreferenceFragment
         implements Preference.OnPreferenceChangeListener {
 
     private static final String KEY_MAC_ADDRESS = "mac_address";
     private static final String KEY_CURRENT_IP_ADDRESS = "current_ip_address";
     private static final String KEY_NUM_CHANNELS = "num_channels";
     private static final String KEY_SLEEP_POLICY = "sleep_policy";
-    
+
     //Tracks ro.debuggable (1 on userdebug builds)
     private static int DEBUGGABLE;
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
+    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        
         addPreferencesFromResource(R.xml.wifi_advanced_settings);
-        
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
         DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0);
 
         /**
@@ -68,9 +73,9 @@
     }
     
     @Override
-    protected void onResume() {
+    public void onResume() {
         super.onResume();
-        
+
         /**
          * Remove user control of regulatory domain
          * channel count settings in non userdebug builds
@@ -86,7 +91,7 @@
         ListPreference pref = (ListPreference) findPreference(KEY_NUM_CHANNELS);
         pref.setOnPreferenceChangeListener(this);
 
-        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+        WifiManager wifiManager = (WifiManager) getSystemService(Activity.WIFI_SERVICE);
         /*
          * Generate the list of valid channel counts to show in the ListPreference.
          * The values are numerical, so the only text to be localized is the
@@ -94,7 +99,7 @@
          */
         int[] validChannelCounts = wifiManager.getValidChannelCounts();
         if (validChannelCounts == null) {
-            Toast.makeText(this, R.string.wifi_setting_num_channels_error,
+            Toast.makeText(getActivity(), R.string.wifi_setting_num_channels_error,
                            Toast.LENGTH_SHORT).show();
             pref.setEnabled(false);
             return;
@@ -104,8 +109,8 @@
 
         for (int i = 0; i < validChannelCounts.length; i++) {
             entryValues[i] = String.valueOf(validChannelCounts[i]);
-            entries[i] = getString(R.string.wifi_setting_num_channels_channel_phrase,
-                                   validChannelCounts[i]);
+            entries[i] = getActivity().getString(R.string.wifi_setting_num_channels_channel_phrase,
+                    validChannelCounts[i]);
         }
         pref.setEntries(entries);
         pref.setEntryValues(entryValues);
@@ -131,13 +136,13 @@
         if (key.equals(KEY_NUM_CHANNELS)) {
             try {
                 int numChannels = Integer.parseInt((String) newValue);
-                WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+                WifiManager wifiManager = (WifiManager) getSystemService(Activity.WIFI_SERVICE);
                 if (!wifiManager.setNumAllowedChannels(numChannels, true)) {
-                    Toast.makeText(this, R.string.wifi_setting_num_channels_error,
+                    Toast.makeText(getActivity(), R.string.wifi_setting_num_channels_error,
                             Toast.LENGTH_SHORT).show();
                 }
             } catch (NumberFormatException e) {
-                Toast.makeText(this, R.string.wifi_setting_num_channels_error,
+                Toast.makeText(getActivity(), R.string.wifi_setting_num_channels_error,
                         Toast.LENGTH_SHORT).show();
                 return false;
             }
@@ -147,24 +152,23 @@
                 Settings.System.putInt(getContentResolver(),
                         Settings.System.WIFI_SLEEP_POLICY, Integer.parseInt(((String) newValue)));
             } catch (NumberFormatException e) {
-                Toast.makeText(this, R.string.wifi_setting_sleep_policy_error,
+                Toast.makeText(getActivity(), R.string.wifi_setting_sleep_policy_error,
                         Toast.LENGTH_SHORT).show();
                 return false;
             }
-
         }
         
         return true;
     }
 
     private void refreshWifiInfo() {
-        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+        WifiManager wifiManager = (WifiManager) getSystemService(Activity.WIFI_SERVICE);
         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
 
         Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS);
         String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
         wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress 
-                : getString(R.string.status_unavailable));
+                : getActivity().getString(R.string.status_unavailable));
 
         Preference wifiIpAddressPref = findPreference(KEY_CURRENT_IP_ADDRESS);
         String ipAddress = null;
@@ -178,7 +182,7 @@
             }
         }
         wifiIpAddressPref.setSummary(ipAddress == null ?
-                getString(R.string.status_unavailable) : ipAddress);
+                getActivity().getString(R.string.status_unavailable) : ipAddress);
     }
 
 }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index acb9ad3..5f6294f 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -188,7 +188,6 @@
         mAddNetwork = findPreference("add_network");
 
         registerForContextMenu(getListView());
-
         setHasOptionsMenu(true);
     }
 
@@ -267,7 +266,7 @@
                 }
                 return true;
             case MENU_ID_ADVANCED:
-                startActivity(new Intent(getActivity(), AdvancedSettings.class));
+                startFragment(this, AdvancedSettings.class.getCanonicalName(), -1, null);
                 return true;
         }
         return super.onOptionsItemSelected(item);
@@ -667,4 +666,12 @@
         mSelectedAccessPoint = null;
         showConfigUi(null, true);
     }
+
+    /* package */ int getAccessPointsCount() {
+        if (mAccessPoints != null) {
+            return mAccessPoints.getPreferenceCount();
+        } else {
+            return 0;
+        }
+    }
 }
diff --git a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
index 2d26645..ef827f6 100644
--- a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
+++ b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
@@ -40,7 +40,7 @@
 
     static {
         stateMap.put(DetailedState.IDLE, DetailedState.DISCONNECTED);
-        stateMap.put(DetailedState.SCANNING, DetailedState.DISCONNECTED);
+        stateMap.put(DetailedState.SCANNING, DetailedState.SCANNING);
         stateMap.put(DetailedState.CONNECTING, DetailedState.CONNECTING);
         stateMap.put(DetailedState.AUTHENTICATING, DetailedState.CONNECTING);
         stateMap.put(DetailedState.OBTAINING_IPADDR, DetailedState.CONNECTING);
@@ -111,28 +111,40 @@
 
     public void updateConnectionState(DetailedState originalState) {
         final DetailedState state = stateMap.get(originalState);
-        final String message;
-        mProgressBar.setIndeterminate(false);
         switch (state) {
+        case SCANNING: {
+            // Let users know the device is working correctly though currently there's
+            // no visible network on the list.
+            if (mWifiSettings.getAccessPointsCount() == 0) {
+                mProgressBar.setIndeterminate(true);
+                mProgressText.setText(Summary.get(this, DetailedState.SCANNING));
+            } else {
+                // Users already already connected to a network, or see available networks.
+                mProgressBar.setIndeterminate(false);
+            }
+            break;
+        }
         case CONNECTING: {
-            message = Summary.get(this, state);
+            mProgressBar.setIndeterminate(false);
             mProgressBar.setProgress(1);
             mStatusText.setText(R.string.wifi_setup_status_connecting);
+            mProgressText.setText(Summary.get(this, state));
             break;
         }
         case CONNECTED: {
-            message = Summary.get(this, state);
+            mProgressBar.setIndeterminate(false);
             mProgressBar.setProgress(2);
             mStatusText.setText(R.string.wifi_setup_status_connected);
+            mProgressText.setText(Summary.get(this, state));
             break;
         }
         default:  // Not connected.
-            message = getString(R.string.wifi_setup_not_connected);
+            mProgressBar.setIndeterminate(false);
             mProgressBar.setProgress(0);
             mStatusText.setText(R.string.wifi_setup_status_select_network);
+            mProgressText.setText(getString(R.string.wifi_setup_not_connected));
             break;
         }
-        mProgressText.setText(message);
     }
 
     public void onWifiConfigPreferenceAttached(boolean isNewNetwork) {