am 42a6c754: am 3a38c110: Merge "Fix mac build"

* commit '42a6c75463a3b4590dbc9a3483222f3478342367':
  Fix mac build
diff --git a/.gitignore b/.gitignore
index 452fd81..60483ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
 *~
 *.bak
 *.pyc
+*.pyc-2.4
 Thumbs.db
-
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b84e1b6..a113c71 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -44,6 +44,8 @@
 #$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
 #$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
 
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/CorpApp_intermediates)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/apps/Development/AndroidManifest.xml b/apps/Development/AndroidManifest.xml
index c809554..ffee933 100644
--- a/apps/Development/AndroidManifest.xml
+++ b/apps/Development/AndroidManifest.xml
@@ -18,6 +18,7 @@
         package="com.android.development"
         android:versionCode="1" android:versionName="1.0">
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.DEVICE_POWER" />
@@ -43,12 +44,12 @@
     <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.YouTubeUser" />
 
     <application android:label="Dev Tools"
-            android:icon="@drawable/ic_launcher_devtools">
+            android:icon="@mipmap/ic_launcher_devtools">
 
         <uses-library android:name="android.test.runner" />
 
         <activity android:name="Development" android:label="Dev Tools"
-            android:icon="@drawable/ic_launcher_devtools">
+            android:icon="@mipmap/ic_launcher_devtools">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -77,7 +78,6 @@
         </activity>
 
         <activity android:name="AccountsTester" android:label="AccountsTester"
-                  android:theme="@android:style/Theme.Light"
                   android:windowSoftInputMode="stateHidden">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -117,7 +117,7 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="MediaScannerActivity" android:label="Media Scanner">
+        <activity android:name="MediaScannerActivity" android:label="Media Provider">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.TEST" />
diff --git a/apps/Development/res/layout/accounts_tester.xml b/apps/Development/res/layout/accounts_tester.xml
index df7c73f..28f1b4e 100644
--- a/apps/Development/res/layout/accounts_tester.xml
+++ b/apps/Development/res/layout/accounts_tester.xml
@@ -14,100 +14,110 @@
      limitations under the License.
 -->
 
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
 
-    <LinearLayout
-       android:orientation="vertical"
-       android:layout_width="match_parent"
-       android:layout_height="wrap_content">
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
 
-      <LinearLayout
-         android:orientation="horizontal"
-         android:layout_width="match_parent"
-         android:layout_height="wrap_content">
+        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
 
-          <TextView android:id="@+id/accounts_tester_account_types_spinner_label"
-                   android:layout_width="wrap_content"
-                   android:layout_height="wrap_content"
-                   android:text="@string/accounts_tester_select_account_type"/>
+            <TextView android:id="@+id/accounts_tester_account_types_spinner_label"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:text="@string/accounts_tester_select_account_type"/>
 
-          <Spinner android:id="@+id/accounts_tester_account_types_spinner"
-                   android:layout_width="wrap_content"
-                   android:layout_height="wrap_content"/>
-      </LinearLayout>
+            <Spinner android:id="@+id/accounts_tester_account_types_spinner"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"/>
+        </LinearLayout>
 
-      <LinearLayout
-         android:orientation="vertical"
-         android:layout_width="match_parent"
-         android:layout_height="wrap_content">
-          <LinearLayout
-             android:orientation="horizontal"
-             android:layout_width="match_parent"
-             android:layout_height="wrap_content">
-         <Button
-            android:id="@+id/accounts_tester_get_accounts_by_type"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/accounts_tester_get_accounts_by_type"/>
+        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
 
-         <Button
-            android:id="@+id/accounts_tester_get_all_accounts"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/accounts_tester_get_all_accounts"/>
-              <Button android:id="@+id/accounts_tester_add_account"
-                 android:layout_width="wrap_content"
-                 android:layout_height="wrap_content"
-                 android:text="@string/accounts_tester_add_account"/>
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                    android:orientation="horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+                <Button
+                        android:id="@+id/accounts_tester_get_accounts_by_type"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/accounts_tester_get_accounts_by_type"/>
 
-              <Button android:id="@+id/accounts_tester_edit_properties"
-                 android:layout_width="wrap_content"
-                 android:layout_height="wrap_content"
-                 android:text="@string/accounts_tester_edit_properties"/>
-          </LinearLayout>
+                <Button
+                        android:id="@+id/accounts_tester_get_all_accounts"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/accounts_tester_get_all_accounts"/>
 
-          <LinearLayout
-             android:orientation="horizontal"
-             android:layout_width="match_parent"
-             android:layout_height="wrap_content">
-              <TextView android:id="@+id/accounts_tester_desiredFeatures"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/accounts_tester_desired_features_label"/>
+                <Button android:id="@+id/accounts_tester_add_account"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/accounts_tester_add_account"/>
 
-          <EditText android:id="@+id/accounts_tester_desired_features"
-                   android:layout_width="wrap_content"
-                   android:layout_height="wrap_content"
-                   android:minEms="15"/>
-          </LinearLayout>
-          <LinearLayout
-             android:orientation="horizontal"
-             android:layout_width="match_parent"
-             android:layout_height="wrap_content">
-              <TextView android:id="@+id/accounts_tester_desiredFeatures"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/accounts_tester_desired_authtokentype_label"/>
+                <Button android:id="@+id/accounts_tester_edit_properties"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/accounts_tester_edit_properties"/>
 
-          <EditText android:id="@+id/accounts_tester_desired_authtokentype"
-                   android:layout_width="wrap_content"
-                   android:layout_height="wrap_content"
-                   android:minEms="15"/>
-          </LinearLayout>
-       </LinearLayout>
+                <Button android:id="@+id/accounts_tester_get_auth_token_by_type_and_feature"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/accounts_tester_get_auth_token_by_type_and_feature"/>
+
+            </LinearLayout>
+
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                    android:orientation="horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+
+                <TextView android:id="@+id/accounts_tester_desiredFeatures"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:text="@string/accounts_tester_desired_features_label"/>
+
+                <EditText android:id="@+id/accounts_tester_desired_features"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:minEms="15"/>
+            </LinearLayout>
+
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                    android:orientation="horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+
+                <TextView android:id="@+id/accounts_tester_desiredFeatures"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:text="@string/accounts_tester_desired_authtokentype_label"/>
+
+                <EditText android:id="@+id/accounts_tester_desired_authtokentype"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:minEms="15"/>
+            </LinearLayout>
+        </LinearLayout>
     </LinearLayout>
 
-    <LinearLayout
-       android:orientation="horizontal"
-       android:layout_width="match_parent"
-       android:layout_height="wrap_content">
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
 
-       <ListView android:id="@+id/accounts_tester_accounts_list"
-           android:layout_width="match_parent" android:layout_height="match_parent"/>
+        <ListView android:id="@+id/accounts_tester_accounts_list"
+                  android:layout_width="match_parent" android:layout_height="match_parent"/>
 
     </LinearLayout>
 
diff --git a/apps/Development/res/layout/connectivity.xml b/apps/Development/res/layout/connectivity.xml
index 612304f..ff0c6ea 100644
--- a/apps/Development/res/layout/connectivity.xml
+++ b/apps/Development/res/layout/connectivity.xml
@@ -17,12 +17,14 @@
 ** limitations under the License.
 */
 -->
-<LinearLayout
-  xmlns:android="http://schemas.android.com/apk/res/android"
-  android:orientation="vertical"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent">
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
 
+  <LinearLayout
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
     <LinearLayout
       android:orientation="horizontal"
       android:layout_width="match_parent"
@@ -202,5 +204,59 @@
           android:layout_height="wrap_content"
           android:text="@string/crash" />
     </LinearLayout>
-</LinearLayout>
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/add_default_route"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/add_default_route" />
+        <Button android:id="@+id/remove_default_route"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/remove_default_route" />
+    </LinearLayout>
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/default_request"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/default_request" />
+        <Button android:id="@+id/default_socket"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/default_socket" />
+    </LinearLayout>
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/bound_http_request"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/bound_http_request" />
+        <Button android:id="@+id/bound_socket_request"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/bound_socket_request" />
+    </LinearLayout>
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/routed_http_request"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/routed_http_request" />
+        <Button android:id="@+id/routed_socket_request"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/routed_socket_request" />
+    </LinearLayout>
+  </LinearLayout>
+</ScrollView>
 
diff --git a/apps/Development/res/layout/development_settings.xml b/apps/Development/res/layout/development_settings.xml
index 16c2cdf..e9b1dad 100644
--- a/apps/Development/res/layout/development_settings.xml
+++ b/apps/Development/res/layout/development_settings.xml
@@ -74,10 +74,16 @@
             android:layout_alignParentLeft="true"
             android:text="@string/development_settings_show_updates_text" />
 
+        <Spinner android:id="@+id/strictmode_visual"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/show_updates"
+            android:layout_alignParentLeft="true" />
+
         <CheckBox android:id="@+id/compatibility_mode"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_below="@id/show_updates"
+            android:layout_below="@id/strictmode_visual"
             android:layout_alignParentLeft="true"
             android:text="@string/development_settings_compatibility_mode_text" />
 
@@ -155,7 +161,14 @@
             android:layout_below="@id/font_hinting"
             android:layout_alignParentLeft="true"
             android:text="@string/development_settings_show_xmpp_text" />
-            
+
+        <CheckBox android:id="@+id/window_orientation_listener_log"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/show_xmpp"
+            android:layout_alignParentLeft="true"
+            android:text="@string/development_settings_window_orientation_listener_log" />
+
     </RelativeLayout>
 
 </ScrollView>
diff --git a/apps/Development/res/layout/get_auth_token_view.xml b/apps/Development/res/layout/get_auth_token_view.xml
index c014cad..cfaed32 100644
--- a/apps/Development/res/layout/get_auth_token_view.xml
+++ b/apps/Development/res/layout/get_auth_token_view.xml
@@ -21,7 +21,8 @@
     android:layout_height="match_parent">
 
     <TextView android:id="@+id/accounts_tester_get_auth_token_dialog_message"
-        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
         android:text="@string/accounts_tester_enter_auth_token_type" />
 
     <EditText android:id="@+id/accounts_tester_auth_token_type"
diff --git a/apps/Development/res/layout/get_features_view.xml b/apps/Development/res/layout/get_features_view.xml
new file mode 100644
index 0000000..02fde28
--- /dev/null
+++ b/apps/Development/res/layout/get_features_view.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView android:id="@+id/accounts_tester_get_auth_token_dialog_message"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/accounts_tester_enter_auth_token_type" />
+
+    <EditText android:id="@+id/accounts_tester_auth_token_type"
+              android:singleLine="true"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:minWidth="250dip"
+              android:scrollHorizontally="true"
+              android:capitalize="none"
+              android:autoText="false"/>
+
+    <TextView android:id="@+id/accounts_tester_get_features_dialog_message"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/accounts_tester_enter_features" />
+
+    <EditText android:id="@+id/accounts_tester_features"
+              android:singleLine="true"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:minWidth="250dip"
+              android:scrollHorizontally="true"
+              android:capitalize="none"
+              android:autoText="false"/>
+
+</LinearLayout>
diff --git a/apps/Development/res/layout/media_scanner_activity.xml b/apps/Development/res/layout/media_scanner_activity.xml
index 974f683..4806843 100644
--- a/apps/Development/res/layout/media_scanner_activity.xml
+++ b/apps/Development/res/layout/media_scanner_activity.xml
@@ -4,9 +4,9 @@
      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.
@@ -14,12 +14,45 @@
      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="horizontal">
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
-    <TextView android:id="@+id/title" android:textSize="16sp" android:textStyle="bold"
-        android:layout_width="match_parent" android:layout_height="wrap_content" />
+    <TextView
+        android:id="@+id/title"
+        android:textSize="16sp"
+        android:textStyle="bold"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <Button
+        android:layout_width="160dip"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:text="@string/scancard"
+        android:onClick="startScan" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:layout_marginTop="30dip">
+
+        <EditText
+            android:id="@+id/numsongs"
+            android:layout_width="150dip"
+            android:layout_height="wrap_content"
+            android:hint="@string/numsongs"
+            android:numeric="integer"
+        />
+
+        <Button
+            android:id="@+id/insertbutton"
+            android:layout_width="150dip"
+            android:layout_height="wrap_content"
+            android:onClick="insertItems" />
+
+    </LinearLayout>
 
 </LinearLayout>
diff --git a/apps/Development/res/drawable-hdpi/ic_launcher_devtools.png b/apps/Development/res/mipmap-hdpi/ic_launcher_devtools.png
similarity index 100%
rename from apps/Development/res/drawable-hdpi/ic_launcher_devtools.png
rename to apps/Development/res/mipmap-hdpi/ic_launcher_devtools.png
Binary files differ
diff --git a/apps/Development/res/drawable-mdpi/ic_launcher_devtools.png b/apps/Development/res/mipmap-mdpi/ic_launcher_devtools.png
similarity index 100%
rename from apps/Development/res/drawable-mdpi/ic_launcher_devtools.png
rename to apps/Development/res/mipmap-mdpi/ic_launcher_devtools.png
Binary files differ
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index 181c4fa..0f4763c 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -36,6 +36,14 @@
     <string name="start_hipri">Start HiPri</string>
     <string name="stop_hipri">Stop HiPri</string>
     <string name="crash">CRASH</string>
+    <string name="add_default_route">Add Default Route</string>
+    <string name="remove_default_route">Remove Default Route</string>
+    <string name="default_request">Make a http request</string>
+    <string name="default_socket">Make a raw request</string>
+    <string name="bound_http_request">Make bound http request</string>
+    <string name="bound_socket_request">Make bound socket request</string>
+    <string name="routed_http_request">Make routed http request</string>
+    <string name="routed_socket_request">Make routed socket request</string>
 
 
         <string name="device_info_default">unknown</string>
@@ -105,6 +113,7 @@
     <string name="development_settings_debug_app_label_text">Debug App:</string>
     <string name="development_settings_show_sleep_text">Show sleep state on LED</string>
     <string name="development_settings_keep_screen_on_text">Keep screen on while plugged in</string>
+    <string name="development_settings_window_orientation_listener_log">Enable window orientation listener log</string>
 
     <string name="monkey_screen_initialActivity_text"></string>
     <string name="monkey_screen_number_of_events_label">Number of Events: </string>
@@ -163,11 +172,13 @@
     <string name="accounts_tester_process_name_header">Process Name:</string>
     <string name="accounts_tester_remove_account">Remove Account</string>
     <string name="accounts_tester_get_auth_token">Get Auth Token</string>
+    <string name="accounts_tester_get_auth_token_by_type_and_feature">Get Auth Token By Type/Feature</string>
     <string name="accounts_tester_test_has_features">Has Features</string>
     <string name="accounts_tester_invalidate_auth_token">Invalidate Token</string>
     <string name="accounts_tester_account_context_menu_title">account operations</string>
-    <string name="accounts_tester_do_get_auth_token">Ok</string>
+    <string name="accounts_tester_ok_button">Ok</string>
     <string name="accounts_tester_enter_auth_token_type">Enter the authtoken type:</string>
+    <string name="accounts_tester_enter_features">Enter the features separated by a space:</string>
     <string name="accounts_tester_update_credentials">Update Credentials</string>
     <string name="accounts_tester_confirm_credentials">Confirm Credentials</string>
     <string name="accounts_tester_clear_password">Clear Password</string>
@@ -208,4 +219,9 @@
     <string name="bad_behavior_anr_service_label">ANR starting a Service</string>
     <string name="bad_behavior_anr_system_label">System ANR (in ActivityManager)</string>
     <string name="bad_behavior_wedge_system_label">Wedge system (5 minute system ANR)</string>
+
+    <!-- MediaScannerActivity -->
+    <string name="scancard">Scan SD card</string>
+    <string name="numsongs"># of albums</string>
+    <string name="insertbutton">Insert %1s albums</string>
 </resources>
diff --git a/apps/Development/src/com/android/development/AccountsTester.java b/apps/Development/src/com/android/development/AccountsTester.java
index f8ff736..e2a0789 100644
--- a/apps/Development/src/com/android/development/AccountsTester.java
+++ b/apps/Development/src/com/android/development/AccountsTester.java
@@ -46,6 +46,8 @@
     private static final int INVALIDATE_AUTH_TOKEN_DIALOG_ID = 3;
     private static final int TEST_HAS_FEATURES_DIALOG_ID = 4;
     private static final int MESSAGE_DIALOG_ID = 5;
+    private static final int GET_AUTH_TOKEN_BY_TYPE_AND_FEATURE_DIALOG_ID = 6;
+
     private EditText mDesiredAuthTokenTypeEditText;
     private EditText mDesiredFeaturesEditText;
     private volatile CharSequence mDialogMessage;
@@ -66,6 +68,8 @@
                 buttonClickListener);
         findViewById(R.id.accounts_tester_add_account).setOnClickListener(buttonClickListener);
         findViewById(R.id.accounts_tester_edit_properties).setOnClickListener(buttonClickListener);
+        findViewById(R.id.accounts_tester_get_auth_token_by_type_and_feature).setOnClickListener(
+                buttonClickListener);
         mDesiredAuthTokenTypeEditText =
                 (EditText) findViewById(R.id.accounts_tester_desired_authtokentype);
         mDesiredFeaturesEditText = (EditText) findViewById(R.id.accounts_tester_desired_features);
@@ -119,8 +123,10 @@
                 if (desc.type.equals(account.type)) {
                     final String packageName = desc.packageName;
                     try {
-                        final Context authContext = getContext().createPackageContext(packageName, 0);
-                        holder.icon.setImageDrawable(authContext.getResources().getDrawable(desc.iconId));
+                        final Context authContext = getContext().createPackageContext(packageName,
+                                0);
+                        holder.icon.setImageDrawable(authContext.getResources().getDrawable(
+                                desc.iconId));
                         holder.icon.setVisibility(View.VISIBLE);
                     } catch (PackageManager.NameNotFoundException e) {
                         Log.d(TAG, "error getting the Package Context for " + packageName, e);
@@ -197,6 +203,8 @@
                         AccountsTester.this,
                         new CallbackToDialog(AccountsTester.this, "edit properties"),
                         null /* handler */);
+            } else if (R.id.accounts_tester_get_auth_token_by_type_and_feature == v.getId()) {
+                showDialog(GET_AUTH_TOKEN_BY_TYPE_AND_FEATURE_DIALOG_ID);
             } else {
                 // unknown button
             }
@@ -265,48 +273,92 @@
 
     @Override
     protected Dialog onCreateDialog(final int id) {
-        if (id == GET_AUTH_TOKEN_DIALOG_ID || id == INVALIDATE_AUTH_TOKEN_DIALOG_ID
-                || id == UPDATE_CREDENTIALS_DIALOG_ID || id == TEST_HAS_FEATURES_DIALOG_ID) {
-            final View view = LayoutInflater.from(this).inflate(R.layout.get_auth_token_view, null);
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setPositiveButton(R.string.accounts_tester_do_get_auth_token,
-                    new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            EditText value = (EditText) view.findViewById(
-                                    R.id.accounts_tester_auth_token_type);
+        switch (id) {
+            case GET_AUTH_TOKEN_DIALOG_ID:
+            case INVALIDATE_AUTH_TOKEN_DIALOG_ID:
+            case UPDATE_CREDENTIALS_DIALOG_ID:
+            case TEST_HAS_FEATURES_DIALOG_ID: {
+                final View view = LayoutInflater.from(this).inflate(R.layout.get_auth_token_view,
+                        null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setPositiveButton(R.string.accounts_tester_ok_button,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int which) {
+                                EditText value = (EditText) view.findViewById(
+                                        R.id.accounts_tester_auth_token_type);
 
-                            String authTokenType = value.getText().toString();
-                            final Account account = mLongPressedAccount;
-                            if (id == GET_AUTH_TOKEN_DIALOG_ID) {
-                                mAccountManager.getAuthToken(account, authTokenType,
-                                        null /* loginOptions */, AccountsTester.this,
-                                        new CallbackToDialog(AccountsTester.this, "get auth token"),
-                                        null /* handler */);
-                            } else if (id == INVALIDATE_AUTH_TOKEN_DIALOG_ID) {
-                                mAccountManager.getAuthToken(account, authTokenType, false,
-                                        new GetAndInvalidateAuthTokenCallback(account), null);
-                            } else if (id == TEST_HAS_FEATURES_DIALOG_ID) {
-                                String[] features = TextUtils.split(authTokenType, ",");
-                                mAccountManager.hasFeatures(account, features,
-                                        new TestHasFeaturesCallback(), null);
-                            } else {
-                                mAccountManager.updateCredentials(
-                                        account,
-                                        authTokenType, null /* loginOptions */,
+                                String authTokenType = value.getText().toString();
+                                final Account account = mLongPressedAccount;
+                                if (id == GET_AUTH_TOKEN_DIALOG_ID) {
+                                    mAccountManager.getAuthToken(account,
+                                            authTokenType,
+                                            null /* loginOptions */,
+                                            AccountsTester.this,
+                                            new CallbackToDialog(AccountsTester.this,
+                                                    "get auth token"),
+                                            null /* handler */);
+                                } else if (id == INVALIDATE_AUTH_TOKEN_DIALOG_ID) {
+                                    mAccountManager.getAuthToken(account, authTokenType, false,
+                                            new GetAndInvalidateAuthTokenCallback(account), null);
+                                } else if (id == TEST_HAS_FEATURES_DIALOG_ID) {
+                                    String[] features = TextUtils.split(authTokenType, ",");
+                                    mAccountManager.hasFeatures(account, features,
+                                            new TestHasFeaturesCallback(), null);
+                                } else {
+                                    mAccountManager.updateCredentials(
+                                            account,
+                                            authTokenType, null /* loginOptions */,
+                                            AccountsTester.this,
+                                            new CallbackToDialog(AccountsTester.this, "update"),
+                                            null /* handler */);
+                                }
+                            }
+                });
+                builder.setView(view);
+                return builder.create();
+            }
+
+            case GET_AUTH_TOKEN_BY_TYPE_AND_FEATURE_DIALOG_ID: {
+                final View view = LayoutInflater.from(this).inflate(R.layout.get_features_view,
+                        null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setPositiveButton(R.string.accounts_tester_ok_button,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int which) {
+                                EditText value = (EditText) view.findViewById(
+                                        R.id.accounts_tester_auth_token_type);
+
+                                String authTokenType = value.getText().toString();
+
+                                value = (EditText) view.findViewById(
+                                        R.id.accounts_tester_features);
+
+                                String features = value.getText().toString();
+
+                                final Account account = mLongPressedAccount;
+                                mAccountManager.getAuthTokenByFeatures(
+                                        getSelectedAuthenticator().type,
+                                        authTokenType,
+                                        TextUtils.isEmpty(features) ? null : features.split(" "),
                                         AccountsTester.this,
-                                        new CallbackToDialog(AccountsTester.this, "update"),
+                                        null /* addAccountOptions */,
+                                        null /* getAuthTokenOptions */,
+                                        new CallbackToDialog(AccountsTester.this,
+                                                "get auth token by features"),
                                         null /* handler */);
                             }
-                        }
-            });
-            builder.setView(view);
-            return builder.create();
+                });
+                builder.setView(view);
+                return builder.create();
+            }
+
+            case MESSAGE_DIALOG_ID: {
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setMessage(mDialogMessage);
+                return builder.create();
+            }
         }
-        if (id == MESSAGE_DIALOG_ID) {
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setMessage(mDialogMessage);
-            return builder.create();
-        }
+
         return super.onCreateDialog(id);
     }
 
@@ -344,7 +396,8 @@
         }
     }
 
-    AccountManagerCallback<Bundle> newAuthTokensCallback(String type, String authTokenType, String[] features) {
+    AccountManagerCallback<Bundle> newAuthTokensCallback(String type, String authTokenType,
+            String[] features) {
         return new GetAuthTokenCallback(type, authTokenType, features);
     }
 
diff --git a/apps/Development/src/com/android/development/Connectivity.java b/apps/Development/src/com/android/development/Connectivity.java
index 59157bf..c7029ec 100644
--- a/apps/Development/src/com/android/development/Connectivity.java
+++ b/apps/Development/src/com/android/development/Connectivity.java
@@ -28,6 +28,7 @@
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.ConnectivityManager;
+import android.net.NetworkUtils;
 import android.net.wifi.WifiManager;
 import android.os.RemoteException;
 import android.os.Handler;
@@ -58,19 +59,27 @@
 
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.Socket;
+import java.util.Enumeration;
 import java.util.Map;
 
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.params.ConnRouteParams;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.HttpResponse;
+import org.apache.http.impl.client.DefaultHttpClient;
+
 public class Connectivity extends Activity {
-    private static final String TAG = "Connectivity";
+    private static final String TAG = "DevTools - Connectivity";
 
     private static final int EVENT_TOGGLE_WIFI = 1;
     private static final int EVENT_TOGGLE_SCREEN = 2;
 
-    private Button mEnableWifiButton;
-    private Button mDisableWifiButton;
-
-    private Button mStartDelayedCycleButton;
-    private Button mStopDelayedCycleButton;
     private EditText mDCOnDurationEdit;
     private EditText mDCOffDurationEdit;
     private TextView mDCCycleCountView;
@@ -78,8 +87,6 @@
     private long mDCOffDuration = 120000;
     private int mDCCycleCount = 0;
 
-    private Button mStartScreenCycleButton;
-    private Button mStopScreenCycleButton;
     private EditText mSCOnDurationEdit;
     private EditText mSCOffDurationEdit;
     private TextView mSCCycleCountView;
@@ -87,12 +94,6 @@
     private long mSCOffDuration = 12000;
     private int mSCCycleCount = 0;
 
-    private Button mStartMmsButton;
-    private Button mStopMmsButton;
-    private Button mStartHiPriButton;
-    private Button mStopHiPriButton;
-    private Button mCrashButton;
-
     private boolean mDelayedCycleStarted = false;
 
     private WifiManager mWm;
@@ -191,15 +192,11 @@
         mPm = (PowerManager)getSystemService(Context.POWER_SERVICE);
         mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
 
-        mEnableWifiButton = (Button)findViewById(R.id.enableWifi);
-        mEnableWifiButton.setOnClickListener(mEnableWifiClicked);
-        mDisableWifiButton = (Button)findViewById(R.id.disableWifi);
-        mDisableWifiButton.setOnClickListener(mDisableWifiClicked);
+        findViewById(R.id.enableWifi).setOnClickListener(mClickListener);
+        findViewById(R.id.disableWifi).setOnClickListener(mClickListener);
 
-        mStartDelayedCycleButton = (Button)findViewById(R.id.startDelayedCycle);
-        mStartDelayedCycleButton.setOnClickListener(mStartDelayedCycleClicked);
-        mStopDelayedCycleButton = (Button)findViewById(R.id.stopDelayedCycle);
-        mStopDelayedCycleButton.setOnClickListener(mStopDelayedCycleClicked);
+        findViewById(R.id.startDelayedCycle).setOnClickListener(mClickListener);
+        findViewById(R.id.stopDelayedCycle).setOnClickListener(mClickListener);
         mDCOnDurationEdit = (EditText)findViewById(R.id.dc_wifi_on_duration);
         mDCOnDurationEdit.setText(Long.toString(mDCOnDuration));
         mDCOffDurationEdit = (EditText)findViewById(R.id.dc_wifi_off_duration);
@@ -207,10 +204,8 @@
         mDCCycleCountView = (TextView)findViewById(R.id.dc_wifi_cycles_done);
         mDCCycleCountView.setText(Integer.toString(mDCCycleCount));
 
-        mStartScreenCycleButton = (Button)findViewById(R.id.startScreenCycle);
-        mStartScreenCycleButton.setOnClickListener(mStartScreenCycleClicked);
-        mStopScreenCycleButton = (Button)findViewById(R.id.stopScreenCycle);
-        mStopScreenCycleButton.setOnClickListener(mStopScreenCycleClicked);
+        findViewById(R.id.startScreenCycle).setOnClickListener(mClickListener);
+        findViewById(R.id.stopScreenCycle).setOnClickListener(mClickListener);
         mSCOnDurationEdit = (EditText)findViewById(R.id.sc_wifi_on_duration);
         mSCOnDurationEdit.setText(Long.toString(mSCOnDuration));
         mSCOffDurationEdit = (EditText)findViewById(R.id.sc_wifi_off_duration);
@@ -218,16 +213,20 @@
         mSCCycleCountView = (TextView)findViewById(R.id.sc_wifi_cycles_done);
         mSCCycleCountView.setText(Integer.toString(mSCCycleCount));
 
-        mStartMmsButton = (Button)findViewById(R.id.start_mms);
-        mStartMmsButton.setOnClickListener(mStartMmsClicked);
-        mStopMmsButton = (Button)findViewById(R.id.stop_mms);
-        mStopMmsButton.setOnClickListener(mStopMmsClicked);
-        mStartHiPriButton = (Button)findViewById(R.id.start_hipri);
-        mStartHiPriButton.setOnClickListener(mStartHiPriClicked);
-        mStopHiPriButton = (Button)findViewById(R.id.stop_hipri);
-        mStopHiPriButton.setOnClickListener(mStopHiPriClicked);
-        mCrashButton = (Button)findViewById(R.id.crash);
-        mCrashButton.setOnClickListener(mCrashClicked);
+        findViewById(R.id.start_mms).setOnClickListener(mClickListener);
+        findViewById(R.id.stop_mms).setOnClickListener(mClickListener);
+        findViewById(R.id.start_hipri).setOnClickListener(mClickListener);
+        findViewById(R.id.stop_hipri).setOnClickListener(mClickListener);
+        findViewById(R.id.crash).setOnClickListener(mClickListener);
+
+        findViewById(R.id.add_default_route).setOnClickListener(mClickListener);
+        findViewById(R.id.remove_default_route).setOnClickListener(mClickListener);
+        findViewById(R.id.bound_http_request).setOnClickListener(mClickListener);
+        findViewById(R.id.bound_socket_request).setOnClickListener(mClickListener);
+        findViewById(R.id.routed_http_request).setOnClickListener(mClickListener);
+        findViewById(R.id.routed_socket_request).setOnClickListener(mClickListener);
+        findViewById(R.id.default_request).setOnClickListener(mClickListener);
+        findViewById(R.id.default_socket).setOnClickListener(mClickListener);
 
         registerReceiver(mReceiver, new IntentFilter(CONNECTIVITY_TEST_ALARM));
     }
@@ -239,62 +238,114 @@
         super.onResume();
     }
 
-    private View.OnClickListener mStartDelayedCycleClicked = new View.OnClickListener() {
+    private View.OnClickListener mClickListener = new View.OnClickListener() {
         public void onClick(View v) {
-            if (!mDelayedCycleStarted) {
-                mDelayedCycleStarted = true;
-                try {
-                    mDCOnDuration = Long.parseLong(mDCOnDurationEdit.getText().toString());
-                    mDCOffDuration = Long.parseLong(mDCOffDurationEdit.getText().toString());
-                } catch (Exception e) { };
-                mDCCycleCount = 0;
-
-                mWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ConnectivityTest");
-                mWakeLock.acquire();
-                mHandler2.sendMessage(mHandler2.obtainMessage(EVENT_TOGGLE_WIFI));
-            }
-        }
-    };
-    private View.OnClickListener mStopDelayedCycleClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            if (mDelayedCycleStarted) {
-                mDelayedCycleStarted = false;
-                mWakeLock.release();
-                mWakeLock = null;
-                if(mHandler2.hasMessages(EVENT_TOGGLE_WIFI)) {
-                    mHandler2.removeMessages(EVENT_TOGGLE_WIFI);
-                }
+            switch (v.getId()) {
+                case R.id.enableWifi:
+                    mWm.setWifiEnabled(true);
+                    break;
+                case R.id.disableWifi:
+                    mWm.setWifiEnabled(false);
+                    break;
+                case R.id.startDelayedCycle:
+                    onStartDelayedCycle();
+                    break;
+                case R.id.stopDelayedCycle:
+                    onStopDelayedCycle();
+                    break;
+                case R.id.startScreenCycle:
+                    onStartScreenCycle();
+                    break;
+                case R.id.stopScreenCycle:
+                    onStopScreenCycle();
+                    break;
+                case R.id.start_mms:
+                    mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                            Phone.FEATURE_ENABLE_MMS);
+                    break;
+                case R.id.stop_mms:
+                    mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                            Phone.FEATURE_ENABLE_MMS);
+                    break;
+                case R.id.default_socket:
+                    onDefaultSocket();
+                    break;
+                case R.id.default_request:
+                    onDefaultRequest();
+                    break;
+                case R.id.routed_socket_request:
+                    onRoutedSocketRequest();
+                    break;
+                case R.id.routed_http_request:
+                    onRoutedHttpRequest();
+                    break;
+                case R.id.bound_socket_request:
+                    onBoundSocketRequest();
+                    break;
+                case R.id.bound_http_request:
+                    onBoundHttpRequest();
+                    break;
+                case R.id.remove_default_route:
+                    onRemoveDefaultRoute();
+                    break;
+                case R.id.add_default_route:
+                    onAddDefaultRoute();
+                    break;
+                case R.id.crash:
+                    onCrash();
+                    break;
+                case R.id.start_hipri:
+                    mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                            Phone.FEATURE_ENABLE_HIPRI);
+                    break;
+                case R.id.stop_hipri:
+                    mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                            Phone.FEATURE_ENABLE_HIPRI);
+                    break;
             }
         }
     };
 
-    private View.OnClickListener mEnableWifiClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            mWm.setWifiEnabled(true);
-        }
-    };
-    private View.OnClickListener mDisableWifiClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            mWm.setWifiEnabled(false);
-        }
-    };
 
-    private View.OnClickListener mStartScreenCycleClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-
+    private void onStartDelayedCycle() {
+        if (!mDelayedCycleStarted) {
+            mDelayedCycleStarted = true;
             try {
-                mSCOnDuration = Long.parseLong(mSCOnDurationEdit.getText().toString());
-                mSCOffDuration = Long.parseLong(mSCOffDurationEdit.getText().toString());
+                mDCOnDuration = Long.parseLong(mDCOnDurationEdit.getText().toString());
+                mDCOffDuration = Long.parseLong(mDCOffDurationEdit.getText().toString());
             } catch (Exception e) { };
-            mSCCycleCount = 0;
+            mDCCycleCount = 0;
 
-            mScreenonWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
-                    "ConnectivityTest");
-            mScreenonWakeLock.acquire();
-
-            scheduleAlarm(10, SCREEN_OFF);
+            mWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ConnectivityTest");
+            mWakeLock.acquire();
+            mHandler2.sendMessage(mHandler2.obtainMessage(EVENT_TOGGLE_WIFI));
         }
-    };
+    }
+
+    private void onStopDelayedCycle() {
+        if (mDelayedCycleStarted) {
+            mDelayedCycleStarted = false;
+            mWakeLock.release();
+            mWakeLock = null;
+            if(mHandler2.hasMessages(EVENT_TOGGLE_WIFI)) {
+                mHandler2.removeMessages(EVENT_TOGGLE_WIFI);
+            }
+        }
+    }
+
+    private void onStartScreenCycle() {
+        try {
+            mSCOnDuration = Long.parseLong(mSCOnDurationEdit.getText().toString());
+            mSCOffDuration = Long.parseLong(mSCOffDurationEdit.getText().toString());
+        } catch (Exception e) { };
+        mSCCycleCount = 0;
+
+        mScreenonWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
+                "ConnectivityTest");
+        mScreenonWakeLock.acquire();
+
+        scheduleAlarm(10, SCREEN_OFF);
+    }
 
     private void scheduleAlarm(long delayMs, String eventType) {
         AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
@@ -310,42 +361,189 @@
         am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delayMs, p);
     }
 
-    private View.OnClickListener mStopScreenCycleClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-        }
-    };
+    private void onStopScreenCycle() {
+    }
 
-    private View.OnClickListener mStartMmsClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
-        }
-    };
+    private void onCrash() {
+        ConnectivityManager foo = null;
+        foo.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                Phone.FEATURE_ENABLE_MMS);
+    }
 
-    private View.OnClickListener mStopMmsClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
-        }
-    };
+    private void onAddDefaultRoute() {
+        try {
+            NetworkUtils.addRoute("eth0", "0.0.0.0", 0, "8.8.8.8");
+        } catch (Exception e) { }
+    }
 
-    private View.OnClickListener mStartHiPriClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-                    Phone.FEATURE_ENABLE_HIPRI);
-        }
-    };
+    private void onRemoveDefaultRoute() {
+        Log.e(TAG, "removeDefaultRoute returned "+NetworkUtils.removeDefaultRoute("eth0"));
+    }
 
-    private View.OnClickListener mStopHiPriClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-                    Phone.FEATURE_ENABLE_HIPRI);
-        }
-    };
+    private void onRoutedHttpRequest() {
+        onRoutedRequest(HTTP);
+    }
 
-    private View.OnClickListener mCrashClicked = new View.OnClickListener() {
-        public void onClick(View v) {
-            ConnectivityManager foo = null;
-            foo.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-                    Phone.FEATURE_ENABLE_MMS);
+    private void onRoutedSocketRequest() {
+        onRoutedRequest(SOCKET);
+    }
+
+    private final static int SOCKET = 1;
+    private final static int HTTP   = 2;
+
+    private void onRoutedRequest(int type) {
+        String url = "www.google.com";
+
+        InetAddress inetAddress = null;
+        try {
+            inetAddress = InetAddress.getByName(url);
+        } catch (Exception e) {
+            Log.e(TAG, "error fetching address for " + url);
+            return;
         }
-    };
+
+        mCm.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI, inetAddress);
+
+        switch (type) {
+            case SOCKET:
+                onBoundSocketRequest();
+                break;
+            case HTTP:
+                HttpGet get = new HttpGet("http://" + url);
+                HttpClient client = new DefaultHttpClient();
+                try {
+                    HttpResponse httpResponse = client.execute(get);
+                    Log.d(TAG, "routed http request gives " + httpResponse.getStatusLine());
+                } catch (Exception e) {
+                    Log.e(TAG, "routed http request exception = " + e);
+                }
+        }
+
+    }
+
+    private void onBoundHttpRequest() {
+        NetworkInterface networkInterface = null;
+        try {
+            networkInterface = NetworkInterface.getByName("rmnet0");
+            Log.d(TAG, "networkInterface is " + networkInterface);
+        } catch (Exception e) {
+            Log.e(TAG, " exception getByName: " + e);
+            return;
+        }
+        if (networkInterface != null) {
+            Enumeration inetAddressess = networkInterface.getInetAddresses();
+            while(inetAddressess.hasMoreElements()) {
+                Log.d(TAG, " inetAddress:" + ((InetAddress)inetAddressess.nextElement()));
+            }
+        }
+
+        HttpParams httpParams = new BasicHttpParams();
+        if (networkInterface != null) {
+            ConnRouteParams.setLocalAddress(httpParams,
+                    networkInterface.getInetAddresses().nextElement());
+        }
+        HttpGet get = new HttpGet("http://www.bbc.com");
+        HttpClient client = new DefaultHttpClient(httpParams);
+        try {
+            HttpResponse response = client.execute(get);
+            Log.d(TAG, "response code = " + response.getStatusLine());
+        } catch (Exception e) {
+            Log.e(TAG, "Exception = "+ e );
+        }
+    }
+
+    private void onBoundSocketRequest() {
+        NetworkInterface networkInterface = null;
+        try {
+            networkInterface = NetworkInterface.getByName("rmnet0");
+        } catch (Exception e) {
+            Log.e(TAG, "exception getByName: " + e);
+            return;
+        }
+        if (networkInterface == null) {
+            try {
+                Log.d(TAG, "getting any networkInterface");
+                networkInterface = NetworkInterface.getNetworkInterfaces().nextElement();
+            } catch (Exception e) {
+                Log.e(TAG, "exception getting any networkInterface: " + e);
+                return;
+            }
+        }
+        if (networkInterface == null) {
+            Log.e(TAG, "couldn't find a local interface");
+            return;
+        }
+        Enumeration inetAddressess = networkInterface.getInetAddresses();
+        while(inetAddressess.hasMoreElements()) {
+            Log.d(TAG, " addr:" + ((InetAddress)inetAddressess.nextElement()));
+        }
+        InetAddress local = null;
+        InetAddress remote = null;
+        try {
+            local = networkInterface.getInetAddresses().nextElement();
+        } catch (Exception e) {
+            Log.e(TAG, "exception getting local InetAddress: " + e);
+            return;
+        }
+        try {
+            remote = InetAddress.getByName("www.flickr.com");
+        } catch (Exception e) {
+            Log.e(TAG, "exception getting remote InetAddress: " + e);
+            return;
+        }
+        Log.d(TAG, "remote addr ="+remote);
+        Log.d(TAG, "local addr ="+local);
+        Socket socket = null;
+        try {
+            socket = new Socket(remote, 80, local, 6000);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception creating socket: " + e);
+            return;
+        }
+        try {
+            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
+            out.println("Hi flickr");
+        } catch (Exception e) {
+            Log.e(TAG, "Exception writing to socket: " + e);
+            return;
+        }
+    }
+
+    private void onDefaultRequest() {
+        HttpParams params = new BasicHttpParams();
+        HttpGet get = new HttpGet("http://www.cnn.com");
+        HttpClient client = new DefaultHttpClient(params);
+        try {
+            HttpResponse response = client.execute(get);
+            Log.e(TAG, "response code = " + response.getStatusLine());
+        } catch (Exception e) {
+            Log.e(TAG, "Exception = " + e);
+        }
+    }
+
+    private void onDefaultSocket() {
+        InetAddress remote = null;
+        try {
+            remote = InetAddress.getByName("www.flickr.com");
+        } catch (Exception e) {
+            Log.e(TAG, "exception getting remote InetAddress: " + e);
+            return;
+        }
+        Log.e(TAG, "remote addr =" + remote);
+        Socket socket = null;
+        try {
+            socket = new Socket(remote, 80);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception creating socket: " + e);
+            return;
+        }
+        try {
+            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
+            out.println("Hi flickr");
+            Log.e(TAG, "written");
+        } catch (Exception e) {
+            Log.e(TAG, "Exception writing to socket: " + e);
+            return;
+        }
+    }
 }
diff --git a/apps/Development/src/com/android/development/DevelopmentSettings.java b/apps/Development/src/com/android/development/DevelopmentSettings.java
index c01ea59..f907a14 100644
--- a/apps/Development/src/com/android/development/DevelopmentSettings.java
+++ b/apps/Development/src/com/android/development/DevelopmentSettings.java
@@ -23,23 +23,26 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.RemoteException;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManagerNative;
+import android.os.StrictMode;
+import android.os.SystemProperties;
 import android.provider.Settings;
-import android.os.Bundle;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.View;
+import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.Spinner;
 import android.widget.Toast;
-import android.widget.AdapterView.OnItemSelectedListener;
 
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -53,6 +56,7 @@
     private CheckBox mWaitForDebuggerCB;
     private CheckBox mAlwaysFinishCB;
     private Spinner mPointerLocationSpinner;
+    private Spinner mStrictModeVisualSpinner;
     private CheckBox mShowLoadCB;
     private CheckBox mShowCpuCB;
     private CheckBox mEnableGLCB;
@@ -60,6 +64,7 @@
     private CheckBox mShowBackgroundCB;
     private CheckBox mShowSleepCB;
     private CheckBox mShowXmppCB;
+    private CheckBox mWindowOrientationListenerLogCB;
     private CheckBox mCompatibilityModeCB;
     private Spinner mMaxProcsSpinner;
     private Spinner mWindowAnimationScaleSpinner;
@@ -70,6 +75,7 @@
     private boolean mWaitForDebugger;
     private boolean mAlwaysFinish;
     private int mPointerLocation;
+    private int mWindowOrientationListenerLog;
     private int mProcessLimit;
     private boolean mShowSleep;
     private boolean mShowXmpp;
@@ -106,6 +112,17 @@
                         "Pointer Location" });
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         mPointerLocationSpinner.setAdapter(adapter);
+        mStrictModeVisualSpinner = (Spinner)findViewById(R.id.strictmode_visual);
+        adapter = new ArrayAdapter<String>(
+                this,
+                android.R.layout.simple_spinner_item,
+                new String[] {
+                        "StrictMode visual indicator: build variant default",
+                        "StrictMode visual indicator: on",
+                        "StrictMode visual indicator: off" });
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mStrictModeVisualSpinner.setAdapter(adapter);
+        mStrictModeVisualSpinner.setOnItemSelectedListener(mStrictModeVisualChanged);
         mShowLoadCB = (CheckBox)findViewById(R.id.show_load);
         mShowLoadCB.setOnClickListener(mShowLoadClicked);
         mShowCpuCB = (CheckBox)findViewById(R.id.show_cpu);
@@ -121,6 +138,8 @@
         mShowSleepCB.setOnClickListener(mShowSleepClicked);
         mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
         mShowXmppCB.setOnClickListener(mShowXmppClicked);
+        mWindowOrientationListenerLogCB = (CheckBox)findViewById(R.id.window_orientation_listener_log);
+        mWindowOrientationListenerLogCB.setOnClickListener(mWindowOrientationListenerLogClicked);
         mCompatibilityModeCB = (CheckBox)findViewById(R.id.compatibility_mode);
         mCompatibilityModeCB.setOnClickListener(mCompatibilityModeClicked);
         mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
@@ -182,11 +201,13 @@
         updateDebugOptions();
         updateFinishOptions();
         updatePointerLocationOptions();
+        updateStrictModeVisualOptions();
         updateProcessLimitOptions();
         updateSharedOptions();
         updateFlingerOptions();
         updateSleepOptions();
         updateXmppOptions();
+        updateWindowOrientationListenerLogOptions();
         updateCompatibilityOptions();
 
         try {
@@ -245,6 +266,35 @@
         mPointerLocationSpinner.setSelection(mPointerLocation);
     }
 
+    private void writeWindowOrientationListenerLogOptions() {
+        Settings.System.putInt(getContentResolver(),
+                Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, mWindowOrientationListenerLog);
+    }
+
+    private void updateWindowOrientationListenerLogOptions() {
+        mWindowOrientationListenerLog = Settings.System.getInt(getContentResolver(),
+                Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, 0);
+        mWindowOrientationListenerLogCB.setChecked(mWindowOrientationListenerLog != 0);
+    }
+
+    // Returns the current state of the system property that controls
+    // strictmode flashes.  One of:
+    //    0: not explicitly set one way or another
+    //    1: on
+    //    2: off
+    // These are the indices in the Spinner's ArrayAdapter.
+    private int currentStrictModeActiveIndex() {
+        if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
+            return 0;
+        }
+        boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
+        return enabled ? 1 : 2;
+    }
+
+    private void updateStrictModeVisualOptions() {
+        mStrictModeVisualSpinner.setSelection(currentStrictModeActiveIndex());
+    }
+
     private void writeProcessLimitOptions() {
         try {
             ActivityManagerNative.getDefault().setProcessLimit(mProcessLimit);
@@ -444,6 +494,13 @@
         }
     };
 
+    private View.OnClickListener mWindowOrientationListenerLogClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            mWindowOrientationListenerLog = ((CheckBox)v).isChecked() ? 1 : 0;
+            writeWindowOrientationListenerLogOptions();
+        }
+    };
+
     private Spinner.OnItemSelectedListener mPointerLocationChanged
                                     = new Spinner.OnItemSelectedListener() {
         public void onItemSelected(android.widget.AdapterView av, View v,
@@ -456,6 +513,41 @@
         }
     };
 
+    private Spinner.OnItemSelectedListener mStrictModeVisualChanged
+                                    = new Spinner.OnItemSelectedListener() {
+        public void onItemSelected(android.widget.AdapterView av, View v,
+                                    int position, long id) {
+            if (position == currentStrictModeActiveIndex()) {
+                // at the existing position, so don't show a Toast.
+                return;
+            }
+
+            try {
+                switch (position) {
+                    case 0:  // default
+                        mWindowManager.setStrictModeVisualIndicatorPreference("");
+                        break;
+                    case 1:  // on
+                        mWindowManager.setStrictModeVisualIndicatorPreference("1");
+                        break;
+                    case 2:  // off
+                        mWindowManager.setStrictModeVisualIndicatorPreference("0");
+                        break;
+                }
+            } catch (RemoteException e) {
+                Log.w(TAG, "Error calling setStrictModeVisualIndicatorPreference", e);
+            }
+
+            Toast.makeText(
+                    DevelopmentSettings.this,
+                    "Setting changed; will take effect per-app next launch, or on reboot",
+                    Toast.LENGTH_LONG).show();
+        }
+
+        public void onNothingSelected(android.widget.AdapterView av) {
+        }
+    };
+
     private Spinner.OnItemSelectedListener mMaxProcsChanged
                                     = new Spinner.OnItemSelectedListener() {
         public void onItemSelected(android.widget.AdapterView av, View v,
diff --git a/apps/Development/src/com/android/development/MediaScannerActivity.java b/apps/Development/src/com/android/development/MediaScannerActivity.java
index f78910a..04f6414 100644
--- a/apps/Development/src/com/android/development/MediaScannerActivity.java
+++ b/apps/Development/src/com/android/development/MediaScannerActivity.java
@@ -17,56 +17,239 @@
 package com.android.development;
 
 import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.BroadcastReceiver;
+import android.database.sqlite.SQLiteConstraintException;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.MediaStore;
+import android.provider.MediaStore.Audio;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
 import android.widget.TextView;
 
+import java.util.Random;
+
 public class MediaScannerActivity extends Activity
 {
+    private TextView mTitle;
+    private int mNumToInsert = 20;
+    private int mArtists;
+    private int mAlbums;
+    private int mSongs;
+    private ContentResolver mResolver;
+    private Uri mAudioUri;
+    ContentValues mValues[] = new ContentValues[10];
+    Random mRandom = new Random();
+    StringBuilder mBuilder = new StringBuilder();
+
     public MediaScannerActivity() {
     }
- 
+
     /** Called when the activity is first created or resumed. */
     @Override
-    public void onResume() {
-        super.onResume();
-        
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
         setContentView(R.layout.media_scanner_activity);
-        
+
         IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
         intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
         intentFilter.addDataScheme("file");
         registerReceiver(mReceiver, intentFilter);
-        
-        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
-                + Environment.getExternalStorageDirectory())));
-            
+
+        EditText t = (EditText) findViewById(R.id.numsongs);
+        t.addTextChangedListener(new TextWatcher() {
+
+            public void afterTextChanged(Editable s) {
+                String text = s.toString();
+                try {
+                    mNumToInsert = Integer.valueOf(text);
+                } catch (NumberFormatException ex) {
+                    mNumToInsert = 20;
+                }
+                setInsertButtonText();
+            }
+
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            }
+
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+            }
+
+        });
         mTitle = (TextView) findViewById(R.id.title);
-        mTitle.setText("Sent ACTION_MEDIA_MOUNTED to trigger the Media Scanner.");
+        mResolver = getContentResolver();
+        mAudioUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
+
+        for (int i = 0; i < 10; i++) {
+            mValues[i] = new ContentValues();
+        }
+        setInsertButtonText();
     }
 
     /** Called when the activity going into the background or being destroyed. */
     @Override
-    public void onPause() {
-        super.onPause();
+    public void onDestroy() {
         unregisterReceiver(mReceiver);
+        mInsertHandler.removeMessages(0);
+        super.onDestroy();
     }
-    
+
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
-                mTitle.setText("Media Scanner started scanning " + intent.getData().getPath());     
+                mTitle.setText("Media Scanner started scanning " + intent.getData().getPath());
             }
             else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
-                mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath());     
+                mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath());
             }
         }
     };
 
-    private TextView mTitle;
+    public void startScan(View v) {
+        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+                + Environment.getExternalStorageDirectory())));
+
+        mTitle.setText("Sent ACTION_MEDIA_MOUNTED to trigger the Media Scanner.");
+    }
+
+    private void setInsertButtonText() {
+        String label = getString(R.string.insertbutton, Integer.valueOf(mNumToInsert));
+        Button b = (Button) findViewById(R.id.insertbutton);
+        b.setText(label);
+    }
+
+
+    public void insertItems(View v) {
+        if (mInsertHandler.hasMessages(0)) {
+            mInsertHandler.removeMessages(0);
+            setInsertButtonText();
+        } else {
+            mInsertHandler.sendEmptyMessage(0);
+        }
+    }
+
+    Handler mInsertHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+
+            if (mNumToInsert-- > 0) {
+                addAlbum();
+                runOnUiThread(mDisplayUpdater);
+
+                if (!isFinishing()) {
+                    sendEmptyMessage(0);
+                }
+            }
+        }
+    };
+
+    Runnable mDisplayUpdater = new Runnable() {
+        public void run() {
+            mTitle.setText("Added " + mArtists + " artists, " + mAlbums + " albums, "
+                    + mSongs + " songs.");
+        }
+    };
+
+    // Add one more album (with 10 songs) to the database. This will be a compilation album,
+    // with one album artist for the album, and a separate artist for each song.
+    private void addAlbum() {
+        try {
+            String albumArtist = "Various Artists";
+            String albumName = getRandomWord(3);
+            int baseYear = 1969 + mRandom.nextInt(30);
+            for (int i = 0; i < 10; i++) {
+                mValues[i].clear();
+                String artist = getRandomName();
+                final ContentValues map = mValues[i];
+                map.put(MediaStore.MediaColumns.DATA,
+                        "http://bogus/" + albumName + "/" + artist + "_" + i);
+                map.put(MediaStore.MediaColumns.TITLE,
+                        getRandomWord(4) + " " + getRandomWord(2) + " " + (i + 1));
+                map.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
+
+                map.put(Audio.Media.ARTIST, artist);
+                map.put("album_artist", albumArtist);
+                map.put(Audio.Media.ALBUM, albumName);
+                map.put(Audio.Media.TRACK, i + 1);
+                map.put(Audio.Media.DURATION, 4*60*1000);
+                map.put(Audio.Media.IS_MUSIC, 1);
+                map.put(Audio.Media.YEAR, baseYear + mRandom.nextInt(10));
+            }
+            mResolver.bulkInsert(mAudioUri, mValues);
+            mSongs += 10;
+            mAlbums++;
+            mArtists += 11;
+        } catch (SQLiteConstraintException ex) {
+            Log.d("@@@@", "insert failed", ex);
+        }
+    }
+
+    /**
+     * Some code to generate random names. This just strings together random
+     * syllables, and randomly inserts a modifier between the first
+     * and last name.
+     */
+    private String[] elements = new String[] {
+            "ab", "am",
+            "bra", "bri",
+            "ci", "co",
+            "de", "di", "do",
+            "fa", "fi",
+            "ki",
+            "la", "li",
+            "ma", "me", "mi", "mo",
+            "na", "ni",
+            "pa",
+            "ta", "ti",
+            "vi", "vo"
+    };
+
+    private String getRandomWord(int len) {
+        int max = elements.length;
+        mBuilder.setLength(0);
+        for (int i = 0; i < len; i++) {
+            mBuilder.append(elements[mRandom.nextInt(max)]);
+        }
+        char c = mBuilder.charAt(0);
+        c = Character.toUpperCase(c);
+        mBuilder.setCharAt(0, c);
+        return mBuilder.toString();
+    }
+
+    private String getRandomName() {
+        boolean longfirst = mRandom.nextInt(5) < 3;
+        String first = getRandomWord(longfirst ? 3 : 2);
+        String last = getRandomWord(3);
+        switch (mRandom.nextInt(6)) {
+            case 1:
+                if (!last.startsWith("Di")) {
+                    last = "di " + last;
+                }
+                break;
+            case 2:
+                last = "van " + last;
+                break;
+            case 3:
+                last = "de " + last;
+                break;
+        }
+        return first + " " + last;
+    }
+
+
+
 }
diff --git a/apps/Development/src/com/android/development/PackageBrowser.java b/apps/Development/src/com/android/development/PackageBrowser.java
index 689183d..eb013ba 100644
--- a/apps/Development/src/com/android/development/PackageBrowser.java
+++ b/apps/Development/src/com/android/development/PackageBrowser.java
@@ -24,6 +24,7 @@
 import android.content.IntentFilter;
 import android.content.BroadcastReceiver;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -143,8 +144,9 @@
             if (packageInfo != null) {
                 getPackageManager().deletePackage(packageInfo.info.packageName,
                                                   new IPackageDeleteObserver.Stub() {
-                    public void packageDeleted(boolean succeeded) throws RemoteException {
-                        if (succeeded) {
+                    public void packageDeleted(String packageName, int returnCode)
+                            throws RemoteException {
+                        if (returnCode == PackageManager.DELETE_SUCCEEDED) {
                             mPackageInfoList.remove(curSelection);
                             mHandler.post(new Runnable() {
                                     public void run() {
diff --git a/apps/Development/src/com/android/development/SyncAdapterDriver.java b/apps/Development/src/com/android/development/SyncAdapterDriver.java
index a91e0ed..0fde732 100644
--- a/apps/Development/src/com/android/development/SyncAdapterDriver.java
+++ b/apps/Development/src/com/android/development/SyncAdapterDriver.java
@@ -367,7 +367,12 @@
                         com.android.internal.R.styleable.SyncAdapter_userVisible, true);
                 final boolean supportsUploading = sa.getBoolean(
                         com.android.internal.R.styleable.SyncAdapter_supportsUploading, true);
-                return new SyncAdapterType(authority, accountType, userVisible, supportsUploading);
+                final boolean isAlwaysSyncable = sa.getBoolean(
+                        com.android.internal.R.styleable.SyncAdapter_isAlwaysSyncable, false);
+                final boolean allowParallelSyncs = sa.getBoolean(
+                        com.android.internal.R.styleable.SyncAdapter_allowParallelSyncs, false);
+                return new SyncAdapterType(authority, accountType, userVisible, supportsUploading,
+                        isAlwaysSyncable, allowParallelSyncs);
             } finally {
                 sa.recycle();
             }
diff --git a/apps/GestureBuilder/AndroidManifest.xml b/apps/GestureBuilder/AndroidManifest.xml
index 9c2f799..d4565a3 100644
--- a/apps/GestureBuilder/AndroidManifest.xml
+++ b/apps/GestureBuilder/AndroidManifest.xml
@@ -19,7 +19,8 @@
     package="com.android.gesture.builder">
 
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
+    
+    <uses-sdk android:targetSdkVersion="11"/>
     <application>
 
         <activity
diff --git a/apps/GraphicsLab/Android.mk b/apps/GraphicsLab/Android.mk
deleted file mode 100644
index e8dd114..0000000
--- a/apps/GraphicsLab/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := GraphicsLab
-
-include $(BUILD_PACKAGE)
diff --git a/apps/GraphicsLab/AndroidManifest.xml b/apps/GraphicsLab/AndroidManifest.xml
deleted file mode 100644
index a91c4fa..0000000
--- a/apps/GraphicsLab/AndroidManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.graphicslab">
-    <application android:label="Graphics Lab">
-		<activity android:name="GraphicsLab">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.TEST" />
-            </intent-filter>
-		</activity>
-    </application>
-</manifest>
diff --git a/apps/GraphicsLab/res/drawable/beach.jpg b/apps/GraphicsLab/res/drawable/beach.jpg
deleted file mode 100644
index ae9794f..0000000
--- a/apps/GraphicsLab/res/drawable/beach.jpg
+++ /dev/null
Binary files differ
diff --git a/apps/GraphicsLab/res/drawable/news_img.jpg b/apps/GraphicsLab/res/drawable/news_img.jpg
deleted file mode 100644
index 16a5ecb..0000000
--- a/apps/GraphicsLab/res/drawable/news_img.jpg
+++ /dev/null
Binary files differ
diff --git a/apps/GraphicsLab/res/layout/graphics_lab.xml b/apps/GraphicsLab/res/layout/graphics_lab.xml
deleted file mode 100644
index 7c0e5d9..0000000
--- a/apps/GraphicsLab/res/layout/graphics_lab.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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:id="@+id/content"
-    android:layout_width="match_parent" android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:paddingLeft="4dip" android:paddingRight="4dip"
-    android:paddingTop="4dip" android:paddingBottom="4dip">        
-</LinearLayout>
-
-
diff --git a/apps/GraphicsLab/src/com/android/graphicslab/GraphicsLab.java b/apps/GraphicsLab/src/com/android/graphicslab/GraphicsLab.java
deleted file mode 100644
index dd5ac5b..0000000
--- a/apps/GraphicsLab/src/com/android/graphicslab/GraphicsLab.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.graphicslab;
-
-import java.util.Map;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.*;
-import android.graphics.utils.*;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.view.*;
-
-public class GraphicsLab extends Activity {
-    public GraphicsLab() {}
-
-    private int mCurrView = 1;
-
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        setContentView(new SampleView(this));
-//        setTitle("Graphics Lab");
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        switch(keyCode) {
-            case KeyEvent.KEYCODE_DPAD_CENTER:
-                if (mCurrView == 1) {
-                    setContentView(new SampleView2(this));
-                    mCurrView = 2;
-                } else {
-                    setContentView(new SampleView(this));
-                    mCurrView = 1;
-                }
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    private static class SampleView2 extends View {
-        private static final int ROWS = 16;
-        private static final int COLS = 16;
-        private static final int UNSTRETCH_MSEC = 250;
-        
-        private Interpolator mInterp;
-        private BoundaryPatch mPatch;
-        private float[] mCubics;
-        private float[] mOrig = new float[24];
-        private Paint mPaint0;
-        private Paint mPaint1;
-        private int mCurrIndex = -1;
-        private float mPrevX;
-        private float mPrevY;
-        
-        public SampleView2(Context context) {
-            super(context);
-            setFocusable(true);
-            
-            Bitmap bm = BitmapFactory.decodeResource(getResources(),
-                                                     R.drawable.news_img);
-            
-            mPatch = new BoundaryPatch();
-            mPatch.setTexture(bm);
-            
-            float unit = 90;
-            mCubics = new float[] {
-                0, 0, 1, 0, 2, 0,
-                3, 0, 3, 1, 3, 2,
-                3, 3, 2, 3, 1, 3,
-                0, 3, 0, 2, 0, 1
-            };
-            for (int i = 0; i < 24; i++) {
-                mCubics[i] *= 90;
-                mCubics[i] += 20;
-            }
-            rebuildPatch();
-            
-            mPaint0 = new Paint();
-            mPaint0.setAntiAlias(true);
-            mPaint0.setStrokeWidth(12);
-            mPaint0.setStrokeCap(Paint.Cap.ROUND);
-            mPaint1 = new Paint(mPaint0);
-            mPaint1.setColor(0xFFFFFFFF);
-            mPaint1.setStrokeWidth(10);
-        }
-        
-        @Override
-        protected void onSizeChanged(int nw, int nh, int ow, int oh) {
-            float[] pts = mCubics;
-            float x1 = nw*0.3333f;
-            float y1 = nh*0.3333f;
-            float x2 = nw*0.6667f;
-            float y2 = nh*0.6667f;
-            pts[0*2+0] = 0;  pts[0*2+1] = 0;
-            pts[1*2+0] = x1; pts[1*2+1] = 0;
-            pts[2*2+0] = x2; pts[2*2+1] = 0;
-
-            pts[3*2+0] = nw; pts[3*2+1] = 0;
-            pts[4*2+0] = nw; pts[4*2+1] = y1;
-            pts[5*2+0] = nw; pts[5*2+1] = y2;
-
-            pts[6*2+0] = nw; pts[6*2+1] = nh;
-            pts[7*2+0] = x2; pts[7*2+1] = nh;
-            pts[8*2+0] = x1; pts[8*2+1] = nh;
-
-            pts[9*2+0] = 0;  pts[9*2+1] = nh;
-            pts[10*2+0] = 0; pts[10*2+1] = y2;
-            pts[11*2+0] = 0; pts[11*2+1] = y1;
-            
-            System.arraycopy(pts, 0, mOrig, 0, 24);
-            rebuildPatch();
-        }
-
-        @Override protected void onDraw(Canvas canvas) {
-            if (mInterp != null) {
-                int now = (int)SystemClock.uptimeMillis();
-                Interpolator.Result result = mInterp.timeToValues(now, mCubics);
-                if (result != Interpolator.Result.NORMAL) {
-                    mInterp = null;
-                } else {
-                    invalidate();
-                }
-                rebuildPatch();
-            }
-            mPatch.draw(canvas);
-        }
-
-        private void rebuildPatch() {
-            mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
-        }
-
-        @Override public boolean onTouchEvent(MotionEvent event) {
-            float x = event.getX();
-            float y = event.getY();
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_DOWN:
-                    System.arraycopy(mOrig, 0, mCubics, 0, 24);
-                    mPrevX = x;
-                    mPrevY = y;
-                    break;
-                case MotionEvent.ACTION_MOVE: {
-                    float scale = 1.5f;
-                    float dx = (x - mPrevX) * scale;
-                    float dy = (y - mPrevY) * scale;
-                    int index;
-
-                    if (dx < 0) {
-                        index = 10;
-                    } else {
-                        index = 4;
-                    }
-                    mCubics[index*2 + 0] = mOrig[index*2 + 0] + dx;
-                    mCubics[index*2 + 2] = mOrig[index*2 + 2] + dx;
-                    
-                    if (dy < 0) {
-                        index = 1;
-                    } else {
-                        index = 7;
-                    }
-                    mCubics[index*2 + 1] = mOrig[index*2 + 1] + dy;
-                    mCubics[index*2 + 3] = mOrig[index*2 + 3] + dy;
-        
-                    rebuildPatch();
-                    invalidate();
-                } break;
-                case MotionEvent.ACTION_UP:
-                case MotionEvent.ACTION_CANCEL: {
-                    int start = (int)SystemClock.uptimeMillis();
-                    mInterp = new Interpolator(24);
-                    mInterp.setKeyFrame(0, start, mCubics,
-                                        new float[] { 0, 0.5f, 0.5f, 1 });
-                    mInterp.setKeyFrame(1, start + UNSTRETCH_MSEC, mOrig
-                                        );
-                    invalidate();
-                } break;
-            }
-            return true;
-        }
-    }
-
-    private static class SampleView extends View {
-        private static final int ROWS = 16;
-        private static final int COLS = 16;
-        
-        private BoundaryPatch mPatch;
-        private float[] mCubics;
-        private float[] mOrig = new float[24];
-        private Paint mPaint0;
-        private Paint mPaint1;
-        private int mCurrIndex = -1;
-        private float mPrevX;
-        private float mPrevY;
-        
-        public SampleView(Context context) {
-        super(context);
-        setFocusable(true);
-        
-        Bitmap bm = BitmapFactory.decodeResource(getResources(),
-                                                 R.drawable.beach);
-        
-        mPatch = new BoundaryPatch();
-        mPatch.setTexture(bm);
-        
-        float unit = 90;
-        mCubics = new float[] {
-            0, 0, 1, 0, 2, 0,
-            3, 0, 3, 1, 3, 2,
-            3, 3, 2, 3, 1, 3,
-            0, 3, 0, 2, 0, 1
-        };
-        for (int i = 0; i < 24; i++) {
-            mCubics[i] *= 90;
-            mCubics[i] += 20;
-        }
-        rebuildPatch();
-        
-        mPaint0 = new Paint();
-        mPaint0.setAntiAlias(true);
-        mPaint0.setStrokeWidth(12);
-        mPaint0.setStrokeCap(Paint.Cap.ROUND);
-        mPaint1 = new Paint(mPaint0);
-        mPaint1.setColor(0xFFFFFFFF);
-        mPaint1.setStrokeWidth(10);
-    }
-    
-    @Override protected void onDraw(Canvas canvas) {
-        canvas.drawColor(0xFFCCCCCC);
-        mPatch.draw(canvas);
-        canvas.drawPoints(mCubics, mPaint0);
-        canvas.drawPoints(mCubics, mPaint1);
-    }
-    
-    private void rebuildPatch() {
-        mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
-    }
-    
-    private int findPtIndex(float x, float y) {
-        final float tolerance = 25;
-        final float[] pts = mCubics;
-        for (int i = 0; i < (pts.length >> 1); i++) {
-            if (Math.abs(pts[i*2 + 0] - x) <= tolerance &&
-                Math.abs(pts[i*2 + 1] - y) <= tolerance) {
-                return i*2;
-            }
-        }
-        return -1;
-    }
-    
-    private void offsetPts(float dx, float dy) {
-        final float[] pts = mCubics;
-        for (int i = 0; i < (pts.length >> 1); i++) {
-            pts[i*2 + 0] += dx;
-            pts[i*2 + 1] += dy;
-        }
-        rebuildPatch();
-    }
-    
-    @Override public boolean onTouchEvent(MotionEvent event) {
-        float x = event.getX();
-        float y = event.getY();
-        switch (event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mCurrIndex = findPtIndex(x, y);
-                mPrevX = x;
-                mPrevY = y;
-                break;
-            case MotionEvent.ACTION_MOVE:
-                if (mCurrIndex >= 0) {
-                    mCubics[mCurrIndex + 0] = x;
-                    mCubics[mCurrIndex + 1] = y;
-                    mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
-                } else {
-                    offsetPts(x - mPrevX, y - mPrevY);
-                    mPrevX = x;
-                    mPrevY = y;
-                }
-                invalidate();
-                break;
-        }
-        return true;
-    }
-}
-}
-
diff --git a/apps/SpareParts/AndroidManifest.xml b/apps/SpareParts/AndroidManifest.xml
index 85de7a4..137f907 100644
--- a/apps/SpareParts/AndroidManifest.xml
+++ b/apps/SpareParts/AndroidManifest.xml
@@ -21,7 +21,7 @@
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     
     <application android:label="@string/app_label"
-            android:icon="@drawable/app_icon">
+            android:icon="@mipmap/app_icon">
 
         <activity android:name="SpareParts">
             <intent-filter>
diff --git a/apps/SpareParts/res/drawable-hdpi/app_icon.png b/apps/SpareParts/res/mipmap-hdpi/app_icon.png
similarity index 100%
rename from apps/SpareParts/res/drawable-hdpi/app_icon.png
rename to apps/SpareParts/res/mipmap-hdpi/app_icon.png
Binary files differ
diff --git a/apps/SpareParts/res/drawable-mdpi/app_icon.png b/apps/SpareParts/res/mipmap-mdpi/app_icon.png
similarity index 100%
rename from apps/SpareParts/res/drawable-mdpi/app_icon.png
rename to apps/SpareParts/res/mipmap-mdpi/app_icon.png
Binary files differ
diff --git a/apps/Term/Android.mk b/apps/Term/Android.mk
deleted file mode 100644
index 9ff6c0d..0000000
--- a/apps/Term/Android.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# 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.
-#
-
-# This makefile shows how to build a shared library and an activity that
-# bundles the shared library and calls it using JNI.
-
-TOP_LOCAL_PATH:= $(call my-dir)
-
-# Build activity
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := eng
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := Term
-
-LOCAL_JNI_SHARED_LIBRARIES := libterm
-
-include $(BUILD_PACKAGE)
-
-# ============================================================
-
-# Also build all of the sub-targets under this one: the shared library.
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/apps/Term/AndroidManifest.xml b/apps/Term/AndroidManifest.xml
deleted file mode 100644
index 7084d2c..0000000
--- a/apps/Term/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.term">
-    <application android:icon="@drawable/app_terminal"
-                android:label="@string/application_terminal">
-        <activity android:name="Term"
-                android:theme="@style/Theme"
-                android:launchMode="singleInstance"
-                android:configChanges="keyboard|keyboardHidden|orientation"
-                android:windowSoftInputMode="adjustResize|stateVisible">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.TEST" />
-            </intent-filter>
-        </activity>
-        <activity android:name="TermPreferences"/>
-    </application>
-</manifest> 
diff --git a/apps/Term/MODULE_LICENSE_APACHE2 b/apps/Term/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/apps/Term/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/apps/Term/NOTICE b/apps/Term/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/apps/Term/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/apps/Term/jni/Android.mk b/apps/Term/jni/Android.mk
deleted file mode 100644
index 2fe4a75..0000000
--- a/apps/Term/jni/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# 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.
-#
-
-# This makefile supplies the rules for building a library of JNI code for
-# use by our example of how to bundle a shared library with an APK.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := eng
-
-# This is the target being built.
-LOCAL_MODULE:= libterm
-
-
-# All of the source files that we will compile.
-LOCAL_SRC_FILES:= \
-  termExec.cpp
-
-# All of the shared libraries we link against.
-LOCAL_SHARED_LIBRARIES := \
-	libutils
-
-# No static libraries.
-LOCAL_STATIC_LIBRARIES :=
-
-# Also need the JNI headers.
-LOCAL_C_INCLUDES += \
-	$(JNI_H_INCLUDE)
-
-# No special compiler flags.
-LOCAL_CFLAGS +=
-
-# Don't prelink this library.  For more efficient code, you may want
-# to add this library to the prelink map and set this to true. However,
-# it's difficult to do this for applications that are not supplied as
-# part of a system image.
-
-LOCAL_PRELINK_MODULE := false
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/Term/jni/termExec.cpp b/apps/Term/jni/termExec.cpp
deleted file mode 100644
index d0666cc..0000000
--- a/apps/Term/jni/termExec.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Exec"
-
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-#include "android_runtime/AndroidRuntime.h"
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <termios.h>
-
-static jclass class_fileDescriptor;
-static jfieldID field_fileDescriptor_descriptor;
-static jmethodID method_fileDescriptor_init;
-
-
-class String8 {
-public:
-    String8() {
-        mString = 0;
-    }
-    
-    ~String8() {
-        if (mString) {
-            free(mString);
-        }
-    }
-
-    void set(const char16_t* o, size_t numChars) {
-        mString = (char*) malloc(numChars + 1);
-        for (size_t i = 0; i < numChars; i++) {
-            mString[i] = (char) o[i];
-        }
-        mString[numChars] = '\0';
-    }
-    
-    const char* string() {
-        return mString;
-    }
-private:
-    char* mString;
-};
-
-static int create_subprocess(const char *cmd, const char *arg0, const char *arg1,
-    int* pProcessId)
-{
-    char *devname;
-    int ptm;
-    pid_t pid;
-
-    ptm = open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
-    if(ptm < 0){
-        LOGE("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
-        return -1;
-    }
-    fcntl(ptm, F_SETFD, FD_CLOEXEC);
-
-    if(grantpt(ptm) || unlockpt(ptm) ||
-       ((devname = (char*) ptsname(ptm)) == 0)){
-        LOGE("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
-        return -1;
-    }
-    
-    pid = fork();
-    if(pid < 0) {
-        LOGE("- fork failed: %s -\n", strerror(errno));
-        return -1;
-    }
-
-    if(pid == 0){
-        close(ptm);
-
-        int pts;
-
-        setsid();
-        
-        pts = open(devname, O_RDWR);
-        if(pts < 0) exit(-1);
-
-        dup2(pts, 0);
-        dup2(pts, 1);
-        dup2(pts, 2);
-
-        execl(cmd, cmd, arg0, arg1, NULL);
-        exit(-1);
-    } else {
-        *pProcessId = (int) pid;
-        return ptm;
-    }
-}
-
-
-static jobject android_os_Exec_createSubProcess(JNIEnv *env, jobject clazz,
-    jstring cmd, jstring arg0, jstring arg1, jintArray processIdArray)
-{
-    const jchar* str = cmd ? env->GetStringCritical(cmd, 0) : 0;
-    String8 cmd_8;
-    if (str) {
-        cmd_8.set(str, env->GetStringLength(cmd));
-        env->ReleaseStringCritical(cmd, str);
-    }
-
-    str = arg0 ? env->GetStringCritical(arg0, 0) : 0;
-    const char* arg0Str = 0;
-    String8 arg0_8;
-    if (str) {
-        arg0_8.set(str, env->GetStringLength(arg0));
-        env->ReleaseStringCritical(arg0, str);
-        arg0Str = arg0_8.string();
-    }
-
-    str = arg1 ? env->GetStringCritical(arg1, 0) : 0;
-    const char* arg1Str = 0;
-    String8 arg1_8;
-    if (str) {
-        arg1_8.set(str, env->GetStringLength(arg1));
-        env->ReleaseStringCritical(arg1, str);
-        arg1Str = arg1_8.string();
-    }
-
-    int procId;
-    int ptm = create_subprocess(cmd_8.string(), arg0Str, arg1Str, &procId);
-    
-    if (processIdArray) {
-        int procIdLen = env->GetArrayLength(processIdArray);
-        if (procIdLen > 0) {
-            jboolean isCopy;
-    
-            int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
-            if (pProcId) {
-                *pProcId = procId;
-                env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
-            }
-        }
-    }
-    
-    jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);
-    
-    if (!result) {
-        LOGE("Couldn't create a FileDescriptor.");
-    }
-    else {
-        env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
-    }
-    
-    return result;
-}
-
-
-static void android_os_Exec_setPtyWindowSize(JNIEnv *env, jobject clazz,
-    jobject fileDescriptor, jint row, jint col, jint xpixel, jint ypixel)
-{
-    int fd;
-    struct winsize sz;
-
-    fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
-
-    if (env->ExceptionOccurred() != NULL) {
-        return;
-    }
-    
-    sz.ws_row = row;
-    sz.ws_col = col;
-    sz.ws_xpixel = xpixel;
-    sz.ws_ypixel = ypixel;
-    
-    ioctl(fd, TIOCSWINSZ, &sz);
-}
-
-static int android_os_Exec_waitFor(JNIEnv *env, jobject clazz,
-    jint procId) {
-    int status;
-    waitpid(procId, &status, 0);
-    int result = 0;
-    if (WIFEXITED(status)) {
-        result = WEXITSTATUS(status);
-    }
-    return result;
-}
-
-static void android_os_Exec_close(JNIEnv *env, jobject clazz, jobject fileDescriptor)
-{
-    int fd;
-    struct winsize sz;
-
-    fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
-
-    if (env->ExceptionOccurred() != NULL) {
-        return;
-    }
-    
-    close(fd);
-}
-
-
-static int register_FileDescriptor(JNIEnv *env)
-{
-    class_fileDescriptor = env->FindClass("java/io/FileDescriptor");
-
-    if (class_fileDescriptor == NULL) {
-        LOGE("Can't find java/io/FileDescriptor");
-        return -1;
-    }
-
-    field_fileDescriptor_descriptor = env->GetFieldID(class_fileDescriptor, "descriptor", "I");
-
-    if (field_fileDescriptor_descriptor == NULL) {
-        LOGE("Can't find FileDescriptor.descriptor");
-        return -1;
-    }
-
-    method_fileDescriptor_init = env->GetMethodID(class_fileDescriptor, "<init>", "()V");
-    if (method_fileDescriptor_init == NULL) {
-        LOGE("Can't find FileDescriptor.init");
-        return -1;
-     }
-     return 0;
-}
-
-
-static const char *classPathName = "com/android/term/Exec";
-
-static JNINativeMethod method_table[] = {
-    { "createSubprocess", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I)Ljava/io/FileDescriptor;",
-        (void*) android_os_Exec_createSubProcess },
-    { "setPtyWindowSize", "(Ljava/io/FileDescriptor;IIII)V",
-        (void*) android_os_Exec_setPtyWindowSize},
-    { "waitFor", "(I)I",
-        (void*) android_os_Exec_waitFor},
-    { "close", "(Ljava/io/FileDescriptor;)V",
-        (void*) android_os_Exec_close}
-};
-
-/*
- * Register several native methods for one class.
- */
-static int registerNativeMethods(JNIEnv* env, const char* className,
-    JNINativeMethod* gMethods, int numMethods)
-{
-    jclass clazz;
-
-    clazz = env->FindClass(className);
-    if (clazz == NULL) {
-        LOGE("Native registration unable to find class '%s'", className);
-        return JNI_FALSE;
-    }
-    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
-        LOGE("RegisterNatives failed for '%s'", className);
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-}
-
-/*
- * Register native methods for all classes we know about.
- *
- * returns JNI_TRUE on success.
- */
-static int registerNatives(JNIEnv* env)
-{
-  if (!registerNativeMethods(env, classPathName, method_table, 
-                 sizeof(method_table) / sizeof(method_table[0]))) {
-    return JNI_FALSE;
-  }
-
-  return JNI_TRUE;
-}
-
-
-// ----------------------------------------------------------------------------
-
-/*
- * This is called by the VM when the shared library is first loaded.
- */
- 
-typedef union {
-    JNIEnv* env;
-    void* venv;
-} UnionJNIEnvToVoid;
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved) {
-    UnionJNIEnvToVoid uenv;
-    uenv.venv = NULL;
-    jint result = -1;
-    JNIEnv* env = NULL;
-    
-    LOGI("JNI_OnLoad");
-
-    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
-        LOGE("ERROR: GetEnv failed");
-        goto bail;
-    }
-    env = uenv.env;
-    
-    if ((result = register_FileDescriptor(env)) < 0) {
-        LOGE("ERROR: registerFileDescriptor failed");
-        goto bail;
-    }
-
-    if (registerNatives(env) != JNI_TRUE) {
-        LOGE("ERROR: registerNatives failed");
-        goto bail;
-    }
-    
-    result = JNI_VERSION_1_4;
-    
-bail:
-    return result;
-}
diff --git a/apps/Term/res/drawable-hdpi/app_terminal.png b/apps/Term/res/drawable-hdpi/app_terminal.png
deleted file mode 100755
index 278b2a5..0000000
--- a/apps/Term/res/drawable-hdpi/app_terminal.png
+++ /dev/null
Binary files differ
diff --git a/apps/Term/res/drawable-hdpi/atari_small.png b/apps/Term/res/drawable-hdpi/atari_small.png
deleted file mode 100755
index 8bdd624..0000000
--- a/apps/Term/res/drawable-hdpi/atari_small.png
+++ /dev/null
Binary files differ
diff --git a/apps/Term/res/drawable-mdpi/app_terminal.png b/apps/Term/res/drawable-mdpi/app_terminal.png
deleted file mode 100644
index 1ec3b4b..0000000
--- a/apps/Term/res/drawable-mdpi/app_terminal.png
+++ /dev/null
Binary files differ
diff --git a/apps/Term/res/drawable-mdpi/atari_small.png b/apps/Term/res/drawable-mdpi/atari_small.png
deleted file mode 100644
index 535e295..0000000
--- a/apps/Term/res/drawable-mdpi/atari_small.png
+++ /dev/null
Binary files differ
diff --git a/apps/Term/res/drawable/atari_small_notice.txt b/apps/Term/res/drawable/atari_small_notice.txt
deleted file mode 100644
index afa8539..0000000
--- a/apps/Term/res/drawable/atari_small_notice.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-COMMENT  Copyright (c) 1999, Thomas A. Fine
-COMMENT
-COMMENT  License to copy, modify, and distribute for both commercial and
-COMMENT  non-commercial use is herby granted, provided this notice
-COMMENT  is preserved.
-COMMENT
-COMMENT  Email to my last name at head.cfa.harvard.edu
-COMMENT  http://hea-www.harvard.edu/~fine/
-COMMENT
-COMMENT  Produced with bdfedit, a tcl/tk font editing program
-COMMENT  written by Thomas A. Fine
\ No newline at end of file
diff --git a/apps/Term/res/layout/term_activity.xml b/apps/Term/res/layout/term_activity.xml
deleted file mode 100644
index 6ce7719..0000000
--- a/apps/Term/res/layout/term_activity.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* 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.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent" 
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <com.android.term.EmulatorView android:id="@+id/emulatorView"
-	      android:layout_width="wrap_content"
-	      android:layout_height="wrap_content"
-	      android:layout_alignParentLeft="true"
-	      />
-   
-</LinearLayout>
diff --git a/apps/Term/res/menu/main.xml b/apps/Term/res/menu/main.xml
deleted file mode 100644
index 5f6e9d8..0000000
--- a/apps/Term/res/menu/main.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_preferences"
-    	android:title="@string/preferences" />
-    <item android:id="@+id/menu_reset"
-    	android:title="@string/reset" />
-    <item android:id="@+id/menu_send_email"
-    	android:title="@string/send_email" />
-    <item android:id="@+id/menu_special_keys"
-    	android:title="@string/special_keys" />
-</menu>
diff --git a/apps/Term/res/values/arrays.xml b/apps/Term/res/values/arrays.xml
deleted file mode 100644
index b4857a2..0000000
--- a/apps/Term/res/values/arrays.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<resources>
-    <string-array name="entries_fontsize_preference">
-        <item>4 x 8 pixels</item>
-        <item>6 pt</item>
-        <item>7 pt</item>
-        <item>8 pt</item>
-        <item>9 pt</item>
-        <item>10 pt</item>
-        <item>12 pt</item>
-        <item>14 pt</item>
-        <item>16 pt</item>
-        <item>20 pt</item>
-    </string-array>
-
-	<!-- Do not localize entryvalues -->
-    <string-array name="entryvalues_fontsize_preference">
-        <item>0</item>
-        <item>6</item>
-        <item>7</item>
-        <item>8</item>
-        <item>9</item>
-        <item>10</item>
-        <item>12</item>
-        <item>14</item>
-        <item>16</item>
-        <item>20</item>  
-    </string-array>
-
-    <string-array name="entries_color_preference">
-        <item>Black text on white</item>
-        <item>White text on black</item>
-        <item>White text on blue</item>  
-    </string-array>
-
-	<!-- Do not localize entryvalues -->
-    <string-array name="entryvalues_color_preference">
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>  
-    </string-array>
-    
-    <string-array name="entries_controlkey_preference">
-        <item>Jog ball</item>
-        <item>\@ key</item>
-        <item>Left Alt key</item>
-        <item>Right Alt key</item>
-    </string-array>
-
-	<!-- Do not localize entryvalues -->
-    <string-array name="entryvalues_controlkey_preference">
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-        <item>3</item>
-    </string-array>
-</resources>
diff --git a/apps/Term/res/values/attrs.xml b/apps/Term/res/values/attrs.xml
deleted file mode 100644
index 3787d7e..0000000
--- a/apps/Term/res/values/attrs.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* 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.
-*/
--->
-
-<resources>
-     <declare-styleable name="EmulatorView">
-    </declare-styleable>
-</resources>
diff --git a/apps/Term/res/values/strings.xml b/apps/Term/res/values/strings.xml
deleted file mode 100644
index b5d622b..0000000
--- a/apps/Term/res/values/strings.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
--->
-<resources>
-   <string name="application_terminal">Terminal Emulator</string>
-   <string name="preferences">Preferences</string>
-   <string name="reset">Reset term</string>
-   <string name="send_email">Email to</string>
-   <string name="special_keys">Special keys</string>
-
-   <!-- Preference dialog -->
-   <string name="text_preferences">Text</string>
-
-   <string name="title_fontsize_preference">Font size</string>
-   <string name="summary_fontsize_preference">Choose character height in points.</string>
-   <string name="dialog_title_fontsize_preference">Font size</string>
-
-   <string name="title_color_preference">Colors</string>
-   <string name="summary_color_preference">Choose text color.</string>
-   <string name="dialog_title_color_preference">Text color</string>
-
-   <string name="keyboard_preferences">Keyboard</string>
-   <string name="title_controlkey_preference">Control key</string>
-   <string name="summary_controlkey_preference">Choose control key.</string>
-   <string name="dialog_title_controlkey_preference">Control key</string>
-
-   <string name="shell_preferences">Shell</string>
-   <string name="title_shell_preference">Command line</string>
-   <string name="summary_shell_preference">Specify the shell command line.</string>
-   <string name="dialog_title_shell_preference">Shell</string>
-
-   <string name="title_initialcommand_preference">Initial command</string>
-   <string name="summary_initialcommand_preference">Sent to the shell when it starts.</string>
-   <string name="dialog_title_initialcommand_preference">Initial Command</string>
-
-   <!-- Don't localize these default values -->
-   <string name="default_value_fontsize_preference">10</string>
-   <string name="default_value_color_preference">2</string>
-   <string name="default_value_controlkey_preference">0</string>
-   <string name="default_value_shell_preference">/system/bin/sh -</string>
-   <string name="default_value_initialcommand_preference">export PATH=/data/local/bin:$PATH</string>
-</resources>
diff --git a/apps/Term/res/values/styles.xml b/apps/Term/res/values/styles.xml
deleted file mode 100644
index 0e59f4a..0000000
--- a/apps/Term/res/values/styles.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <style name="Theme" parent="@android:style/Theme.Light">
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowFrame">@null</item>
-    </style>
-</resources>
-
diff --git a/apps/Term/res/xml/preferences.xml b/apps/Term/res/xml/preferences.xml
deleted file mode 100644
index 7792153..0000000
--- a/apps/Term/res/xml/preferences.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen
-        xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <PreferenceCategory
-            android:title="@string/text_preferences">
-
-        <ListPreference
-                android:key="fontsize"
-                android:defaultValue="@string/default_value_fontsize_preference"
-                android:title="@string/title_fontsize_preference"
-                android:summary="@string/summary_fontsize_preference"
-                android:entries="@array/entries_fontsize_preference"
-                android:entryValues="@array/entryvalues_fontsize_preference"
-                android:dialogTitle="@string/dialog_title_fontsize_preference" />
-
-        <ListPreference
-                android:key="color"
-                android:defaultValue="@string/default_value_color_preference"
-                android:title="@string/title_color_preference"
-                android:summary="@string/summary_color_preference"
-                android:entries="@array/entries_color_preference"
-                android:entryValues="@array/entryvalues_color_preference"
-                android:dialogTitle="@string/dialog_title_color_preference" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-            android:title="@string/keyboard_preferences">
-
-        <ListPreference
-                android:key="controlkey"
-                android:defaultValue="@string/default_value_controlkey_preference"
-                android:title="@string/title_controlkey_preference"
-                android:summary="@string/summary_controlkey_preference"
-                android:entries="@array/entries_controlkey_preference"
-                android:entryValues="@array/entryvalues_controlkey_preference"
-                android:dialogTitle="@string/dialog_title_controlkey_preference" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:title="@string/shell_preferences">
-
-    <EditTextPreference
-            android:key="shell"
-            android:defaultValue="@string/default_value_shell_preference"
-            android:title="@string/title_shell_preference"
-            android:summary="@string/summary_shell_preference"
-            android:dialogTitle="@string/dialog_title_shell_preference" />
-    <EditTextPreference
-            android:key="initialcommand"
-            android:defaultValue="@string/default_value_initialcommand_preference"
-            android:title="@string/title_initialcommand_preference"
-            android:summary="@string/summary_initialcommand_preference"
-            android:dialogTitle="@string/dialog_title_initialcommand_preference" />
-    </PreferenceCategory>
-</PreferenceScreen>
diff --git a/apps/Term/src/com/android/term/Exec.java b/apps/Term/src/com/android/term/Exec.java
deleted file mode 100644
index b53acfc..0000000
--- a/apps/Term/src/com/android/term/Exec.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.term;
-
-import java.io.FileDescriptor;
-
-/**
- * Utility methods for creating and managing a subprocess.
- * <p>
- * Note: The native methods access a package-private
- * java.io.FileDescriptor field to get and set the raw Linux
- * file descriptor. This might break if the implementation of
- * java.io.FileDescriptor is changed.
- */
-
-public class Exec
-{
-    static {
-        System.loadLibrary("term");
-    }
-
-    /**
-     * Create a subprocess. Differs from java.lang.ProcessBuilder in
-     * that a pty is used to communicate with the subprocess.
-     * <p>
-     * Callers are responsible for calling Exec.close() on the returned
-     * file descriptor.
-     *
-     * @param cmd The command to execute
-     * @param arg0 The first argument to the command, may be null
-     * @param arg1 the second argument to the command, may be null
-     * @param processId A one-element array to which the process ID of the
-     * started process will be written.
-     * @return the file descriptor of the started process.
-     *
-     */
-    public static native FileDescriptor createSubprocess(
-        String cmd, String arg0, String arg1, int[] processId);
-        
-    /**
-     * Set the widow size for a given pty. Allows programs
-     * connected to the pty learn how large their screen is.
-     */
-    public static native void setPtyWindowSize(FileDescriptor fd,
-       int row, int col, int xpixel, int ypixel);
-
-    /**
-     * Causes the calling thread to wait for the process associated with the
-     * receiver to finish executing.
-     *
-     * @return The exit value of the Process being waited on
-     *
-     */
-    public static native int waitFor(int processId);
-
-    /**
-     * Close a given file descriptor.
-     */
-    public static native void close(FileDescriptor fd);
-}
-
diff --git a/apps/Term/src/com/android/term/Term.java b/apps/Term/src/com/android/term/Term.java
deleted file mode 100644
index 6d3796a..0000000
--- a/apps/Term/src/com/android/term/Term.java
+++ /dev/null
@@ -1,3274 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.term;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.preference.PreferenceManager;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.inputmethod.BaseInputConnection;
-import android.view.inputmethod.CompletionInfo;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.ExtractedText;
-import android.view.inputmethod.ExtractedTextRequest;
-import android.view.inputmethod.InputConnection;
-
-/**
- * A terminal emulator activity.
- */
-
-public class Term extends Activity {
-    /**
-     * Set to true to add debugging code and logging.
-     */
-    public static final boolean DEBUG = false;
-
-    /**
-     * Set to true to log each character received from the remote process to the
-     * android log, which makes it easier to debug some kinds of problems with
-     * emulating escape sequences and control codes.
-     */
-    public static final boolean LOG_CHARACTERS_FLAG = DEBUG && false;
-
-    /**
-     * Set to true to log unknown escape sequences.
-     */
-    public static final boolean LOG_UNKNOWN_ESCAPE_SEQUENCES = DEBUG && false;
-
-    /**
-     * The tag we use when logging, so that our messages can be distinguished
-     * from other messages in the log. Public because it's used by several
-     * classes.
-     */
-    public static final String LOG_TAG = "Term";
-
-    /**
-     * Our main view. Displays the emulated terminal screen.
-     */
-    private EmulatorView mEmulatorView;
-
-    /**
-     * The pseudo-teletype (pty) file descriptor that we use to communicate with
-     * another process, typically a shell.
-     */
-    private FileDescriptor mTermFd;
-
-    /**
-     * Used to send data to the remote process.
-     */
-    private FileOutputStream mTermOut;
-
-    /**
-     * A key listener that tracks the modifier keys and allows the full ASCII
-     * character set to be entered.
-     */
-    private TermKeyListener mKeyListener;
-
-    /**
-     * The name of our emulator view in the view resource.
-     */
-    private static final int EMULATOR_VIEW = R.id.emulatorView;
-
-    private int mFontSize = 9;
-    private int mColorId = 2;
-    private int mControlKeyId = 0;
-
-    private static final String FONTSIZE_KEY = "fontsize";
-    private static final String COLOR_KEY = "color";
-    private static final String CONTROLKEY_KEY = "controlkey";
-    private static final String SHELL_KEY = "shell";
-    private static final String INITIALCOMMAND_KEY = "initialcommand";
-
-    public static final int WHITE = 0xffffffff;
-    public static final int BLACK = 0xff000000;
-    public static final int BLUE = 0xff344ebd;
-
-    private static final int[][] COLOR_SCHEMES = {
-        {BLACK, WHITE}, {WHITE, BLACK}, {WHITE, BLUE}};
-
-    private static final int[] CONTROL_KEY_SCHEMES = {
-        KeyEvent.KEYCODE_DPAD_CENTER,
-        KeyEvent.KEYCODE_AT,
-        KeyEvent.KEYCODE_ALT_LEFT,
-        KeyEvent.KEYCODE_ALT_RIGHT
-    };
-    private static final String[] CONTROL_KEY_NAME = {
-        "Ball", "@", "Left-Alt", "Right-Alt"
-    };
-
-    private int mControlKeyCode;
-
-    private final static String DEFAULT_SHELL = "/system/bin/sh -";
-    private String mShell;
-
-    private final static String DEFAULT_INITIAL_COMMAND =
-        "export PATH=/data/local/bin:$PATH";
-    private String mInitialCommand;
-
-    private SharedPreferences mPrefs;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        Log.e(Term.LOG_TAG, "onCreate");
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-        readPrefs();
-
-        setContentView(R.layout.term_activity);
-
-        mEmulatorView = (EmulatorView) findViewById(EMULATOR_VIEW);
-
-        startListening();
-
-        mKeyListener = new TermKeyListener();
-
-        mEmulatorView.setFocusable(true);
-        mEmulatorView.setFocusableInTouchMode(true);
-        mEmulatorView.requestFocus();
-        mEmulatorView.register(mKeyListener);
-
-        updatePrefs();
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (mTermFd != null) {
-            Exec.close(mTermFd);
-            mTermFd = null;
-        }
-    }
-
-    private void startListening() {
-        int[] processId = new int[1];
-
-        createSubprocess(processId);
-        final int procId = processId[0];
-
-        final Handler handler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-            }
-        };
-
-        Runnable watchForDeath = new Runnable() {
-
-            public void run() {
-                Log.i(Term.LOG_TAG, "waiting for: " + procId);
-               int result = Exec.waitFor(procId);
-                Log.i(Term.LOG_TAG, "Subprocess exited: " + result);
-                handler.sendEmptyMessage(result);
-             }
-
-        };
-        Thread watcher = new Thread(watchForDeath);
-        watcher.start();
-
-        mTermOut = new FileOutputStream(mTermFd);
-
-        mEmulatorView.initialize(mTermFd, mTermOut);
-
-        sendInitialCommand();
-    }
-
-    private void sendInitialCommand() {
-        String initialCommand = mInitialCommand;
-        if (initialCommand == null || initialCommand.equals("")) {
-            initialCommand = DEFAULT_INITIAL_COMMAND;
-        }
-        if (initialCommand.length() > 0) {
-            write(initialCommand + '\r');
-        }
-    }
-
-    private void restart() {
-        startActivity(getIntent());
-        finish();
-    }
-
-    private void write(String data) {
-        try {
-            mTermOut.write(data.getBytes());
-            mTermOut.flush();
-        } catch (IOException e) {
-            // Ignore exception
-            // We don't really care if the receiver isn't listening.
-            // We just make a best effort to answer the query.
-        }
-    }
-
-    private void createSubprocess(int[] processId) {
-        String shell = mShell;
-        if (shell == null || shell.equals("")) {
-            shell = DEFAULT_SHELL;
-        }
-        ArrayList<String> args = parse(shell);
-        String arg0 = args.get(0);
-        String arg1 = null;
-        String arg2 = null;
-        if (args.size() >= 2) {
-            arg1 = args.get(1);
-        }
-        if (args.size() >= 3) {
-            arg2 = args.get(2);
-        }
-        mTermFd = Exec.createSubprocess(arg0, arg1, arg2, processId);
-    }
-
-    private ArrayList<String> parse(String cmd) {
-        final int PLAIN = 0;
-        final int WHITESPACE = 1;
-        final int INQUOTE = 2;
-        int state = WHITESPACE;
-        ArrayList<String> result =  new ArrayList<String>();
-        int cmdLen = cmd.length();
-        StringBuilder builder = new StringBuilder();
-        for (int i = 0; i < cmdLen; i++) {
-            char c = cmd.charAt(i);
-            if (state == PLAIN) {
-                if (Character.isWhitespace(c)) {
-                    result.add(builder.toString());
-                    builder.delete(0,builder.length());
-                    state = WHITESPACE;
-                } else if (c == '"') {
-                    state = INQUOTE;
-                } else {
-                    builder.append(c);
-                }
-            } else if (state == WHITESPACE) {
-                if (Character.isWhitespace(c)) {
-                    // do nothing
-                } else if (c == '"') {
-                    state = INQUOTE;
-                } else {
-                    state = PLAIN;
-                    builder.append(c);
-                }
-            } else if (state == INQUOTE) {
-                if (c == '\\') {
-                    if (i + 1 < cmdLen) {
-                        i += 1;
-                        builder.append(cmd.charAt(i));
-                    }
-                } else if (c == '"') {
-                    state = PLAIN;
-                } else {
-                    builder.append(c);
-                }
-            }
-        }
-        if (builder.length() > 0) {
-            result.add(builder.toString());
-        }
-        return result;
-    }
-
-    private void readPrefs() {
-        mFontSize = readIntPref(FONTSIZE_KEY, mFontSize, 20);
-        mColorId = readIntPref(COLOR_KEY, mColorId, COLOR_SCHEMES.length - 1);
-        mControlKeyId = readIntPref(CONTROLKEY_KEY, mControlKeyId,
-                CONTROL_KEY_SCHEMES.length - 1);
-        {
-            String newShell = readStringPref(SHELL_KEY, mShell);
-            if ((newShell == null) || ! newShell.equals(mShell)) {
-                if (mShell != null) {
-                    Log.i(Term.LOG_TAG, "New shell set. Restarting.");
-                    restart();
-                }
-                mShell = newShell;
-            }
-        }
-        {
-            String newInitialCommand = readStringPref(INITIALCOMMAND_KEY,
-                    mInitialCommand);
-            if ((newInitialCommand == null)
-                    || ! newInitialCommand.equals(mInitialCommand)) {
-                if (mInitialCommand != null) {
-                    Log.i(Term.LOG_TAG, "New initial command set. Restarting.");
-                    restart();
-                }
-                mInitialCommand = newInitialCommand;
-            }
-        }
-    }
-
-    private void updatePrefs() {
-        DisplayMetrics metrics = new DisplayMetrics();
-        getWindowManager().getDefaultDisplay().getMetrics(metrics);
-        mEmulatorView.setTextSize((int) (mFontSize * metrics.density));
-        setColors();
-        mControlKeyCode = CONTROL_KEY_SCHEMES[mControlKeyId];
-    }
-
-    private int readIntPref(String key, int defaultValue, int maxValue) {
-        int val;
-        try {
-            val = Integer.parseInt(
-                mPrefs.getString(key, Integer.toString(defaultValue)));
-        } catch (NumberFormatException e) {
-            val = defaultValue;
-        }
-        val = Math.max(0, Math.min(val, maxValue));
-        return val;
-    }
-
-    private String readStringPref(String key, String defaultValue) {
-        return mPrefs.getString(key, defaultValue);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        readPrefs();
-        updatePrefs();
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        mEmulatorView.updateSize();
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (handleControlKey(keyCode, true)) {
-            return true;
-        } else if (isSystemKey(keyCode, event)) {
-            // Don't intercept the system keys
-            return super.onKeyDown(keyCode, event);
-        } else if (handleDPad(keyCode, true)) {
-            return true;
-        }
-
-        // Translate the keyCode into an ASCII character.
-        int letter = mKeyListener.keyDown(keyCode, event);
-
-        if (letter >= 0) {
-            try {
-                mTermOut.write(letter);
-            } catch (IOException e) {
-                // Ignore I/O exceptions
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (handleControlKey(keyCode, false)) {
-            return true;
-        } else if (isSystemKey(keyCode, event)) {
-            // Don't intercept the system keys
-            return super.onKeyUp(keyCode, event);
-        } else if (handleDPad(keyCode, false)) {
-            return true;
-        }
-
-        mKeyListener.keyUp(keyCode);
-        return true;
-    }
-
-    private boolean handleControlKey(int keyCode, boolean down) {
-        if (keyCode == mControlKeyCode) {
-            mKeyListener.handleControlKey(down);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Handle dpad left-right-up-down events. Don't handle
-     * dpad-center, that's our control key.
-     * @param keyCode
-     * @param down
-     */
-    private boolean handleDPad(int keyCode, boolean down) {
-        if (keyCode < KeyEvent.KEYCODE_DPAD_UP ||
-                keyCode > KeyEvent.KEYCODE_DPAD_CENTER) {
-            return false;
-        }
-
-        if (down) {
-            try {
-                if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
-                    mTermOut.write('\r');
-                } else {
-                    char code;
-                    switch (keyCode) {
-                    case KeyEvent.KEYCODE_DPAD_UP:
-                        code = 'A';
-                        break;
-                    case KeyEvent.KEYCODE_DPAD_DOWN:
-                        code = 'B';
-                        break;
-                    case KeyEvent.KEYCODE_DPAD_LEFT:
-                        code = 'D';
-                        break;
-                    default:
-                    case KeyEvent.KEYCODE_DPAD_RIGHT:
-                        code = 'C';
-                        break;
-                    }
-                    mTermOut.write(27); // ESC
-                    if (mEmulatorView.getKeypadApplicationMode()) {
-                        mTermOut.write('O');
-                    } else {
-                        mTermOut.write('[');
-                    }
-                    mTermOut.write(code);
-                }
-            } catch (IOException e) {
-                // Ignore
-            }
-        }
-        return true;
-    }
-
-    private boolean isSystemKey(int keyCode, KeyEvent event) {
-        return event.isSystem();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.main, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        int id = item.getItemId();
-        if (id == R.id.menu_preferences) {
-            doPreferences();
-        } else if (id == R.id.menu_reset) {
-            doResetTerminal();
-        } else if (id == R.id.menu_send_email) {
-            doEmailTranscript();
-        } else if (id == R.id.menu_special_keys) {
-            doDocumentKeys();
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private void doPreferences() {
-        startActivity(new Intent(this, TermPreferences.class));
-    }
-
-    private void setColors() {
-        int[] scheme = COLOR_SCHEMES[mColorId];
-        mEmulatorView.setColors(scheme[0], scheme[1]);
-    }
-
-    private void doResetTerminal() {
-        restart();
-    }
-
-    private void doEmailTranscript() {
-        // Don't really want to supply an address, but
-        // currently it's required, otherwise we get an
-        // exception.
-        String addr = "user@example.com";
-        Intent intent =
-                new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"
-                        + addr));
-
-        intent.putExtra("body", mEmulatorView.getTranscriptText());
-        startActivity(intent);
-    }
-
-    private void doDocumentKeys() {
-        String controlKey = CONTROL_KEY_NAME[mControlKeyId];
-        new AlertDialog.Builder(this).
-            setTitle("Press " + controlKey + " and Key").
-            setMessage(controlKey + " Space ==> Control-@ (NUL)\n"
-                    + controlKey + " A..Z ==> Control-A..Z\n"
-                    + controlKey + " 1 ==> Control-[ (ESC)\n"
-                    + controlKey + " 5 ==> Control-_\n"
-                    + controlKey + " . ==> Control-\\\n"
-                    + controlKey + " 0 ==> Control-]\n"
-                    + controlKey + " 6 ==> Control-^").
-            show();
-     }
-}
-
-
-/**
- * An abstract screen interface. A terminal screen stores lines of text. (The
- * reason to abstract it is to allow different implementations, and to hide
- * implementation details from clients.)
- */
-interface Screen {
-
-    /**
-     * Set line wrap flag for a given row. Affects how lines are logically
-     * wrapped when changing screen size or converting to a transcript.
-     */
-    void setLineWrap(int row);
-
-    /**
-     * Store byte b into the screen at location (x, y)
-     *
-     * @param x X coordinate (also known as column)
-     * @param y Y coordinate (also known as row)
-     * @param b ASCII character to store
-     * @param foreColor the foreground color
-     * @param backColor the background color
-     */
-    void set(int x, int y, byte b, int foreColor, int backColor);
-
-    /**
-     * Scroll the screen down one line. To scroll the whole screen of a 24 line
-     * screen, the arguments would be (0, 24).
-     *
-     * @param topMargin First line that is scrolled.
-     * @param bottomMargin One line after the last line that is scrolled.
-     */
-    void scroll(int topMargin, int bottomMargin, int foreColor, int backColor);
-
-    /**
-     * Block copy characters from one position in the screen to another. The two
-     * positions can overlap. All characters of the source and destination must
-     * be within the bounds of the screen, or else an InvalidParemeterException
-     * will be thrown.
-     *
-     * @param sx source X coordinate
-     * @param sy source Y coordinate
-     * @param w width
-     * @param h height
-     * @param dx destination X coordinate
-     * @param dy destination Y coordinate
-     */
-    void blockCopy(int sx, int sy, int w, int h, int dx, int dy);
-
-    /**
-     * Block set characters. All characters must be within the bounds of the
-     * screen, or else and InvalidParemeterException will be thrown. Typically
-     * this is called with a "val" argument of 32 to clear a block of
-     * characters.
-     *
-     * @param sx source X
-     * @param sy source Y
-     * @param w width
-     * @param h height
-     * @param val value to set.
-     * @param foreColor the foreground color
-     * @param backColor the background color
-     */
-    void blockSet(int sx, int sy, int w, int h, int val, int foreColor, int
-            backColor);
-
-    /**
-     * Get the contents of the transcript buffer as a text string.
-     *
-     * @return the contents of the transcript buffer.
-     */
-    String getTranscriptText();
-
-    /**
-     * Resize the screen
-     * @param columns
-     * @param rows
-     */
-    void resize(int columns, int rows, int foreColor, int backColor);
-}
-
-
-/**
- * A TranscriptScreen is a screen that remembers data that's been scrolled. The
- * old data is stored in a ring buffer to minimize the amount of copying that
- * needs to be done. The transcript does its own drawing, to avoid having to
- * expose its internal data structures.
- */
-class TranscriptScreen implements Screen {
-
-    /**
-     * The width of the transcript, in characters. Fixed at initialization.
-     */
-    private int mColumns;
-
-    /**
-     * The total number of rows in the transcript and the screen. Fixed at
-     * initialization.
-     */
-    private int mTotalRows;
-
-    /**
-     * The number of rows in the active portion of the transcript. Doesn't
-     * include the screen.
-     */
-    private int mActiveTranscriptRows;
-
-    /**
-     * Which row is currently the topmost line of the transcript. Used to
-     * implement a circular buffer.
-     */
-    private int mHead;
-
-    /**
-     * The number of active rows, includes both the transcript and the screen.
-     */
-    private int mActiveRows;
-
-    /**
-     * The number of rows in the screen.
-     */
-    private int mScreenRows;
-
-    /**
-     * The data for both the screen and the transcript. The first mScreenRows *
-     * mLineWidth characters are the screen, the rest are the transcript.
-     * The low byte encodes the ASCII character, the high byte encodes the
-     * foreground and background colors, plus underline and bold.
-     */
-    private char[] mData;
-
-    /**
-     * The data's stored as color-encoded chars, but the drawing routines require chars, so we
-     * need a temporary buffer to hold a row's worth of characters.
-     */
-    private char[] mRowBuffer;
-
-    /**
-     * Flags that keep track of whether the current line logically wraps to the
-     * next line. This is used when resizing the screen and when copying to the
-     * clipboard or an email attachment
-     */
-
-    private boolean[] mLineWrap;
-
-    /**
-     * Create a transcript screen.
-     *
-     * @param columns the width of the screen in characters.
-     * @param totalRows the height of the entire text area, in rows of text.
-     * @param screenRows the height of just the screen, not including the
-     *        transcript that holds lines that have scrolled off the top of the
-     *        screen.
-     */
-    public TranscriptScreen(int columns, int totalRows, int screenRows,
-            int foreColor, int backColor) {
-        init(columns, totalRows, screenRows, foreColor, backColor);
-    }
-
-    private void init(int columns, int totalRows, int screenRows, int foreColor, int backColor) {
-        mColumns = columns;
-        mTotalRows = totalRows;
-        mActiveTranscriptRows = 0;
-        mHead = 0;
-        mActiveRows = screenRows;
-        mScreenRows = screenRows;
-        int totalSize = columns * totalRows;
-        mData = new char[totalSize];
-        blockSet(0, 0, mColumns, mScreenRows, ' ', foreColor, backColor);
-        mRowBuffer = new char[columns];
-        mLineWrap = new boolean[totalRows];
-        consistencyCheck();
-   }
-
-    /**
-     * Convert a row value from the public external coordinate system to our
-     * internal private coordinate system. External coordinate system:
-     * -mActiveTranscriptRows to mScreenRows-1, with the screen being
-     * 0..mScreenRows-1 Internal coordinate system: 0..mScreenRows-1 rows of
-     * mData are the visible rows. mScreenRows..mActiveRows - 1 are the
-     * transcript, stored as a circular buffer.
-     *
-     * @param row a row in the external coordinate system.
-     * @return The row corresponding to the input argument in the private
-     *         coordinate system.
-     */
-    private int externalToInternalRow(int row) {
-        if (row < -mActiveTranscriptRows || row >= mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-        if (row >= 0) {
-            return row; // This is a visible row.
-        }
-        return mScreenRows
-                + ((mHead + mActiveTranscriptRows + row) % mActiveTranscriptRows);
-    }
-
-    private int getOffset(int externalLine) {
-        return externalToInternalRow(externalLine) * mColumns;
-    }
-
-    private int getOffset(int x, int y) {
-        return getOffset(y) + x;
-    }
-
-    public void setLineWrap(int row) {
-        mLineWrap[externalToInternalRow(row)] = true;
-    }
-
-    /**
-     * Store byte b into the screen at location (x, y)
-     *
-     * @param x X coordinate (also known as column)
-     * @param y Y coordinate (also known as row)
-     * @param b ASCII character to store
-     * @param foreColor the foreground color
-     * @param backColor the background color
-     */
-    public void set(int x, int y, byte b, int foreColor, int backColor) {
-        mData[getOffset(x, y)] = encode(b, foreColor, backColor);
-    }
-
-    private char encode(int b, int foreColor, int backColor) {
-        return (char) ((foreColor << 12) | (backColor << 8) | b);
-    }
-
-    /**
-     * Scroll the screen down one line. To scroll the whole screen of a 24 line
-     * screen, the arguments would be (0, 24).
-     *
-     * @param topMargin First line that is scrolled.
-     * @param bottomMargin One line after the last line that is scrolled.
-     */
-    public void scroll(int topMargin, int bottomMargin, int foreColor,
-            int backColor) {
-        if (topMargin > bottomMargin - 2 || topMargin > mScreenRows - 2
-                || bottomMargin > mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-
-        // Adjust the transcript so that the last line of the transcript
-        // is ready to receive the newly scrolled data
-        consistencyCheck();
-        int expansionRows = Math.min(1, mTotalRows - mActiveRows);
-        int rollRows = 1 - expansionRows;
-        mActiveRows += expansionRows;
-        mActiveTranscriptRows += expansionRows;
-        if (mActiveTranscriptRows > 0) {
-            mHead = (mHead + rollRows) % mActiveTranscriptRows;
-        }
-        consistencyCheck();
-
-        // Block move the scroll line to the transcript
-        int topOffset = getOffset(topMargin);
-        int destOffset = getOffset(-1);
-        System.arraycopy(mData, topOffset, mData, destOffset, mColumns);
-
-        int topLine = externalToInternalRow(topMargin);
-        int destLine = externalToInternalRow(-1);
-        System.arraycopy(mLineWrap, topLine, mLineWrap, destLine, 1);
-
-        // Block move the scrolled data up
-        int numScrollChars = (bottomMargin - topMargin - 1) * mColumns;
-        System.arraycopy(mData, topOffset + mColumns, mData, topOffset,
-                numScrollChars);
-        int numScrollLines = (bottomMargin - topMargin - 1);
-        System.arraycopy(mLineWrap, topLine + 1, mLineWrap, topLine,
-                numScrollLines);
-
-        // Erase the bottom line of the scroll region
-        blockSet(0, bottomMargin - 1, mColumns, 1, ' ', foreColor, backColor);
-        mLineWrap[externalToInternalRow(bottomMargin-1)] = false;
-    }
-
-    private void consistencyCheck() {
-        checkPositive(mColumns);
-        checkPositive(mTotalRows);
-        checkRange(0, mActiveTranscriptRows, mTotalRows);
-        if (mActiveTranscriptRows == 0) {
-            checkEqual(mHead, 0);
-        } else {
-            checkRange(0, mHead, mActiveTranscriptRows-1);
-        }
-        checkEqual(mScreenRows + mActiveTranscriptRows, mActiveRows);
-        checkRange(0, mScreenRows, mTotalRows);
-
-        checkEqual(mTotalRows, mLineWrap.length);
-        checkEqual(mTotalRows*mColumns, mData.length);
-        checkEqual(mColumns, mRowBuffer.length);
-    }
-
-    private void checkPositive(int n) {
-        if (n < 0) {
-            throw new IllegalArgumentException("checkPositive " + n);
-        }
-    }
-
-    private void checkRange(int a, int b, int c) {
-        if (a > b || b > c) {
-            throw new IllegalArgumentException("checkRange " + a + " <= " + b + " <= " + c);
-        }
-    }
-
-    private void checkEqual(int a, int b) {
-        if (a != b) {
-            throw new IllegalArgumentException("checkEqual " + a + " == " + b);
-        }
-    }
-
-    /**
-     * Block copy characters from one position in the screen to another. The two
-     * positions can overlap. All characters of the source and destination must
-     * be within the bounds of the screen, or else an InvalidParemeterException
-     * will be thrown.
-     *
-     * @param sx source X coordinate
-     * @param sy source Y coordinate
-     * @param w width
-     * @param h height
-     * @param dx destination X coordinate
-     * @param dy destination Y coordinate
-     */
-    public void blockCopy(int sx, int sy, int w, int h, int dx, int dy) {
-        if (sx < 0 || sx + w > mColumns || sy < 0 || sy + h > mScreenRows
-                || dx < 0 || dx + w > mColumns || dy < 0
-                || dy + h > mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-        if (sy <= dy) {
-            // Move in increasing order
-            for (int y = 0; y < h; y++) {
-                int srcOffset = getOffset(sx, sy + y);
-                int dstOffset = getOffset(dx, dy + y);
-                System.arraycopy(mData, srcOffset, mData, dstOffset, w);
-            }
-        } else {
-            // Move in decreasing order
-            for (int y = 0; y < h; y++) {
-                int y2 = h - (y + 1);
-                int srcOffset = getOffset(sx, sy + y2);
-                int dstOffset = getOffset(dx, dy + y2);
-                System.arraycopy(mData, srcOffset, mData, dstOffset, w);
-            }
-        }
-    }
-
-    /**
-     * Block set characters. All characters must be within the bounds of the
-     * screen, or else and InvalidParemeterException will be thrown. Typically
-     * this is called with a "val" argument of 32 to clear a block of
-     * characters.
-     *
-     * @param sx source X
-     * @param sy source Y
-     * @param w width
-     * @param h height
-     * @param val value to set.
-     */
-    public void blockSet(int sx, int sy, int w, int h, int val,
-            int foreColor, int backColor) {
-        if (sx < 0 || sx + w > mColumns || sy < 0 || sy + h > mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-        char[] data = mData;
-        char encodedVal = encode(val, foreColor, backColor);
-        for (int y = 0; y < h; y++) {
-            int offset = getOffset(sx, sy + y);
-            for (int x = 0; x < w; x++) {
-                data[offset + x] = encodedVal;
-            }
-        }
-    }
-
-    /**
-     * Draw a row of text. Out-of-bounds rows are blank, not errors.
-     *
-     * @param row The row of text to draw.
-     * @param canvas The canvas to draw to.
-     * @param x The x coordinate origin of the drawing
-     * @param y The y coordinate origin of the drawing
-     * @param renderer The renderer to use to draw the text
-     * @param cx the cursor X coordinate, -1 means don't draw it
-     */
-    public final void drawText(int row, Canvas canvas, float x, float y,
-            TextRenderer renderer, int cx) {
-
-        // Out-of-bounds rows are blank.
-        if (row < -mActiveTranscriptRows || row >= mScreenRows) {
-            return;
-        }
-
-        // Copy the data from the byte array to a char array so they can
-        // be drawn.
-
-        int offset = getOffset(row);
-        char[] rowBuffer = mRowBuffer;
-        char[] data = mData;
-        int columns = mColumns;
-        int lastColors = 0;
-        int lastRunStart = -1;
-        final int CURSOR_MASK = 0x10000;
-        for (int i = 0; i < columns; i++) {
-            char c = data[offset + i];
-            int colors = (char) (c & 0xff00);
-            if (cx == i) {
-                // Set cursor background color:
-                colors |= CURSOR_MASK;
-            }
-            rowBuffer[i] = (char) (c & 0x00ff);
-            if (colors != lastColors) {
-                if (lastRunStart >= 0) {
-                    renderer.drawTextRun(canvas, x, y, lastRunStart, rowBuffer,
-                            lastRunStart, i - lastRunStart,
-                            (lastColors & CURSOR_MASK) != 0,
-                            0xf & (lastColors >> 12), 0xf & (lastColors >> 8));
-                }
-                lastColors = colors;
-                lastRunStart = i;
-            }
-        }
-        if (lastRunStart >= 0) {
-            renderer.drawTextRun(canvas, x, y, lastRunStart, rowBuffer,
-                    lastRunStart, columns - lastRunStart,
-                    (lastColors & CURSOR_MASK) != 0,
-                    0xf & (lastColors >> 12), 0xf & (lastColors >> 8));
-        }
-     }
-
-    /**
-     * Get the count of active rows.
-     *
-     * @return the count of active rows.
-     */
-    public int getActiveRows() {
-        return mActiveRows;
-    }
-
-    /**
-     * Get the count of active transcript rows.
-     *
-     * @return the count of active transcript rows.
-     */
-    public int getActiveTranscriptRows() {
-        return mActiveTranscriptRows;
-    }
-
-    public String getTranscriptText() {
-        return internalGetTranscriptText(true);
-    }
-
-    private String internalGetTranscriptText(boolean stripColors) {
-        StringBuilder builder = new StringBuilder();
-        char[] rowBuffer = mRowBuffer;
-        char[] data = mData;
-        int columns = mColumns;
-        for (int row = -mActiveTranscriptRows; row < mScreenRows; row++) {
-            int offset = getOffset(row);
-            int lastPrintingChar = -1;
-            for (int column = 0; column < columns; column++) {
-                char c = data[offset + column];
-                if (stripColors) {
-                    c = (char) (c & 0xff);
-                }
-                if ((c & 0xff) != ' ') {
-                    lastPrintingChar = column;
-                }
-                rowBuffer[column] = c;
-            }
-            if (mLineWrap[externalToInternalRow(row)]) {
-                builder.append(rowBuffer, 0, columns);
-            } else {
-                builder.append(rowBuffer, 0, lastPrintingChar + 1);
-                builder.append('\n');
-            }
-        }
-        return builder.toString();
-    }
-
-    public void resize(int columns, int rows, int foreColor, int backColor) {
-        init(columns, mTotalRows, rows, foreColor, backColor);
-    }
-}
-
-/**
- * Renders text into a screen. Contains all the terminal-specific knowlege and
- * state. Emulates a subset of the X Window System xterm terminal, which in turn
- * is an emulator for a subset of the Digital Equipment Corporation vt100
- * terminal. Missing functionality: text attributes (bold, underline, reverse
- * video, color) alternate screen cursor key and keypad escape sequences.
- */
-class TerminalEmulator {
-
-    /**
-     * The cursor row. Numbered 0..mRows-1.
-     */
-    private int mCursorRow;
-
-    /**
-     * The cursor column. Numbered 0..mColumns-1.
-     */
-    private int mCursorCol;
-
-    /**
-     * The number of character rows in the terminal screen.
-     */
-    private int mRows;
-
-    /**
-     * The number of character columns in the terminal screen.
-     */
-    private int mColumns;
-
-    /**
-     * Used to send data to the remote process. Needed to implement the various
-     * "report" escape sequences.
-     */
-    private FileOutputStream mTermOut;
-
-    /**
-     * Stores the characters that appear on the screen of the emulated terminal.
-     */
-    private Screen mScreen;
-
-    /**
-     * Keeps track of the current argument of the current escape sequence.
-     * Ranges from 0 to MAX_ESCAPE_PARAMETERS-1. (Typically just 0 or 1.)
-     */
-    private int mArgIndex;
-
-    /**
-     * The number of parameter arguments. This name comes from the ANSI standard
-     * for terminal escape codes.
-     */
-    private static final int MAX_ESCAPE_PARAMETERS = 16;
-
-    /**
-     * Holds the arguments of the current escape sequence.
-     */
-    private int[] mArgs = new int[MAX_ESCAPE_PARAMETERS];
-
-    // Escape processing states:
-
-    /**
-     * Escape processing state: Not currently in an escape sequence.
-     */
-    private static final int ESC_NONE = 0;
-
-    /**
-     * Escape processing state: Have seen an ESC character
-     */
-    private static final int ESC = 1;
-
-    /**
-     * Escape processing state: Have seen ESC POUND
-     */
-    private static final int ESC_POUND = 2;
-
-    /**
-     * Escape processing state: Have seen ESC and a character-set-select char
-     */
-    private static final int ESC_SELECT_LEFT_PAREN = 3;
-
-    /**
-     * Escape processing state: Have seen ESC and a character-set-select char
-     */
-    private static final int ESC_SELECT_RIGHT_PAREN = 4;
-
-    /**
-     * Escape processing state: ESC [
-     */
-    private static final int ESC_LEFT_SQUARE_BRACKET = 5;
-
-    /**
-     * Escape processing state: ESC [ ?
-     */
-    private static final int ESC_LEFT_SQUARE_BRACKET_QUESTION_MARK = 6;
-
-    /**
-     * True if the current escape sequence should continue, false if the current
-     * escape sequence should be terminated. Used when parsing a single
-     * character.
-     */
-    private boolean mContinueSequence;
-
-    /**
-     * The current state of the escape sequence state machine.
-     */
-    private int mEscapeState;
-
-    /**
-     * Saved state of the cursor row, Used to implement the save/restore cursor
-     * position escape sequences.
-     */
-    private int mSavedCursorRow;
-
-    /**
-     * Saved state of the cursor column, Used to implement the save/restore
-     * cursor position escape sequences.
-     */
-    private int mSavedCursorCol;
-
-    // DecSet booleans
-
-    /**
-     * This mask indicates 132-column mode is set. (As opposed to 80-column
-     * mode.)
-     */
-    private static final int K_132_COLUMN_MODE_MASK = 1 << 3;
-
-    /**
-     * This mask indicates that origin mode is set. (Cursor addressing is
-     * relative to the absolute screen size, rather than the currently set top
-     * and bottom margins.)
-     */
-    private static final int K_ORIGIN_MODE_MASK = 1 << 6;
-
-    /**
-     * This mask indicates that wraparound mode is set. (As opposed to
-     * stop-at-right-column mode.)
-     */
-    private static final int K_WRAPAROUND_MODE_MASK = 1 << 7;
-
-    /**
-     * Holds multiple DECSET flags. The data is stored this way, rather than in
-     * separate booleans, to make it easier to implement the save-and-restore
-     * semantics. The various k*ModeMask masks can be used to extract and modify
-     * the individual flags current states.
-     */
-    private int mDecFlags;
-
-    /**
-     * Saves away a snapshot of the DECSET flags. Used to implement save and
-     * restore escape sequences.
-     */
-    private int mSavedDecFlags;
-
-    // Modes set with Set Mode / Reset Mode
-
-    /**
-     * True if insert mode (as opposed to replace mode) is active. In insert
-     * mode new characters are inserted, pushing existing text to the right.
-     */
-    private boolean mInsertMode;
-
-    /**
-     * Automatic newline mode. Configures whether pressing return on the
-     * keyboard automatically generates a return as well. Not currently
-     * implemented.
-     */
-    private boolean mAutomaticNewlineMode;
-
-    /**
-     * An array of tab stops. mTabStop[i] is true if there is a tab stop set for
-     * column i.
-     */
-    private boolean[] mTabStop;
-
-    // The margins allow portions of the screen to be locked.
-
-    /**
-     * The top margin of the screen, for scrolling purposes. Ranges from 0 to
-     * mRows-2.
-     */
-    private int mTopMargin;
-
-    /**
-     * The bottom margin of the screen, for scrolling purposes. Ranges from
-     * mTopMargin + 2 to mRows. (Defines the first row after the scrolling
-     * region.
-     */
-    private int mBottomMargin;
-
-    /**
-     * True if the next character to be emitted will be automatically wrapped to
-     * the next line. Used to disambiguate the case where the cursor is
-     * positioned on column mColumns-1.
-     */
-    private boolean mAboutToAutoWrap;
-
-    /**
-     * Used for debugging, counts how many chars have been processed.
-     */
-    private int mProcessedCharCount;
-
-    /**
-     * Foreground color, 0..7, mask with 8 for bold
-     */
-    private int mForeColor;
-
-    /**
-     * Background color, 0..7, mask with 8 for underline
-     */
-    private int mBackColor;
-
-    private boolean mInverseColors;
-
-    private boolean mbKeypadApplicationMode;
-
-    private boolean mAlternateCharSet;
-
-    /**
-     * Construct a terminal emulator that uses the supplied screen
-     *
-     * @param screen the screen to render characters into.
-     * @param columns the number of columns to emulate
-     * @param rows the number of rows to emulate
-     * @param termOut the output file descriptor that talks to the pseudo-tty.
-     */
-    public TerminalEmulator(Screen screen, int columns, int rows,
-            FileOutputStream termOut) {
-        mScreen = screen;
-        mRows = rows;
-        mColumns = columns;
-        mTabStop = new boolean[mColumns];
-        mTermOut = termOut;
-        reset();
-    }
-
-    public void updateSize(int columns, int rows) {
-        if (mRows == rows && mColumns == columns) {
-            return;
-        }
-        String transcriptText = mScreen.getTranscriptText();
-
-        mScreen.resize(columns, rows, mForeColor, mBackColor);
-
-        if (mRows != rows) {
-            mRows = rows;
-            mTopMargin = 0;
-            mBottomMargin = mRows;
-        }
-        if (mColumns != columns) {
-            int oldColumns = mColumns;
-            mColumns = columns;
-            boolean[] oldTabStop = mTabStop;
-            mTabStop = new boolean[mColumns];
-            int toTransfer = Math.min(oldColumns, columns);
-            System.arraycopy(oldTabStop, 0, mTabStop, 0, toTransfer);
-            while (mCursorCol >= columns) {
-                mCursorCol -= columns;
-                mCursorRow = Math.min(mBottomMargin-1, mCursorRow + 1);
-            }
-        }
-        mCursorRow = 0;
-        mCursorCol = 0;
-        mAboutToAutoWrap = false;
-
-        int end = transcriptText.length()-1;
-        while ((end >= 0) && transcriptText.charAt(end) == '\n') {
-            end--;
-        }
-        for(int i = 0; i <= end; i++) {
-            byte c = (byte) transcriptText.charAt(i);
-            if (c == '\n') {
-                setCursorCol(0);
-                doLinefeed();
-            } else {
-                emit(c);
-            }
-        }
-    }
-
-    /**
-     * Get the cursor's current row.
-     *
-     * @return the cursor's current row.
-     */
-    public final int getCursorRow() {
-        return mCursorRow;
-    }
-
-    /**
-     * Get the cursor's current column.
-     *
-     * @return the cursor's current column.
-     */
-    public final int getCursorCol() {
-        return mCursorCol;
-    }
-
-    public final boolean getKeypadApplicationMode() {
-        return mbKeypadApplicationMode;
-    }
-
-    private void setDefaultTabStops() {
-        for (int i = 0; i < mColumns; i++) {
-            mTabStop[i] = (i & 7) == 0 && i != 0;
-        }
-    }
-
-    /**
-     * Accept bytes (typically from the pseudo-teletype) and process them.
-     *
-     * @param buffer a byte array containing the bytes to be processed
-     * @param base the first index of the array to process
-     * @param length the number of bytes in the array to process
-     */
-    public void append(byte[] buffer, int base, int length) {
-        for (int i = 0; i < length; i++) {
-            byte b = buffer[base + i];
-            try {
-                if (Term.LOG_CHARACTERS_FLAG) {
-                    char printableB = (char) b;
-                    if (b < 32 || b > 126) {
-                        printableB = ' ';
-                    }
-                    Log.w(Term.LOG_TAG, "'" + Character.toString(printableB)
-                            + "' (" + Integer.toString(b) + ")");
-                }
-                process(b);
-                mProcessedCharCount++;
-            } catch (Exception e) {
-                Log.e(Term.LOG_TAG, "Exception while processing character "
-                        + Integer.toString(mProcessedCharCount) + " code "
-                        + Integer.toString(b), e);
-            }
-        }
-    }
-
-    private void process(byte b) {
-        switch (b) {
-        case 0: // NUL
-            // Do nothing
-            break;
-
-        case 7: // BEL
-            // Do nothing
-            break;
-
-        case 8: // BS
-            setCursorCol(Math.max(0, mCursorCol - 1));
-            break;
-
-        case 9: // HT
-            // Move to next tab stop, but not past edge of screen
-            setCursorCol(nextTabStop(mCursorCol));
-            break;
-
-        case 13:
-            setCursorCol(0);
-            break;
-
-        case 10: // CR
-        case 11: // VT
-        case 12: // LF
-            doLinefeed();
-            break;
-
-        case 14: // SO:
-            setAltCharSet(true);
-            break;
-
-        case 15: // SI:
-            setAltCharSet(false);
-            break;
-
-
-        case 24: // CAN
-        case 26: // SUB
-            if (mEscapeState != ESC_NONE) {
-                mEscapeState = ESC_NONE;
-                emit((byte) 127);
-            }
-            break;
-
-        case 27: // ESC
-            // Always starts an escape sequence
-            startEscapeSequence(ESC);
-            break;
-
-        case (byte) 0x9b: // CSI
-            startEscapeSequence(ESC_LEFT_SQUARE_BRACKET);
-            break;
-
-        default:
-            mContinueSequence = false;
-            switch (mEscapeState) {
-            case ESC_NONE:
-                if (b >= 32) {
-                    emit(b);
-                }
-                break;
-
-            case ESC:
-                doEsc(b);
-                break;
-
-            case ESC_POUND:
-                doEscPound(b);
-                break;
-
-            case ESC_SELECT_LEFT_PAREN:
-                doEscSelectLeftParen(b);
-                break;
-
-            case ESC_SELECT_RIGHT_PAREN:
-                doEscSelectRightParen(b);
-                break;
-
-            case ESC_LEFT_SQUARE_BRACKET:
-                doEscLeftSquareBracket(b);
-                break;
-
-            case ESC_LEFT_SQUARE_BRACKET_QUESTION_MARK:
-                doEscLSBQuest(b);
-                break;
-
-            default:
-                unknownSequence(b);
-                break;
-            }
-            if (!mContinueSequence) {
-                mEscapeState = ESC_NONE;
-            }
-            break;
-        }
-    }
-
-    private void setAltCharSet(boolean alternateCharSet) {
-        mAlternateCharSet = alternateCharSet;
-    }
-
-    private int nextTabStop(int cursorCol) {
-        for (int i = cursorCol; i < mColumns; i++) {
-            if (mTabStop[i]) {
-                return i;
-            }
-        }
-        return mColumns - 1;
-    }
-
-    private void doEscLSBQuest(byte b) {
-        int mask = getDecFlagsMask(getArg0(0));
-        switch (b) {
-        case 'h': // Esc [ ? Pn h - DECSET
-            mDecFlags |= mask;
-            break;
-
-        case 'l': // Esc [ ? Pn l - DECRST
-            mDecFlags &= ~mask;
-            break;
-
-        case 'r': // Esc [ ? Pn r - restore
-            mDecFlags = (mDecFlags & ~mask) | (mSavedDecFlags & mask);
-            break;
-
-        case 's': // Esc [ ? Pn s - save
-            mSavedDecFlags = (mSavedDecFlags & ~mask) | (mDecFlags & mask);
-            break;
-
-        default:
-            parseArg(b);
-            break;
-        }
-
-        // 132 column mode
-        if ((mask & K_132_COLUMN_MODE_MASK) != 0) {
-            // We don't actually set 132 cols, but we do want the
-            // side effect of clearing the screen and homing the cursor.
-            blockClear(0, 0, mColumns, mRows);
-            setCursorRowCol(0, 0);
-        }
-
-        // origin mode
-        if ((mask & K_ORIGIN_MODE_MASK) != 0) {
-            // Home the cursor.
-            setCursorPosition(0, 0);
-        }
-    }
-
-    private int getDecFlagsMask(int argument) {
-        if (argument >= 1 && argument <= 9) {
-            return (1 << argument);
-        }
-
-        return 0;
-    }
-
-    private void startEscapeSequence(int escapeState) {
-        mEscapeState = escapeState;
-        mArgIndex = 0;
-        for (int j = 0; j < MAX_ESCAPE_PARAMETERS; j++) {
-            mArgs[j] = -1;
-        }
-    }
-
-    private void doLinefeed() {
-        int newCursorRow = mCursorRow + 1;
-        if (newCursorRow >= mBottomMargin) {
-            scroll();
-            newCursorRow = mBottomMargin - 1;
-        }
-        setCursorRow(newCursorRow);
-    }
-
-    private void continueSequence() {
-        mContinueSequence = true;
-    }
-
-    private void continueSequence(int state) {
-        mEscapeState = state;
-        mContinueSequence = true;
-    }
-
-    private void doEscSelectLeftParen(byte b) {
-        doSelectCharSet(true, b);
-    }
-
-    private void doEscSelectRightParen(byte b) {
-        doSelectCharSet(false, b);
-    }
-
-    private void doSelectCharSet(boolean isG0CharSet, byte b) {
-        switch (b) {
-        case 'A': // United Kingdom character set
-            break;
-        case 'B': // ASCII set
-            break;
-        case '0': // Special Graphics
-            break;
-        case '1': // Alternate character set
-            break;
-        case '2':
-            break;
-        default:
-            unknownSequence(b);
-        }
-    }
-
-    private void doEscPound(byte b) {
-        switch (b) {
-        case '8': // Esc # 8 - DECALN alignment test
-            mScreen.blockSet(0, 0, mColumns, mRows, 'E',
-                    getForeColor(), getBackColor());
-            break;
-
-        default:
-            unknownSequence(b);
-            break;
-        }
-    }
-
-    private void doEsc(byte b) {
-        switch (b) {
-        case '#':
-            continueSequence(ESC_POUND);
-            break;
-
-        case '(':
-            continueSequence(ESC_SELECT_LEFT_PAREN);
-            break;
-
-        case ')':
-            continueSequence(ESC_SELECT_RIGHT_PAREN);
-            break;
-
-        case '7': // DECSC save cursor
-            mSavedCursorRow = mCursorRow;
-            mSavedCursorCol = mCursorCol;
-            break;
-
-        case '8': // DECRC restore cursor
-            setCursorRowCol(mSavedCursorRow, mSavedCursorCol);
-            break;
-
-        case 'D': // INDEX
-            doLinefeed();
-            break;
-
-        case 'E': // NEL
-            setCursorCol(0);
-            doLinefeed();
-            break;
-
-        case 'F': // Cursor to lower-left corner of screen
-            setCursorRowCol(0, mBottomMargin - 1);
-            break;
-
-        case 'H': // Tab set
-            mTabStop[mCursorCol] = true;
-            break;
-
-        case 'M': // Reverse index
-            if (mCursorRow == 0) {
-                mScreen.blockCopy(0, mTopMargin + 1, mColumns, mBottomMargin
-                        - (mTopMargin + 1), 0, mTopMargin);
-                blockClear(0, mBottomMargin - 1, mColumns);
-            } else {
-                mCursorRow--;
-            }
-
-            break;
-
-        case 'N': // SS2
-            unimplementedSequence(b);
-            break;
-
-        case '0': // SS3
-            unimplementedSequence(b);
-            break;
-
-        case 'P': // Device control string
-            unimplementedSequence(b);
-            break;
-
-        case 'Z': // return terminal ID
-            sendDeviceAttributes();
-            break;
-
-        case '[':
-            continueSequence(ESC_LEFT_SQUARE_BRACKET);
-            break;
-
-        case '=': // DECKPAM
-            mbKeypadApplicationMode = true;
-            break;
-
-        case '>' : // DECKPNM
-            mbKeypadApplicationMode = false;
-            break;
-
-        default:
-            unknownSequence(b);
-            break;
-        }
-    }
-
-    private void doEscLeftSquareBracket(byte b) {
-        switch (b) {
-        case '@': // ESC [ Pn @ - ICH Insert Characters
-        {
-            int charsAfterCursor = mColumns - mCursorCol;
-            int charsToInsert = Math.min(getArg0(1), charsAfterCursor);
-            int charsToMove = charsAfterCursor - charsToInsert;
-            mScreen.blockCopy(mCursorCol, mCursorRow, charsToMove, 1,
-                    mCursorCol + charsToInsert, mCursorRow);
-            blockClear(mCursorCol, mCursorRow, charsToInsert);
-        }
-            break;
-
-        case 'A': // ESC [ Pn A - Cursor Up
-            setCursorRow(Math.max(mTopMargin, mCursorRow - getArg0(1)));
-            break;
-
-        case 'B': // ESC [ Pn B - Cursor Down
-            setCursorRow(Math.min(mBottomMargin - 1, mCursorRow + getArg0(1)));
-            break;
-
-        case 'C': // ESC [ Pn C - Cursor Right
-            setCursorCol(Math.min(mColumns - 1, mCursorCol + getArg0(1)));
-            break;
-
-        case 'D': // ESC [ Pn D - Cursor Left
-            setCursorCol(Math.max(0, mCursorCol - getArg0(1)));
-            break;
-
-        case 'G': // ESC [ Pn G - Cursor Horizontal Absolute
-            setCursorCol(Math.min(Math.max(1, getArg0(1)), mColumns) - 1);
-            break;
-
-        case 'H': // ESC [ Pn ; H - Cursor Position
-            setHorizontalVerticalPosition();
-            break;
-
-        case 'J': // ESC [ Pn J - Erase in Display
-            switch (getArg0(0)) {
-            case 0: // Clear below
-                blockClear(mCursorCol, mCursorRow, mColumns - mCursorCol);
-                blockClear(0, mCursorRow + 1, mColumns,
-                        mBottomMargin - (mCursorRow + 1));
-                break;
-
-            case 1: // Erase from the start of the screen to the cursor.
-                blockClear(0, mTopMargin, mColumns, mCursorRow - mTopMargin);
-                blockClear(0, mCursorRow, mCursorCol + 1);
-                break;
-
-            case 2: // Clear all
-                blockClear(0, mTopMargin, mColumns, mBottomMargin - mTopMargin);
-                break;
-
-            default:
-                unknownSequence(b);
-                break;
-            }
-            break;
-
-        case 'K': // ESC [ Pn K - Erase in Line
-            switch (getArg0(0)) {
-            case 0: // Clear to right
-                blockClear(mCursorCol, mCursorRow, mColumns - mCursorCol);
-                break;
-
-            case 1: // Erase start of line to cursor (including cursor)
-                blockClear(0, mCursorRow, mCursorCol + 1);
-                break;
-
-            case 2: // Clear whole line
-                blockClear(0, mCursorRow, mColumns);
-                break;
-
-            default:
-                unknownSequence(b);
-                break;
-            }
-            break;
-
-        case 'L': // Insert Lines
-        {
-            int linesAfterCursor = mBottomMargin - mCursorRow;
-            int linesToInsert = Math.min(getArg0(1), linesAfterCursor);
-            int linesToMove = linesAfterCursor - linesToInsert;
-            mScreen.blockCopy(0, mCursorRow, mColumns, linesToMove, 0,
-                    mCursorRow + linesToInsert);
-            blockClear(0, mCursorRow, mColumns, linesToInsert);
-        }
-            break;
-
-        case 'M': // Delete Lines
-        {
-            int linesAfterCursor = mBottomMargin - mCursorRow;
-            int linesToDelete = Math.min(getArg0(1), linesAfterCursor);
-            int linesToMove = linesAfterCursor - linesToDelete;
-            mScreen.blockCopy(0, mCursorRow + linesToDelete, mColumns,
-                    linesToMove, 0, mCursorRow);
-            blockClear(0, mCursorRow + linesToMove, mColumns, linesToDelete);
-        }
-            break;
-
-        case 'P': // Delete Characters
-        {
-            int charsAfterCursor = mColumns - mCursorCol;
-            int charsToDelete = Math.min(getArg0(1), charsAfterCursor);
-            int charsToMove = charsAfterCursor - charsToDelete;
-            mScreen.blockCopy(mCursorCol + charsToDelete, mCursorRow,
-                    charsToMove, 1, mCursorCol, mCursorRow);
-            blockClear(mCursorCol + charsToMove, mCursorRow, charsToDelete);
-        }
-            break;
-
-        case 'T': // Mouse tracking
-            unimplementedSequence(b);
-            break;
-
-        case '?': // Esc [ ? -- start of a private mode set
-            continueSequence(ESC_LEFT_SQUARE_BRACKET_QUESTION_MARK);
-            break;
-
-        case 'c': // Send device attributes
-            sendDeviceAttributes();
-            break;
-
-        case 'd': // ESC [ Pn d - Vert Position Absolute
-            setCursorRow(Math.min(Math.max(1, getArg0(1)), mRows) - 1);
-            break;
-
-        case 'f': // Horizontal and Vertical Position
-            setHorizontalVerticalPosition();
-            break;
-
-        case 'g': // Clear tab stop
-            switch (getArg0(0)) {
-            case 0:
-                mTabStop[mCursorCol] = false;
-                break;
-
-            case 3:
-                for (int i = 0; i < mColumns; i++) {
-                    mTabStop[i] = false;
-                }
-                break;
-
-            default:
-                // Specified to have no effect.
-                break;
-            }
-            break;
-
-        case 'h': // Set Mode
-            doSetMode(true);
-            break;
-
-        case 'l': // Reset Mode
-            doSetMode(false);
-            break;
-
-        case 'm': // Esc [ Pn m - character attributes.
-            selectGraphicRendition();
-            break;
-
-        case 'r': // Esc [ Pn ; Pn r - set top and bottom margins
-        {
-            // The top margin defaults to 1, the bottom margin
-            // (unusually for arguments) defaults to mRows.
-            //
-            // The escape sequence numbers top 1..23, but we
-            // number top 0..22.
-            // The escape sequence numbers bottom 2..24, and
-            // so do we (because we use a zero based numbering
-            // scheme, but we store the first line below the
-            // bottom-most scrolling line.
-            // As a result, we adjust the top line by -1, but
-            // we leave the bottom line alone.
-            //
-            // Also require that top + 2 <= bottom
-
-            int top = Math.max(0, Math.min(getArg0(1) - 1, mRows - 2));
-            int bottom = Math.max(top + 2, Math.min(getArg1(mRows), mRows));
-            mTopMargin = top;
-            mBottomMargin = bottom;
-
-            // The cursor is placed in the home position
-            setCursorRowCol(mTopMargin, 0);
-        }
-            break;
-
-        default:
-            parseArg(b);
-            break;
-        }
-    }
-
-    private void selectGraphicRendition() {
-        for (int i = 0; i <= mArgIndex; i++) {
-            int code = mArgs[i];
-            if ( code < 0) {
-                if (mArgIndex > 0) {
-                    continue;
-                } else {
-                    code = 0;
-                }
-            }
-            if (code == 0) { // reset
-                mInverseColors = false;
-                mForeColor = 7;
-                mBackColor = 0;
-            } else if (code == 1) { // bold
-                mForeColor |= 0x8;
-            } else if (code == 4) { // underscore
-                mBackColor |= 0x8;
-            } else if (code == 7) { // inverse
-                mInverseColors = true;
-            } else if (code >= 30 && code <= 37) { // foreground color
-                mForeColor = (mForeColor & 0x8) | (code - 30);
-            } else if (code >= 40 && code <= 47) { // background color
-                mBackColor = (mBackColor & 0x8) | (code - 40);
-            } else {
-                if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-                    Log.w(Term.LOG_TAG, String.format("SGR unknown code %d", code));
-                }
-            }
-        }
-    }
-
-    private void blockClear(int sx, int sy, int w) {
-        blockClear(sx, sy, w, 1);
-    }
-
-    private void blockClear(int sx, int sy, int w, int h) {
-        mScreen.blockSet(sx, sy, w, h, ' ', getForeColor(), getBackColor());
-    }
-
-    private int getForeColor() {
-        return mInverseColors ?
-                ((mBackColor & 0x7) | (mForeColor & 0x8)) : mForeColor;
-    }
-
-    private int getBackColor() {
-        return mInverseColors ?
-                ((mForeColor & 0x7) | (mBackColor & 0x8)) : mBackColor;
-    }
-
-    private void doSetMode(boolean newValue) {
-        int modeBit = getArg0(0);
-        switch (modeBit) {
-        case 4:
-            mInsertMode = newValue;
-            break;
-
-        case 20:
-            mAutomaticNewlineMode = newValue;
-            break;
-
-        default:
-            unknownParameter(modeBit);
-            break;
-        }
-    }
-
-    private void setHorizontalVerticalPosition() {
-
-        // Parameters are Row ; Column
-
-        setCursorPosition(getArg1(1) - 1, getArg0(1) - 1);
-    }
-
-    private void setCursorPosition(int x, int y) {
-        int effectiveTopMargin = 0;
-        int effectiveBottomMargin = mRows;
-        if ((mDecFlags & K_ORIGIN_MODE_MASK) != 0) {
-            effectiveTopMargin = mTopMargin;
-            effectiveBottomMargin = mBottomMargin;
-        }
-        int newRow =
-                Math.max(effectiveTopMargin, Math.min(effectiveTopMargin + y,
-                        effectiveBottomMargin - 1));
-        int newCol = Math.max(0, Math.min(x, mColumns - 1));
-        setCursorRowCol(newRow, newCol);
-    }
-
-    private void sendDeviceAttributes() {
-        // This identifies us as a DEC vt100 with advanced
-        // video options. This is what the xterm terminal
-        // emulator sends.
-        byte[] attributes =
-                {
-                /* VT100 */
-                 (byte) 27, (byte) '[', (byte) '?', (byte) '1',
-                 (byte) ';', (byte) '2', (byte) 'c'
-
-                /* VT220
-                (byte) 27, (byte) '[', (byte) '?', (byte) '6',
-                (byte) '0',  (byte) ';',
-                (byte) '1',  (byte) ';',
-                (byte) '2',  (byte) ';',
-                (byte) '6',  (byte) ';',
-                (byte) '8',  (byte) ';',
-                (byte) '9',  (byte) ';',
-                (byte) '1',  (byte) '5', (byte) ';',
-                (byte) 'c'
-                */
-                };
-
-        write(attributes);
-    }
-
-    /**
-     * Send data to the shell process
-     * @param data
-     */
-    private void write(byte[] data) {
-        try {
-            mTermOut.write(data);
-            mTermOut.flush();
-        } catch (IOException e) {
-            // Ignore exception
-            // We don't really care if the receiver isn't listening.
-            // We just make a best effort to answer the query.
-        }
-    }
-
-    private void scroll() {
-        mScreen.scroll(mTopMargin, mBottomMargin,
-                getForeColor(), getBackColor());
-    }
-
-    /**
-     * Process the next ASCII character of a parameter.
-     *
-     * @param b The next ASCII character of the paramater sequence.
-     */
-    private void parseArg(byte b) {
-        if (b >= '0' && b <= '9') {
-            if (mArgIndex < mArgs.length) {
-                int oldValue = mArgs[mArgIndex];
-                int thisDigit = b - '0';
-                int value;
-                if (oldValue >= 0) {
-                    value = oldValue * 10 + thisDigit;
-                } else {
-                    value = thisDigit;
-                }
-                mArgs[mArgIndex] = value;
-            }
-            continueSequence();
-        } else if (b == ';') {
-            if (mArgIndex < mArgs.length) {
-                mArgIndex++;
-            }
-            continueSequence();
-        } else {
-            unknownSequence(b);
-        }
-    }
-
-    private int getArg0(int defaultValue) {
-        return getArg(0, defaultValue);
-    }
-
-    private int getArg1(int defaultValue) {
-        return getArg(1, defaultValue);
-    }
-
-    private int getArg(int index, int defaultValue) {
-        int result = mArgs[index];
-        if (result < 0) {
-            result = defaultValue;
-        }
-        return result;
-    }
-
-    private void unimplementedSequence(byte b) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            logError("unimplemented", b);
-        }
-        finishSequence();
-    }
-
-    private void unknownSequence(byte b) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            logError("unknown", b);
-        }
-        finishSequence();
-    }
-
-    private void unknownParameter(int parameter) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            StringBuilder buf = new StringBuilder();
-            buf.append("Unknown parameter");
-            buf.append(parameter);
-            logError(buf.toString());
-        }
-    }
-
-    private void logError(String errorType, byte b) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            StringBuilder buf = new StringBuilder();
-            buf.append(errorType);
-            buf.append(" sequence ");
-            buf.append(" EscapeState: ");
-            buf.append(mEscapeState);
-            buf.append(" char: '");
-            buf.append((char) b);
-            buf.append("' (");
-            buf.append(b);
-            buf.append(")");
-            boolean firstArg = true;
-            for (int i = 0; i <= mArgIndex; i++) {
-                int value = mArgs[i];
-                if (value >= 0) {
-                    if (firstArg) {
-                        firstArg = false;
-                        buf.append("args = ");
-                    }
-                    buf.append(String.format("%d; ", value));
-                }
-            }
-            logError(buf.toString());
-        }
-    }
-
-    private void logError(String error) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            Log.e(Term.LOG_TAG, error);
-        }
-        finishSequence();
-    }
-
-    private void finishSequence() {
-        mEscapeState = ESC_NONE;
-    }
-
-    private boolean autoWrapEnabled() {
-        // Always enable auto wrap, because it's useful on a small screen
-        return true;
-        // return (mDecFlags & K_WRAPAROUND_MODE_MASK) != 0;
-    }
-
-    /**
-     * Send an ASCII character to the screen.
-     *
-     * @param b the ASCII character to display.
-     */
-    private void emit(byte b) {
-        boolean autoWrap = autoWrapEnabled();
-
-        if (autoWrap) {
-            if (mCursorCol == mColumns - 1 && mAboutToAutoWrap) {
-                mScreen.setLineWrap(mCursorRow);
-                mCursorCol = 0;
-                if (mCursorRow + 1 < mBottomMargin) {
-                    mCursorRow++;
-                } else {
-                    scroll();
-                }
-            }
-        }
-
-        if (mInsertMode) { // Move character to right one space
-            int destCol = mCursorCol + 1;
-            if (destCol < mColumns) {
-                mScreen.blockCopy(mCursorCol, mCursorRow, mColumns - destCol,
-                        1, destCol, mCursorRow);
-            }
-        }
-
-        mScreen.set(mCursorCol, mCursorRow, b, getForeColor(), getBackColor());
-
-        if (autoWrap) {
-            mAboutToAutoWrap = (mCursorCol == mColumns - 1);
-        }
-
-        mCursorCol = Math.min(mCursorCol + 1, mColumns - 1);
-    }
-
-    private void setCursorRow(int row) {
-        mCursorRow = row;
-        mAboutToAutoWrap = false;
-    }
-
-    private void setCursorCol(int col) {
-        mCursorCol = col;
-        mAboutToAutoWrap = false;
-    }
-
-    private void setCursorRowCol(int row, int col) {
-        mCursorRow = Math.min(row, mRows-1);
-        mCursorCol = Math.min(col, mColumns-1);
-        mAboutToAutoWrap = false;
-    }
-
-    /**
-     * Reset the terminal emulator to its initial state.
-     */
-    public void reset() {
-        mCursorRow = 0;
-        mCursorCol = 0;
-        mArgIndex = 0;
-        mContinueSequence = false;
-        mEscapeState = ESC_NONE;
-        mSavedCursorRow = 0;
-        mSavedCursorCol = 0;
-        mDecFlags = 0;
-        mSavedDecFlags = 0;
-        mInsertMode = false;
-        mAutomaticNewlineMode = false;
-        mTopMargin = 0;
-        mBottomMargin = mRows;
-        mAboutToAutoWrap = false;
-        mForeColor = 7;
-        mBackColor = 0;
-        mInverseColors = false;
-        mbKeypadApplicationMode = false;
-        mAlternateCharSet = false;
-        // mProcessedCharCount is preserved unchanged.
-        setDefaultTabStops();
-        blockClear(0, 0, mColumns, mRows);
-    }
-
-    public String getTranscriptText() {
-        return mScreen.getTranscriptText();
-    }
-}
-
-/**
- * Text renderer interface
- */
-
-interface TextRenderer {
-    int getCharacterWidth();
-    int getCharacterHeight();
-    void drawTextRun(Canvas canvas, float x, float y,
-            int lineOffset, char[] text,
-            int index, int count, boolean cursor, int foreColor, int backColor);
-}
-
-abstract class BaseTextRenderer implements TextRenderer {
-    protected int[] mForePaint = {
-            0xff000000, // Black
-            0xffff0000, // Red
-            0xff00ff00, // green
-            0xffffff00, // yellow
-            0xff0000ff, // blue
-            0xffff00ff, // magenta
-            0xff00ffff, // cyan
-            0xffffffff  // white -- is overridden by constructor
-    };
-    protected int[] mBackPaint = {
-            0xff000000, // Black -- is overridden by constructor
-            0xffcc0000, // Red
-            0xff00cc00, // green
-            0xffcccc00, // yellow
-            0xff0000cc, // blue
-            0xffff00cc, // magenta
-            0xff00cccc, // cyan
-            0xffffffff  // white
-    };
-    protected final static int mCursorPaint = 0xff808080;
-
-    public BaseTextRenderer(int forePaintColor, int backPaintColor) {
-        mForePaint[7] = forePaintColor;
-        mBackPaint[0] = backPaintColor;
-
-    }
-}
-
-class Bitmap4x8FontRenderer extends BaseTextRenderer {
-    private final static int kCharacterWidth = 4;
-    private final static int kCharacterHeight = 8;
-    private Bitmap mFont;
-    private int mCurrentForeColor;
-    private int mCurrentBackColor;
-    private float[] mColorMatrix;
-    private Paint mPaint;
-    private static final float BYTE_SCALE = 1.0f / 255.0f;
-
-    public Bitmap4x8FontRenderer(Resources resources,
-            int forePaintColor, int backPaintColor) {
-        super(forePaintColor, backPaintColor);
-        mFont = BitmapFactory.decodeResource(resources,
-                R.drawable.atari_small);
-        mPaint = new Paint();
-        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
-    }
-
-    public int getCharacterWidth() {
-        return kCharacterWidth;
-    }
-
-    public int getCharacterHeight() {
-        return kCharacterHeight;
-    }
-
-    public void drawTextRun(Canvas canvas, float x, float y,
-            int lineOffset, char[] text, int index, int count,
-            boolean cursor, int foreColor, int backColor) {
-        setColorMatrix(mForePaint[foreColor & 7],
-                cursor ? mCursorPaint : mBackPaint[backColor & 7]);
-        int destX = (int) x + kCharacterWidth * lineOffset;
-        int destY = (int) y;
-        Rect srcRect = new Rect();
-        Rect destRect = new Rect();
-        destRect.top = (destY - kCharacterHeight);
-        destRect.bottom = destY;
-        for(int i = 0; i < count; i++) {
-            char c = text[i + index];
-            if ((cursor || (c != 32)) && (c < 128)) {
-                int cellX = c & 31;
-                int cellY = (c >> 5) & 3;
-                int srcX = cellX * kCharacterWidth;
-                int srcY = cellY * kCharacterHeight;
-                srcRect.set(srcX, srcY,
-                        srcX + kCharacterWidth, srcY + kCharacterHeight);
-                destRect.left = destX;
-                destRect.right = destX + kCharacterWidth;
-                canvas.drawBitmap(mFont, srcRect, destRect, mPaint);
-            }
-            destX += kCharacterWidth;
-        }
-    }
-
-    private void setColorMatrix(int foreColor, int backColor) {
-        if ((foreColor != mCurrentForeColor)
-                || (backColor != mCurrentBackColor)
-                || (mColorMatrix == null)) {
-            mCurrentForeColor = foreColor;
-            mCurrentBackColor = backColor;
-            if (mColorMatrix == null) {
-                mColorMatrix = new float[20];
-                mColorMatrix[18] = 1.0f; // Just copy Alpha
-            }
-            for (int component = 0; component < 3; component++) {
-                int rightShift = (2 - component) << 3;
-                int fore = 0xff & (foreColor >> rightShift);
-                int back = 0xff & (backColor >> rightShift);
-                int delta = back - fore;
-                mColorMatrix[component * 6] = delta * BYTE_SCALE;
-                mColorMatrix[component * 5 + 4] = fore;
-            }
-            mPaint.setColorFilter(new ColorMatrixColorFilter(mColorMatrix));
-        }
-    }
-}
-
-class PaintRenderer extends BaseTextRenderer {
-    public PaintRenderer(int fontSize, int forePaintColor, int backPaintColor) {
-        super(forePaintColor, backPaintColor);
-        mTextPaint = new Paint();
-        mTextPaint.setTypeface(Typeface.MONOSPACE);
-        mTextPaint.setAntiAlias(true);
-        mTextPaint.setTextSize(fontSize);
-
-        mCharHeight = (int) Math.ceil(mTextPaint.getFontSpacing());
-        mCharAscent = (int) Math.ceil(mTextPaint.ascent());
-        mCharDescent = mCharHeight + mCharAscent;
-        mCharWidth = (int) mTextPaint.measureText(EXAMPLE_CHAR, 0, 1);
-    }
-
-    public void drawTextRun(Canvas canvas, float x, float y, int lineOffset,
-            char[] text, int index, int count,
-            boolean cursor, int foreColor, int backColor) {
-        if (cursor) {
-            mTextPaint.setColor(mCursorPaint);
-        } else {
-            mTextPaint.setColor(mBackPaint[backColor & 0x7]);
-        }
-        float left = x + lineOffset * mCharWidth;
-        canvas.drawRect(left, y + mCharAscent,
-                left + count * mCharWidth, y + mCharDescent,
-                mTextPaint);
-        boolean bold = ( foreColor & 0x8 ) != 0;
-        boolean underline = (backColor & 0x8) != 0;
-        if (bold) {
-            mTextPaint.setFakeBoldText(true);
-        }
-        if (underline) {
-            mTextPaint.setUnderlineText(true);
-        }
-        mTextPaint.setColor(mForePaint[foreColor & 0x7]);
-        canvas.drawText(text, index, count, left, y, mTextPaint);
-        if (bold) {
-            mTextPaint.setFakeBoldText(false);
-        }
-        if (underline) {
-            mTextPaint.setUnderlineText(false);
-        }
-    }
-
-    public int getCharacterHeight() {
-        return mCharHeight;
-    }
-
-    public int getCharacterWidth() {
-        return mCharWidth;
-    }
-
-
-    private Paint mTextPaint;
-    private int mCharWidth;
-    private int mCharHeight;
-    private int mCharAscent;
-    private int mCharDescent;
-    private static final char[] EXAMPLE_CHAR = {'X'};
-    }
-
-/**
- * A multi-thread-safe produce-consumer byte array.
- * Only allows one producer and one consumer.
- */
-
-class ByteQueue {
-    public ByteQueue(int size) {
-        mBuffer = new byte[size];
-    }
-
-    public int getBytesAvailable() {
-        synchronized(this) {
-            return mStoredBytes;
-        }
-    }
-
-    public int read(byte[] buffer, int offset, int length)
-        throws InterruptedException {
-        if (length + offset > buffer.length) {
-            throw
-                new IllegalArgumentException("length + offset > buffer.length");
-        }
-        if (length < 0) {
-            throw
-            new IllegalArgumentException("length < 0");
-
-        }
-        if (length == 0) {
-            return 0;
-        }
-        synchronized(this) {
-            while (mStoredBytes == 0) {
-                wait();
-            }
-            int totalRead = 0;
-            int bufferLength = mBuffer.length;
-            boolean wasFull = bufferLength == mStoredBytes;
-            while (length > 0 && mStoredBytes > 0) {
-                int oneRun = Math.min(bufferLength - mHead, mStoredBytes);
-                int bytesToCopy = Math.min(length, oneRun);
-                System.arraycopy(mBuffer, mHead, buffer, offset, bytesToCopy);
-                mHead += bytesToCopy;
-                if (mHead >= bufferLength) {
-                    mHead = 0;
-                }
-                mStoredBytes -= bytesToCopy;
-                length -= bytesToCopy;
-                offset += bytesToCopy;
-                totalRead += bytesToCopy;
-            }
-            if (wasFull) {
-                notify();
-            }
-            return totalRead;
-        }
-    }
-
-    public void write(byte[] buffer, int offset, int length)
-    throws InterruptedException {
-        if (length + offset > buffer.length) {
-            throw
-                new IllegalArgumentException("length + offset > buffer.length");
-        }
-        if (length < 0) {
-            throw
-            new IllegalArgumentException("length < 0");
-
-        }
-        if (length == 0) {
-            return;
-        }
-        synchronized(this) {
-            int bufferLength = mBuffer.length;
-            boolean wasEmpty = mStoredBytes == 0;
-            while (length > 0) {
-                while(bufferLength == mStoredBytes) {
-                    wait();
-                }
-                int tail = mHead + mStoredBytes;
-                int oneRun;
-                if (tail >= bufferLength) {
-                    tail = tail - bufferLength;
-                    oneRun = mHead - tail;
-                } else {
-                    oneRun = bufferLength - tail;
-                }
-                int bytesToCopy = Math.min(oneRun, length);
-                System.arraycopy(buffer, offset, mBuffer, tail, bytesToCopy);
-                offset += bytesToCopy;
-                mStoredBytes += bytesToCopy;
-                length -= bytesToCopy;
-            }
-            if (wasEmpty) {
-                notify();
-            }
-        }
-    }
-
-    private byte[] mBuffer;
-    private int mHead;
-    private int mStoredBytes;
-}
-/**
- * A view on a transcript and a terminal emulator. Displays the text of the
- * transcript and the current cursor position of the terminal emulator.
- */
-class EmulatorView extends View implements GestureDetector.OnGestureListener {
-
-    /**
-     * We defer some initialization until we have been layed out in the view
-     * hierarchy. The boolean tracks when we know what our size is.
-     */
-    private boolean mKnownSize;
-
-    /**
-     * Our transcript. Contains the screen and the transcript.
-     */
-    private TranscriptScreen mTranscriptScreen;
-
-    /**
-     * Number of rows in the transcript.
-     */
-    private static final int TRANSCRIPT_ROWS = 10000;
-
-    /**
-     * Total width of each character, in pixels
-     */
-    private int mCharacterWidth;
-
-    /**
-     * Total height of each character, in pixels
-     */
-    private int mCharacterHeight;
-
-    /**
-     * Used to render text
-     */
-    private TextRenderer mTextRenderer;
-
-    /**
-     * Text size. Zero means 4 x 8 font.
-     */
-    private int mTextSize;
-
-    /**
-     * Foreground color.
-     */
-    private int mForeground;
-
-    /**
-     * Background color.
-     */
-    private int mBackground;
-
-    /**
-     * Used to paint the cursor
-     */
-    private Paint mCursorPaint;
-
-    private Paint mBackgroundPaint;
-
-    /**
-     * Our terminal emulator. We use this to get the current cursor position.
-     */
-    private TerminalEmulator mEmulator;
-
-    /**
-     * The number of rows of text to display.
-     */
-    private int mRows;
-
-    /**
-     * The number of columns of text to display.
-     */
-    private int mColumns;
-
-    /**
-     * The number of columns that are visible on the display.
-     */
-
-    private int mVisibleColumns;
-
-    /**
-     * The top row of text to display. Ranges from -activeTranscriptRows to 0
-     */
-    private int mTopRow;
-
-    private int mLeftColumn;
-
-    private FileDescriptor mTermFd;
-    /**
-     * Used to receive data from the remote process.
-     */
-    private FileInputStream mTermIn;
-
-    private FileOutputStream mTermOut;
-
-    private ByteQueue mByteQueue;
-
-    /**
-     * Used to temporarily hold data received from the remote process. Allocated
-     * once and used permanently to minimize heap thrashing.
-     */
-    private byte[] mReceiveBuffer;
-
-    /**
-     * Our private message id, which we use to receive new input from the
-     * remote process.
-     */
-    private static final int UPDATE = 1;
-
-    /**
-     * Thread that polls for input from the remote process
-     */
-
-    private Thread mPollingThread;
-
-    private GestureDetector mGestureDetector;
-    private float mScrollRemainder;
-    private TermKeyListener mKeyListener;
-
-    /**
-     * Our message handler class. Implements a periodic callback.
-     */
-    private final Handler mHandler = new Handler() {
-        /**
-         * Handle the callback message. Call our enclosing class's update
-         * method.
-         *
-         * @param msg The callback message.
-         */
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == UPDATE) {
-                update();
-            }
-        }
-    };
-
-    public EmulatorView(Context context) {
-        super(context);
-        commonConstructor(context);
-    }
-
-    public void register(TermKeyListener listener) {
-        mKeyListener = listener;
-    }
-
-    public void setColors(int foreground, int background) {
-        mForeground = foreground;
-        mBackground = background;
-        updateText();
-    }
-
-    public String getTranscriptText() {
-        return mEmulator.getTranscriptText();
-    }
-
-    public void resetTerminal() {
-        mEmulator.reset();
-        invalidate();
-    }
-
-    @Override
-    public boolean onCheckIsTextEditor() {
-        return true;
-    }
-
-    @Override
-    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        return new BaseInputConnection(this, false) {
-
-            @Override
-            public boolean beginBatchEdit() {
-                return true;
-            }
-
-            @Override
-            public boolean clearMetaKeyStates(int states) {
-                return true;
-            }
-
-            @Override
-            public boolean commitCompletion(CompletionInfo text) {
-                return true;
-            }
-
-            @Override
-            public boolean commitText(CharSequence text, int newCursorPosition) {
-                sendText(text);
-                return true;
-            }
-
-            @Override
-            public boolean deleteSurroundingText(int leftLength, int rightLength) {
-                return true;
-            }
-
-            @Override
-            public boolean endBatchEdit() {
-                return true;
-            }
-
-            @Override
-            public boolean finishComposingText() {
-                return true;
-            }
-
-            @Override
-            public int getCursorCapsMode(int reqModes) {
-                return 0;
-            }
-
-            @Override
-            public ExtractedText getExtractedText(ExtractedTextRequest request,
-                    int flags) {
-                return null;
-            }
-
-            @Override
-            public CharSequence getTextAfterCursor(int n, int flags) {
-                return null;
-            }
-
-            @Override
-            public CharSequence getTextBeforeCursor(int n, int flags) {
-                return null;
-            }
-
-            @Override
-            public boolean performEditorAction(int actionCode) {
-                if(actionCode == EditorInfo.IME_ACTION_UNSPECIFIED) {
-                    // The "return" key has been pressed on the IME.
-                    sendText("\n");
-                    return true;
-                }
-                return false;
-            }
-
-            @Override
-            public boolean performContextMenuAction(int id) {
-                return true;
-            }
-
-            @Override
-            public boolean performPrivateCommand(String action, Bundle data) {
-                return true;
-            }
-
-            @Override
-            public boolean sendKeyEvent(KeyEvent event) {
-                if (event.getAction() == KeyEvent.ACTION_DOWN) {
-                    switch(event.getKeyCode()) {
-                    case KeyEvent.KEYCODE_DEL:
-                        sendChar(127);
-                        break;
-                    }
-                }
-                return true;
-            }
-
-            @Override
-            public boolean setComposingText(CharSequence text, int newCursorPosition) {
-                return true;
-            }
-
-            @Override
-            public boolean setSelection(int start, int end) {
-                return true;
-            }
-
-            private void sendChar(int c) {
-                try {
-                    mapAndSend(c);
-                } catch (IOException ex) {
-
-                }
-            }
-            private void sendText(CharSequence text) {
-                int n = text.length();
-                try {
-                    for(int i = 0; i < n; i++) {
-                        char c = text.charAt(i);
-                        mapAndSend(c);
-                    }
-                } catch (IOException e) {
-                }
-            }
-
-            private void mapAndSend(int c) throws IOException {
-                mTermOut.write(
-                        mKeyListener.mapControlChar(c));
-            }
-        };
-    }
-
-    public boolean getKeypadApplicationMode() {
-        return mEmulator.getKeypadApplicationMode();
-    }
-
-    public EmulatorView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public EmulatorView(Context context, AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a =
-                context.obtainStyledAttributes(android.R.styleable.View);
-        initializeScrollbars(a);
-        a.recycle();
-        commonConstructor(context);
-    }
-
-    private void commonConstructor(Context context) {
-        mTextRenderer = null;
-        mCursorPaint = new Paint();
-        mCursorPaint.setARGB(255,128,128,128);
-        mBackgroundPaint = new Paint();
-        mTopRow = 0;
-        mLeftColumn = 0;
-        mGestureDetector = new GestureDetector(context, this, null);
-        mGestureDetector.setIsLongpressEnabled(false);
-        setVerticalScrollBarEnabled(true);
-    }
-
-    @Override
-    protected int computeVerticalScrollRange() {
-        return mTranscriptScreen.getActiveRows();
-    }
-
-    @Override
-    protected int computeVerticalScrollExtent() {
-        return mRows;
-    }
-
-    @Override
-    protected int computeVerticalScrollOffset() {
-        return mTranscriptScreen.getActiveRows() + mTopRow - mRows;
-    }
-
-    /**
-     * Call this to initialize the view.
-     *
-     * @param termFd the file descriptor
-     * @param termOut the output stream for the pseudo-teletype
-     */
-    public void initialize(FileDescriptor termFd, FileOutputStream termOut) {
-        mTermOut = termOut;
-        mTermFd = termFd;
-        mTextSize = 10;
-        mForeground = Term.WHITE;
-        mBackground = Term.BLACK;
-        updateText();
-        mTermIn = new FileInputStream(mTermFd);
-        mReceiveBuffer = new byte[4 * 1024];
-        mByteQueue = new ByteQueue(4 * 1024);
-    }
-
-    /**
-     * Accept a sequence of bytes (typically from the pseudo-tty) and process
-     * them.
-     *
-     * @param buffer a byte array containing bytes to be processed
-     * @param base the index of the first byte in the buffer to process
-     * @param length the number of bytes to process
-     */
-    public void append(byte[] buffer, int base, int length) {
-        mEmulator.append(buffer, base, length);
-        ensureCursorVisible();
-        invalidate();
-    }
-
-    /**
-     * Page the terminal view (scroll it up or down by delta screenfulls.)
-     *
-     * @param delta the number of screens to scroll. Positive means scroll down,
-     *        negative means scroll up.
-     */
-    public void page(int delta) {
-        mTopRow =
-                Math.min(0, Math.max(-(mTranscriptScreen
-                        .getActiveTranscriptRows()), mTopRow + mRows * delta));
-        invalidate();
-    }
-
-    /**
-     * Page the terminal view horizontally.
-     *
-     * @param deltaColumns the number of columns to scroll. Positive scrolls to
-     *        the right.
-     */
-    public void pageHorizontal(int deltaColumns) {
-        mLeftColumn =
-                Math.max(0, Math.min(mLeftColumn + deltaColumns, mColumns
-                        - mVisibleColumns));
-        invalidate();
-    }
-
-    /**
-     * Sets the text size, which in turn sets the number of rows and columns
-     *
-     * @param fontSize the new font size, in pixels.
-     */
-    public void setTextSize(int fontSize) {
-        mTextSize = fontSize;
-        updateText();
-    }
-
-    // Begin GestureDetector.OnGestureListener methods
-
-    public boolean onSingleTapUp(MotionEvent e) {
-        return true;
-    }
-
-    public void onLongPress(MotionEvent e) {
-    }
-
-    public boolean onScroll(MotionEvent e1, MotionEvent e2,
-            float distanceX, float distanceY) {
-        distanceY += mScrollRemainder;
-        int deltaRows = (int) (distanceY / mCharacterHeight);
-        mScrollRemainder = distanceY - deltaRows * mCharacterHeight;
-        mTopRow =
-            Math.min(0, Math.max(-(mTranscriptScreen
-                    .getActiveTranscriptRows()), mTopRow + deltaRows));
-        invalidate();
-
-        return true;
-   }
-
-    public void onSingleTapConfirmed(MotionEvent e) {
-    }
-
-    public boolean onJumpTapDown(MotionEvent e1, MotionEvent e2) {
-       // Scroll to bottom
-       mTopRow = 0;
-       invalidate();
-       return true;
-    }
-
-    public boolean onJumpTapUp(MotionEvent e1, MotionEvent e2) {
-        // Scroll to top
-        mTopRow = -mTranscriptScreen.getActiveTranscriptRows();
-        invalidate();
-        return true;
-    }
-
-    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
-            float velocityY) {
-        // TODO: add animation man's (non animated) fling
-        mScrollRemainder = 0.0f;
-        onScroll(e1, e2, 2 * velocityX, -2 * velocityY);
-        return true;
-    }
-
-    public void onShowPress(MotionEvent e) {
-    }
-
-    public boolean onDown(MotionEvent e) {
-        mScrollRemainder = 0.0f;
-        return true;
-    }
-
-    // End GestureDetector.OnGestureListener methods
-
-    @Override public boolean onTouchEvent(MotionEvent ev) {
-        return mGestureDetector.onTouchEvent(ev);
-    }
-
-    private void updateText() {
-        if (mTextSize > 0) {
-            mTextRenderer = new PaintRenderer(mTextSize, mForeground,
-                    mBackground);
-        }
-        else {
-            mTextRenderer = new Bitmap4x8FontRenderer(getResources(),
-                    mForeground, mBackground);
-        }
-        mBackgroundPaint.setColor(mBackground);
-        mCharacterWidth = mTextRenderer.getCharacterWidth();
-        mCharacterHeight = mTextRenderer.getCharacterHeight();
-
-        if (mKnownSize) {
-            updateSize(getWidth(), getHeight());
-        }
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        updateSize(w, h);
-        if (!mKnownSize) {
-            mKnownSize = true;
-
-            // Set up a thread to read input from the
-            // pseudo-teletype:
-
-            mPollingThread = new Thread(new Runnable() {
-
-                public void run() {
-                    try {
-                        while(true) {
-                            int read = mTermIn.read(mBuffer);
-                            mByteQueue.write(mBuffer, 0, read);
-                            mHandler.sendMessage(
-                                    mHandler.obtainMessage(UPDATE));
-                        }
-                    } catch (IOException e) {
-                    } catch (InterruptedException e) {
-                    }
-                }
-                private byte[] mBuffer = new byte[4096];
-            });
-            mPollingThread.setName("Input reader");
-            mPollingThread.start();
-        }
-    }
-
-    private void updateSize(int w, int h) {
-        mColumns = w / mCharacterWidth;
-        mRows = h / mCharacterHeight;
-
-        // Inform the attached pty of our new size:
-        Exec.setPtyWindowSize(mTermFd, mRows, mColumns, w, h);
-
-
-        if (mTranscriptScreen != null) {
-            mEmulator.updateSize(mColumns, mRows);
-        } else {
-            mTranscriptScreen =
-                    new TranscriptScreen(mColumns, TRANSCRIPT_ROWS, mRows, 0, 7);
-            mEmulator =
-                    new TerminalEmulator(mTranscriptScreen, mColumns, mRows,
-                            mTermOut);
-        }
-
-        // Reset our paging:
-        mTopRow = 0;
-        mLeftColumn = 0;
-
-        invalidate();
-    }
-
-    void updateSize() {
-        if (mKnownSize) {
-            updateSize(getWidth(), getHeight());
-        }
-    }
-
-    /**
-     * Look for new input from the ptty, send it to the terminal emulator.
-     */
-    private void update() {
-        int bytesAvailable = mByteQueue.getBytesAvailable();
-        int bytesToRead = Math.min(bytesAvailable, mReceiveBuffer.length);
-        try {
-            int bytesRead = mByteQueue.read(mReceiveBuffer, 0, bytesToRead);
-            append(mReceiveBuffer, 0, bytesRead);
-        } catch (InterruptedException e) {
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        int w = getWidth();
-        int h = getHeight();
-        canvas.drawRect(0, 0, w, h, mBackgroundPaint);
-        mVisibleColumns = w / mCharacterWidth;
-        float x = -mLeftColumn * mCharacterWidth;
-        float y = mCharacterHeight;
-        int endLine = mTopRow + mRows;
-        int cx = mEmulator.getCursorCol();
-        int cy = mEmulator.getCursorRow();
-        for (int i = mTopRow; i < endLine; i++) {
-            int cursorX = -1;
-            if (i == cy) {
-                cursorX = cx;
-            }
-            mTranscriptScreen.drawText(i, canvas, x, y, mTextRenderer, cursorX);
-            y += mCharacterHeight;
-        }
-    }
-
-    private void ensureCursorVisible() {
-        mTopRow = 0;
-        if (mVisibleColumns > 0) {
-            int cx = mEmulator.getCursorCol();
-            int visibleCursorX = mEmulator.getCursorCol() - mLeftColumn;
-            if (visibleCursorX < 0) {
-                mLeftColumn = cx;
-            } else if (visibleCursorX >= mVisibleColumns) {
-                mLeftColumn = (cx - mVisibleColumns) + 1;
-            }
-        }
-    }
-}
-
-
-/**
- * An ASCII key listener. Supports control characters and escape. Keeps track of
- * the current state of the alt, shift, and control keys.
- */
-class TermKeyListener {
-    /**
-     * The state engine for a modifier key. Can be pressed, released, locked,
-     * and so on.
-     *
-     */
-    private class ModifierKey {
-
-        private int mState;
-
-        private static final int UNPRESSED = 0;
-
-        private static final int PRESSED = 1;
-
-        private static final int RELEASED = 2;
-
-        private static final int USED = 3;
-
-        private static final int LOCKED = 4;
-
-        /**
-         * Construct a modifier key. UNPRESSED by default.
-         *
-         */
-        public ModifierKey() {
-            mState = UNPRESSED;
-        }
-
-        public void onPress() {
-            switch (mState) {
-            case PRESSED:
-                // This is a repeat before use
-                break;
-            case RELEASED:
-                mState = LOCKED;
-                break;
-            case USED:
-                // This is a repeat after use
-                break;
-            case LOCKED:
-                mState = UNPRESSED;
-                break;
-            default:
-                mState = PRESSED;
-                break;
-            }
-        }
-
-        public void onRelease() {
-            switch (mState) {
-            case USED:
-                mState = UNPRESSED;
-                break;
-            case PRESSED:
-                mState = RELEASED;
-                break;
-            default:
-                // Leave state alone
-                break;
-            }
-        }
-
-        public void adjustAfterKeypress() {
-            switch (mState) {
-            case PRESSED:
-                mState = USED;
-                break;
-            case RELEASED:
-                mState = UNPRESSED;
-                break;
-            default:
-                // Leave state alone
-                break;
-            }
-        }
-
-        public boolean isActive() {
-            return mState != UNPRESSED;
-        }
-    }
-
-    private ModifierKey mAltKey = new ModifierKey();
-
-    private ModifierKey mCapKey = new ModifierKey();
-
-    private ModifierKey mControlKey = new ModifierKey();
-
-    /**
-     * Construct a term key listener.
-     *
-     */
-    public TermKeyListener() {
-    }
-
-    public void handleControlKey(boolean down) {
-        if (down) {
-            mControlKey.onPress();
-        } else {
-            mControlKey.onRelease();
-        }
-    }
-
-    public int mapControlChar(int ch) {
-        int result = ch;
-        if (mControlKey.isActive()) {
-            // Search is the control key.
-            if (result >= 'a' && result <= 'z') {
-                result = (char) (result - 'a' + '\001');
-            } else if (result == ' ') {
-                result = 0;
-            } else if ((result == '[') || (result == '1')) {
-                result = 27;
-            } else if ((result == '\\') || (result == '.')) {
-                result = 28;
-            } else if ((result == ']') || (result == '0')) {
-                result = 29;
-            } else if ((result == '^') || (result == '6')) {
-                result = 30; // control-^
-            } else if ((result == '_') || (result == '5')) {
-                result = 31;
-            }
-        }
-
-        if (result > -1) {
-            mAltKey.adjustAfterKeypress();
-            mCapKey.adjustAfterKeypress();
-            mControlKey.adjustAfterKeypress();
-        }
-        return result;
-    }
-
-    /**
-     * Handle a keyDown event.
-     *
-     * @param keyCode the keycode of the keyDown event
-     * @return the ASCII byte to transmit to the pseudo-teletype, or -1 if this
-     *         event does not produce an ASCII byte.
-     */
-    public int keyDown(int keyCode, KeyEvent event) {
-        int result = -1;
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_ALT_RIGHT:
-        case KeyEvent.KEYCODE_ALT_LEFT:
-            mAltKey.onPress();
-            break;
-
-        case KeyEvent.KEYCODE_SHIFT_LEFT:
-        case KeyEvent.KEYCODE_SHIFT_RIGHT:
-            mCapKey.onPress();
-            break;
-
-        case KeyEvent.KEYCODE_ENTER:
-            // Convert newlines into returns. The vt100 sends a
-            // '\r' when the 'Return' key is pressed, but our
-            // KeyEvent translates this as a '\n'.
-            result = '\r';
-            break;
-
-        case KeyEvent.KEYCODE_DEL:
-            // Convert DEL into 127 (instead of 8)
-            result = 127;
-            break;
-
-        default: {
-            result = event.getUnicodeChar(
-                   (mCapKey.isActive() ? KeyEvent.META_SHIFT_ON : 0) |
-                   (mAltKey.isActive() ? KeyEvent.META_ALT_ON : 0));
-            break;
-            }
-        }
-
-        result = mapControlChar(result);
-
-        return result;
-    }
-
-    /**
-     * Handle a keyUp event.
-     *
-     * @param keyCode the keyCode of the keyUp event
-     */
-    public void keyUp(int keyCode) {
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_ALT_LEFT:
-        case KeyEvent.KEYCODE_ALT_RIGHT:
-            mAltKey.onRelease();
-            break;
-        case KeyEvent.KEYCODE_SHIFT_LEFT:
-        case KeyEvent.KEYCODE_SHIFT_RIGHT:
-            mCapKey.onRelease();
-            break;
-        default:
-            // Ignore other keyUps
-            break;
-        }
-    }
-}
diff --git a/apps/Term/src/com/android/term/TermPreferences.java b/apps/Term/src/com/android/term/TermPreferences.java
deleted file mode 100644
index 3102963..0000000
--- a/apps/Term/src/com/android/term/TermPreferences.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.term;
-
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-
-public class TermPreferences extends PreferenceActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Load the preferences from an XML resource
-        addPreferencesFromResource(R.xml.preferences);
-    }
-
-}
diff --git a/apps/WidgetPreview/Android.mk b/apps/WidgetPreview/Android.mk
new file mode 100644
index 0000000..04a4927
--- /dev/null
+++ b/apps/WidgetPreview/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := WidgetPreview
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/apps/WidgetPreview/AndroidManifest.xml b/apps/WidgetPreview/AndroidManifest.xml
new file mode 100644
index 0000000..ea70e0c
--- /dev/null
+++ b/apps/WidgetPreview/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.widgetpreview">
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.BIND_APPWIDGET" />
+        
+    <uses-sdk android:targetSdkVersion="11"/>
+    
+    <application android:label="@string/application_label">
+
+        <activity
+                android:name="WidgetPreviewActivity"
+                android:label="@string/application_label"
+                android:icon="@drawable/ic_widget_preview">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/apps/WidgetPreview/res/drawable-hdpi/ic_widget_preview.png b/apps/WidgetPreview/res/drawable-hdpi/ic_widget_preview.png
new file mode 100644
index 0000000..168cdda
--- /dev/null
+++ b/apps/WidgetPreview/res/drawable-hdpi/ic_widget_preview.png
Binary files differ
diff --git a/apps/WidgetPreview/res/drawable-mdpi/ic_widget_preview.png b/apps/WidgetPreview/res/drawable-mdpi/ic_widget_preview.png
new file mode 100644
index 0000000..55c7661
--- /dev/null
+++ b/apps/WidgetPreview/res/drawable-mdpi/ic_widget_preview.png
Binary files differ
diff --git a/apps/WidgetPreview/res/layout/activity_main.xml b/apps/WidgetPreview/res/layout/activity_main.xml
new file mode 100644
index 0000000..e43d246
--- /dev/null
+++ b/apps/WidgetPreview/res/layout/activity_main.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="20dp">
+    <Button
+            android:id="@+id/email_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:text="@string/email_button" />
+    <Button
+            android:id="@+id/snapshot_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_above="@id/email_button"
+            android:text="@string/snapshot_button" />
+    <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_above="@id/snapshot_button"
+            android:layout_centerHorizontal="true">
+        <FrameLayout
+                android:id="@+id/main_frame"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content">
+        </FrameLayout>
+    </FrameLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git a/apps/WidgetPreview/res/values-land/dimens.xml b/apps/WidgetPreview/res/values-land/dimens.xml
new file mode 100644
index 0000000..dea2576
--- /dev/null
+++ b/apps/WidgetPreview/res/values-land/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="workspace_cell_width">106dip</dimen>
+    <dimen name="workspace_cell_height">74dip</dimen>
+    <dimen name="workspace_width_gap">0dp</dimen>
+    <dimen name="workspace_height_gap">0dp</dimen>
+</resources>
diff --git a/apps/WidgetPreview/res/values-port/dimens.xml b/apps/WidgetPreview/res/values-port/dimens.xml
new file mode 100644
index 0000000..0276ffb
--- /dev/null
+++ b/apps/WidgetPreview/res/values-port/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="workspace_cell_width">80dip</dimen>
+    <dimen name="workspace_cell_height">100dip</dimen>
+    <dimen name="workspace_width_gap">0dp</dimen>
+    <dimen name="workspace_height_gap">0dp</dimen>
+</resources>
diff --git a/apps/WidgetPreview/res/values-xlarge/dimens.xml b/apps/WidgetPreview/res/values-xlarge/dimens.xml
new file mode 100644
index 0000000..b6b5dfe
--- /dev/null
+++ b/apps/WidgetPreview/res/values-xlarge/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="workspace_cell_width">96dip</dimen>
+    <dimen name="workspace_cell_height">96dip</dimen>
+    <dimen name="workspace_width_gap">0dp</dimen>
+    <dimen name="workspace_height_gap">0dp</dimen>
+</resources>
diff --git a/apps/WidgetPreview/res/values/dimens.xml b/apps/WidgetPreview/res/values/dimens.xml
new file mode 100644
index 0000000..79b8b57
--- /dev/null
+++ b/apps/WidgetPreview/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="preview_cell_size">96dip</dimen>
+</resources>
diff --git a/apps/WidgetPreview/res/values/strings.xml b/apps/WidgetPreview/res/values/strings.xml
new file mode 100644
index 0000000..2cc9ccf
--- /dev/null
+++ b/apps/WidgetPreview/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="application_label">Widget Preview</string>
+    <string name="saving_preview">Saving widget preview...</string>
+    <string name="preview_saved">Widget preview saved!</string>
+    <string name="no_preview">Please take a snapshot first</string>
+    <string name="preview_save_error">Error saving preview</string>
+    <string name="configure_error">Error configuring, no configuration activity found</string>
+    <string name="email_subject">Widget preview</string>
+    <string name="email_body">Attached is the preview of your AppWidget</string>
+
+    <string name="snapshot_button">Take Snapshot</string>
+    <string name="email_button">Email Preview</string>
+</resources>
diff --git a/apps/WidgetPreview/src/com/android/widgetpreview/WidgetPreviewActivity.java b/apps/WidgetPreview/src/com/android/widgetpreview/WidgetPreviewActivity.java
new file mode 100644
index 0000000..1026ba8
--- /dev/null
+++ b/apps/WidgetPreview/src/com/android/widgetpreview/WidgetPreviewActivity.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.widgetpreview;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class WidgetPreviewActivity extends Activity implements OnClickListener {
+
+    private static final String LOG_TAG = "WidgetPreviewActivity";
+    private static final boolean DEBUG = true;
+    private static final int APPWIDGET_HOST_ID = 2048;
+    private static final int REQUEST_WIDGET = 0;
+    private static final int REQUEST_CONFIGURE = 1;
+
+    private AppWidgetHost mAppWidgetHost = null;
+    private FrameLayout mAppWidgetFrame = null;
+    private AppWidgetHostView mAppWidgetView = null;
+    private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+    private String mAppWidgetName;
+    private int mPreviewWidth;
+    private int mPreviewHeight;
+
+    private Button mSnapshotButton = null;
+    private Button mEmailButton = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        mAppWidgetFrame = (FrameLayout)findViewById(R.id.main_frame);
+        mSnapshotButton = (Button)findViewById(R.id.snapshot_button);
+        mSnapshotButton.setOnClickListener(this);
+        mEmailButton = (Button)findViewById(R.id.email_button);
+        mEmailButton.setOnClickListener(this);
+
+        mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID);
+
+        final Object retainedObj = getLastNonConfigurationInstance();
+        if (retainedObj instanceof AppWidgetProviderInfo) {
+            AppWidgetProviderInfo info = (AppWidgetProviderInfo) retainedObj;
+            int id = mAppWidgetHost.allocateAppWidgetId();
+            AppWidgetManager.getInstance(getBaseContext()).bindAppWidgetId(id, info.provider);
+            setAppWidget(id);
+        } else {
+            startChooseActivity();
+        }
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        mAppWidgetHost.startListening();
+    }
+
+    @Override
+    public Object onRetainNonConfigurationInstance() {
+        AppWidgetProviderInfo info = AppWidgetManager.getInstance(
+                getBaseContext()).getAppWidgetInfo(mAppWidgetId);
+        return info;
+    }
+
+    private void startChooseActivity() {
+        int id = mAppWidgetHost.allocateAppWidgetId();
+        Intent selectIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
+        selectIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
+        startActivityForResult(selectIntent, REQUEST_WIDGET);
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_WIDGET) {
+            if (data != null) {
+                int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+                if (data.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
+                    appWidgetId = data.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
+                }
+
+                if (resultCode == RESULT_OK) {
+                    setAppWidget(appWidgetId);
+                } else {
+                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+                    finish();
+                }
+            } else {
+                finish();
+            }
+        } else if (requestCode == REQUEST_CONFIGURE) {
+            if (data != null) {
+                int appWidgetId = data.getExtras().getInt(
+                        AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+                if (resultCode == RESULT_OK) {
+                    finishSetAppWidget(appWidgetId);
+                } else {
+                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+                }
+            }
+        }
+    }
+
+    private void setAppWidget(int appWidgetId) {
+        if (mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+            mAppWidgetHost.deleteAppWidgetId(mAppWidgetId);
+        }
+
+        /* Check for configuration */
+        AppWidgetProviderInfo providerInfo =
+            AppWidgetManager.getInstance(getBaseContext()).getAppWidgetInfo(appWidgetId);
+
+        if (providerInfo.configure != null) {
+            Intent configureIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
+            configureIntent.setComponent(providerInfo.configure);
+            configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+
+            if (configureIntent != null) {
+                try {
+                    startActivityForResult(configureIntent, REQUEST_CONFIGURE);
+                } catch (ActivityNotFoundException e) {
+                    Log.d(LOG_TAG, "Configuration activity not found: " + e);
+                    Toast errorToast = Toast.makeText(
+                            getBaseContext(), R.string.configure_error, Toast.LENGTH_SHORT);
+                    errorToast.show();
+                }
+            }
+        } else {
+            finishSetAppWidget(appWidgetId);
+        }
+    }
+
+    private void finishSetAppWidget(int appWidgetId) {
+        AppWidgetProviderInfo providerInfo =
+            AppWidgetManager.getInstance(getBaseContext()).getAppWidgetInfo(appWidgetId);
+        if (providerInfo != null) {
+            mAppWidgetView =
+                    mAppWidgetHost.createView(getBaseContext(), appWidgetId, providerInfo);
+
+            int [] dimensions =
+                    getLauncherCellDimensions(providerInfo.minWidth, providerInfo.minHeight);
+
+            mPreviewWidth = dimensions[0];
+            mPreviewHeight = dimensions[1];
+
+            mAppWidgetName =
+                AppWidgetManager.getInstance(getBaseContext()).getAppWidgetInfo(appWidgetId).label;
+            mAppWidgetName = mAppWidgetName.replaceAll("[^a-zA-Z0-9]", "_");
+
+            ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+            mAppWidgetView.setLayoutParams(p);
+            mAppWidgetFrame.removeAllViews();
+            mAppWidgetHost.deleteAppWidgetId(mAppWidgetId);
+            mAppWidgetFrame.addView(mAppWidgetView, mPreviewWidth, mPreviewHeight);
+            mAppWidgetId = appWidgetId;
+        }
+    }
+
+    // Taken from CellLayout.java
+    public int[] getLauncherCellDimensions(int width, int height) {
+        // Always assume we're working with the smallest span to make sure we
+        // reserve enough space in both orientations.
+        Resources resources = getResources();
+        int cellWidth = resources.getDimensionPixelSize(R.dimen.workspace_cell_width);
+        int cellHeight = resources.getDimensionPixelSize(R.dimen.workspace_cell_height);
+        int widthGap = resources.getDimensionPixelSize(R.dimen.workspace_width_gap);
+        int heightGap = resources.getDimensionPixelSize(R.dimen.workspace_height_gap);
+        int previewCellSize = resources.getDimensionPixelSize(R.dimen.preview_cell_size);
+
+        // This logic imitates Launcher's CellLayout.rectToCell.
+        // Always round up to next largest cell
+        int smallerSize = Math.min(cellWidth, cellHeight);
+        int spanX = (width + smallerSize) / smallerSize;
+        int spanY = (height + smallerSize) / smallerSize;
+
+        // We use a fixed preview cell size so that you get the same preview image for
+        // the same cell-sized widgets across all devices
+        width = spanX * previewCellSize + ((spanX - 1) * widthGap);
+        height = spanY * previewCellSize + ((spanY - 1) * heightGap);
+        return new int[] { width, height };
+    }
+
+    private File buildFile(String name) {
+        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            return null;
+        }
+
+        File path = Environment.getExternalStoragePublicDirectory(
+                Environment.DIRECTORY_DOWNLOADS);
+        int orientationCode = getResources().getConfiguration().orientation;
+        String orientation;
+        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            orientation = "landscape";
+        } else if (orientationCode == Configuration.ORIENTATION_PORTRAIT) {
+            orientation = "portrait";
+        } else if (orientationCode == Configuration.ORIENTATION_SQUARE) {
+            orientation = "square";
+        } else {
+            orientation = "undefined";
+        }
+        return new File(path, name + "_ori_" + orientation + ".png");
+    }
+
+    public Bitmap getPreviewBitmap() {
+        mAppWidgetView.invalidate();
+        Bitmap bmp = Bitmap.createBitmap(
+                mAppWidgetView.getWidth(), mAppWidgetView.getHeight(), Config.ARGB_8888);
+        Canvas c = new Canvas(bmp);
+        mAppWidgetView.draw(c);
+        return bmp;
+    }
+
+    private boolean saveImage(Bitmap bmp, String name) {
+        File pic = buildFile(mAppWidgetName);
+        if (pic == null) {
+            Log.d(LOG_TAG, "External storage not present");
+            return false;
+        }
+
+        pic.getParentFile().mkdirs();
+        FileOutputStream fout = null;
+        try {
+            fout = new FileOutputStream(pic);
+            if (!bmp.compress(CompressFormat.PNG, 100, fout)) {
+                Log.d(LOG_TAG, "Failed to compress image");
+                return false;
+            }
+            return true;
+        } catch (IOException e) {
+            Log.d(LOG_TAG, "Error writing to disk: " + e);
+        } finally {
+            try {
+                if (fout != null) {
+                    fout.close();
+                }
+            } catch (IOException e) {
+                Log.d(LOG_TAG, "Could not close file: " + e);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (!getFragmentManager().popBackStackImmediate()) {
+            startChooseActivity();
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v == mSnapshotButton) {
+            int textId = R.string.saving_preview;
+
+            Toast preToast = Toast.makeText(getBaseContext(), textId, Toast.LENGTH_SHORT);
+            preToast.show();
+
+            Bitmap bmp = getPreviewBitmap();
+            if (saveImage(bmp, mAppWidgetName)) {
+                textId = R.string.preview_saved;
+            } else {
+                textId = R.string.preview_save_error;
+            }
+
+            Toast postToast = Toast.makeText(getBaseContext(), textId, Toast.LENGTH_SHORT);
+            postToast.show();
+        } else if (v == mEmailButton) {
+            File file = buildFile(mAppWidgetName);
+            if (file.exists()) {
+                Intent emailIntent = new Intent(Intent.ACTION_SEND);
+                emailIntent.setType("image/png");
+                emailIntent.putExtra(Intent.EXTRA_SUBJECT,
+                        getResources().getString(R.string.email_subject));
+                emailIntent.putExtra(Intent.EXTRA_TEXT,
+                        getResources().getString(R.string.email_body));
+                emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
+                startActivity(emailIntent);
+            } else {
+                Toast postToast = Toast.makeText(
+                        getBaseContext(), R.string.no_preview, Toast.LENGTH_SHORT);
+                postToast.show();
+            }
+        }
+    }
+}
diff --git a/build/Android.mk b/build/Android.mk
index 2864ea3..7e5d180 100644
--- a/build/Android.mk
+++ b/build/Android.mk
@@ -64,3 +64,14 @@
 	$(hide)$(ACP) $< $@
 
 ALL_SDK_FILES += $(android_jar_full_target)
+
+
+android-support-v4_build_module := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android-support-v4_intermediates/javalib.jar
+android-support-v4_intermediates := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/android-support-v4_intermediates
+android-support-v4_full_target := $(android-support-v4_intermediates)/android-support-v4.jar
+$(android-support-v4_full_target): $(android-support-v4_build_module)
+	@echo Package android-support-v4.jar: $@
+	$(hide)mkdir -p $(dir $@)
+	$(hide)$(ACP) $< $@
+
+ALL_SDK_FILES += $(android-support-v4_full_target)
diff --git a/build/sdk.atree b/build/sdk.atree
index a988f06..a4f4d76 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -1,4 +1,4 @@
-#
+ #
 # Copyright (C) 2007 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,12 +41,12 @@
 bin/adb                                       platform-tools/adb
 bin/aapt                                      platform-tools/aapt
 bin/aidl                                      platform-tools/aidl
+bin/llvm-rs-cc                                platform-tools/llvm-rs-cc
 # dx
 bin/dx                                        platform-tools/dx
 bin/dexdump                                   platform-tools/dexdump
 framework/dx.jar                              platform-tools/lib/dx.jar
 
-sdk/files/sdk_files_NOTICE.txt                platform-tools/NOTICE.txt
 development/sdk/plat_tools_source.properties  platform-tools/source.properties
 
 ##############################################################################
@@ -54,10 +54,10 @@
 ##############################################################################
 
 # version files for the SDK updater, from sdk.git
-development/sdk/platform_source.properties platforms/${PLATFORM_NAME}/source.properties
+development/sdk/platform_source.properties    platforms/${PLATFORM_NAME}/source.properties
 
 # copy build prop from out/.../sdk/
-sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop
+sdk/sdk-build.prop                            platforms/${PLATFORM_NAME}/build.prop
 
 # the uper-jar file that apps link against. This is the public API
 ${OUT_DIR}/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
@@ -65,6 +65,11 @@
 # the aidl precompiled include
 obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl
 
+# Framework include for Renderscript
+frameworks/base/libs/rs/scriptc  platforms/${PLATFORM_NAME}/renderscript/include
+external/clang/lib/Headers       platforms/${PLATFORM_NAME}/renderscript/clang-include
+external/clang/LICENSE.TXT       platforms/${PLATFORM_NAME}/renderscript/clang-include/LICENSE.TXT
+
 # System images + Kernel
 system.img                              platforms/${PLATFORM_NAME}/images/${TARGET_CPU_ABI}/system.img
 ramdisk.img                             platforms/${PLATFORM_NAME}/images/${TARGET_CPU_ABI}/ramdisk.img
@@ -72,15 +77,16 @@
 prebuilt/android-${TARGET_ARCH}/kernel/kernel-qemu platforms/${PLATFORM_NAME}/images/${TARGET_CPU_ABI}/kernel-qemu
 
 # emulator skins from sdk.git
-development/tools/emulator/skins/QVGA      platforms/${PLATFORM_NAME}/skins/QVGA
-development/tools/emulator/skins/WQVGA432  platforms/${PLATFORM_NAME}/skins/WQVGA432
-development/tools/emulator/skins/WQVGA400  platforms/${PLATFORM_NAME}/skins/WQVGA400
-development/tools/emulator/skins/HVGA      platforms/${PLATFORM_NAME}/skins/HVGA
-development/tools/emulator/skins/WVGA800   platforms/${PLATFORM_NAME}/skins/WVGA800
-development/tools/emulator/skins/WVGA854   platforms/${PLATFORM_NAME}/skins/WVGA854
+#development/tools/emulator/skins/QVGA      platforms/${PLATFORM_NAME}/skins/QVGA
+#development/tools/emulator/skins/WQVGA432  platforms/${PLATFORM_NAME}/skins/WQVGA432
+#development/tools/emulator/skins/WQVGA400  platforms/${PLATFORM_NAME}/skins/WQVGA400
+#development/tools/emulator/skins/HVGA      platforms/${PLATFORM_NAME}/skins/HVGA
+#development/tools/emulator/skins/WVGA800   platforms/${PLATFORM_NAME}/skins/WVGA800
+#development/tools/emulator/skins/WVGA854   platforms/${PLATFORM_NAME}/skins/WVGA854
+development/tools/emulator/skins/WXGA       platforms/${PLATFORM_NAME}/skins/WXGA
 
 # Platform SDK properties
-sdk/files/sdk.properties     platforms/${PLATFORM_NAME}/sdk.properties
+development/sdk/sdk.properties               platforms/${PLATFORM_NAME}/sdk.properties
 
 # sdk.git Ant templates for project files
 sdk/templates/AndroidManifest.template        platforms/${PLATFORM_NAME}/templates/AndroidManifest.template
@@ -138,48 +144,70 @@
 
 # samples to include in the sdk samples package
 #
-# the list here should match the list of samples that we generate docs for, 
+# the list here should match the list of samples that we generate docs for,
 # (see web_docs_sample_code_flags in frameworks/base/Android.mk)
 development/apps/GestureBuilder              samples/${PLATFORM_NAME}/GestureBuilder
 development/samples/source.properties        samples/${PLATFORM_NAME}/source.properties
 #
 # PLEASE KEEP THE SAMPLES IN ALPHABETICAL ORDER.
 #
-development/samples/AccessibilityService     samples/${PLATFORM_NAME}/AccessibilityService
-development/samples/AccelerometerPlay        samples/${PLATFORM_NAME}/AccelerometerPlay
-development/samples/ApiDemos                 samples/${PLATFORM_NAME}/ApiDemos
-development/samples/BackupRestore            samples/${PLATFORM_NAME}/BackupRestore
-development/samples/BasicGLSurfaceView       samples/${PLATFORM_NAME}/BasicGLSurfaceView
-development/samples/BluetoothChat            samples/${PLATFORM_NAME}/BluetoothChat
-development/samples/ContactManager           samples/${PLATFORM_NAME}/ContactManager
-development/samples/CrossCompatibility       samples/${PLATFORM_NAME}/CrossCompatibility
-development/samples/CubeLiveWallpaper        samples/${PLATFORM_NAME}/CubeLiveWallpaper
-development/samples/Home                     samples/${PLATFORM_NAME}/Home
-development/samples/JetBoy                   samples/${PLATFORM_NAME}/JetBoy
-development/samples/LunarLander              samples/${PLATFORM_NAME}/LunarLander
-development/samples/MultiResolution          samples/${PLATFORM_NAME}/MultiResolution
-development/samples/NFCDemo                  samples/${PLATFORM_NAME}/NFCDemo
-development/samples/NotePad                  samples/${PLATFORM_NAME}/NotePad
-development/samples/SampleSyncAdapter        samples/${PLATFORM_NAME}/SampleSyncAdapter
-development/samples/SearchableDictionary     samples/${PLATFORM_NAME}/SearchableDictionary
-development/samples/SipDemo                  samples/${PLATFORM_NAME}/SipDemo
-development/samples/SkeletonApp              samples/${PLATFORM_NAME}/SkeletonApp
-development/samples/Snake                    samples/${PLATFORM_NAME}/Snake
-development/samples/SoftKeyboard             samples/${PLATFORM_NAME}/SoftKeyboard
-development/samples/Spinner                  samples/${PLATFORM_NAME}/Spinner
-development/samples/SpinnerTest              samples/${PLATFORM_NAME}/SpinnerTest
-development/samples/TicTacToeLib             samples/${PLATFORM_NAME}/TicTacToeLib
-development/samples/TicTacToeMain            samples/${PLATFORM_NAME}/TicTacToeMain
-development/samples/VoiceRecognitionService  samples/${PLATFORM_NAME}/VoiceRecognitionService
-development/samples/Wiktionary               samples/${PLATFORM_NAME}/Wiktionary
-development/samples/WiktionarySimple         samples/${PLATFORM_NAME}/WiktionarySimple
+development/samples/AccessibilityService       samples/${PLATFORM_NAME}/AccessibilityService
+development/samples/AccelerometerPlay          samples/${PLATFORM_NAME}/AccelerometerPlay
+development/samples/ApiDemos                   samples/${PLATFORM_NAME}/ApiDemos
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-v4_intermediates/android-support-v4.jar    samples/${PLATFORM_NAME}/ApiDemos/libs/android-support-v4.jar
+development/samples/BackupRestore              samples/${PLATFORM_NAME}/BackupRestore
+development/samples/BasicGLSurfaceView         samples/${PLATFORM_NAME}/BasicGLSurfaceView
+development/samples/BluetoothChat              samples/${PLATFORM_NAME}/BluetoothChat
+development/samples/ContactManager             samples/${PLATFORM_NAME}/ContactManager
+development/samples/CrossCompatibility         samples/${PLATFORM_NAME}/CrossCompatibility
+development/samples/CubeLiveWallpaper          samples/${PLATFORM_NAME}/CubeLiveWallpaper
+development/samples/Home                       samples/${PLATFORM_NAME}/Home
+development/samples/HoneycombGallery           samples/${PLATFORM_NAME}/HoneycombGallery
+development/samples/JetBoy                     samples/${PLATFORM_NAME}/JetBoy
+development/samples/LunarLander                samples/${PLATFORM_NAME}/LunarLander
+development/samples/MultiResolution            samples/${PLATFORM_NAME}/MultiResolution
+development/samples/NotePad                    samples/${PLATFORM_NAME}/NotePad
+development/samples/SampleSyncAdapter          samples/${PLATFORM_NAME}/SampleSyncAdapter
+development/samples/SearchableDictionary       samples/${PLATFORM_NAME}/SearchableDictionary
+development/samples/SipDemo                    samples/${PLATFORM_NAME}/SipDemo
+development/samples/SkeletonApp                samples/${PLATFORM_NAME}/SkeletonApp
+development/samples/Snake                      samples/${PLATFORM_NAME}/Snake
+development/samples/SoftKeyboard               samples/${PLATFORM_NAME}/SoftKeyboard
+development/samples/Spinner                    samples/${PLATFORM_NAME}/Spinner
+development/samples/SpinnerTest                samples/${PLATFORM_NAME}/SpinnerTest
+development/samples/TicTacToeLib               samples/${PLATFORM_NAME}/TicTacToeLib
+development/samples/TicTacToeMain              samples/${PLATFORM_NAME}/TicTacToeMain
+development/samples/USB/MissileLauncher        samples/${PLATFORM_NAME}/USB/MissileLauncher
+development/samples/USB/AdbTest                samples/${PLATFORM_NAME}/USB/AdbTest
+development/samples/VoiceRecognitionService    samples/${PLATFORM_NAME}/VoiceRecognitionService
+development/samples/WeatherListWidget          samples/${PLATFORM_NAME}/WeatherListWidget
+development/apps/WidgetPreview                 samples/${PLATFORM_NAME}/WidgetPreview
+development/samples/Wiktionary                 samples/${PLATFORM_NAME}/Wiktionary
+development/samples/WiktionarySimple           samples/${PLATFORM_NAME}/WiktionarySimple
+development/samples/XmlAdapters                samples/${PLATFORM_NAME}/XmlAdapters
+development/samples/RenderScript/Balls         samples/${PLATFORM_NAME}/RenderScript/Balls
+development/samples/RenderScript/Fountain      samples/${PLATFORM_NAME}/RenderScript/Fountain
+development/samples/RenderScript/HelloCompute  samples/${PLATFORM_NAME}/RenderScript/HelloCompute
+development/samples/RenderScript/HelloWorld    samples/${PLATFORM_NAME}/RenderScript/HelloWorld
+development/samples/RenderScript/MiscSamples   samples/${PLATFORM_NAME}/RenderScript/MiscSamples
 
 # NOTICE files are copied by build/core/Makefile from sdk.git
 sdk/files/sdk_files_NOTICE.txt samples/${PLATFORM_NAME}/NOTICE.txt
 
 ##############################################################################
-# Samples Component
+# Add-on Folder
 ##############################################################################
 
 # empty add-on folder with just a readme copied from sdk.git
 sdk/files/README_add-ons.txt add-ons/README.txt
+
+##############################################################################
+# Extra Component: Compatibility
+##############################################################################
+
+development/sdk/compatibility_source.properties                                                   extras/android/compatibility/source.properties
+development/sdk/compatibility_README.txt                                                          extras/android/compatibility/README.txt
+sdk/files/sdk_files_NOTICE.txt                                                                    extras/android/compatibility/NOTICE.txt
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-v4_intermediates/android-support-v4.jar    extras/android/compatibility/v4/android-support-v4.jar
+frameworks/support/v4                                                                             extras/android/compatibility/v4/src
+development/samples/ApiDemos                                                                      extras/android/compatibility/v4/samples/ApiDemos
diff --git a/build/tools/patch_windows_sdk.sh b/build/tools/patch_windows_sdk.sh
index baaa173..17424b7 100755
--- a/build/tools/patch_windows_sdk.sh
+++ b/build/tools/patch_windows_sdk.sh
@@ -59,11 +59,13 @@
 LIB=$TEMP_SDK_DIR/tools/lib
 rm $V $TOOLS/{dmtracedump,etc1tool,hprof-conv,sqlite3,zipalign}
 rm $V $LIB/*/swt.jar
-rm $V $PLATFORM_TOOLS/{adb,aapt,aidl,dx,dexdump}
+rm $V $PLATFORM_TOOLS/{adb,aapt,aidl,dx,dexdump,llvm-rs-cc}
 
 # Copy all the new stuff in tools
 # Note: some tools are first copied here and then moved in platforms/<name>/tools/
 cp $V $WIN_OUT_DIR/host/windows-x86/bin/*.{exe,dll} $TOOLS/
+# Remove some tools we don't want to take in the SDK
+rm $V -f $TOOLS/{fastboot.exe,rs-spec-gen.exe,tblgen.exe}
 mkdir -pv $LIB/x86
 cp $V ${TOPDIR}prebuilt/windows/swt/swt.jar         $LIB/x86/
 mkdir -pv $LIB/x86_64
@@ -97,7 +99,9 @@
 
 # Copy or move platform specific tools to the default platform.
 cp $V ${TOPDIR}dalvik/dx/etc/dx.bat $PLATFORM_TOOLS/
-mv $V $TOOLS/{adb.exe,aapt.exe,aidl.exe,dexdump.exe} $TOOLS/Adb*.dll $PLATFORM_TOOLS/
+mv $V $TOOLS/{adb.exe,aapt.exe,aidl.exe,dexdump.exe} $PLATFORM_TOOLS/
+mv $V $TOOLS/llvm-rs-cc.exe $PLATFORM_TOOLS/
+mv $V $TOOLS/Adb*.dll $PLATFORM_TOOLS/
 
 # Fix EOL chars to make window users happy - fix all files at the top level
 # as well as all batch files including those in platforms/<name>/tools/
diff --git a/build/tools/windows_sdk.mk b/build/tools/windows_sdk.mk
index 1f8bc45..8421a91 100644
--- a/build/tools/windows_sdk.mk
+++ b/build/tools/windows_sdk.mk
@@ -24,17 +24,28 @@
 
 include $(TOPDIR)sdk/build/windows_sdk_tools.mk
 
+# This is the list of target that we want to generate as
+# Windows executables.
 WIN_TARGETS := \
 	aapt adb aidl \
 	etc1tool \
 	dexdump dmtracedump \
 	fastboot \
 	hprof-conv \
+	llvm-rs-cc \
 	prebuilt \
 	sqlite3 \
 	zipalign \
 	$(WIN_SDK_TARGETS)
 
+# This is the list of *Linux* build tools that we need
+# in order to be able to make the WIN_TARGETS. They are
+# build prerequisites.
+WIN_BUILD_PREREQ := \
+	acp \
+	llvm-rs-cc
+
+
 # MAIN_SDK_NAME/DIR is set in build/core/Makefile
 WIN_SDK_NAME := $(subst $(HOST_OS)-$(HOST_ARCH),windows,$(MAIN_SDK_NAME))
 WIN_SDK_DIR  := $(subst $(HOST_OS)-$(HOST_ARCH),windows,$(MAIN_SDK_DIR))
@@ -60,7 +71,7 @@
 win_sdk: $(WIN_SDK_ZIP)
 	$(call winsdk-banner,Done)
 
-winsdk-tools: acp
+winsdk-tools: $(WIN_BUILD_PREREQ)
 	$(call winsdk-banner,Build Windows Tools)
 	$(hide) USE_MINGW=1 USE_CCACHE="" $(MAKE) PRODUCT-$(TARGET_PRODUCT)-$(strip $(WIN_TARGETS)) $(if $(hide),,showcommands)
 
@@ -73,10 +84,7 @@
 	$(hide) USB_DRIVER_HOOK=$(USB_DRIVER_HOOK) \
 		$(TOPDIR)development/build/tools/patch_windows_sdk.sh $(subst @,-q,$(hide)) \
 		$(WIN_SDK_DIR)/$(WIN_SDK_NAME) $(OUT_DIR) $(TOPDIR)
-	# TODO remove test once llvm-rs-cc is merged
-	$(hide) if [ -f $(WIN_SDK_DIR)/$(WIN_SDK_NAME)/platform-tools/llvm-rs-cc.exe ]; then \
-			strip --strip-all $(WIN_SDK_DIR)/$(WIN_SDK_NAME)/platform-tools/llvm-rs-cc.exe; \
-		fi
+	$(hide) strip --strip-all $(WIN_SDK_DIR)/$(WIN_SDK_NAME)/platform-tools/llvm-rs-cc.exe
 	$(hide) $(TOPDIR)sdk/build/patch_windows_sdk.sh $(subst @,-q,$(hide)) \
 		$(WIN_SDK_DIR)/$(WIN_SDK_NAME) $(OUT_DIR) $(TOPDIR)
 	$(hide) ( \
diff --git a/cmds/monkey/monkey b/cmds/monkey/monkey
index 45f43a4..bbe27f6 100755
--- a/cmds/monkey/monkey
+++ b/cmds/monkey/monkey
@@ -3,5 +3,6 @@
 #
 base=/system
 export CLASSPATH=$base/framework/monkey.jar
+trap "" HUP
 exec app_process $base/bin com.android.commands.monkey.Monkey $*
 
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index a1f3060..343c344 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -136,6 +136,17 @@
      */
     private boolean mRequestAppCrashBugreport = false;
 
+    /**Request the bugreport based on the mBugreportFrequency. */
+    private boolean mGetPeriodicBugreport = true;
+
+    /**
+     * Request the bugreport based on the mBugreportFrequency.
+     */
+    private boolean mRequestPeriodicBugreport = false;
+
+    /** Bugreport frequency. */
+    private long mBugreportFrequency = 10;
+
     /** Failure process name */
     private String mReportProcessName;
 
@@ -337,9 +348,8 @@
                 synchronized (Monkey.this) {
                     mAbort = true;
                 }
-                return (mKillProcessAfterError) ? -1 : 0;
             }
-            return 0;
+            return (mKillProcessAfterError) ? -1 : 1;
         }
     }
 
@@ -452,9 +462,6 @@
      * @param args The command-line arguments
      */
     public static void main(String[] args) {
-        // Set ro.monkey if it's not set yet.
-        SystemProperties.set("ro.monkey", "true");
-
         // Set the process name showing in "ps" or "top"
         Process.setArgV0("com.android.commands.monkey");
 
@@ -551,13 +558,13 @@
             mCountEvents = false;
         } else if (mScriptFileNames != null && mScriptFileNames.size() > 1) {
             if (mSetupFileName != null) {
-                mEventSource = new MonkeySourceRandomScript(mSetupFileName, 
+                mEventSource = new MonkeySourceRandomScript(mSetupFileName,
                         mScriptFileNames, mThrottle, mRandomizeThrottle, mRandom,
                         mProfileWaitTime, mDeviceSleepTime, mRandomizeScript);
                 mCount++;
             } else {
                 mEventSource = new MonkeySourceRandomScript(mScriptFileNames,
-                        mThrottle, mRandomizeThrottle, mRandom, 
+                        mThrottle, mRandomizeThrottle, mRandom,
                         mProfileWaitTime, mDeviceSleepTime, mRandomizeScript);
             }
             mEventSource.setVerbose(mVerbose);
@@ -615,12 +622,16 @@
             }
             if (mRequestAppCrashBugreport){
                 getBugreport("app_crash" + mReportProcessName + "_");
-                mRequestAnrBugreport = false;
+                mRequestAppCrashBugreport = false;
             }
             if (mRequestDumpsysMemInfo) {
                 reportDumpsysMemInfo();
                 mRequestDumpsysMemInfo = false;
             }
+            if (mRequestPeriodicBugreport){
+                getBugreport("Bugreport_");
+                mRequestPeriodicBugreport = false;
+            }
         }
 
         if (mGenerateHprof) {
@@ -732,6 +743,9 @@
                 } else if (opt.equals("--pct-anyevent")) {
                     int i = MonkeySourceRandom.FACTOR_ANYTHING;
                     mFactors[i] = -nextOptionLong("any events percentage");
+                } else if (opt.equals("--pct-pinchzoom")) {
+                    int i = MonkeySourceRandom.FACTOR_PINCHZOOM;
+                    mFactors[i] = -nextOptionLong("pinch zoom events percentage");
                 } else if (opt.equals("--pkg-blacklist-file")) {
                     mPkgBlacklistFile = nextOptionData();
                 } else if (opt.equals("--pkg-whitelist-file")) {
@@ -762,6 +776,9 @@
                     mScriptLog = true;
                 } else if (opt.equals("--bugreport")) {
                     mRequestBugreport = true;
+                } else if (opt.equals("--periodic-bugreport")){
+                    mGetPeriodicBugreport = true;
+                    mBugreportFrequency = nextOptionLong("Number of iterations");
                 } else if (opt.equals("-h")) {
                     showUsage();
                     return false;
@@ -861,18 +878,6 @@
      * @return Returns true if ready to rock.
      */
     private boolean checkInternalConfiguration() {
-        // Check KEYCODE name array, make sure it's up to date.
-
-        String lastKeyName = null;
-        try {
-            lastKeyName = MonkeySourceRandom.getLastKeyName();
-        } catch (RuntimeException e) {
-        }
-        if (!"TAG_LAST_KEYCODE".equals(lastKeyName)) {
-            System.err.println("** Error: Key names array malformed (internal error).");
-            return false;
-        }
-
         return true;
     }
 
@@ -1003,7 +1008,11 @@
                 }
                 if (mRequestAppCrashBugreport){
                     getBugreport("app_crash" + mReportProcessName + "_");
-                    mRequestAnrBugreport = false;
+                    mRequestAppCrashBugreport = false;
+                }
+                if (mRequestPeriodicBugreport){
+                    getBugreport("Bugreport_");
+                    mRequestPeriodicBugreport = false;
                 }
                 if (mRequestDumpsysMemInfo) {
                     mRequestDumpsysMemInfo = false;
@@ -1094,6 +1103,12 @@
                 if (!mCountEvents) {
                     cycleCounter++;
                     writeScriptLog(cycleCounter);
+                    //Capture the bugreport after n iteration
+                    if (mGetPeriodicBugreport) {
+                        if ((cycleCounter % mBugreportFrequency) == 0) {
+                            mRequestPeriodicBugreport = true;
+                        }
+                    }
                 } else {
                     // Event Source has signaled that we have no more events to process
                     break;
@@ -1258,7 +1273,7 @@
         usage.append("              [--pct-trackball PERCENT] [--pct-syskeys PERCENT]\n");
         usage.append("              [--pct-nav PERCENT] [--pct-majornav PERCENT]\n");
         usage.append("              [--pct-appswitch PERCENT] [--pct-flip PERCENT]\n");
-        usage.append("              [--pct-anyevent PERCENT]\n");
+        usage.append("              [--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]\n");
         usage.append("              [--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]\n");
         usage.append("              [--pkg-whitelist-file PACKAGE_WHITELIST_FILE]\n");
         usage.append("              [--wait-dbg] [--dbg-no-events]\n");
@@ -1271,6 +1286,7 @@
         usage.append("              [--randomize-script]\n");
         usage.append("              [--script-log]\n");
         usage.append("              [--bugreport]\n");
+        usage.append("              [--periodic-bugreport]\n");
         usage.append("              COUNT\n");
         System.err.println(usage.toString());
     }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyActivityEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyActivityEvent.java
index 262377a..4661d8c 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyActivityEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyActivityEvent.java
@@ -22,7 +22,6 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.view.IWindowManager;
-import android.util.Log;
 
 /**
  * monkey activity event
@@ -57,7 +56,7 @@
     public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
         Intent intent = getEvent();
         if (verbose > 0) {
-            System.out.println(":Switch: " + intent.toURI());
+            System.out.println(":Switch: " + intent.toUri(0));
         }
 
         if (mAlarmTime != 0){
@@ -75,7 +74,7 @@
         } catch (SecurityException e) {
             if (verbose > 0) {
                 System.out.println("** Permissions error starting activity "
-                        + intent.toURI());
+                        + intent.toUri(0));
             }
             return MonkeyEvent.INJECT_ERROR_SECURITY_EXCEPTION;
         }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
index 2783dde..1f703ea 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
@@ -25,7 +25,7 @@
 public abstract class MonkeyEvent {
     protected int eventType;
     public static final int EVENT_TYPE_KEY = 0;
-    public static final int EVENT_TYPE_POINTER = 1;
+    public static final int EVENT_TYPE_TOUCH = 1;
     public static final int EVENT_TYPE_TRACKBALL = 2;
     public static final int EVENT_TYPE_ACTIVITY = 3;
     public static final int EVENT_TYPE_FLIP = 4; // Keyboard flip
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
index d9c68af..455c009 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
@@ -117,11 +117,11 @@
             }
 
             try {
-                System.out.println(":SendKey (" + note + "): "
+                System.out.println(":Sending Key (" + note + "): "
                         + mKeyCode + "    // "
                         + MonkeySourceRandom.getKeyName(mKeyCode));
             } catch (ArrayIndexOutOfBoundsException e) {
-                System.out.println(":SendKey (ACTION_UP): "
+                System.out.println(":Sending Key (" + note + "): "
                         + mKeyCode + "    // Unknown key event");
             }
         }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
index 81c64b4..c59382f 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
@@ -19,144 +19,184 @@
 import android.app.IActivityManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.util.SparseArray;
 import android.view.IWindowManager;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 
 /**
  * monkey motion event
  */
-public class MonkeyMotionEvent extends MonkeyEvent {
-    private long mDownTime = -1;
-    private long mEventTime = -1;    
-    private int mAction = -1;
-    private float mX = -1;
-    private float mY = -1;
-    private float mPressure = -1;
-    private float mSize = -1;
-    private int mMetaState = -1;
-    private float mXPrecision = -1;
-    private float mYPrecision = -1;
-    private int mDeviceId = -1;
-    private int mEdgeFlags = -1;
-    
+public abstract class MonkeyMotionEvent extends MonkeyEvent {
+    private long mDownTime;
+    private long mEventTime;
+    private int mAction;
+    private SparseArray<MotionEvent.PointerCoords> mPointers;
+    private int mMetaState;
+    private float mXPrecision;
+    private float mYPrecision;
+    private int mDeviceId;
+    private int mSource;
+    private int mFlags;
+    private int mEdgeFlags;
+
     //If true, this is an intermediate step (more verbose logging, only)
-    private boolean mIntermediateNote;  
-        
-    public MonkeyMotionEvent(int type, long downAt, int action, 
-            float x, float y, int metaState) {
+    private boolean mIntermediateNote;
+
+    protected MonkeyMotionEvent(int type, int source, int action) {
         super(type);
-        mDownTime = downAt;
+        mSource = source;
+        mDownTime = -1;
+        mEventTime = -1;
         mAction = action;
-        mX = x;
-        mY = y;
-        mMetaState = metaState;
+        mPointers = new SparseArray<MotionEvent.PointerCoords>();
+        mXPrecision = 1;
+        mYPrecision = 1;
     }
-    
-    public MonkeyMotionEvent(int type, long downTime, long eventTime, int action,
-            float x, float y, float pressure, float size, int metaState,
-            float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
-        super(type);
-        mDownTime = downTime;
-        mEventTime = eventTime;
-        mAction = action;
-        mX = x;
-        mY = y;
-        mPressure = pressure;
-        mSize = size;
-        mMetaState = metaState;
-        mXPrecision = xPrecision;
-        mYPrecision = yPrecision;
-        mDeviceId = deviceId;
-        mEdgeFlags = edgeFlags;
-    }    
-    
-    public void setIntermediateNote(boolean b) {
+
+    public MonkeyMotionEvent addPointer(int id, float x, float y) {
+        return addPointer(id, x, y, 0, 0);
+    }
+
+    public MonkeyMotionEvent addPointer(int id, float x, float y,
+            float pressure, float size) {
+        MotionEvent.PointerCoords c = new MotionEvent.PointerCoords();
+        c.x = x;
+        c.y = y;
+        c.pressure = pressure;
+        c.size = size;
+        mPointers.append(id, c);
+        return this;
+    }
+
+    public MonkeyMotionEvent setIntermediateNote(boolean b) {
         mIntermediateNote = b;
+        return this;
     }
-    
+
     public boolean getIntermediateNote() {
         return mIntermediateNote;
     }
-    
-    public float getX() {
-        return mX;
-    }
-    
-    public float getY() {
-        return mY;
-    }
-    
+
     public int getAction() {
         return mAction;
     }
-    
+
     public long getDownTime() {
         return mDownTime;
     }
-    
+
     public long getEventTime() {
         return mEventTime;
     }
-    
-    public void setDownTime(long downTime) {
+
+    public MonkeyMotionEvent setDownTime(long downTime) {
         mDownTime = downTime;
+        return this;
     }
-    
-    public void setEventTime(long eventTime) {
+
+    public MonkeyMotionEvent setEventTime(long eventTime) {
         mEventTime = eventTime;
+        return this;
     }
-    
+
+    public MonkeyMotionEvent setMetaState(int metaState) {
+        mMetaState = metaState;
+        return this;
+    }
+
+    public MonkeyMotionEvent setPrecision(float xPrecision, float yPrecision) {
+        mXPrecision = xPrecision;
+        mYPrecision = yPrecision;
+        return this;
+    }
+
+    public MonkeyMotionEvent setDeviceId(int deviceId) {
+        mDeviceId = deviceId;
+        return this;
+    }
+
+    public MonkeyMotionEvent setEdgeFlags(int edgeFlags) {
+        mEdgeFlags = edgeFlags;
+        return this;
+    }
+
     /**
      * 
      * @return instance of a motion event
      */
     private MotionEvent getEvent() {
-        if (mDeviceId < 0) {
-            return MotionEvent.obtain(mDownTime, SystemClock.uptimeMillis(), 
-                mAction, mX, mY, mMetaState);
+        int pointerCount = mPointers.size();
+        int[] pointerIds = new int[pointerCount];
+        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount];
+        for (int i = 0; i < pointerCount; i++) {
+            pointerIds[i] = mPointers.keyAt(i);
+            pointerCoords[i] = mPointers.valueAt(i);
         }
-        
-        // for scripts
-        return MotionEvent.obtain(mDownTime, mEventTime, 
-                mAction, mX, mY, mPressure, mSize, mMetaState,
-                mXPrecision, mYPrecision, mDeviceId, mEdgeFlags);
+
+        MotionEvent ev = MotionEvent.obtain(mDownTime,
+                mEventTime < 0 ? SystemClock.uptimeMillis() : mEventTime,
+                mAction, pointerCount, pointerIds, pointerCoords,
+                mMetaState, mXPrecision, mYPrecision, mDeviceId, mEdgeFlags, mSource, mFlags);
+        return ev;
     }
 
     @Override
     public boolean isThrottlable() {
-        return (getAction() == KeyEvent.ACTION_UP);
+        return (getAction() == MotionEvent.ACTION_UP);
     }
-    
+
     @Override
     public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
-        
-        String note;
+        MotionEvent me = getEvent();
         if ((verbose > 0 && !mIntermediateNote) || verbose > 1) {
-            if (mAction == MotionEvent.ACTION_DOWN) {
-                note = "DOWN";
-            } else if (mAction == MotionEvent.ACTION_UP) {
-                note = "UP";
-            } else {
-                note = "MOVE";
+            StringBuilder msg = new StringBuilder(":Sending ");
+            msg.append(getTypeLabel()).append(" (");
+            switch (me.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN:
+                    msg.append("ACTION_DOWN");
+                    break;
+                case MotionEvent.ACTION_MOVE:
+                    msg.append("ACTION_MOVE");
+                    break;
+                case MotionEvent.ACTION_UP:
+                    msg.append("ACTION_UP");
+                    break;
+                case MotionEvent.ACTION_CANCEL:
+                    msg.append("ACTION_CANCEL");
+                    break;
+                case MotionEvent.ACTION_POINTER_DOWN:
+                    msg.append("ACTION_POINTER_DOWN ").append(me.getPointerId(me.getActionIndex()));
+                    break;
+                case MotionEvent.ACTION_POINTER_UP:
+                    msg.append("ACTION_POINTER_UP ").append(me.getPointerId(me.getActionIndex()));
+                    break;
+                default:
+                    msg.append(me.getAction());
+                    break;
             }
-            System.out.println(":Sending Pointer ACTION_" + note + 
-                    " x=" + mX + " y=" + mY);
+            msg.append("):");
+
+            int pointerCount = me.getPointerCount();
+            for (int i = 0; i < pointerCount; i++) {
+                msg.append(" ").append(me.getPointerId(i));
+                msg.append(":(").append(me.getX(i)).append(",").append(me.getY(i)).append(")");
+            }
+            System.out.println(msg.toString());
         }
         try {
-            int type = this.getEventType();
-            MotionEvent me = getEvent();
-            
-            if ((type == MonkeyEvent.EVENT_TYPE_POINTER && 
-                    !iwm.injectPointerEvent(me, false))
-                    || (type == MonkeyEvent.EVENT_TYPE_TRACKBALL && 
-                            !iwm.injectTrackballEvent(me, false))) {
+            if (!injectMotionEvent(iwm, me)) {
                 return MonkeyEvent.INJECT_FAIL;
             }
         } catch (RemoteException ex) {
             return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION;
+        } finally {
+            me.recycle();
         }
         return MonkeyEvent.INJECT_SUCCESS;
     }
+
+    protected abstract String getTypeLabel();
+    protected abstract boolean injectMotionEvent(IWindowManager iwm, MotionEvent me)
+            throws RemoteException;
 }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
index a9a1db4..0b4e269 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
@@ -159,8 +159,8 @@
                     return EARG;
                 }
 
-                queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
-                                                         -1, action, x, y, 0));
+                queue.enqueueEvent(new MonkeyTouchEvent(action)
+                        .addPointer(0, x, y));
                 return OK;
             }
             return EARG;
@@ -187,8 +187,8 @@
                     Log.e(TAG, "Got something that wasn't a number", e);
                     return EARG;
                 }
-                queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, -1,
-                                                         MotionEvent.ACTION_MOVE, dx, dy, 0));
+                queue.enqueueEvent(new MonkeyTrackballEvent(MotionEvent.ACTION_MOVE)
+                        .addPointer(0, dx, dy));
                 return OK;
 
             }
@@ -294,7 +294,7 @@
                 // Convert the string to an array of KeyEvent's for
                 // the built in keymap.
                 KeyCharacterMap keyCharacterMap = KeyCharacterMap.
-                        load(KeyCharacterMap.BUILT_IN_KEYBOARD);
+                        load(KeyCharacterMap.VIRTUAL_KEYBOARD);
                 KeyEvent[] events = keyCharacterMap.getEvents(chars);
 
                 // enqueue all the events we just got.
@@ -341,12 +341,10 @@
                     return EARG;
                 }
 
-                queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
-                                                         -1, MotionEvent.ACTION_DOWN,
-                                                         x, y, 0));
-                queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
-                                                         -1, MotionEvent.ACTION_UP,
-                                                         x, y, 0));
+                queue.enqueueEvent(new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
+                        .addPointer(0, x, y));
+                queue.enqueueEvent(new MonkeyTouchEvent(MotionEvent.ACTION_UP)
+                        .addPointer(0, x, y));
                 return OK;
             }
             return EARG;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
index 3d7834c..af740b3 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
@@ -17,6 +17,7 @@
 package com.android.commands.monkey;
 
 import android.content.ComponentName;
+import android.graphics.PointF;
 import android.os.SystemClock;
 import android.view.Display;
 import android.view.KeyCharacterMap;
@@ -48,7 +49,7 @@
     private static final int[] SYS_KEYS = {
         KeyEvent.KEYCODE_HOME, KeyEvent.KEYCODE_BACK,
         KeyEvent.KEYCODE_CALL, KeyEvent.KEYCODE_ENDCALL,
-        KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN,
+        KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE,
         KeyEvent.KEYCODE_MUTE,
     };
     /** If a physical key exists? */
@@ -63,134 +64,21 @@
         }
     }
 
-    /** Nice names for all key events. */
-    private static final String[] KEY_NAMES = {
-        "KEYCODE_UNKNOWN",
-        "KEYCODE_SOFT_LEFT",
-        "KEYCODE_SOFT_RIGHT",
-        "KEYCODE_HOME",
-        "KEYCODE_BACK",
-        "KEYCODE_CALL",
-        "KEYCODE_ENDCALL",
-        "KEYCODE_0",
-        "KEYCODE_1",
-        "KEYCODE_2",
-        "KEYCODE_3",
-        "KEYCODE_4",
-        "KEYCODE_5",
-        "KEYCODE_6",
-        "KEYCODE_7",
-        "KEYCODE_8",
-        "KEYCODE_9",
-        "KEYCODE_STAR",
-        "KEYCODE_POUND",
-        "KEYCODE_DPAD_UP",
-        "KEYCODE_DPAD_DOWN",
-        "KEYCODE_DPAD_LEFT",
-        "KEYCODE_DPAD_RIGHT",
-        "KEYCODE_DPAD_CENTER",
-        "KEYCODE_VOLUME_UP",
-        "KEYCODE_VOLUME_DOWN",
-        "KEYCODE_POWER",
-        "KEYCODE_CAMERA",
-        "KEYCODE_CLEAR",
-        "KEYCODE_A",
-        "KEYCODE_B",
-        "KEYCODE_C",
-        "KEYCODE_D",
-        "KEYCODE_E",
-        "KEYCODE_F",
-        "KEYCODE_G",
-        "KEYCODE_H",
-        "KEYCODE_I",
-        "KEYCODE_J",
-        "KEYCODE_K",
-        "KEYCODE_L",
-        "KEYCODE_M",
-        "KEYCODE_N",
-        "KEYCODE_O",
-        "KEYCODE_P",
-        "KEYCODE_Q",
-        "KEYCODE_R",
-        "KEYCODE_S",
-        "KEYCODE_T",
-        "KEYCODE_U",
-        "KEYCODE_V",
-        "KEYCODE_W",
-        "KEYCODE_X",
-        "KEYCODE_Y",
-        "KEYCODE_Z",
-        "KEYCODE_COMMA",
-        "KEYCODE_PERIOD",
-        "KEYCODE_ALT_LEFT",
-        "KEYCODE_ALT_RIGHT",
-        "KEYCODE_SHIFT_LEFT",
-        "KEYCODE_SHIFT_RIGHT",
-        "KEYCODE_TAB",
-        "KEYCODE_SPACE",
-        "KEYCODE_SYM",
-        "KEYCODE_EXPLORER",
-        "KEYCODE_ENVELOPE",
-        "KEYCODE_ENTER",
-        "KEYCODE_DEL",
-        "KEYCODE_GRAVE",
-        "KEYCODE_MINUS",
-        "KEYCODE_EQUALS",
-        "KEYCODE_LEFT_BRACKET",
-        "KEYCODE_RIGHT_BRACKET",
-        "KEYCODE_BACKSLASH",
-        "KEYCODE_SEMICOLON",
-        "KEYCODE_APOSTROPHE",
-        "KEYCODE_SLASH",
-        "KEYCODE_AT",
-        "KEYCODE_NUM",
-        "KEYCODE_HEADSETHOOK",
-        "KEYCODE_FOCUS",
-        "KEYCODE_PLUS",
-        "KEYCODE_MENU",
-        "KEYCODE_NOTIFICATION",
-        "KEYCODE_SEARCH",
-        "KEYCODE_PLAYPAUSE",
-        "KEYCODE_STOP",
-        "KEYCODE_NEXTSONG",
-        "KEYCODE_PREVIOUSSONG",
-        "KEYCODE_REWIND",
-        "KEYCODE_FORWARD",
-        "KEYCODE_MUTE",
-        "KEYCODE_PAGE_UP",
-        "KEYCODE_PAGE_DOWN",
-        "KEYCODE_PICTSYMBOLS",
-        "KEYCODE_SWITCH_CHARSET",
-        "KEYCODE_BUTTON_A",
-        "KEYCODE_BUTTON_B",
-        "KEYCODE_BUTTON_C",
-        "KEYCODE_BUTTON_X",
-        "KEYCODE_BUTTON_Y",
-        "KEYCODE_BUTTON_Z",
-        "KEYCODE_BUTTON_L1",
-        "KEYCODE_BUTTON_R1",
-        "KEYCODE_BUTTON_L2",
-        "KEYCODE_BUTTON_R2",
-        "KEYCODE_BUTTON_THUMBL",
-        "KEYCODE_BUTTON_THUMBR",
-        "KEYCODE_BUTTON_START",
-        "KEYCODE_BUTTON_SELECT",
-        "KEYCODE_BUTTON_MODE",
-
-        "TAG_LAST_KEYCODE"      // EOL.  used to keep the lists in sync
-    };
-
     public static final int FACTOR_TOUCH        = 0;
     public static final int FACTOR_MOTION       = 1;
-    public static final int FACTOR_TRACKBALL    = 2;
-    public static final int FACTOR_NAV          = 3;
-    public static final int FACTOR_MAJORNAV     = 4;
-    public static final int FACTOR_SYSOPS       = 5;
-    public static final int FACTOR_APPSWITCH    = 6;
-    public static final int FACTOR_FLIP         = 7;
-    public static final int FACTOR_ANYTHING     = 8;
-    public static final int FACTORZ_COUNT       = 9;    // should be last+1
+    public static final int FACTOR_PINCHZOOM    = 2;
+    public static final int FACTOR_TRACKBALL    = 3;
+    public static final int FACTOR_NAV          = 4;
+    public static final int FACTOR_MAJORNAV     = 5;
+    public static final int FACTOR_SYSOPS       = 6;
+    public static final int FACTOR_APPSWITCH    = 7;
+    public static final int FACTOR_FLIP         = 8;
+    public static final int FACTOR_ANYTHING     = 9;
+    public static final int FACTORZ_COUNT       = 10;    // should be last+1
 
+    private static final int GESTURE_TAP = 0;
+    private static final int GESTURE_DRAG = 1;
+    private static final int GESTURE_PINCH_OR_ZOOM = 2;
 
     /** percentages for each type of event.  These will be remapped to working
      * values after we read any optional values.
@@ -205,15 +93,8 @@
 
     private boolean mKeyboardOpen = false;
 
-    /**
-     * @return the last name in the key list
-     */
-    public static String getLastKeyName() {
-        return KEY_NAMES[KeyEvent.getMaxKeyCode() + 1];
-    }
-
     public static String getKeyName(int keycode) {
-        return KEY_NAMES[keycode];
+        return KeyEvent.keyCodeToString(keycode);
     }
 
     /**
@@ -224,12 +105,7 @@
      * @returns the intenger keyCode value, or -1 if not found
      */
     public static int getKeyCode(String keyName) {
-        for (int x = 0; x < KEY_NAMES.length; x++) {
-            if (KEY_NAMES[x].equals(keyName)) {
-                return x;
-            }
-        }
-        return -1;
+        return KeyEvent.keyCodeFromString(keyName);
     }
 
     public MonkeySourceRandom(Random random, ArrayList<ComponentName> MainApps,
@@ -245,7 +121,8 @@
         mFactors[FACTOR_SYSOPS] = 2.0f;
         mFactors[FACTOR_APPSWITCH] = 2.0f;
         mFactors[FACTOR_FLIP] = 1.0f;
-        mFactors[FACTOR_ANYTHING] = 15.0f;
+        mFactors[FACTOR_ANYTHING] = 13.0f;
+        mFactors[FACTOR_PINCHZOOM] = 2.0f;
 
         mRandom = random;
         mMainApps = MainApps;
@@ -367,46 +244,84 @@
      * generate fling gestures, which are important).
      *
      * @param random Random number source for positioning
-     * @param motionEvent If false, touch/release.  If true, touch/move/release.
+     * @param gesture The gesture to perform.
      *
      */
-    private void generateMotionEvent(Random random, boolean motionEvent){
-
+    private void generatePointerEvent(Random random, int gesture){
         Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
 
-        float x = Math.abs(random.nextInt() % display.getWidth());
-        float y = Math.abs(random.nextInt() % display.getHeight());
-        long downAt = SystemClock.uptimeMillis();
-        long eventTime = SystemClock.uptimeMillis();
-        if (downAt == -1) {
-            downAt = eventTime;
-        }
+        PointF p1 = randomPoint(random, display);
+        PointF v1 = randomVector(random);
 
-        MonkeyMotionEvent e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
-                downAt, MotionEvent.ACTION_DOWN, x, y, 0);
-        e.setIntermediateNote(false);
-        mQ.addLast(e);
+        long downAt = SystemClock.uptimeMillis();
+
+        mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
+                .setDownTime(downAt)
+                .addPointer(0, p1.x, p1.y)
+                .setIntermediateNote(false));
 
         // sometimes we'll move during the touch
-        if (motionEvent) {
+        if (gesture == GESTURE_DRAG) {
             int count = random.nextInt(10);
             for (int i = 0; i < count; i++) {
-                // generate some slop in the up event
-                x = (x + (random.nextInt() % 10)) % display.getWidth();
-                y = (y + (random.nextInt() % 10)) % display.getHeight();
+                randomWalk(random, display, p1, v1);
 
-                e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
-                        downAt, MotionEvent.ACTION_MOVE, x, y, 0);
-                e.setIntermediateNote(true);
-                mQ.addLast(e);
+                mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
+                        .setDownTime(downAt)
+                        .addPointer(0, p1.x, p1.y)
+                        .setIntermediateNote(true));
             }
+        } else if (gesture == GESTURE_PINCH_OR_ZOOM) {
+            PointF p2 = randomPoint(random, display);
+            PointF v2 = randomVector(random);
+
+            randomWalk(random, display, p1, v1);
+            mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_DOWN
+                            | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
+                    .setDownTime(downAt)
+                    .addPointer(0, p1.x, p1.y).addPointer(1, p2.x, p2.y)
+                    .setIntermediateNote(true));
+
+            int count = random.nextInt(10);
+            for (int i = 0; i < count; i++) {
+                randomWalk(random, display, p1, v1);
+                randomWalk(random, display, p2, v2);
+
+                mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
+                        .setDownTime(downAt)
+                        .addPointer(0, p1.x, p1.y).addPointer(1, p2.x, p2.y)
+                        .setIntermediateNote(true));
+            }
+
+            randomWalk(random, display, p1, v1);
+            randomWalk(random, display, p2, v2);
+            mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_UP
+                            | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
+                    .setDownTime(downAt)
+                    .addPointer(0, p1.x, p1.y).addPointer(1, p2.x, p2.y)
+                    .setIntermediateNote(true));
         }
 
-        // TODO generate some slop in the up event
-        e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
-                downAt, MotionEvent.ACTION_UP, x, y, 0);
-        e.setIntermediateNote(false);
-        mQ.addLast(e);
+        randomWalk(random, display, p1, v1);
+        mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_UP)
+                .setDownTime(downAt)
+                .addPointer(0, p1.x, p1.y)
+                .setIntermediateNote(false));
+    }
+
+    private PointF randomPoint(Random random, Display display) {
+        return new PointF(random.nextInt(display.getWidth()), random.nextInt(display.getHeight()));
+    }
+
+    private PointF randomVector(Random random) {
+        return new PointF((random.nextFloat() - 0.5f) * 50, (random.nextFloat() - 0.5f) * 50);
+    }
+
+    private void randomWalk(Random random, Display display, PointF point, PointF vector) {
+        point.x = (float) Math.max(Math.min(point.x + random.nextFloat() * vector.x,
+                display.getWidth()), 0);
+        point.y = (float) Math.max(Math.min(point.y + random.nextFloat() * vector.y,
+                display.getHeight()), 0);
     }
 
     /**
@@ -428,34 +343,29 @@
 
         boolean drop = false;
         int count = random.nextInt(10);
-        MonkeyMotionEvent e;
         for (int i = 0; i < 10; ++i) {
             // generate a small random step
             int dX = random.nextInt(10) - 5;
             int dY = random.nextInt(10) - 5;
 
-
-            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, -1,
-                    MotionEvent.ACTION_MOVE, dX, dY, 0);
-            e.setIntermediateNote(i > 0);
-            mQ.addLast(e);
+            mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_MOVE)
+                    .addPointer(0, dX, dY)
+                    .setIntermediateNote(i > 0));
         }
 
         // 10% of trackball moves end with a click
         if (0 == random.nextInt(10)) {
             long downAt = SystemClock.uptimeMillis();
 
+            mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_DOWN)
+                    .setDownTime(downAt)
+                    .addPointer(0, 0, 0)
+                    .setIntermediateNote(true));
 
-            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt,
-                    MotionEvent.ACTION_DOWN, 0, 0, 0);
-            e.setIntermediateNote(true);
-            mQ.addLast(e);
-
-
-            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt,
-                    MotionEvent.ACTION_UP, 0, 0, 0);
-            e.setIntermediateNote(false);
-            mQ.addLast(e);
+            mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_UP)
+                    .setDownTime(downAt)
+                    .addPointer(0, 0, 0)
+                    .setIntermediateNote(false));
         }
     }
 
@@ -466,14 +376,16 @@
         float cls = mRandom.nextFloat();
         int lastKey = 0;
 
-        boolean touchEvent = cls < mFactors[FACTOR_TOUCH];
-        boolean motionEvent = !touchEvent && (cls < mFactors[FACTOR_MOTION]);
-        if (touchEvent || motionEvent) {
-            generateMotionEvent(mRandom, motionEvent);
+        if (cls < mFactors[FACTOR_TOUCH]) {
+            generatePointerEvent(mRandom, GESTURE_TAP);
             return;
-        }
-
-        if (cls < mFactors[FACTOR_TRACKBALL]) {
+        } else if (cls < mFactors[FACTOR_MOTION]) {
+            generatePointerEvent(mRandom, GESTURE_DRAG);
+            return;
+        } else if (cls < mFactors[FACTOR_PINCHZOOM]) {
+            generatePointerEvent(mRandom, GESTURE_PINCH_OR_ZOOM);
+            return;
+        } else if (cls < mFactors[FACTOR_TRACKBALL]) {
             generateTrackballEvent(mRandom);
             return;
         }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
index 6defcb0..09ec8e9 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.os.SystemClock;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 
 import java.io.BufferedReader;
 import java.io.DataInputStream;
@@ -112,6 +113,10 @@
 
     private static final String EVENT_KEYWORD_INPUT_STRING = "DispatchString";
 
+    private static final String EVENT_KEYWORD_PRESSANDHOLD = "PressAndHold";
+
+    private static final String EVENT_KEYWORD_DRAG = "Drag";
+
     // a line at the end of the header
     private static final String STARTING_DATA_LINE = "start data >>";
 
@@ -267,12 +272,21 @@
                 float yPrecision = Float.parseFloat(args[9]);
                 int device = Integer.parseInt(args[10]);
                 int edgeFlags = Integer.parseInt(args[11]);
-                int type = MonkeyEvent.EVENT_TYPE_TRACKBALL;
+
+                MonkeyMotionEvent e;
                 if (s.indexOf("Pointer") > 0) {
-                    type = MonkeyEvent.EVENT_TYPE_POINTER;
+                    e = new MonkeyTouchEvent(action);
+                } else {
+                    e = new MonkeyTrackballEvent(action);
                 }
-                MonkeyMotionEvent e = new MonkeyMotionEvent(type, downTime, eventTime, action, x,
-                        y, pressure, size, metaState, xPrecision, yPrecision, device, edgeFlags);
+
+                e.setDownTime(downTime)
+                        .setEventTime(eventTime)
+                        .setMetaState(metaState)
+                        .setPrecision(xPrecision, yPrecision)
+                        .setDeviceId(device)
+                        .setEdgeFlags(edgeFlags)
+                        .addPointer(0, x, y, pressure, size);
                 mQ.addLast(e);
             } catch (NumberFormatException e) {
             }
@@ -287,25 +301,45 @@
 
                 // Set the default parameters
                 long downTime = SystemClock.uptimeMillis();
-                float pressure = 1;
-                float xPrecision = 1;
-                float yPrecision = 1;
-                int edgeFlags = 0;
-                float size = 5;
-                int device = 0;
-                int metaState = 0;
-                int type = MonkeyEvent.EVENT_TYPE_POINTER;
 
-                MonkeyMotionEvent e1 =
-                        new MonkeyMotionEvent(type, downTime, downTime, KeyEvent.ACTION_DOWN, x,
-                                y, pressure, size, metaState, xPrecision, yPrecision, device,
-                                edgeFlags);
-                MonkeyMotionEvent e2 =
-                        new MonkeyMotionEvent(type, downTime, downTime, KeyEvent.ACTION_UP, x,
-                                y, pressure, size, metaState, xPrecision, yPrecision, device,
-                                edgeFlags);
+                MonkeyMotionEvent e1 = new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
+                        .setDownTime(downTime)
+                        .setEventTime(downTime)
+                        .addPointer(0, x, y, 1, 5);
+                MonkeyMotionEvent e2 = new MonkeyTouchEvent(MotionEvent.ACTION_UP)
+                        .setDownTime(downTime)
+                        .setEventTime(downTime)
+                        .addPointer(0, x, y, 1, 5);
                 mQ.addLast(e1);
                 mQ.addLast(e2);
+            } catch (NumberFormatException e) {
+                System.err.println("// " + e.toString());
+            }
+            return;
+        }
+
+        //Handle the press and hold
+        if ((s.indexOf(EVENT_KEYWORD_PRESSANDHOLD) >= 0) && args.length == 3) {
+            try {
+                float x = Float.parseFloat(args[0]);
+                float y = Float.parseFloat(args[1]);
+                long pressDuration = Long.parseLong(args[2]);
+
+                // Set the default parameters
+                long downTime = SystemClock.uptimeMillis();
+
+                MonkeyMotionEvent e1 = new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
+                        .setDownTime(downTime)
+                        .setEventTime(downTime)
+                        .addPointer(0, x, y, 1, 5);
+                MonkeyWaitEvent e2 = new MonkeyWaitEvent(pressDuration);
+                MonkeyMotionEvent e3 = new MonkeyTouchEvent(MotionEvent.ACTION_UP)
+                        .setDownTime(downTime + pressDuration)
+                        .setEventTime(downTime + pressDuration)
+                        .addPointer(0, x, y, 1, 5);
+                mQ.addLast(e1);
+                mQ.addLast(e2);
+                mQ.addLast(e2);
 
             } catch (NumberFormatException e) {
                 System.err.println("// " + e.toString());
@@ -313,6 +347,44 @@
             return;
         }
 
+        // Handle drag event
+        if ((s.indexOf(EVENT_KEYWORD_DRAG) >= 0) && args.length == 5) {
+            float xStart = Float.parseFloat(args[0]);
+            float yStart = Float.parseFloat(args[1]);
+            float xEnd = Float.parseFloat(args[2]);
+            float yEnd = Float.parseFloat(args[3]);
+            int stepCount = Integer.parseInt(args[4]);
+
+            float x = xStart;
+            float y = yStart;
+            long downTime = SystemClock.uptimeMillis();
+            long eventTime = SystemClock.uptimeMillis();
+
+            if (stepCount > 0) {
+                float xStep = (xEnd - xStart) / stepCount;
+                float yStep = (yEnd - yStart) / stepCount;
+
+                MonkeyMotionEvent e =
+                        new MonkeyTouchEvent(MotionEvent.ACTION_DOWN).setDownTime(downTime)
+                                .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
+                mQ.addLast(e);
+
+                for (int i = 0; i < stepCount; ++i) {
+                    x += xStep;
+                    y += yStep;
+                    eventTime = SystemClock.uptimeMillis();
+                    e = new MonkeyTouchEvent(MotionEvent.ACTION_MOVE).setDownTime(downTime)
+                        .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
+                    mQ.addLast(e);
+                }
+
+                eventTime = SystemClock.uptimeMillis();
+                e = new MonkeyTouchEvent(MotionEvent.ACTION_UP).setDownTime(downTime)
+                    .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
+                mQ.addLast(e);
+            }
+        }
+
         // Handle flip events
         if (s.indexOf(EVENT_KEYWORD_FLIP) >= 0 && args.length == 1) {
             boolean keyboardOpen = Boolean.parseBoolean(args[0]);
@@ -597,41 +669,19 @@
     }
 
     /**
-     * Adjust motion downtime and eventtime according to both recorded values
-     * and current system time.
+     * Adjust motion downtime and eventtime according to current system time.
      *
      * @param e A KeyEvent
      */
     private void adjustMotionEventTime(MonkeyMotionEvent e) {
+        long updatedDownTime = 0;
+
         if (e.getEventTime() < 0) {
             return;
-        }
-        long thisDownTime = 0;
-        long thisEventTime = 0;
-        long expectedDelay = 0;
-
-        if (mLastRecordedEventTime <= 0) {
-            // first time event
-            thisDownTime = SystemClock.uptimeMillis();
-            thisEventTime = thisDownTime;
-        } else {
-            if (e.getDownTime() != mLastRecordedDownTimeMotion) {
-                thisDownTime = e.getDownTime();
-            } else {
-                thisDownTime = mLastExportDownTimeMotion;
-            }
-            expectedDelay = (long) ((e.getEventTime() - mLastRecordedEventTime) * mSpeed);
-            thisEventTime = mLastExportEventTime + expectedDelay;
-            // add sleep to simulate everything in recording
-            needSleep(expectedDelay - SLEEP_COMPENSATE_DIFF);
-        }
-
-        mLastRecordedDownTimeMotion = e.getDownTime();
-        mLastRecordedEventTime = e.getEventTime();
-        e.setDownTime(thisDownTime);
-        e.setEventTime(thisEventTime);
-        mLastExportDownTimeMotion = thisDownTime;
-        mLastExportEventTime = thisEventTime;
+        }      
+        updatedDownTime = SystemClock.uptimeMillis();
+        e.setDownTime(updatedDownTime);
+        e.setEventTime(updatedDownTime);
     }
 
     /**
@@ -665,7 +715,7 @@
 
         if (ev.getEventType() == MonkeyEvent.EVENT_TYPE_KEY) {
             adjustKeyEventTime((MonkeyKeyEvent) ev);
-        } else if (ev.getEventType() == MonkeyEvent.EVENT_TYPE_POINTER
+        } else if (ev.getEventType() == MonkeyEvent.EVENT_TYPE_TOUCH
                 || ev.getEventType() == MonkeyEvent.EVENT_TYPE_TRACKBALL) {
             adjustMotionEventTime((MonkeyMotionEvent) ev);
         }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyTouchEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyTouchEvent.java
new file mode 100644
index 0000000..7a91c46
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyTouchEvent.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.monkey;
+
+import android.os.RemoteException;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+
+/**
+ * monkey touch event
+ */
+public class MonkeyTouchEvent extends MonkeyMotionEvent {
+    public MonkeyTouchEvent(int action) {
+        super(MonkeyEvent.EVENT_TYPE_TOUCH, InputDevice.SOURCE_TOUCHSCREEN, action);
+    }
+
+    @Override
+    protected String getTypeLabel() {
+        return "Touch";
+    }
+
+    @Override
+    protected boolean injectMotionEvent(IWindowManager iwm, MotionEvent me)
+            throws RemoteException {
+        return iwm.injectPointerEvent(me, false);
+    }
+}
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyTrackballEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyTrackballEvent.java
new file mode 100644
index 0000000..5033be0
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyTrackballEvent.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.monkey;
+
+import android.os.RemoteException;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+
+/**
+ * monkey trackball event
+ */
+public class MonkeyTrackballEvent extends MonkeyMotionEvent {
+    public MonkeyTrackballEvent(int action) {
+        super(MonkeyEvent.EVENT_TYPE_TRACKBALL, InputDevice.SOURCE_TRACKBALL, action);
+    }
+
+    @Override
+    protected String getTypeLabel() {
+        return "Trackball";
+    }
+
+    @Override
+    protected boolean injectMotionEvent(IWindowManager iwm, MotionEvent me)
+            throws RemoteException {
+        return iwm.injectTrackballEvent(me, false);
+    }
+}
diff --git a/docs/copyright-templates/asm.txt b/docs/copyright-templates/asm.txt
index da03f47..f33c86d 100644
--- a/docs/copyright-templates/asm.txt
+++ b/docs/copyright-templates/asm.txt
@@ -1,4 +1,4 @@
-; Copyright (C) 2010 The Android Open Source Project
+; Copyright (C) 2011 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.
diff --git a/docs/copyright-templates/bash.txt b/docs/copyright-templates/bash.txt
index 7a0cbd4..ae90a87 100644
--- a/docs/copyright-templates/bash.txt
+++ b/docs/copyright-templates/bash.txt
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# Copyright (C) 2010 The Android Open Source Project
+# Copyright (C) 2011 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.
diff --git a/docs/copyright-templates/bsd/c.txt b/docs/copyright-templates/bsd/c.txt
index 56e5294..39e77f0 100644
--- a/docs/copyright-templates/bsd/c.txt
+++ b/docs/copyright-templates/bsd/c.txt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/docs/copyright-templates/c.txt b/docs/copyright-templates/c.txt
index e3dd5ee..efa50f3 100644
--- a/docs/copyright-templates/c.txt
+++ b/docs/copyright-templates/c.txt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 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.
diff --git a/docs/copyright-templates/java.txt b/docs/copyright-templates/java.txt
index e3dd5ee..efa50f3 100644
--- a/docs/copyright-templates/java.txt
+++ b/docs/copyright-templates/java.txt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 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.
diff --git a/docs/copyright-templates/make.txt b/docs/copyright-templates/make.txt
index 01a0ff3..851a7a8 100644
--- a/docs/copyright-templates/make.txt
+++ b/docs/copyright-templates/make.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 The Android Open Source Project
+# Copyright (C) 2011 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.
diff --git a/docs/copyright-templates/plain.txt b/docs/copyright-templates/plain.txt
index da97d29..12f1016 100644
--- a/docs/copyright-templates/plain.txt
+++ b/docs/copyright-templates/plain.txt
@@ -1,4 +1,4 @@
-Copyright (C) 2010 The Android Open Source Project
+Copyright (C) 2011 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.
diff --git a/docs/copyright-templates/sh.txt b/docs/copyright-templates/sh.txt
index fbe9d5e..7a3adb8 100644
--- a/docs/copyright-templates/sh.txt
+++ b/docs/copyright-templates/sh.txt
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright (C) 2010 The Android Open Source Project
+# Copyright (C) 2011 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.
diff --git a/docs/copyright-templates/xml.txt b/docs/copyright-templates/xml.txt
index b479654..1be0191 100644
--- a/docs/copyright-templates/xml.txt
+++ b/docs/copyright-templates/xml.txt
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 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.
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index debf9a1..1323287 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="packages/apps/AccountsAndSyncSettings/src"/>
 	<classpathentry kind="src" path="packages/apps/Bluetooth/src"/>
 	<classpathentry kind="src" path="packages/apps/Browser/src"/>
 	<classpathentry kind="src" path="packages/apps/Calendar/src"/>
@@ -10,6 +9,8 @@
 	<classpathentry kind="src" path="packages/apps/Contacts/src"/>
 	<classpathentry kind="src" path="packages/apps/DeskClock/src"/>
 	<classpathentry kind="src" path="packages/apps/Email/src"/>
+	<classpathentry kind="src" path="packages/apps/Email/emailcommon/src"/>
+	<classpathentry kind="src" path="packages/apps/Exchange/src"/>
 	<classpathentry kind="src" path="packages/apps/Gallery3D/src"/>
 	<classpathentry kind="src" path="packages/apps/HTMLViewer/src"/>
 	<classpathentry kind="src" path="packages/apps/Launcher2/src"/>
@@ -21,7 +22,6 @@
 	<classpathentry kind="src" path="packages/apps/Settings/src"/>
 	<classpathentry kind="src" path="packages/apps/SoundRecorder/src"/>
 	<classpathentry kind="src" path="packages/apps/Stk/src"/>
-	<classpathentry kind="src" path="packages/apps/Tag/src"/>
 	<classpathentry kind="src" path="packages/apps/VoiceDialer/src"/>
 	<classpathentry kind="src" path="packages/providers/CalendarProvider/src"/>
 	<classpathentry kind="src" path="packages/providers/ContactsProvider/src"/>
@@ -29,20 +29,22 @@
 	<classpathentry kind="src" path="packages/providers/DrmProvider/src"/>
 	<classpathentry kind="src" path="packages/providers/MediaProvider/src"/>
 	<classpathentry kind="src" path="packages/providers/TelephonyProvider/src"/>
-	<classpathentry kind="src" path="frameworks/base/awt"/>
 	<classpathentry kind="src" path="frameworks/base/cmds/am/src"/>
 	<classpathentry kind="src" path="frameworks/base/cmds/input/src"/>
 	<classpathentry kind="src" path="frameworks/base/cmds/pm/src"/>
 	<classpathentry kind="src" path="frameworks/base/cmds/svc/src"/>
 	<classpathentry kind="src" path="frameworks/base/core/java"/>
 	<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
+	<classpathentry kind="src" path="frameworks/base/drm/java"/>
 	<classpathentry kind="src" path="frameworks/base/graphics/java"/>
+	<classpathentry kind="src" path="frameworks/base/icu4j/java"/>
 	<classpathentry kind="src" path="frameworks/base/keystore/java"/>
 	<classpathentry kind="src" path="frameworks/base/location/java"/>
 	<classpathentry kind="src" path="frameworks/base/media/java"/>
 	<classpathentry kind="src" path="frameworks/base/obex"/>
 	<classpathentry kind="src" path="frameworks/base/opengl/java"/>
 	<classpathentry kind="src" path="frameworks/base/packages/SettingsProvider/src"/>
+	<classpathentry kind="src" path="frameworks/base/packages/SystemUI/src"/>
 	<classpathentry kind="src" path="frameworks/base/policy/src"/>
 	<classpathentry kind="src" path="frameworks/base/sax/java"/>
 	<classpathentry kind="src" path="frameworks/base/services/java"/>
@@ -51,7 +53,9 @@
 	<classpathentry kind="src" path="frameworks/base/voip/java"/>
 	<classpathentry kind="src" path="frameworks/base/vpn/java"/>
 	<classpathentry kind="src" path="frameworks/base/wifi/java"/>
+	<classpathentry kind="src" path="frameworks/ex/carousel/java"/>
 	<classpathentry kind="src" path="frameworks/ex/common/java"/>
+	<classpathentry kind="src" path="frameworks/opt/vcard/java"/>
 	<classpathentry kind="src" path="development/samples/ApiDemos/src"/>
 	<classpathentry kind="src" path="development/samples/ApiDemos/tests/src"/>
 	<classpathentry kind="src" path="development/samples/Compass/src"/>
@@ -69,7 +73,6 @@
 	<classpathentry kind="src" path="development/samples/Snake/tests/src"/>
 	<classpathentry kind="src" path="development/apps/Term/src"/>
 	<classpathentry kind="src" path="libcore/dalvik/src/main/java"/>
-	<classpathentry kind="src" path="libcore/icu/src/main/java"/>
 	<classpathentry kind="src" path="libcore/json/src/main/java"/>
 	<classpathentry kind="src" path="libcore/junit/src/main/java"/>
 	<classpathentry kind="src" path="libcore/luni/src/main/java"/>
@@ -78,10 +81,13 @@
 	<classpathentry kind="src" path="out/target/common/obj/APPS/Browser_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/CalendarProvider_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/ContactsProvider_intermediates/src/src"/>
-	<classpathentry kind="src" path="out/target/common/obj/APPS/Email_intermediates/src/src"/>
+	<classpathentry kind="src" path="out/target/common/obj/APPS/Launcher2_intermediates/src/renderscript/src"/>
+	<classpathentry kind="src" path="out/target/common/obj/APPS/MediaProvider_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/Music_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/Phone_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/QuickSearchBox_intermediates/src/src"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/android-common-carousel_intermediates/src/renderscript/src"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/com.android.emailcommon_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/location/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java"/>
@@ -91,10 +97,15 @@
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/wifi/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/services_intermediates/src"/>
 	<classpathentry kind="src" path="out/target/common/R"/>
-	<classpathentry kind="src" path="external/tagsoup/src"/>
 	<classpathentry kind="src" path="external/apache-http/src"/>
 	<classpathentry kind="src" path="external/bouncycastle/src/main/java"/>
+	<classpathentry kind="src" path="external/libphonenumber/java/src"/>
 	<classpathentry kind="src" path="external/nist-sip/java"/>
+	<classpathentry kind="src" path="external/tagsoup/src"/>
+	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes-jarjar.jar"/>
+	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/android-support-v4_intermediates/javalib.jar"/>
+	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/google-common_intermediates/javalib.jar"/>
+	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/gsf-client_intermediates/javalib.jar"/>
 	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/guava_intermediates/javalib.jar"/>
 	<classpathentry kind="lib" path="packages/apps/Calculator/arity-2.1.2.jar"/>
 	<classpathentry kind="output" path="out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes"/>
diff --git a/ndk/platforms/android-11/arch-arm/lib/libandroid.so b/ndk/platforms/android-11/arch-arm/lib/libandroid.so
new file mode 100755
index 0000000..3dce838
--- /dev/null
+++ b/ndk/platforms/android-11/arch-arm/lib/libandroid.so
Binary files differ
diff --git a/ndk/platforms/android-11/arch-arm/symbols/libandroid.so.txt b/ndk/platforms/android-11/arch-arm/symbols/libandroid.so.txt
new file mode 100644
index 0000000..5baa7c6
--- /dev/null
+++ b/ndk/platforms/android-11/arch-arm/symbols/libandroid.so.txt
@@ -0,0 +1,153 @@
+AAssetDir_close
+AAssetDir_getNextFileName
+AAssetDir_rewind
+AAssetManager_fromJava
+AAssetManager_open
+AAssetManager_openDir
+AAsset_close
+AAsset_getBuffer
+AAsset_getLength
+AAsset_getLength64
+AAsset_getRemainingLength
+AAsset_getRemainingLength64
+AAsset_isAllocated
+AAsset_openFileDescriptor
+AAsset_openFileDescriptor64
+AAsset_read
+AAsset_seek
+AAsset_seek64
+AConfiguration_copy
+AConfiguration_delete
+AConfiguration_diff
+AConfiguration_fromAssetManager
+AConfiguration_getCountry
+AConfiguration_getDensity
+AConfiguration_getKeyboard
+AConfiguration_getKeysHidden
+AConfiguration_getLanguage
+AConfiguration_getMcc
+AConfiguration_getMnc
+AConfiguration_getNavHidden
+AConfiguration_getNavigation
+AConfiguration_getOrientation
+AConfiguration_getScreenLong
+AConfiguration_getScreenSize
+AConfiguration_getSdkVersion
+AConfiguration_getTouchscreen
+AConfiguration_getUiModeNight
+AConfiguration_getUiModeType
+AConfiguration_isBetterThan
+AConfiguration_match
+AConfiguration_new
+AConfiguration_setCountry
+AConfiguration_setDensity
+AConfiguration_setKeyboard
+AConfiguration_setKeysHidden
+AConfiguration_setLanguage
+AConfiguration_setMcc
+AConfiguration_setMnc
+AConfiguration_setNavHidden
+AConfiguration_setNavigation
+AConfiguration_setOrientation
+AConfiguration_setScreenLong
+AConfiguration_setScreenSize
+AConfiguration_setSdkVersion
+AConfiguration_setTouchscreen
+AConfiguration_setUiModeNight
+AConfiguration_setUiModeType
+AInputEvent_getDeviceId
+AInputEvent_getSource
+AInputEvent_getType
+AInputQueue_attachLooper
+AInputQueue_detachLooper
+AInputQueue_finishEvent
+AInputQueue_getEvent
+AInputQueue_hasEvents
+AInputQueue_preDispatchEvent
+AKeyEvent_getAction
+AKeyEvent_getDownTime
+AKeyEvent_getEventTime
+AKeyEvent_getFlags
+AKeyEvent_getKeyCode
+AKeyEvent_getMetaState
+AKeyEvent_getRepeatCount
+AKeyEvent_getScanCode
+ALooper_acquire
+ALooper_addFd
+ALooper_forThread
+ALooper_pollAll
+ALooper_pollOnce
+ALooper_prepare
+ALooper_release
+ALooper_removeFd
+ALooper_wake
+AMotionEvent_getAction
+AMotionEvent_getDownTime
+AMotionEvent_getEdgeFlags
+AMotionEvent_getEventTime
+AMotionEvent_getFlags
+AMotionEvent_getHistoricalEventTime
+AMotionEvent_getHistoricalPressure
+AMotionEvent_getHistoricalSize
+AMotionEvent_getHistoricalX
+AMotionEvent_getHistoricalY
+AMotionEvent_getHistorySize
+AMotionEvent_getMetaState
+AMotionEvent_getOrientation
+AMotionEvent_getPointerCount
+AMotionEvent_getPointerId
+AMotionEvent_getPressure
+AMotionEvent_getRawX
+AMotionEvent_getRawY
+AMotionEvent_getSize
+AMotionEvent_getToolMajor
+AMotionEvent_getToolMinor
+AMotionEvent_getTouchMajor
+AMotionEvent_getTouchMinor
+AMotionEvent_getX
+AMotionEvent_getXOffset
+AMotionEvent_getXPrecision
+AMotionEvent_getY
+AMotionEvent_getYOffset
+AMotionEvent_getYPrecision
+ANativeActivity_finish
+ANativeActivity_hideSoftInput
+ANativeActivity_setWindowFlags
+ANativeActivity_setWindowFormat
+ANativeActivity_showSoftInput
+ANativeWindow_acquire
+ANativeWindow_fromSurface
+ANativeWindow_getFormat
+ANativeWindow_getHeight
+ANativeWindow_getWidth
+ANativeWindow_lock
+ANativeWindow_release
+ANativeWindow_setBuffersGeometry
+ANativeWindow_unlockAndPost
+AObbInfo_delete
+AObbInfo_getFlags
+AObbInfo_getPackageName
+AObbInfo_getVersion
+AObbScanner_getObbInfo
+ASensorEventQueue_disableSensor
+ASensorEventQueue_enableSensor
+ASensorEventQueue_getEvents
+ASensorEventQueue_hasEvents
+ASensorEventQueue_setEventRate
+ASensorManager_createEventQueue
+ASensorManager_destroyEventQueue
+ASensorManager_getDefaultSensor
+ASensorManager_getInstance
+ASensorManager_getSensorList
+ASensor_getMinDelay
+ASensor_getName
+ASensor_getResolution
+ASensor_getType
+ASensor_getVendor
+AStorageManager_delete
+AStorageManager_getMountedObbPath
+AStorageManager_isObbMounted
+AStorageManager_mountObb
+AStorageManager_new
+AStorageManager_unmountObb
+
diff --git a/ndk/platforms/android-11/include/android/asset_manager.h b/ndk/platforms/android-11/include/android/asset_manager.h
new file mode 100644
index 0000000..f5df46b
--- /dev/null
+++ b/ndk/platforms/android-11/include/android/asset_manager.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_ASSET_MANAGER_H
+#define ANDROID_ASSET_MANAGER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AAssetManager;
+typedef struct AAssetManager AAssetManager;
+
+struct AAssetDir;
+typedef struct AAssetDir AAssetDir;
+
+struct AAsset;
+typedef struct AAsset AAsset;
+
+/* Available modes for opening assets */
+enum {
+    AASSET_MODE_UNKNOWN      = 0,
+    AASSET_MODE_RANDOM       = 1,
+    AASSET_MODE_STREAMING    = 2,
+    AASSET_MODE_BUFFER       = 3
+};
+
+
+/**
+ * Open the named directory within the asset hierarchy.  The directory can then
+ * be inspected with the AAssetDir functions.  To open the top-level directory,
+ * pass in "" as the dirName.
+ *
+ * The object returned here should be freed by calling AAssetDir_close().
+ */
+AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName);
+
+/**
+ * Open an asset.
+ *
+ * The object returned here should be freed by calling AAsset_close().
+ */
+AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode);
+
+/**
+ * Iterate over the files in an asset directory.  A NULL string is returned
+ * when all the file names have been returned.
+ *
+ * The returned file name is suitable for passing to AAssetManager_open().
+ *
+ * The string returned here is owned by the AssetDir implementation and is not
+ * guaranteed to remain valid if any other calls are made on this AAssetDir
+ * instance.
+ */
+const char* AAssetDir_getNextFileName(AAssetDir* assetDir);
+
+/**
+ * Reset the iteration state of AAssetDir_getNextFileName() to the beginning.
+ */
+void AAssetDir_rewind(AAssetDir* assetDir);
+
+/**
+ * Close an opened AAssetDir, freeing any related resources.
+ */
+void AAssetDir_close(AAssetDir* assetDir);
+
+/**
+ * Attempt to read 'count' bytes of data from the current offset.
+ *
+ * Returns the number of bytes read, zero on EOF, or < 0 on error.
+ */
+int AAsset_read(AAsset* asset, void* buf, size_t count);
+
+/**
+ * Seek to the specified offset within the asset data.  'whence' uses the
+ * same constants as lseek()/fseek().
+ *
+ * Returns the new position on success, or (off_t) -1 on error.
+ */
+off_t AAsset_seek(AAsset* asset, off_t offset, int whence);
+
+/**
+ * Seek to the specified offset within the asset data.  'whence' uses the
+ * same constants as lseek()/fseek().
+ *
+ * Uses 64-bit data type for large files as opposed to the 32-bit type used
+ * by AAsset_seek.
+ *
+ * Returns the new position on success, or (off64_t) -1 on error.
+ */
+off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence);
+
+/**
+ * Close the asset, freeing all associated resources.
+ */
+void AAsset_close(AAsset* asset);
+
+/**
+ * Get a pointer to a buffer holding the entire contents of the assset.
+ *
+ * Returns NULL on failure.
+ */
+const void* AAsset_getBuffer(AAsset* asset);
+
+/**
+ * Report the total size of the asset data.
+ */
+off_t AAsset_getLength(AAsset* asset);
+
+/**
+ * Report the total size of the asset data. Reports the size using a 64-bit
+ * number insted of 32-bit as AAsset_getLength.
+ */
+off64_t AAsset_getLength64(AAsset* asset);
+
+/**
+ * Report the total amount of asset data that can be read from the current position.
+ */
+off_t AAsset_getRemainingLength(AAsset* asset);
+
+/**
+ * Report the total amount of asset data that can be read from the current position.
+ *
+ * Uses a 64-bit number instead of a 32-bit number as AAsset_getRemainingLength does.
+ */
+off64_t AAsset_getRemainingLength64(AAsset* asset);
+
+/**
+ * Open a new file descriptor that can be used to read the asset data. If the
+ * start or length cannot be represented by a 32-bit number, it will be
+ * truncated. If the file is large, use AAsset_openFileDescriptor64 instead.
+ *
+ * Returns < 0 if direct fd access is not possible (for example, if the asset is
+ * compressed).
+ */
+int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength);
+
+/**
+ * Open a new file descriptor that can be used to read the asset data.
+ *
+ * Uses a 64-bit number for the offset and length instead of 32-bit instead of
+ * as AAsset_openFileDescriptor does.
+ *
+ * Returns < 0 if direct fd access is not possible (for example, if the asset is
+ * compressed).
+ */
+int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength);
+
+/**
+ * Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not
+ * mmapped).
+ */
+int AAsset_isAllocated(AAsset* asset);
+
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif      // ANDROID_ASSET_MANAGER_H
diff --git a/ndk/platforms/android-11/include/android/input.h b/ndk/platforms/android-11/include/android/input.h
new file mode 100644
index 0000000..e196686
--- /dev/null
+++ b/ndk/platforms/android-11/include/android/input.h
@@ -0,0 +1,724 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_INPUT_H
+#define _ANDROID_INPUT_H
+
+/******************************************************************
+ *
+ * IMPORTANT NOTICE:
+ *
+ *   This file is part of Android's set of stable system headers
+ *   exposed by the Android NDK (Native Development Kit).
+ *
+ *   Third-party source AND binary code relies on the definitions
+ *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
+ *
+ *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
+ *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
+ *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
+ *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
+ */
+
+/*
+ * Structures and functions to receive and process input events in
+ * native code.
+ *
+ * NOTE: These functions MUST be implemented by /system/lib/libui.so
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <android/keycodes.h>
+#include <android/looper.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Key states (may be returned by queries about the current state of a
+ * particular key code, scan code or switch).
+ */
+enum {
+    /* The key state is unknown or the requested key itself is not supported. */
+    AKEY_STATE_UNKNOWN = -1,
+
+    /* The key is up. */
+    AKEY_STATE_UP = 0,
+
+    /* The key is down. */
+    AKEY_STATE_DOWN = 1,
+
+    /* The key is down but is a virtual key press that is being emulated by the system. */
+    AKEY_STATE_VIRTUAL = 2
+};
+
+/*
+ * Meta key / modifer state.
+ */
+enum {
+    /* No meta keys are pressed. */
+    AMETA_NONE = 0,
+
+    /* This mask is used to check whether one of the ALT meta keys is pressed. */
+    AMETA_ALT_ON = 0x02,
+
+    /* This mask is used to check whether the left ALT meta key is pressed. */
+    AMETA_ALT_LEFT_ON = 0x10,
+
+    /* This mask is used to check whether the right ALT meta key is pressed. */
+    AMETA_ALT_RIGHT_ON = 0x20,
+
+    /* This mask is used to check whether one of the SHIFT meta keys is pressed. */
+    AMETA_SHIFT_ON = 0x01,
+
+    /* This mask is used to check whether the left SHIFT meta key is pressed. */
+    AMETA_SHIFT_LEFT_ON = 0x40,
+
+    /* This mask is used to check whether the right SHIFT meta key is pressed. */
+    AMETA_SHIFT_RIGHT_ON = 0x80,
+
+    /* This mask is used to check whether the SYM meta key is pressed. */
+    AMETA_SYM_ON = 0x04,
+
+    /* This mask is used to check whether the FUNCTION meta key is pressed. */
+    AMETA_FUNCTION_ON = 0x08,
+
+    /* This mask is used to check whether one of the CTRL meta keys is pressed. */
+    AMETA_CTRL_ON = 0x1000,
+
+    /* This mask is used to check whether the left CTRL meta key is pressed. */
+    AMETA_CTRL_LEFT_ON = 0x2000,
+
+    /* This mask is used to check whether the right CTRL meta key is pressed. */
+    AMETA_CTRL_RIGHT_ON = 0x4000,
+
+    /* This mask is used to check whether one of the META meta keys is pressed. */
+    AMETA_META_ON = 0x10000,
+
+    /* This mask is used to check whether the left META meta key is pressed. */
+    AMETA_META_LEFT_ON = 0x20000,
+
+    /* This mask is used to check whether the right META meta key is pressed. */
+    AMETA_META_RIGHT_ON = 0x40000,
+
+    /* This mask is used to check whether the CAPS LOCK meta key is on. */
+    AMETA_CAPS_LOCK_ON = 0x100000,
+
+    /* This mask is used to check whether the NUM LOCK meta key is on. */
+    AMETA_NUM_LOCK_ON = 0x200000,
+
+    /* This mask is used to check whether the SCROLL LOCK meta key is on. */
+    AMETA_SCROLL_LOCK_ON = 0x400000,
+};
+
+/*
+ * Input events.
+ *
+ * Input events are opaque structures.  Use the provided accessors functions to
+ * read their properties.
+ */
+struct AInputEvent;
+typedef struct AInputEvent AInputEvent;
+
+/*
+ * Input event types.
+ */
+enum {
+    /* Indicates that the input event is a key event. */
+    AINPUT_EVENT_TYPE_KEY = 1,
+
+    /* Indicates that the input event is a motion event. */
+    AINPUT_EVENT_TYPE_MOTION = 2
+};
+
+/*
+ * Key event actions.
+ */
+enum {
+    /* The key has been pressed down. */
+    AKEY_EVENT_ACTION_DOWN = 0,
+
+    /* The key has been released. */
+    AKEY_EVENT_ACTION_UP = 1,
+
+    /* Multiple duplicate key events have occurred in a row, or a complex string is
+     * being delivered.  The repeat_count property of the key event contains the number
+     * of times the given key code should be executed.
+     */
+    AKEY_EVENT_ACTION_MULTIPLE = 2
+};
+
+/*
+ * Key event flags.
+ */
+enum {
+    /* This mask is set if the device woke because of this key event. */
+    AKEY_EVENT_FLAG_WOKE_HERE = 0x1,
+
+    /* This mask is set if the key event was generated by a software keyboard. */
+    AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,
+
+    /* This mask is set if we don't want the key event to cause us to leave touch mode. */
+    AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,
+
+    /* This mask is set if an event was known to come from a trusted part
+     * of the system.  That is, the event is known to come from the user,
+     * and could not have been spoofed by a third party component. */
+    AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
+
+    /* This mask is used for compatibility, to identify enter keys that are
+     * coming from an IME whose enter key has been auto-labelled "next" or
+     * "done".  This allows TextView to dispatch these as normal enter keys
+     * for old applications, but still do the appropriate action when
+     * receiving them. */
+    AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10,
+
+    /* When associated with up key events, this indicates that the key press
+     * has been canceled.  Typically this is used with virtual touch screen
+     * keys, where the user can slide from the virtual key area on to the
+     * display: in that case, the application will receive a canceled up
+     * event and should not perform the action normally associated with the
+     * key.  Note that for this to work, the application can not perform an
+     * action for a key until it receives an up or the long press timeout has
+     * expired. */
+    AKEY_EVENT_FLAG_CANCELED = 0x20,
+
+    /* This key event was generated by a virtual (on-screen) hard key area.
+     * Typically this is an area of the touchscreen, outside of the regular
+     * display, dedicated to "hardware" buttons. */
+    AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,
+
+    /* This flag is set for the first key repeat that occurs after the
+     * long press timeout. */
+    AKEY_EVENT_FLAG_LONG_PRESS = 0x80,
+
+    /* Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long
+     * press action was executed while it was down. */
+    AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,
+
+    /* Set for AKEY_EVENT_ACTION_UP when this event's key code is still being
+     * tracked from its initial down.  That is, somebody requested that tracking
+     * started on the key down and a long press has not caused
+     * the tracking to be canceled. */
+    AKEY_EVENT_FLAG_TRACKING = 0x200,
+
+    /* Set when a key event has been synthesized to implement default behavior
+     * for an event that the application did not handle.
+     * Fallback key events are generated by unhandled trackball motions
+     * (to emulate a directional keypad) and by certain unhandled key presses
+     * that are declared in the key map (such as special function numeric keypad
+     * keys when numlock is off). */
+    AKEY_EVENT_FLAG_FALLBACK = 0x400,
+};
+
+/*
+ * Motion event actions.
+ */
+
+/* Bit shift for the action bits holding the pointer index as
+ * defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK.
+ */
+#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8
+
+enum {
+    /* Bit mask of the parts of the action code that are the action itself.
+     */
+    AMOTION_EVENT_ACTION_MASK = 0xff,
+
+    /* Bits in the action code that represent a pointer index, used with
+     * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP.  Shifting
+     * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
+     * index where the data for the pointer going up or down can be found.
+     */
+    AMOTION_EVENT_ACTION_POINTER_INDEX_MASK  = 0xff00,
+
+    /* A pressed gesture has started, the motion contains the initial starting location.
+     */
+    AMOTION_EVENT_ACTION_DOWN = 0,
+
+    /* A pressed gesture has finished, the motion contains the final release location
+     * as well as any intermediate points since the last down or move event.
+     */
+    AMOTION_EVENT_ACTION_UP = 1,
+
+    /* A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
+     * AMOTION_EVENT_ACTION_UP).  The motion contains the most recent point, as well as
+     * any intermediate points since the last down or move event.
+     */
+    AMOTION_EVENT_ACTION_MOVE = 2,
+
+    /* The current gesture has been aborted.
+     * You will not receive any more points in it.  You should treat this as
+     * an up event, but not perform any action that you normally would.
+     */
+    AMOTION_EVENT_ACTION_CANCEL = 3,
+
+    /* A movement has happened outside of the normal bounds of the UI element.
+     * This does not provide a full gesture, but only the initial location of the movement/touch.
+     */
+    AMOTION_EVENT_ACTION_OUTSIDE = 4,
+
+    /* A non-primary pointer has gone down.
+     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
+     */
+    AMOTION_EVENT_ACTION_POINTER_DOWN = 5,
+
+    /* A non-primary pointer has gone up.
+     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
+     */
+    AMOTION_EVENT_ACTION_POINTER_UP = 6
+};
+
+/*
+ * Motion event flags.
+ */
+enum {
+    /* This flag indicates that the window that received this motion event is partly
+     * or wholly obscured by another visible window above it.  This flag is set to true
+     * even if the event did not directly pass through the obscured area.
+     * A security sensitive application can check this flag to identify situations in which
+     * a malicious application may have covered up part of its content for the purpose
+     * of misleading the user or hijacking touches.  An appropriate response might be
+     * to drop the suspect touches or to take additional precautions to confirm the user's
+     * actual intent.
+     */
+    AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1,
+};
+
+/*
+ * Motion event edge touch flags.
+ */
+enum {
+    /* No edges intersected */
+    AMOTION_EVENT_EDGE_FLAG_NONE = 0,
+
+    /* Flag indicating the motion event intersected the top edge of the screen. */
+    AMOTION_EVENT_EDGE_FLAG_TOP = 0x01,
+
+    /* Flag indicating the motion event intersected the bottom edge of the screen. */
+    AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,
+
+    /* Flag indicating the motion event intersected the left edge of the screen. */
+    AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04,
+
+    /* Flag indicating the motion event intersected the right edge of the screen. */
+    AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08
+};
+
+/*
+ * Input sources.
+ *
+ * Refer to the documentation on android.view.InputDevice for more details about input sources
+ * and their correct interpretation.
+ */
+enum {
+    AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
+
+    AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
+    AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
+    AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
+    AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
+};
+
+enum {
+    AINPUT_SOURCE_UNKNOWN = 0x00000000,
+
+    AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
+    AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
+    AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
+    AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
+    AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
+    AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
+
+    AINPUT_SOURCE_ANY = 0xffffff00,
+};
+
+/*
+ * Keyboard types.
+ *
+ * Refer to the documentation on android.view.InputDevice for more details.
+ */
+enum {
+    AINPUT_KEYBOARD_TYPE_NONE = 0,
+    AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1,
+    AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2,
+};
+
+/*
+ * Constants used to retrieve information about the range of motion for a particular
+ * coordinate of a motion event.
+ *
+ * Refer to the documentation on android.view.InputDevice for more details about input sources
+ * and their correct interpretation.
+ */
+enum {
+    AINPUT_MOTION_RANGE_X = 0,
+    AINPUT_MOTION_RANGE_Y = 1,
+    AINPUT_MOTION_RANGE_PRESSURE = 2,
+    AINPUT_MOTION_RANGE_SIZE = 3,
+    AINPUT_MOTION_RANGE_TOUCH_MAJOR = 4,
+    AINPUT_MOTION_RANGE_TOUCH_MINOR = 5,
+    AINPUT_MOTION_RANGE_TOOL_MAJOR = 6,
+    AINPUT_MOTION_RANGE_TOOL_MINOR = 7,
+    AINPUT_MOTION_RANGE_ORIENTATION = 8,
+};
+
+
+/*
+ * Input event accessors.
+ *
+ * Note that most functions can only be used on input events that are of a given type.
+ * Calling these functions on input events of other types will yield undefined behavior.
+ */
+
+/*** Accessors for all input events. ***/
+
+/* Get the input event type. */
+int32_t AInputEvent_getType(const AInputEvent* event);
+
+/* Get the id for the device that an input event came from.
+ *
+ * Input events can be generated by multiple different input devices.
+ * Use the input device id to obtain information about the input
+ * device that was responsible for generating a particular event.
+ *
+ * An input device id of 0 indicates that the event didn't come from a physical device;
+ * other numbers are arbitrary and you shouldn't depend on the values.
+ * Use the provided input device query API to obtain information about input devices.
+ */
+int32_t AInputEvent_getDeviceId(const AInputEvent* event);
+
+/* Get the input event source. */
+int32_t AInputEvent_getSource(const AInputEvent* event);
+
+/*** Accessors for key events only. ***/
+
+/* Get the key event action. */
+int32_t AKeyEvent_getAction(const AInputEvent* key_event);
+
+/* Get the key event flags. */
+int32_t AKeyEvent_getFlags(const AInputEvent* key_event);
+
+/* Get the key code of the key event.
+ * This is the physical key that was pressed, not the Unicode character. */
+int32_t AKeyEvent_getKeyCode(const AInputEvent* key_event);
+
+/* Get the hardware key id of this key event.
+ * These values are not reliable and vary from device to device. */
+int32_t AKeyEvent_getScanCode(const AInputEvent* key_event);
+
+/* Get the meta key state. */
+int32_t AKeyEvent_getMetaState(const AInputEvent* key_event);
+
+/* Get the repeat count of the event.
+ * For both key up an key down events, this is the number of times the key has
+ * repeated with the first down starting at 0 and counting up from there.  For
+ * multiple key events, this is the number of down/up pairs that have occurred. */
+int32_t AKeyEvent_getRepeatCount(const AInputEvent* key_event);
+
+/* Get the time of the most recent key down event, in the
+ * java.lang.System.nanoTime() time base.  If this is a down event,
+ * this will be the same as eventTime.
+ * Note that when chording keys, this value is the down time of the most recently
+ * pressed key, which may not be the same physical key of this event. */
+int64_t AKeyEvent_getDownTime(const AInputEvent* key_event);
+
+/* Get the time this event occurred, in the
+ * java.lang.System.nanoTime() time base. */
+int64_t AKeyEvent_getEventTime(const AInputEvent* key_event);
+
+/*** Accessors for motion events only. ***/
+
+/* Get the combined motion event action code and pointer index. */
+int32_t AMotionEvent_getAction(const AInputEvent* motion_event);
+
+/* Get the motion event flags. */
+int32_t AMotionEvent_getFlags(const AInputEvent* motion_event);
+
+/* Get the state of any meta / modifier keys that were in effect when the
+ * event was generated. */
+int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event);
+
+/* Get a bitfield indicating which edges, if any, were touched by this motion event.
+ * For touch events, clients can use this to determine if the user's finger was
+ * touching the edge of the display. */
+int32_t AMotionEvent_getEdgeFlags(const AInputEvent* motion_event);
+
+/* Get the time when the user originally pressed down to start a stream of
+ * position events, in the java.lang.System.nanoTime() time base. */
+int64_t AMotionEvent_getDownTime(const AInputEvent* motion_event);
+
+/* Get the time when this specific event was generated,
+ * in the java.lang.System.nanoTime() time base. */
+int64_t AMotionEvent_getEventTime(const AInputEvent* motion_event);
+
+/* Get the X coordinate offset.
+ * For touch events on the screen, this is the delta that was added to the raw
+ * screen coordinates to adjust for the absolute position of the containing windows
+ * and views. */
+float AMotionEvent_getXOffset(const AInputEvent* motion_event);
+
+/* Get the precision of the Y coordinates being reported.
+ * For touch events on the screen, this is the delta that was added to the raw
+ * screen coordinates to adjust for the absolute position of the containing windows
+ * and views. */
+float AMotionEvent_getYOffset(const AInputEvent* motion_event);
+
+/* Get the precision of the X coordinates being reported.
+ * You can multiply this number with an X coordinate sample to find the
+ * actual hardware value of the X coordinate. */
+float AMotionEvent_getXPrecision(const AInputEvent* motion_event);
+
+/* Get the precision of the Y coordinates being reported.
+ * You can multiply this number with a Y coordinate sample to find the
+ * actual hardware value of the Y coordinate. */
+float AMotionEvent_getYPrecision(const AInputEvent* motion_event);
+
+/* Get the number of pointers of data contained in this event.
+ * Always >= 1. */
+size_t AMotionEvent_getPointerCount(const AInputEvent* motion_event);
+
+/* Get the pointer identifier associated with a particular pointer
+ * data index is this event.  The identifier tells you the actual pointer
+ * number associated with the data, accounting for individual pointers
+ * going up and down since the start of the current gesture. */
+int32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the original raw X coordinate of this event.
+ * For touch events on the screen, this is the original location of the event
+ * on the screen, before it had been adjusted for the containing window
+ * and views. */
+float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the original raw X coordinate of this event.
+ * For touch events on the screen, this is the original location of the event
+ * on the screen, before it had been adjusted for the containing window
+ * and views. */
+float AMotionEvent_getRawY(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current X coordinate of this event for the given pointer index.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float AMotionEvent_getX(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current Y coordinate of this event for the given pointer index.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float AMotionEvent_getY(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current pressure of this event for the given pointer index.
+ * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
+ * however values higher than 1 may be generated depending on the calibration of
+ * the input device. */
+float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current scaled value of the approximate size for the given pointer index.
+ * This represents some approximation of the area of the screen being
+ * pressed; the actual value in pixels corresponding to the
+ * touch is normalized with the device specific range of values
+ * and scaled to a value between 0 and 1.  The value of size can be used to
+ * determine fat touch events. */
+float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current length of the major axis of an ellipse that describes the touch area
+ * at the point of contact for the given pointer index. */
+float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current length of the minor axis of an ellipse that describes the touch area
+ * at the point of contact for the given pointer index. */
+float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current length of the major axis of an ellipse that describes the size
+ * of the approaching tool for the given pointer index.
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact. */
+float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current length of the minor axis of an ellipse that describes the size
+ * of the approaching tool for the given pointer index.
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact. */
+float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the current orientation of the touch area and tool area in radians clockwise from
+ * vertical for the given pointer index.
+ * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * upwards, is perfectly circular or is of unknown orientation.  A positive angle
+ * indicates that the major axis of contact is oriented to the right.  A negative angle
+ * indicates that the major axis of contact is oriented to the left.
+ * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
+ * (finger pointing fully right). */
+float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the number of historical points in this event.  These are movements that
+ * have occurred between this event and the previous event.  This only applies
+ * to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.
+ * Historical samples are indexed from oldest to newest. */
+size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event);
+
+/* Get the time that a historical movement occurred between this event and
+ * the previous event, in the java.lang.System.nanoTime() time base. */
+int64_t AMotionEvent_getHistoricalEventTime(AInputEvent* motion_event,
+        size_t history_index);
+
+/* Get the historical raw X coordinate of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * For touch events on the screen, this is the original location of the event
+ * on the screen, before it had been adjusted for the containing window
+ * and views.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the historical raw Y coordinate of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * For touch events on the screen, this is the original location of the event
+ * on the screen, before it had been adjusted for the containing window
+ * and views.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index);
+
+/* Get the historical X coordinate of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float AMotionEvent_getHistoricalX(AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical Y coordinate of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float AMotionEvent_getHistoricalY(AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical pressure of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
+ * however values higher than 1 may be generated depending on the calibration of
+ * the input device. */
+float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the current scaled value of the approximate size for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * This represents some approximation of the area of the screen being
+ * pressed; the actual value in pixels corresponding to the
+ * touch is normalized with the device specific range of values
+ * and scaled to a value between 0 and 1.  The value of size can be used to
+ * determine fat touch events. */
+float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical length of the major axis of an ellipse that describes the touch area
+ * at the point of contact for the given pointer index that
+ * occurred between this event and the previous motion event. */
+float AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical length of the minor axis of an ellipse that describes the touch area
+ * at the point of contact for the given pointer index that
+ * occurred between this event and the previous motion event. */
+float AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical length of the major axis of an ellipse that describes the size
+ * of the approaching tool for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact. */
+float AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical length of the minor axis of an ellipse that describes the size
+ * of the approaching tool for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact. */
+float AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical orientation of the touch area and tool area in radians clockwise from
+ * vertical for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * upwards, is perfectly circular or is of unknown orientation.  A positive angle
+ * indicates that the major axis of contact is oriented to the right.  A negative angle
+ * indicates that the major axis of contact is oriented to the left.
+ * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
+ * (finger pointing fully right). */
+float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index,
+        size_t history_index);
+
+
+/*
+ * Input queue
+ *
+ * An input queue is the facility through which you retrieve input
+ * events.
+ */
+struct AInputQueue;
+typedef struct AInputQueue AInputQueue;
+
+/*
+ * Add this input queue to a looper for processing.  See
+ * ALooper_addFd() for information on the ident, callback, and data params.
+ */
+void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
+        int ident, ALooper_callbackFunc callback, void* data);
+
+/*
+ * Remove the input queue from the looper it is currently attached to.
+ */
+void AInputQueue_detachLooper(AInputQueue* queue);
+
+/*
+ * Returns true if there are one or more events available in the
+ * input queue.  Returns 1 if the queue has events; 0 if
+ * it does not have events; and a negative value if there is an error.
+ */
+int32_t AInputQueue_hasEvents(AInputQueue* queue);
+
+/*
+ * Returns the next available event from the queue.  Returns a negative
+ * value if no events are available or an error has occurred.
+ */
+int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent);
+
+/*
+ * Sends the key for standard pre-dispatching -- that is, possibly deliver
+ * it to the current IME to be consumed before the app.  Returns 0 if it
+ * was not pre-dispatched, meaning you can process it right now.  If non-zero
+ * is returned, you must abandon the current event processing and allow the
+ * event to appear again in the event queue (if it does not get consumed during
+ * pre-dispatching).
+ */
+int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event);
+
+/*
+ * Report that dispatching has finished with the given event.
+ * This must be called after receiving an event with AInputQueue_get_event().
+ */
+void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ANDROID_INPUT_H
diff --git a/ndk/platforms/android-11/include/android/keycodes.h b/ndk/platforms/android-11/include/android/keycodes.h
new file mode 100644
index 0000000..b026a0c
--- /dev/null
+++ b/ndk/platforms/android-11/include/android/keycodes.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_KEYCODES_H
+#define _ANDROID_KEYCODES_H
+
+/******************************************************************
+ *
+ * IMPORTANT NOTICE:
+ *
+ *   This file is part of Android's set of stable system headers
+ *   exposed by the Android NDK (Native Development Kit).
+ *
+ *   Third-party source AND binary code relies on the definitions
+ *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
+ *
+ *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
+ *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
+ *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
+ *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
+ */
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Key codes.
+ */
+enum {
+    AKEYCODE_UNKNOWN         = 0,
+    AKEYCODE_SOFT_LEFT       = 1,
+    AKEYCODE_SOFT_RIGHT      = 2,
+    AKEYCODE_HOME            = 3,
+    AKEYCODE_BACK            = 4,
+    AKEYCODE_CALL            = 5,
+    AKEYCODE_ENDCALL         = 6,
+    AKEYCODE_0               = 7,
+    AKEYCODE_1               = 8,
+    AKEYCODE_2               = 9,
+    AKEYCODE_3               = 10,
+    AKEYCODE_4               = 11,
+    AKEYCODE_5               = 12,
+    AKEYCODE_6               = 13,
+    AKEYCODE_7               = 14,
+    AKEYCODE_8               = 15,
+    AKEYCODE_9               = 16,
+    AKEYCODE_STAR            = 17,
+    AKEYCODE_POUND           = 18,
+    AKEYCODE_DPAD_UP         = 19,
+    AKEYCODE_DPAD_DOWN       = 20,
+    AKEYCODE_DPAD_LEFT       = 21,
+    AKEYCODE_DPAD_RIGHT      = 22,
+    AKEYCODE_DPAD_CENTER     = 23,
+    AKEYCODE_VOLUME_UP       = 24,
+    AKEYCODE_VOLUME_DOWN     = 25,
+    AKEYCODE_POWER           = 26,
+    AKEYCODE_CAMERA          = 27,
+    AKEYCODE_CLEAR           = 28,
+    AKEYCODE_A               = 29,
+    AKEYCODE_B               = 30,
+    AKEYCODE_C               = 31,
+    AKEYCODE_D               = 32,
+    AKEYCODE_E               = 33,
+    AKEYCODE_F               = 34,
+    AKEYCODE_G               = 35,
+    AKEYCODE_H               = 36,
+    AKEYCODE_I               = 37,
+    AKEYCODE_J               = 38,
+    AKEYCODE_K               = 39,
+    AKEYCODE_L               = 40,
+    AKEYCODE_M               = 41,
+    AKEYCODE_N               = 42,
+    AKEYCODE_O               = 43,
+    AKEYCODE_P               = 44,
+    AKEYCODE_Q               = 45,
+    AKEYCODE_R               = 46,
+    AKEYCODE_S               = 47,
+    AKEYCODE_T               = 48,
+    AKEYCODE_U               = 49,
+    AKEYCODE_V               = 50,
+    AKEYCODE_W               = 51,
+    AKEYCODE_X               = 52,
+    AKEYCODE_Y               = 53,
+    AKEYCODE_Z               = 54,
+    AKEYCODE_COMMA           = 55,
+    AKEYCODE_PERIOD          = 56,
+    AKEYCODE_ALT_LEFT        = 57,
+    AKEYCODE_ALT_RIGHT       = 58,
+    AKEYCODE_SHIFT_LEFT      = 59,
+    AKEYCODE_SHIFT_RIGHT     = 60,
+    AKEYCODE_TAB             = 61,
+    AKEYCODE_SPACE           = 62,
+    AKEYCODE_SYM             = 63,
+    AKEYCODE_EXPLORER        = 64,
+    AKEYCODE_ENVELOPE        = 65,
+    AKEYCODE_ENTER           = 66,
+    AKEYCODE_DEL             = 67,
+    AKEYCODE_GRAVE           = 68,
+    AKEYCODE_MINUS           = 69,
+    AKEYCODE_EQUALS          = 70,
+    AKEYCODE_LEFT_BRACKET    = 71,
+    AKEYCODE_RIGHT_BRACKET   = 72,
+    AKEYCODE_BACKSLASH       = 73,
+    AKEYCODE_SEMICOLON       = 74,
+    AKEYCODE_APOSTROPHE      = 75,
+    AKEYCODE_SLASH           = 76,
+    AKEYCODE_AT              = 77,
+    AKEYCODE_NUM             = 78,
+    AKEYCODE_HEADSETHOOK     = 79,
+    AKEYCODE_FOCUS           = 80,   // *Camera* focus
+    AKEYCODE_PLUS            = 81,
+    AKEYCODE_MENU            = 82,
+    AKEYCODE_NOTIFICATION    = 83,
+    AKEYCODE_SEARCH          = 84,
+    AKEYCODE_MEDIA_PLAY_PAUSE= 85,
+    AKEYCODE_MEDIA_STOP      = 86,
+    AKEYCODE_MEDIA_NEXT      = 87,
+    AKEYCODE_MEDIA_PREVIOUS  = 88,
+    AKEYCODE_MEDIA_REWIND    = 89,
+    AKEYCODE_MEDIA_FAST_FORWARD = 90,
+    AKEYCODE_MUTE            = 91,
+    AKEYCODE_PAGE_UP         = 92,
+    AKEYCODE_PAGE_DOWN       = 93,
+    AKEYCODE_PICTSYMBOLS     = 94,
+    AKEYCODE_SWITCH_CHARSET  = 95,
+    AKEYCODE_BUTTON_A        = 96,
+    AKEYCODE_BUTTON_B        = 97,
+    AKEYCODE_BUTTON_C        = 98,
+    AKEYCODE_BUTTON_X        = 99,
+    AKEYCODE_BUTTON_Y        = 100,
+    AKEYCODE_BUTTON_Z        = 101,
+    AKEYCODE_BUTTON_L1       = 102,
+    AKEYCODE_BUTTON_R1       = 103,
+    AKEYCODE_BUTTON_L2       = 104,
+    AKEYCODE_BUTTON_R2       = 105,
+    AKEYCODE_BUTTON_THUMBL   = 106,
+    AKEYCODE_BUTTON_THUMBR   = 107,
+    AKEYCODE_BUTTON_START    = 108,
+    AKEYCODE_BUTTON_SELECT   = 109,
+    AKEYCODE_BUTTON_MODE     = 110,
+    AKEYCODE_ESCAPE          = 111,
+    AKEYCODE_FORWARD_DEL     = 112,
+    AKEYCODE_CTRL_LEFT       = 113,
+    AKEYCODE_CTRL_RIGHT      = 114,
+    AKEYCODE_CAPS_LOCK       = 115,
+    AKEYCODE_SCROLL_LOCK     = 116,
+    AKEYCODE_META_LEFT       = 117,
+    AKEYCODE_META_RIGHT      = 118,
+    AKEYCODE_FUNCTION        = 119,
+    AKEYCODE_SYSRQ           = 120,
+    AKEYCODE_BREAK           = 121,
+    AKEYCODE_MOVE_HOME       = 122,
+    AKEYCODE_MOVE_END        = 123,
+    AKEYCODE_INSERT          = 124,
+    AKEYCODE_FORWARD         = 125,
+    AKEYCODE_MEDIA_PLAY      = 126,
+    AKEYCODE_MEDIA_PAUSE     = 127,
+    AKEYCODE_MEDIA_CLOSE     = 128,
+    AKEYCODE_MEDIA_EJECT     = 129,
+    AKEYCODE_MEDIA_RECORD    = 130,
+    AKEYCODE_F1              = 131,
+    AKEYCODE_F2              = 132,
+    AKEYCODE_F3              = 133,
+    AKEYCODE_F4              = 134,
+    AKEYCODE_F5              = 135,
+    AKEYCODE_F6              = 136,
+    AKEYCODE_F7              = 137,
+    AKEYCODE_F8              = 138,
+    AKEYCODE_F9              = 139,
+    AKEYCODE_F10             = 140,
+    AKEYCODE_F11             = 141,
+    AKEYCODE_F12             = 142,
+    AKEYCODE_NUM_LOCK        = 143,
+    AKEYCODE_NUMPAD_0        = 144,
+    AKEYCODE_NUMPAD_1        = 145,
+    AKEYCODE_NUMPAD_2        = 146,
+    AKEYCODE_NUMPAD_3        = 147,
+    AKEYCODE_NUMPAD_4        = 148,
+    AKEYCODE_NUMPAD_5        = 149,
+    AKEYCODE_NUMPAD_6        = 150,
+    AKEYCODE_NUMPAD_7        = 151,
+    AKEYCODE_NUMPAD_8        = 152,
+    AKEYCODE_NUMPAD_9        = 153,
+    AKEYCODE_NUMPAD_DIVIDE   = 154,
+    AKEYCODE_NUMPAD_MULTIPLY = 155,
+    AKEYCODE_NUMPAD_SUBTRACT = 156,
+    AKEYCODE_NUMPAD_ADD      = 157,
+    AKEYCODE_NUMPAD_DOT      = 158,
+    AKEYCODE_NUMPAD_COMMA    = 159,
+    AKEYCODE_NUMPAD_ENTER    = 160,
+    AKEYCODE_NUMPAD_EQUALS   = 161,
+    AKEYCODE_NUMPAD_LEFT_PAREN = 162,
+    AKEYCODE_NUMPAD_RIGHT_PAREN = 163,
+    AKEYCODE_VOLUME_MUTE     = 164,
+    AKEYCODE_INFO            = 165,
+    AKEYCODE_CHANNEL_UP      = 166,
+    AKEYCODE_CHANNEL_DOWN    = 167,
+    AKEYCODE_ZOOM_IN         = 168,
+    AKEYCODE_ZOOM_OUT        = 169,
+    AKEYCODE_TV              = 170,
+    AKEYCODE_WINDOW          = 171,
+    AKEYCODE_GUIDE           = 172,
+    AKEYCODE_DVR             = 173,
+    AKEYCODE_BOOKMARK        = 174,
+    AKEYCODE_CAPTIONS        = 175,
+    AKEYCODE_SETTINGS        = 176,
+    AKEYCODE_TV_POWER        = 177,
+    AKEYCODE_TV_INPUT        = 178,
+    AKEYCODE_STB_POWER       = 179,
+    AKEYCODE_STB_INPUT       = 180,
+    AKEYCODE_AVR_POWER       = 181,
+    AKEYCODE_AVR_INPUT       = 182,
+    AKEYCODE_PROG_RED        = 183,
+    AKEYCODE_PROG_GREEN      = 184,
+    AKEYCODE_PROG_YELLOW     = 185,
+    AKEYCODE_PROG_BLUE       = 186,
+    AKEYCODE_APP_SWITCH      = 187,
+
+    // NOTE: If you add a new keycode here you must also add it to several other files.
+    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ANDROID_KEYCODES_H
diff --git a/ndk/platforms/android-11/include/android/native_activity.h b/ndk/platforms/android-11/include/android/native_activity.h
new file mode 100644
index 0000000..a361846
--- /dev/null
+++ b/ndk/platforms/android-11/include/android/native_activity.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_NATIVE_ACTIVITY_H
+#define ANDROID_NATIVE_ACTIVITY_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <jni.h>
+
+#include <android/asset_manager.h>
+#include <android/input.h>
+#include <android/native_window.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ANativeActivityCallbacks;
+
+/**
+ * This structure defines the native side of an android.app.NativeActivity.
+ * It is created by the framework, and handed to the application's native
+ * code as it is being launched.
+ */
+typedef struct ANativeActivity {
+    /**
+     * Pointer to the callback function table of the native application.
+     * You can set the functions here to your own callbacks.  The callbacks
+     * pointer itself here should not be changed; it is allocated and managed
+     * for you by the framework.
+     */
+    struct ANativeActivityCallbacks* callbacks;
+
+    /**
+     * The global handle on the process's Java VM.
+     */
+    JavaVM* vm;
+
+    /**
+     * JNI context for the main thread of the app.  Note that this field
+     * can ONLY be used from the main thread of the process; that is, the
+     * thread that calls into the ANativeActivityCallbacks.
+     */
+    JNIEnv* env;
+
+    /**
+     * The NativeActivity Java class.
+     */
+    jobject clazz;
+
+    /**
+     * Path to this application's internal data directory.
+     */
+    const char* internalDataPath;
+    
+    /**
+     * Path to this application's external (removable/mountable) data directory.
+     */
+    const char* externalDataPath;
+    
+    /**
+     * The platform's SDK version code.
+     */
+    int32_t sdkVersion;
+    
+    /**
+     * This is the native instance of the application.  It is not used by
+     * the framework, but can be set by the application to its own instance
+     * state.
+     */
+    void* instance;
+
+    /**
+     * Pointer to the Asset Manager instance for the application.  The application
+     * uses this to access binary assets bundled inside its own .apk file.
+     */
+    AAssetManager* assetManager;
+
+    /**
+     * Available starting with Honeycomb: path to the directory containing
+     * the application's OBB files (if any).  If the app doesn't have any
+     * OBB files, this directory may not exist.
+     */
+    const char* obbPath;
+} ANativeActivity;
+
+/**
+ * These are the callbacks the framework makes into a native application.
+ * All of these callbacks happen on the main thread of the application.
+ * By default, all callbacks are NULL; set to a pointer to your own function
+ * to have it called.
+ */
+typedef struct ANativeActivityCallbacks {
+    /**
+     * NativeActivity has started.  See Java documentation for Activity.onStart()
+     * for more information.
+     */
+    void (*onStart)(ANativeActivity* activity);
+    
+    /**
+     * NativeActivity has resumed.  See Java documentation for Activity.onResume()
+     * for more information.
+     */
+    void (*onResume)(ANativeActivity* activity);
+    
+    /**
+     * Framework is asking NativeActivity to save its current instance state.
+     * See Java documentation for Activity.onSaveInstanceState() for more
+     * information.  The returned pointer needs to be created with malloc();
+     * the framework will call free() on it for you.  You also must fill in
+     * outSize with the number of bytes in the allocation.  Note that the
+     * saved state will be persisted, so it can not contain any active
+     * entities (pointers to memory, file descriptors, etc).
+     */
+    void* (*onSaveInstanceState)(ANativeActivity* activity, size_t* outSize);
+    
+    /**
+     * NativeActivity has paused.  See Java documentation for Activity.onPause()
+     * for more information.
+     */
+    void (*onPause)(ANativeActivity* activity);
+    
+    /**
+     * NativeActivity has stopped.  See Java documentation for Activity.onStop()
+     * for more information.
+     */
+    void (*onStop)(ANativeActivity* activity);
+    
+    /**
+     * NativeActivity is being destroyed.  See Java documentation for Activity.onDestroy()
+     * for more information.
+     */
+    void (*onDestroy)(ANativeActivity* activity);
+
+    /**
+     * Focus has changed in this NativeActivity's window.  This is often used,
+     * for example, to pause a game when it loses input focus.
+     */
+    void (*onWindowFocusChanged)(ANativeActivity* activity, int hasFocus);
+    
+    /**
+     * The drawing window for this native activity has been created.  You
+     * can use the given native window object to start drawing.
+     */
+    void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window);
+
+    /**
+     * The drawing window for this native activity has been resized.  You should
+     * retrieve the new size from the window and ensure that your rendering in
+     * it now matches.
+     */
+    void (*onNativeWindowResized)(ANativeActivity* activity, ANativeWindow* window);
+
+    /**
+     * The drawing window for this native activity needs to be redrawn.  To avoid
+     * transient artifacts during screen changes (such resizing after rotation),
+     * applications should not return from this function until they have finished
+     * drawing their window in its current state.
+     */
+    void (*onNativeWindowRedrawNeeded)(ANativeActivity* activity, ANativeWindow* window);
+
+    /**
+     * The drawing window for this native activity is going to be destroyed.
+     * You MUST ensure that you do not touch the window object after returning
+     * from this function: in the common case of drawing to the window from
+     * another thread, that means the implementation of this callback must
+     * properly synchronize with the other thread to stop its drawing before
+     * returning from here.
+     */
+    void (*onNativeWindowDestroyed)(ANativeActivity* activity, ANativeWindow* window);
+    
+    /**
+     * The input queue for this native activity's window has been created.
+     * You can use the given input queue to start retrieving input events.
+     */
+    void (*onInputQueueCreated)(ANativeActivity* activity, AInputQueue* queue);
+    
+    /**
+     * The input queue for this native activity's window is being destroyed.
+     * You should no longer try to reference this object upon returning from this
+     * function.
+     */
+    void (*onInputQueueDestroyed)(ANativeActivity* activity, AInputQueue* queue);
+
+    /**
+     * The rectangle in the window in which content should be placed has changed.
+     */
+    void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect);
+
+    /**
+     * The current device AConfiguration has changed.  The new configuration can
+     * be retrieved from assetManager.
+     */
+    void (*onConfigurationChanged)(ANativeActivity* activity);
+
+    /**
+     * The system is running low on memory.  Use this callback to release
+     * resources you do not need, to help the system avoid killing more
+     * important processes.
+     */
+    void (*onLowMemory)(ANativeActivity* activity);
+} ANativeActivityCallbacks;
+
+/**
+ * This is the function that must be in the native code to instantiate the
+ * application's native activity.  It is called with the activity instance (see
+ * above); if the code is being instantiated from a previously saved instance,
+ * the savedState will be non-NULL and point to the saved data.  You must make
+ * any copy of this data you need -- it will be released after you return from
+ * this function.
+ */
+typedef void ANativeActivity_createFunc(ANativeActivity* activity,
+        void* savedState, size_t savedStateSize);
+
+/**
+ * The name of the function that NativeInstance looks for when launching its
+ * native code.  This is the default function that is used, you can specify
+ * "android.app.func_name" string meta-data in your manifest to use a different
+ * function.
+ */
+extern ANativeActivity_createFunc ANativeActivity_onCreate;
+
+/**
+ * Finish the given activity.  Its finish() method will be called, causing it
+ * to be stopped and destroyed.  Note that this method can be called from
+ * *any* thread; it will send a message to the main thread of the process
+ * where the Java finish call will take place.
+ */
+void ANativeActivity_finish(ANativeActivity* activity);
+
+/**
+ * Change the window format of the given activity.  Calls getWindow().setFormat()
+ * of the given activity.  Note that this method can be called from
+ * *any* thread; it will send a message to the main thread of the process
+ * where the Java finish call will take place.
+ */
+void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
+
+/**
+ * Change the window flags of the given activity.  Calls getWindow().setFlags()
+ * of the given activity.  Note that this method can be called from
+ * *any* thread; it will send a message to the main thread of the process
+ * where the Java finish call will take place.  See window.h for flag constants.
+ */
+void ANativeActivity_setWindowFlags(ANativeActivity* activity,
+        uint32_t addFlags, uint32_t removeFlags);
+
+/**
+ * Flags for ANativeActivity_showSoftInput; see the Java InputMethodManager
+ * API for documentation.
+ */
+enum {
+    ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT = 0x0001,
+    ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,
+};
+
+/**
+ * Show the IME while in the given activity.  Calls InputMethodManager.showSoftInput()
+ * for the given activity.  Note that this method can be called from
+ * *any* thread; it will send a message to the main thread of the process
+ * where the Java finish call will take place.
+ */
+void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);
+
+/**
+ * Flags for ANativeActivity_hideSoftInput; see the Java InputMethodManager
+ * API for documentation.
+ */
+enum {
+    ANATIVEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY = 0x0001,
+    ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,
+};
+
+/**
+ * Hide the IME while in the given activity.  Calls InputMethodManager.hideSoftInput()
+ * for the given activity.  Note that this method can be called from
+ * *any* thread; it will send a message to the main thread of the process
+ * where the Java finish call will take place.
+ */
+void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_NATIVE_ACTIVITY_H
+
diff --git a/pdk/Pdk.mk b/pdk/Pdk.mk
index 676f5dc..afe4dc6 100644
--- a/pdk/Pdk.mk
+++ b/pdk/Pdk.mk
@@ -77,7 +77,7 @@
 #   descriptions for the new headers and point to the new doxygen created html.
 pdk_headers := \
     $(pdk_legacy_hardware_dir)/AudioHardwareInterface.h \
-    $(pdk_legacy_hardware_dir)/gps.h \
+    $(pdk_hardware_dir)/gps.h \
     $(pdk_legacy_hardware_dir)/wifi.h \
     $(pdk_camera_dir)/CameraHardwareInterface.h \
     $(pdk_hardware_dir)/sensors.h \
@@ -182,7 +182,6 @@
 
 LOCAL_SRC_FILES := pdk-timestamp samples/samplejni/src/com/example/jniexample/JNIExample.java  
 LOCAL_MODULE_CLASS := development/pdk/pndk/samples/samplejni/src/com/example/jniexample
-LOCAL_DROIDDOC_SOURCE_PATH := $(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
 LOCAL_DROIDDOC_HTML_DIR := ../../../$(pdk_app_eng_root)
 
 LOCAL_MODULE := online-pdk
diff --git a/pdk/docs/compatibility/2.3/versions.jd b/pdk/docs/compatibility/2.3/versions.jd
index 5f634ed..5b7fcee 100644
--- a/pdk/docs/compatibility/2.3/versions.jd
+++ b/pdk/docs/compatibility/2.3/versions.jd
@@ -15,6 +15,5 @@
 <p>The value of <code>android.os.Build.VERSION.RELEASE</code> for Android 2.3
 MUST be one of the following strings:</p>
 <ul>
-<li>2.3</li>
-<li>2.3.1</li>
+<li>2.3.3</li>
 </ul>
diff --git a/pdk/docs/compatibility/android-2.3.3-cdd.pdf b/pdk/docs/compatibility/android-2.3.3-cdd.pdf
new file mode 100644
index 0000000..d2a1927
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.3.3-cdd.pdf
@@ -0,0 +1,5584 @@
+%PDF-1.4

+%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com

+% 'BasicFonts': class PDFDictionary 

+1 0 obj

+% The standard fonts dictionary

+<< /F1 2 0 R

+ /F2 4 0 R

+ /F3 139 0 R

+ /F4 141 0 R

+ /F5 152 0 R >>

+endobj

+% 'F1': class PDFType1Font 

+2 0 obj

+% Font Helvetica

+<< /BaseFont /Helvetica

+ /Encoding /WinAnsiEncoding

+ /Name /F1

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'FormXob.294f5b945901682cd975a2767b600f63': class PDFImageXObject 

+3 0 obj

+<< /BitsPerComponent 8

+ /ColorSpace /DeviceRGB

+ /Filter [ /ASCII85Decode

+ /DCTDecode ]

+ /Height 49

+ /Length 11548

+ /Subtype /Image

+ /Type /XObject

+ /Width 369 >>

+stream

+s4IA0!"_al8O`[\!<<*#!!*'"s5F.Y8OGjP:f:(Y8PDPQ!<E0#"70H8E,5RU!!$kRFE18L66KB5=s+('!!3-/!"JuF!'"CsF)XEA:eUihzzzzzzp=93Ezdk,!IE,5LSzzzzzzzzzzz!"O$O=]te*!A"3N!#0'J=]te*!C-Vb!#/mE=]te*!E9%!!#0X!E-)'[!GDH5!#/pV@:T?<!IOkI!%`.i;F:Ea!N5tu!"NX@;F:Ea!Or+0!"NI;;F:Ea!QY6@!"O0^B64+R!S@AP!&/;$Bl3nN!XJc+!'"M#F(51M!^H_c!+]V]@r22G!i,er!;^PLDe&hJ"/#Vo!%;>rEc_9]"3:HB!$kZL=s*eFzS#-/c9N;&m!jGd0=s*eFz2.HUdTBcIW)6m:H=s*eFz--ZDi'@d'_[`)?O=s*eFzo@O$D!!!!"('ntn1GSq1!!!!"$b$*9"d]2go2bnl#:TWQrR_)LqmZV*rMBPp"53_T_"M8\EcqE_z!!*,F!!$MOEcqE_z!!*,F!!$MOEcqE_z!!*,F!!%1PB64+Rz!!*'"d<#?g!!!!"zd<#?g!!!!"zd<#?g!!!!"!!$nIBl3nNz!&+BQW.4jJ;ZHdt1dD$@W^$Oa-C4]4'&*Bd:d>!\<'UEb1G]"41G]"41G`QQF(51Mz!")7n+A>Tf0K(cgzzzzzzzzzzzzzzzzzzz!!$kPF^kCOz!"o83!"<aS:/:ii!"o83!9eBD:fIDp!"o83!9eKI;agZd!"o83!9e$/7S*R[!"o83!9ds%6q[L[!"o83!9e`B6V[U]!"o83!9e$87T'3d!"o83!9e0+8l,Kf!"o83!9e!3<Drkt!"o83!9eB<:eUih!"o83!9eBD6;dd`!"o83!9e!878j0d!"o83!9e`B<*'&"!"o83!9eHG;H3\s!"o83!9e3:92Y`i!"o83!9ds)6q%(U!"o83!9e<::.tWf!"o83!9e-=8Q5Zi!"o83!9aDR!)NY<!)*Ah!&FU/!&ag7!!$kQDe&hJz,4GR4-BJ3-!!'kS8:U[?zzz!!%+PG]Woc!!#B)E-ZJ<B4uB06#^dZALnrqDIY:M+>PW)3<9*<!'ittBk@>F9hbU;!!!!)!!.jh!!E9%!!*'"!#bh;!!!!#TE5)r!!!!"!!!%>TE>/s!!!!"!!!!Rzs4[N@!!30%!<E3&!<E3&!WiE)"9S],!WiN-"9Sc2"U5/8"U,&6#71Y?#7(P<"UGJA#RLeE$46tB$OdCM$jd7J$NJi\6NI5i!WiE)"Tni1$3gY<$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$4?gK!"fJ:0`c7r!?qLF&HMtG!WU(<*rl9A"T\W)!<E3$z!!!!"!WrQ/"pYD?$4HmP!4<@<!W`B*!X&T/"U"r.!!.KK!WrE*&Hrdj0gQ!W;.0\RE>10ZOeE%*6F"?A;UOtZ1LbBV#mqFa(`=5<-7:2j.Ps"@2`NfY6UX@47n?3D;cHat='/U/@q9._B4u!oF*)PJGBeCZK7nr5LPUeEP*;,qQC!u,R\HRQV5C/hWN*81['d?O\@K2f_o0O6a2lBFdaQ^rf%8R-g>V&OjQ5OekiqC&o(2MHp@n@XqZ"J6*ru?D!<E3%!<E3%!<<*"!!!!"!WrQ/"pYD?$4HmP!4<C=!W`?*"9Sc3"U"r.!<RHF!<N?8"9fr'"qj4!#@VTc+u4]T'LIqUZ,$_k1K*]W@WKj'(*k`q-1Mcg)&ahL-n-W'2E*TU3^Z;(7Rp!@8lJ\h<``C+>%;)SAnPdkC3+K>G'A1VH@gd&KnbA=M2II[Pa.Q$R$jD;USO``Vl6SpZEppG[^WcW]#)A'`Q#s>ai`&\eCE.%f\,!<j5f=akNM0qo(2MHp@n@XqZ#7L$j-M1!YGMH!'^J^eG-NC01u",nG`Ffa4e4cpM":c88PCn1>L,"M]>S:ok/CblnWoh&#FYmpsZ*f6h'8mIO]^cdki!c&P7/NgtMOeqa+M.%A^H91+Y[F`*5e<*0Mi!INs5)nE7bT"_o(ZnRPP2Nh[.g9G3_gNKo-lLr5u4W\?PoW5p3@jts8l?<$bImu"h-G_]Y9cn@#KZ+/=&hgW]6hUSBAOXXZQb5utFf-?0\bAC!hWk54??CH'+Xo;O,jZG?r;L%q4D\)X+`4lUfe,0a9]im!P8(?-k&mdiO\P%4N?n)n$Q%8b5Fp!n'):A!Ka'XdT$0Jnj:W*cqej&YZfjBR'Fe(>,CGj$GbqP,0%C8O#^@IG;jCJ**k\`QbG[BRlGD?)2bH'P!Mo.J7I.habPKfAp*E`N;/hl%*^`@[$cPM&TPC,dJ*Zp1[)*CitkYc-sl>I+ngHfO/M)V4C(nk#UJIB;1SYM_H:A!sdj,-^>D82D8Dl2B[R=?+S!,173r#XEH9g\0]*Zr/drfuTXdO0tuK)O\?6HlmA+5R1C$_NdeK?,m`.fH'T-XM&0?-thFr#p\uZgaIr8Zpk6)S!%tSk+OlB=:NoQP#<P2]:Wr2f="DrKb/,Hs9gg6Wro\]p?!I/9;=5l-Q5-Z-+3EN[-)A?ml.3+HLm^=5jbW]qG/T`EJmkoT+fW-h,o[rOd)oNn6P2=CTdF(LUlW7b[`':!8PYA<L,<_K!Qd4$>c/lfIC1APF]KP1DaBXi7%4.e$[]KU;Z<[db]32%;q>L"]b>JZ[uV==1hB9*0-'#9;<UJ:9A#k3q:d?OD68Hn^W!\u#+g/bYBLAZRMZD0h>MM%_$IUNI'E$j\(?NWGP4B3u0_qSMQI"n=4?iVB/9ID:Og%=j<7bA@^)R9b3iD:0%hP1do%p#`.@(VkB)$2ELUM*<9Vrk%0LCtK[W9<E)&G$2U_1Ft7L)CcLP2`<EVa0&A%[Y7.ZH'R9if!jdcZr'8(FbLN,5Qqj!5Qqj^kn4j[E2oZab]!RT-B\\/\V2Xfj]Ngj6R/@D<X4^P*C6NEHZ]A=<B7]^iTko40+?10fd<OX->571\j`2]`cCAdG81rWJW:1PC]=AIr!hV7'kr+(nHXkZ[FFl47[\$92t)PF@rNAdP!B&(al$d8WJeVjK9]&kMG6S-Uq)sd036duDVJI9FH,!&U:LOC<@p/JSfQC#Y;FKK?F%2Re)V+ugY6!ZZ<K?7(0+7)'=@8]k\Dn:.<lI(,!Wr,iWL1j>)SHGR+N%)B8=LT_/S.MS/gRl3N%hQ;c.V8'W3Q`G.!XMlL+:j/TbI53XR@&WT$,QBQmLC>2Hr(B/TVD9oN.T8J>?"EJ09*"l#0TalHI&S#^<a]_fm.i]oa^,D@!\!&Aso"6sZ5;O_]!9(CeE]'J*:O.qL]^aPq7!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!9X82Hrf`t_7p8jN4`^a_VJg+@><Jio$8ff66IN^iE5Y9_ObP^)u^1+i/PZ._i7WSn4hD",-?@27R,t#BRf^t+8R0RpMUDk=_W=&e+ESsdPrA(as;]Y:a2Wf(]Y&2q=ZHV`7_U5ic=r$.QD0fGZ/h[C86u`hcVI5h$dMe.ZPt3a!^@8p4Mj1a/pu^o>;/G>?t>d$gS2=!TO]]X;OT1;mhAc,928sSepAkmHsDh_7h>/nA^aPm7159;`$;e>J+sodOE!EP"BTu,Ba&Hj!1#e>5>B$$2%e=DnL"f)d(A#e00Z]fJ`p[;H+^QO9lrs4U!t2'u\a@:0j+3`C3kH3h4`KQV)8[<i4s.h<b+-e^_)73f1j*lHKbGrX't@dnnS'ZIZZ1X&rTKiEkk+:*RgWbb0T>h\eV.f<K]lpo!'=L)pVaa8RC"/Z5>@P&12aXr75u`&!-"e/X%"8HYFP^\B3GKp;T;"RRl)[76bF?A([#?^V!d+CG^V%L,FN%maIXm=#!7-AgZ1qYJZ*oR^iK0cWR!R07Rl(qS,5:Cg&4+[/XqAD4AID)@]qrr>3(QT;sO2gZ=trX(aFE9GF>F/p&%"PlHP*o`C_*^/GQrr<N$:](TX]t<5,Xf[Z$T+,"-gS@]LK4mS@JNtOs,iF!3:ZGa^q\eWZ>X,Sc`!2,pJPDZd&_[g.*_Mp!"]P;n!"M'tkJgQ_]I#EfU&Cf(ou>P\KNBInc/%u6?YB;#F]1r&Ij:cYQi%O>iI8JC6)8:f):\;WXs?tNfbulGN0B4BJdS]\!<#"2V>PB/d@kppn8*P-f<i`%`1HcV+Lec4$V8G/a^`*o)tVB8*UCh^i1j<g:[n*DeJcjlEuqVr8bNV0)CHhPkXm;EYc5BUJ,)%,&,uX^Iae;s8M2N07hBYm:P@!^pknUD<s]4TKgc.eNBJ8!es=eTm$jO)Umo&TTCDC>"b4oYeUR'<.eKoq5IAaf5!9jc*<t*_a&0-u8TA6d(FCnW^,Al5-m_1)#UFE2-`m)]@:c;551&s#3mou1Mb1Ai`=`>SrS!iqgll)/r"=T%5PFU:Q*$!<$qAh:0uPuLb`FR;Hh6p5[uB>%P9$"5)iTe$SgnIfO0VUDk)4F];Jk*iWF*,DocW:=H_-Yqch=R3#Jf.r0+M`_(V5X+/0\#,Au_RRal'e9!#(!8!BbF^MW$-Oi1k`$P3!>NiV'Mj7DF*nF%%<%oa479jstZ9#OS@`Ho^`Xh[[:Pi![:3C)3Tshii9F._a`X'+qcq!?'g'jE@^Wq"OYiplFE1_`Q0JlJD[kdNZAf0Js7(VjKkP_u,&%Qt*LRGB>3b?8iO;Q!>@X'.bJK(s8,lUp/:1k)\/;DUmLhb=&rdC/qT`QJF*=T>qJ%SeTYgB7$h<)H:eC2B)7F['=t#gOhOJL6Hd=L$'ZuaMiDmlne1jZtO<j#rdV3%79(S!*>J2DW6ltm3"-\m&B%qP]f%crr=%1I08C<r0Y:_ra6Ybrf4Ri^[P"Eq')9*rJ`W5!9lAKD=+ZGhhs7;A8A2OgCMTXJp'jT;i5GjX/)6[D1+p"8u,be7Yci(4q8+X2ak.)o^-&]U\cU#CRCr*Ym)r(=3O&'mdg+2WS<TH#Eh4L!;?0<jm^U8Y6F]a(`$3%i;6-b`rXD*X5KSbmB&#]J'(-c&,Ps[rr>WeW;cj74'QM#!0=l)lu-9'@@DG9Q73Vj\soJu&_mplH("VW\@rm+T`l9*35lT[[_1+l.<g3t;,+M+HC%/"'S!r16#VM3TK)!?\BjfNA,&(ST>BD(r%?hSn:T#E']p@89=,!V%KJIr#oFe:#UCLj+E]Hmg"]`=T098oDXj+N#=).JN"mkiN,aaNVu@"XU)d1Q[]t4ba)to)!TAKCTuZ'rj^2@b'u]o$'4A%(ls+O0nS4ft&uO[Q_j]l=GJ;e"-W2`l]A2a;B:J@BpV.\3+hrRZ22'ML:hJ4Te0RS=6g$\$?rc;fbIIKG389C4UQEtijWp-6p$.&!f-Mg2DuTeb&+M%H^8Lu2d^Q(&J)qrA+8+oKo[bC:U;]6-%HV_;@iOPBdONH8[5o13n;jR#rmdA8!!hKQQ[l4;-0b9F`R*/ko\lXjLkqnd&*NBBPd$(!_dGA.k]8uHTH=a3oIks-rr<RAddABM?^&]gm77i0j@^.?4iod@:6gV3FoMH`;##87!+/WRkkH[ArOBW'gpMY.qR$8&dHOu'G?YZ:Tu<1po$_Q:4lmC5Qa+2fT3K8oVtP%O[>LGj9Zm<nIQL3m&&U;t%fZOf(t=K-)F>b,[5<HnAcsSRStM@o#GN.(^'B%8n?9m%>uL:3)K"TAl$$nVMoAM'7KfKGUuOO@+S>E*rl`(IDr)6/!3fB$!9d-`62pofgn#1UGd?5P?Sh(-N)OrFNO"N'e)%bXUGC*blBr[pX^tBiRWTU>MGDQs#sp-!bBl1\[sa-mUq%.cT$?fCj0+19"6anhmtpB`m[!_E>K729WGjOoTB78)5j=f%5j=Fn81'5V'Y&k+,`3HY(s!pG^2X)PJre"jn99V]1'$^@bX)ub!\on"`-u10LX?&$j9oW#!+)r1!9bW@O"AQGGciO?0GA6T:lQ8328%rs/&&\[$]LRRj4_JPn1PZ.hu3cJVi(-h$q&s4<q#oHnk3W+'#tiOOc$DD,b/BbB9G!23`j&Ib[7X2XgGjMJ&GR%/^^DPk2\rU-nKqPh`*d*Jb`@X(M4Q8%"89\QW@'sM4BcnJt8-9c*OnDl7.s[Bgpb<^5r9o"VpfLH)S]!XEZC"ZaY+qh((u[QgRfa80.5akRDklNd`AN5N2?ek4k(Bl6WgYiCP8@Fn6N"pt2j1NQ&@8EX"NL!(c\,paA"rXM4liY3!,^Q7[C`'SSh`#!$aWgGg)I$KchP+8IYK"TJJRY)iS_Uh77X]L0V_%.c#.0!oUS_pMIm/k$4TeXTQPV"NUDHKbo\LGEc@7oAdQp>+/G-@!PZ_B'He;m'@ge]OX\NuJ?L/V>U)E1o`mai>7C>PP])D1"><>N4Cu"im?P)R\[jm(IaTOi8!o3s.4\0[D]q*Aa4:h>@Jc\$YoRi<ZQ&dPX3+Z#[+B:g'G\@tEF?,bF(\?6/nqg=o@!@/NR*RbB]`/%nKlm!t<Irr<:<m?,F(GcZB1@5+&W5M%,0pt;j#fgaKOaj"B2m3d@br/`j7,d47*m!mrg?Opb]N\*W63kQ$1@S*>\.7t+V\Jb>2g@]rPrWpo#*^@V:X_h90>:$jRaH3luNK'E/Y3%:8!Pumo`Gm!.`MK]Wm+LA)Xt?E2i0)AV*RHO#c.kt&8a(?0%$&P%HLid)1H54FT2$rj3.uAQ!+3a'\aL/Mr];'O``J0Hd_a0>$%"O)bt5s@W4-nlIIHA>o7Lbhl#U1srX([D'Y&:lpj&r4&7QlI8`G_sHBeWnl'#C3_9^k/_4MPAGAZ7GD[L4tIF[\))d-d8,Xu<3+]Gk4ntR3%A%d"lZP6SB?N@_iFElbHharg(0E;-?r`TtqXh6Q?o3O7_dj"elJrs7H/Kms4,>KB$4O^0!\@+VXSkjb,Y%jA[)!/-qb\_`TC=C/PUBs4aN,5NZm3LG0>$fCeOE4B^.rTcV4ceX$m1\E=J@7A!G`iH8]?C0Q!+W7=<A)+-QZC"I>`^b`,k)9R1O]K+dd_^.eSZs\Itmg-NLdE[jOGk')?BR58!/b8aZ(/#E]_m@Ib#:cpV4,&_eV?WFI!eWYXr;d""U@c+KGU\"EB'$9OH[\BpLR?HA(Su(@\];b2!XD&kVp"9mm4OO3[?'-H7^?.Tfq$iuUVlh!YCngtTJam'c;n[-&p">nQ&04T3".)>HS;[ltbZ]JlhTVTre.H`6X()0In^2]^*C"D!)4N/hW0&,uWJItiD.nO9X92.$l/)F;')@=n(/j,t^33!)DP-jd]FJd-M9afK9]pa@Y"l?=rW)rQaQX4b;`>GHXVEXm%l1kn`8_8]ZkDt]dtorS('eb"^k08AlQ\[9F_`m[Q.:G?At43VA]WD3XW-'!8SJBg.S!#(^9Ge>A=*(MQFW@Tm$)(o\]Wj_V&f'`7Y``8OO;SU<M$faasmfn.JnDo$@nSu($Y%9=jg"IQ_B5fVGOoPK),k7#HO:REP!5lji(&n8%hc9[V^ppDBr"MF0D-Oe08thC8DhG%M&\?Gpk?g\oeeV'?Heg:?i\o%i,Y$\7)[^C+DVgc$)"b#<`8`hP2rZrK%g.`M)P.O>\*fMO-TH24gK(c:?dR33P+,%sa3XbcnF>rMrrCG*eN`OU3p?PYrnP6tIO"Wnf>4qB*i#Oe?d>n.bA^?]UlgZP)3j5cM#_K\-^$!Grr@Xi=P8`Cpm4koZ2L?Q_\&MKhln7cF4V9Tig9A]Yd0&E^V`3(.nJ6:od!,+;urOjjpe#FHu<bHACo)ao?K4k_Xog>XtgZDV&RkV;-HSiZhW!ErH;Q2$?]?+2UA3JU5JoRl9'"Yh"Y=;mtmYDmA'/_R.o39AuN1:=i)s?Z$C5HjcAD/=<40"1QH]B<f-]\r-6Z^HX/R-rL1,UM='5'jde!k@1j:lh6Y3bF,lYGoZ\-@\X*Z`/*@X'*!S<GC6`9Gbp^GD>drg<P0p=u8t0k`:<*V/1ZD3KYDIRBf!48MKlVEMh+A%UEH9''N9>18Z7@DcQN[!-)9%"%i*BFEa6]5SD\;2qHlfrPm'TK[,Zbc4nsJJDca$+'NEBSiS=pf**=d/`m1f.5'ua\I@;#8d`ta>LEN@7j^3+-;)^sFk92-&Mmnf9-daqHGL%0fT:WNJ8g1*XYphOC/%oLd&[04"&BeAHiPmj_)8J)Rl)p'D>\K1VRp:g<?ip4qD_o&&VnD9"EX53#$NJ^t2Vcu"%<@qd<\4$RW/BU#'&?gJU\<d:YphXJ\\@L1mMLpJMN+:$Jh5$d1[sJ%B[_7sT]=lF<LUqWjOl.5j8^q-&>[$@bd*E:a.-hMH&&<g(/,Lf@"3/%lq!7G`=RcoVD_19&^6*:#DBUa1jfTWUb@C:dg`3I^"`oW]r<5W<"tq+:iph7CmVP'2D(Rp:_j=`V6JN5gp,k;-oC-[Ur+5BL8@@rRLMo%!@FpUa'pK.`W+_u'9!1oJ&2VdtlWN,SoFfo+!RRsG>WdHZ[9"6k#dh)G^4WUArN:S\pnQk._T9AOi;Wd'YH7D1Y9SX5"Cbc<,\9=a!Q;U\rpDl"c>d2#e>\brR&hqu9%]SOO!7s&me4+jg3\*Z\J69`RbaQ<i,@?lj#sSu[*(FYB=lts+L7"Qe88^*<4Gp/6\)Eqj:6-"c?aT7?eJ)fh\3Xgn[$.u+$Lfl8pq=(7bUhN[CLj]B6bL7D+>P&.S'5h)'i_*I0&;$2I.9=g2<$88rm\a_[E2K$<7.h1#%T#:G:Z(_H$)jo.5:TX?EBs3'o&eQH?S%1U[(kpNt\T.:"qqf_J=^g2Fsfg#)Lkf7#1DGN!trM"LXcAb%.!#p`?QZ:MlT@>o*,KmmIQk8eRepoXEYI!#/*i*4N^[bnEOX(hO2@nA!_QSYjGFaoZM8cd'E8\c5?O0!#rWph>e;oE,6\W#c]X3,<Zq&o\;M=Dl=\ZGL1^CYKnWCo^+J&?bjhBhYMm%aR\$L:Tuo/0P;p$d<AIUXUqcB(FKeU`r<*"i`;?=3R@C4@-!-Be9dPMm8#3`X1spXd"-W3Y(^!KK!J5fnj%&Z-7`P&l2qqLXUtC2f.\j01M%4aBq-3.!KFMro_fXP6Nn)`EuY=mB(peMQt`IIWYSHu!g#G%a&l[d_9&RSqcCI7YP.":G@2gSF_H6P)/=&'V\,1;C9,_]O\\hQu1%ME_UC)>-X^$=i8PgHoM78<G0W`,"s(goMG83:2kmJYJnQ_,r6`?&c]nXHLP&p:")8-180YkrAA"mH,cf1tQg2aa\-QNi(Km&)!.D=c-WuBPs5*A#Wf`&i88elW_-.cbb/NGQYjpmu"c#Us5gmlh=5CXKIc1Pu8bKhW`QL1s@kd&'LIC7Xa#J;S_dn17iDS0[)9#`6Nt$,&r8M>h:O!]!^!]5uW0ddW_tfn*I79*uT<-j4D4T:LEVAjfP?1d]Kq4p?`hum^[O?)_`5I;B$jc)='bei%GuJ!5j9<GgUmpHJ1ZhBb$rIlsNX@A;#R^2M8Z@gRS2ZNbdi..FR.e*A"Z/K2lL+6Fs=kQYfJqjaLP/]Cc\F\Phe^I/EePp]nff/GOqgrr>pca+j%?#bf`nNo@)lg/.nB@:3Ug@6k7`,ie!)9'j</I03aE0C8]=X6I>>dOoI@I-YD\er[8e'j8ng#b[B4ahZg9H37KI7<I/?>W$/^5A8[#ifpnGD%99%pXF)LI,8Lorl8=kpo/PsX'Z-WYMk/'7[KlQq%.:BY40VW-L?8e3Wjm=b@_[m%.XTUO2#,lLAJZCY-n90%/`]-nFPJWdTkG-aV>\RiZn8aPtt\`GI@\Uq?su^=2dtfn)4erY7o+>%:&1EIJ(AtCQhB$8Chqa!6h_nJ8b`DN8l95-G6G+KcB"9(b*j7q9cKSdXK<7CO<@?FL"J@m^6o=9W@oG>4t-krMG#FBcdOhddA[#.5&:ko15$K8tfgM<!"%JgZ9]Cc8kRbpF_7-dB*EhrK]SG!8f!5GJbN,8&4R&l^%D&pH%0./`[DMHBm8[$a;W1ei8bqaQQA063sc2kH/1.gb"H*ES/K8=u!q3^ESXsc;cI;S_KC:GAdE\IumR*i7i"u$M]84f>\mKr$(q7j"%kMp`98u-2s`d*7cgFL-Ve[bT0;+&-m]Lp$H+)f8b4`p^cBAL-HV>DrV:3gHM%,9[BQ\P6Q56->?"^``/lZ*9/ED7npMB.*Zg<cRa;ib+")V[o+YJP47;*V4F-!ddPF'Wu4N,Z/jdZ4skZ)rM?k_:PQ;BZhC5n#1O9/RGjNb<&0H]8;ND3c>q-KduiP7^M5ufhC4*N<RAAbU1ohV\!ebpTX\8k#+:iI!K!@D%E*-/[mOKp79heieYA*"mOiX_@\B^2\AgY9=1+e;QL=56e[*qBmdAcSHmR3ZoH/d9):8%\G)GS._tHo3`5;a(8.f!#d"3e1m7InJrrBB,m2+cC*U'+'DYur$pk%Mb8>`f(Q/a;M^2O-Ee[@NI</)CNj,=oQb)5i_Sem,qKu1]lGu:VrBu4R2eYC<fH98=qg(c)ba][?<aaY**3dc2IjkuVhL";m&^8k^#3MI/1/ZpC9,`<cIFD;WS7EZ?p!W(EWp`JG&SJUYQ@IS'l4@.sf:eaY^:ct]bR7UI"AiCibaN=V+Y=5BI4Z:2]dr%!j>1"rSDW#bW@$G55NIb,2*Phl>`jrDC':p-^>8rXA4C)]drKk89`]TT)`Mfh?^#*Vh.+>M>]<gYKqZ_:;g.+j^j42tu"j';o;6_3@Z7%*X!k=kRIK["PH2DICh@\1`;&6\GP?g-@Q+5e^=A$Li$NS=VBu)ola+<P8hsaEKJ_*tD>f!OeP1^kt>Bhg[.2_\Tn?ZWi8b]C*i7I>+n@RV5V`q`OFM>B%RNiBWeLhV=MDKia![9&<##6u/3$_SC;W'*39]$.WQ=!Do)AQa[;cW!YnUnS+Mb,O5QF>8`a\dH-g=GjT5MA'3*]3C'm7$O1`*+OC05e/o>FS!&HO[SL:jH,S=7[C?-53#@)<VmRYAs)]M^O@/-`VE7$._&b2!OCj7i;S=2F'h,h-)X:l1c6R%t_a[.s!_!C0]1_Vn/X7DnOml-Jrn)rr@\d&AC:+bZ\VPnETK9I_XBbC+XH!M!\eZYuO/J@n'U"pL=>Qnot2M&T3%WIb4QPnG`KDDZ1+%BJt0acf\V>>=tq/85m`VRRBsP=N1m\Oq1KA5/O&.6iJ7c,$B;6b.3L'?rLFEjat-E\WhBfk1stN)>b4f="OrTIr7INps[8%hgl``4rCu_<o6`aNo@)lg//0"[jkXD\thgYESt[o,/*GEJkMXik1UQnaTJOOj!:T*VkUoG#EdBLk.&WWADFFpQWdO46]kU'C@5c.Pah)c-gVH'Ii*D`_0Ys&]>Ji]A'_3U_]A@R(4D$o+^:*136j3K3'8*dg;h#.0_%*@hhJ_7LV,KkHZ*]#ip(l(%#G5Xi-`U9g`'7R>6>4Xi7GY>?;u/2#p'hZOo&:.3&nWh0)963Ssm'*6@G$jI"?q8BVLC]"&P_L-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ii[!U5nkC5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Tg$Z~>endstream

+endobj

+% 'F2': class PDFType1Font 

+4 0 obj

+% Font Helvetica-Bold

+<< /BaseFont /Helvetica-Bold

+ /Encoding /WinAnsiEncoding

+ /Name /F2

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER1': class PDFDictionary 

+5 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (mailto:compatibility@android.com) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 55

+ 626.125

+ 145.135

+ 637.375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER2': class LinkAnnotation 

+6 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 55

+ 747.2637

+ 0 ]

+ /Rect [ 70

+ 564.9375

+ 117.5275

+ 576.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER3': class LinkAnnotation 

+7 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 55

+ 458.5763

+ 0 ]

+ /Rect [ 70

+ 553.6875

+ 114.1825

+ 564.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER4': class LinkAnnotation 

+8 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 55

+ 441.1388

+ 0 ]

+ /Rect [ 70

+ 542.4375

+ 107.935

+ 553.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER5': class LinkAnnotation 

+9 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 55

+ 357.86

+ 0 ]

+ /Rect [ 85

+ 529.1875

+ 190.045

+ 540.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER6': class LinkAnnotation 

+10 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 55

+ 216.735

+ 0 ]

+ /Rect [ 85

+ 517.9375

+ 172.12

+ 529.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER7': class LinkAnnotation 

+11 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 55

+ 140.4275

+ 0 ]

+ /Rect [ 100

+ 504.6875

+ 161.6875

+ 515.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER8': class LinkAnnotation 

+12 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 144 0 R

+ /XYZ

+ 55

+ 521.615

+ 0 ]

+ /Rect [ 100

+ 493.4375

+ 178.3675

+ 504.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER9': class LinkAnnotation 

+13 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 144 0 R

+ /XYZ

+ 55

+ 521.615

+ 0 ]

+ /Rect [ 100

+ 482.1875

+ 184.6225

+ 493.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER10': class LinkAnnotation 

+14 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 144 0 R

+ /XYZ

+ 55

+ 457.615

+ 0 ]

+ /Rect [ 115

+ 468.9375

+ 221.725

+ 480.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER11': class LinkAnnotation 

+15 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 144 0 R

+ /XYZ

+ 55

+ 91.615

+ 0 ]

+ /Rect [ 115

+ 457.6875

+ 195.46

+ 468.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER12': class LinkAnnotation 

+16 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 145 0 R

+ /XYZ

+ 55

+ 677.115

+ 0 ]

+ /Rect [ 115

+ 446.4375

+ 206.7175

+ 457.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER13': class LinkAnnotation 

+17 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 145 0 R

+ /XYZ

+ 55

+ 581.115

+ 0 ]

+ /Rect [ 115

+ 435.1875

+ 200.47

+ 446.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER14': class LinkAnnotation 

+18 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 145 0 R

+ /XYZ

+ 55

+ 516.2975

+ 0 ]

+ /Rect [ 85

+ 421.9375

+ 180.0325

+ 433.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER15': class LinkAnnotation 

+19 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 158 0 R

+ /XYZ

+ 55

+ 710.0475

+ 0 ]

+ /Rect [ 85

+ 410.6875

+ 160.0225

+ 421.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER16': class LinkAnnotation 

+20 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 158 0 R

+ /XYZ

+ 55

+ 622.49

+ 0 ]

+ /Rect [ 100

+ 397.4375

+ 197.53

+ 408.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER17': class LinkAnnotation 

+21 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 158 0 R

+ /XYZ

+ 55

+ 249.49

+ 0 ]

+ /Rect [ 100

+ 386.1875

+ 193.36

+ 397.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER18': class LinkAnnotation 

+22 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 162 0 R

+ /XYZ

+ 55

+ 698.7975

+ 0 ]

+ /Rect [ 85

+ 372.9375

+ 194.2075

+ 384.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER19': class LinkAnnotation 

+23 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 162 0 R

+ /XYZ

+ 55

+ 531.1725

+ 0 ]

+ /Rect [ 85

+ 361.6875

+ 157.5325

+ 372.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER20': class LinkAnnotation 

+24 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 162 0 R

+ /XYZ

+ 55

+ 105.5475

+ 0 ]

+ /Rect [ 85

+ 350.4375

+ 196.285

+ 361.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER21': class LinkAnnotation 

+25 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 172 0 R

+ /XYZ

+ 55

+ 678.0475

+ 0 ]

+ /Rect [ 85

+ 339.1875

+ 191.7025

+ 350.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER22': class LinkAnnotation 

+26 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 172 0 R

+ /XYZ

+ 55

+ 612.99

+ 0 ]

+ /Rect [ 100

+ 325.9375

+ 147.94

+ 337.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER23': class LinkAnnotation 

+27 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 172 0 R

+ /XYZ

+ 55

+ 494.49

+ 0 ]

+ /Rect [ 100

+ 314.6875

+ 161.695

+ 325.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER24': class LinkAnnotation 

+28 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 172 0 R

+ /XYZ

+ 55

+ 387.24

+ 0 ]

+ /Rect [ 100

+ 303.4375

+ 144.61

+ 314.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER25': class LinkAnnotation 

+29 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 172 0 R

+ /XYZ

+ 55

+ 214.24

+ 0 ]

+ /Rect [ 100

+ 292.1875

+ 143.3575

+ 303.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER26': class LinkAnnotation 

+30 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 172 0 R

+ /XYZ

+ 55

+ 161.49

+ 0 ]

+ /Rect [ 100

+ 280.9375

+ 174.1975

+ 292.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER27': class LinkAnnotation 

+31 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 177 0 R

+ /XYZ

+ 55

+ 632.6387

+ 0 ]

+ /Rect [ 70

+ 267.6875

+ 197.1325

+ 278.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER28': class LinkAnnotation 

+32 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 177 0 R

+ /XYZ

+ 55

+ 528.2012

+ 0 ]

+ /Rect [ 70

+ 256.4375

+ 159.6025

+ 267.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER29': class LinkAnnotation 

+33 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 177 0 R

+ /XYZ

+ 55

+ 444.9225

+ 0 ]

+ /Rect [ 85

+ 243.1875

+ 147.5275

+ 254.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER30': class LinkAnnotation 

+34 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 177 0 R

+ /XYZ

+ 55

+ 292.5475

+ 0 ]

+ /Rect [ 85

+ 231.9375

+ 160.45

+ 243.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER31': class LinkAnnotation 

+35 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 178 0 R

+ /XYZ

+ 55

+ 394.7975

+ 0 ]

+ /Rect [ 85

+ 220.6875

+ 160.0375

+ 231.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER32': class LinkAnnotation 

+36 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 179 0 R

+ /XYZ

+ 55

+ 521.9116

+ 0 ]

+ /Rect [ 85

+ 209.4375

+ 155.035

+ 220.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER33': class LinkAnnotation 

+37 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 179 0 R

+ /XYZ

+ 55

+ 303.2866

+ 0 ]

+ /Rect [ 85

+ 198.1875

+ 147.1225

+ 209.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER34': class LinkAnnotation 

+38 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 184 0 R

+ /XYZ

+ 55

+ 517.3887

+ 0 ]

+ /Rect [ 70

+ 184.9375

+ 174.1975

+ 196.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER35': class LinkAnnotation 

+39 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 184 0 R

+ /XYZ

+ 55

+ 275.7013

+ 0 ]

+ /Rect [ 70

+ 173.6875

+ 155.8525

+ 184.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER36': class LinkAnnotation 

+40 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 188 0 R

+ /XYZ

+ 55

+ 657.2975

+ 0 ]

+ /Rect [ 85

+ 160.4375

+ 170.8675

+ 171.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER37': class LinkAnnotation 

+41 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 188 0 R

+ /XYZ

+ 55

+ 580.99

+ 0 ]

+ /Rect [ 100

+ 147.1875

+ 195.0475

+ 158.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER38': class LinkAnnotation 

+42 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 188 0 R

+ /XYZ

+ 55

+ 279.49

+ 0 ]

+ /Rect [ 100

+ 135.9375

+ 171.685

+ 147.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER39': class LinkAnnotation 

+43 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 188 0 R

+ /XYZ

+ 55

+ 237.99

+ 0 ]

+ /Rect [ 100

+ 124.6875

+ 205.0525

+ 135.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER40': class LinkAnnotation 

+44 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 188 0 R

+ /XYZ

+ 55

+ 173.99

+ 0 ]

+ /Rect [ 100

+ 113.4375

+ 183.3775

+ 124.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER41': class LinkAnnotation 

+45 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 191 0 R

+ /XYZ

+ 55

+ 710.865

+ 0 ]

+ /Rect [ 100

+ 102.1875

+ 201.7075

+ 113.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER42': class LinkAnnotation 

+46 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 191 0 R

+ /XYZ

+ 55

+ 504.7975

+ 0 ]

+ /Rect [ 85

+ 88.9375

+ 145.03

+ 100.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page1': class PDFPage 

+47 0 obj

+% Page dictionary

+<< /Annots [ 5 0 R

+ 6 0 R

+ 7 0 R

+ 8 0 R

+ 9 0 R

+ 10 0 R

+ 11 0 R

+ 12 0 R

+ 13 0 R

+ 14 0 R

+ 15 0 R

+ 16 0 R

+ 17 0 R

+ 18 0 R

+ 19 0 R

+ 20 0 R

+ 21 0 R

+ 22 0 R

+ 23 0 R

+ 24 0 R

+ 25 0 R

+ 26 0 R

+ 27 0 R

+ 28 0 R

+ 29 0 R

+ 30 0 R

+ 31 0 R

+ 32 0 R

+ 33 0 R

+ 34 0 R

+ 35 0 R

+ 36 0 R

+ 37 0 R

+ 38 0 R

+ 39 0 R

+ 40 0 R

+ 41 0 R

+ 42 0 R

+ 43 0 R

+ 44 0 R

+ 45 0 R

+ 46 0 R ]

+ /Contents 321 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ]

+ /XObject << /FormXob.294f5b945901682cd975a2767b600f63 3 0 R >> >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER43': class LinkAnnotation 

+48 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 191 0 R

+ /XYZ

+ 55

+ 450.99

+ 0 ]

+ /Rect [ 100

+ 730.6775

+ 152.95

+ 741.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER44': class LinkAnnotation 

+49 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 191 0 R

+ /XYZ

+ 55

+ 313.24

+ 0 ]

+ /Rect [ 100

+ 719.4275

+ 192.9625

+ 730.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER45': class LinkAnnotation 

+50 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 191 0 R

+ /XYZ

+ 55

+ 213.24

+ 0 ]

+ /Rect [ 100

+ 708.1775

+ 173.785

+ 719.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER46': class LinkAnnotation 

+51 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 191 0 R

+ /XYZ

+ 55

+ 117.24

+ 0 ]

+ /Rect [ 100

+ 696.9275

+ 182.545

+ 708.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER47': class LinkAnnotation 

+52 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 196 0 R

+ /XYZ

+ 55

+ 670.2975

+ 0 ]

+ /Rect [ 85

+ 683.6775

+ 127.105

+ 694.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER48': class LinkAnnotation 

+53 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 196 0 R

+ /XYZ

+ 55

+ 428.24

+ 0 ]

+ /Rect [ 100

+ 670.4275

+ 169.195

+ 681.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER49': class LinkAnnotation 

+54 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 196 0 R

+ /XYZ

+ 55

+ 312.99

+ 0 ]

+ /Rect [ 100

+ 659.1775

+ 169.2025

+ 670.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER50': class LinkAnnotation 

+55 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 196 0 R

+ /XYZ

+ 55

+ 197.74

+ 0 ]

+ /Rect [ 100

+ 647.9275

+ 136.69

+ 659.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER51': class LinkAnnotation 

+56 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 196 0 R

+ /XYZ

+ 55

+ 144.99

+ 0 ]

+ /Rect [ 100

+ 636.6775

+ 157.1125

+ 647.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER52': class LinkAnnotation 

+57 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 708.865

+ 0 ]

+ /Rect [ 100

+ 625.4275

+ 155.86

+ 636.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER53': class LinkAnnotation 

+58 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 633.365

+ 0 ]

+ /Rect [ 100

+ 614.1775

+ 165.8575

+ 625.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER54': class LinkAnnotation 

+59 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 569.365

+ 0 ]

+ /Rect [ 100

+ 602.9275

+ 159.6175

+ 614.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER55': class LinkAnnotation 

+60 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 527.865

+ 0 ]

+ /Rect [ 100

+ 591.6775

+ 177.5275

+ 602.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER56': class LinkAnnotation 

+61 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 451.7975

+ 0 ]

+ /Rect [ 85

+ 578.4275

+ 158.365

+ 589.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER57': class LinkAnnotation 

+62 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 386.74

+ 0 ]

+ /Rect [ 100

+ 565.1775

+ 155.8675

+ 576.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER58': class LinkAnnotation 

+63 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 245.74

+ 0 ]

+ /Rect [ 100

+ 553.9275

+ 185.035

+ 565.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER59': class LinkAnnotation 

+64 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 198 0 R

+ /XYZ

+ 55

+ 192.99

+ 0 ]

+ /Rect [ 100

+ 542.6775

+ 152.5375

+ 553.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER60': class LinkAnnotation 

+65 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 210 0 R

+ /XYZ

+ 55

+ 742.865

+ 0 ]

+ /Rect [ 100

+ 531.4275

+ 213.7825

+ 542.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER61': class LinkAnnotation 

+66 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 210 0 R

+ /XYZ

+ 66.25

+ 193.615

+ 0 ]

+ /Rect [ 100

+ 520.1775

+ 215.86

+ 531.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER62': class LinkAnnotation 

+67 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 213 0 R

+ /XYZ

+ 66.25

+ 745.7975

+ 0 ]

+ /Rect [ 85

+ 506.9275

+ 130.015

+ 518.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER63': class LinkAnnotation 

+68 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 213 0 R

+ /XYZ

+ 66.25

+ 658.24

+ 0 ]

+ /Rect [ 100

+ 493.6775

+ 190.8625

+ 504.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER64': class LinkAnnotation 

+69 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 213 0 R

+ /XYZ

+ 66.25

+ 522.49

+ 0 ]

+ /Rect [ 100

+ 482.4275

+ 192.115

+ 493.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER65': class LinkAnnotation 

+70 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 213 0 R

+ /XYZ

+ 66.25

+ 286.74

+ 0 ]

+ /Rect [ 100

+ 471.1775

+ 193.375

+ 482.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER66': class LinkAnnotation 

+71 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 214 0 R

+ /XYZ

+ 66.25

+ 633.865

+ 0 ]

+ /Rect [ 100

+ 459.9275

+ 186.2875

+ 471.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER67': class LinkAnnotation 

+72 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 214 0 R

+ /XYZ

+ 66.25

+ 569.0475

+ 0 ]

+ /Rect [ 85

+ 446.6775

+ 169.6225

+ 457.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER68': class LinkAnnotation 

+73 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 214 0 R

+ /XYZ

+ 66.25

+ 503.99

+ 0 ]

+ /Rect [ 100

+ 433.4275

+ 223.375

+ 444.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER69': class LinkAnnotation 

+74 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 214 0 R

+ /XYZ

+ 66.25

+ 332.74

+ 0 ]

+ /Rect [ 100

+ 422.1775

+ 212.1475

+ 433.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER70': class LinkAnnotation 

+75 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 218 0 R

+ /XYZ

+ 66.25

+ 745.7975

+ 0 ]

+ /Rect [ 85

+ 408.9275

+ 115.015

+ 420.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER71': class LinkAnnotation 

+76 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 218 0 R

+ /XYZ

+ 66.25

+ 605.7637

+ 0 ]

+ /Rect [ 70

+ 395.6775

+ 166.2775

+ 406.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER72': class LinkAnnotation 

+77 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 218 0 R

+ /XYZ

+ 66.25

+ 372.0763

+ 0 ]

+ /Rect [ 70

+ 384.4275

+ 172.945

+ 395.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER73': class LinkAnnotation 

+78 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 218 0 R

+ /XYZ

+ 66.25

+ 277.5475

+ 0 ]

+ /Rect [ 85

+ 371.1775

+ 140.4325

+ 382.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER74': class LinkAnnotation 

+79 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 218 0 R

+ /XYZ

+ 66.25

+ 200.4225

+ 0 ]

+ /Rect [ 85

+ 359.9275

+ 186.295

+ 371.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER75': class LinkAnnotation 

+80 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 218 0 R

+ /XYZ

+ 66.25

+ 123.2975

+ 0 ]

+ /Rect [ 85

+ 348.6775

+ 178.3525

+ 359.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER76': class LinkAnnotation 

+81 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 221 0 R

+ /XYZ

+ 66.25

+ 710.0475

+ 0 ]

+ /Rect [ 85

+ 337.4275

+ 212.56

+ 348.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER77': class LinkAnnotation 

+82 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 221 0 R

+ /XYZ

+ 66.25

+ 325.5138

+ 0 ]

+ /Rect [ 70

+ 324.1775

+ 183.79

+ 335.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER78': class LinkAnnotation 

+83 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 221 0 R

+ /XYZ

+ 66.25

+ 210.235

+ 0 ]

+ /Rect [ 85

+ 310.9275

+ 182.5375

+ 322.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER79': class LinkAnnotation 

+84 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 225 0 R

+ /XYZ

+ 66.25

+ 698.7975

+ 0 ]

+ /Rect [ 85

+ 299.6775

+ 144.6025

+ 310.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER80': class LinkAnnotation 

+85 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 225 0 R

+ /XYZ

+ 66.25

+ 535.1725

+ 0 ]

+ /Rect [ 85

+ 288.4275

+ 180.88

+ 299.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER81': class LinkAnnotation 

+86 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 225 0 R

+ /XYZ

+ 66.25

+ 425.3888

+ 0 ]

+ /Rect [ 70

+ 275.1775

+ 148.375

+ 286.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER82': class LinkAnnotation 

+87 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 225 0 R

+ /XYZ

+ 66.25

+ 198.4513

+ 0 ]

+ /Rect [ 70

+ 263.9275

+ 119.605

+ 275.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER83': class LinkAnnotation 

+88 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 226 0 R

+ /XYZ

+ 66.25

+ 747.2637

+ 0 ]

+ /Rect [ 70

+ 252.6775

+ 200.065

+ 263.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page2': class PDFPage 

+89 0 obj

+% Page dictionary

+<< /Annots [ 48 0 R

+ 49 0 R

+ 50 0 R

+ 51 0 R

+ 52 0 R

+ 53 0 R

+ 54 0 R

+ 55 0 R

+ 56 0 R

+ 57 0 R

+ 58 0 R

+ 59 0 R

+ 60 0 R

+ 61 0 R

+ 62 0 R

+ 63 0 R

+ 64 0 R

+ 65 0 R

+ 66 0 R

+ 67 0 R

+ 68 0 R

+ 69 0 R

+ 70 0 R

+ 71 0 R

+ 72 0 R

+ 73 0 R

+ 74 0 R

+ 75 0 R

+ 76 0 R

+ 77 0 R

+ 78 0 R

+ 79 0 R

+ 80 0 R

+ 81 0 R

+ 82 0 R

+ 83 0 R

+ 84 0 R

+ 85 0 R

+ 86 0 R

+ 87 0 R

+ 88 0 R ]

+ /Contents 322 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER84': class LinkAnnotation 

+90 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 419.365

+ 0 ]

+ /Rect [ 125.8675

+ 663.865

+ 170.05

+ 675.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER85': class LinkAnnotation 

+91 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 221 0 R

+ /XYZ

+ 66.25

+ 325.5138

+ 0 ]

+ /Rect [ 237.16

+ 579.115

+ 272.5975

+ 590.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER86': class LinkAnnotation 

+92 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 392.865

+ 0 ]

+ /Rect [ 401.8075

+ 567.865

+ 445.99

+ 579.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER87': class PDFDictionary 

+93 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.ietf.org/rfc/rfc2119.txt) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 189.625

+ 407.1775

+ 297.1675

+ 418.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER88': class PDFDictionary 

+94 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://source.android.com/compatibility/index.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 205.45

+ 393.9275

+ 369.6775

+ 405.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER89': class PDFDictionary 

+95 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://source.android.com/) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 167.965

+ 380.6775

+ 254.6725

+ 391.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER90': class PDFDictionary 

+96 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/packages.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 184.2325

+ 367.4275

+ 363.4825

+ 378.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER91': class PDFDictionary 

+97 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/Manifest.permission.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 172.9525

+ 354.1775

+ 413.8825

+ 365.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER92': class PDFDictionary 

+98 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/os/Build.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 157.96

+ 340.9275

+ 358.885

+ 352.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER93': class PDFDictionary 

+99 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://source.android.com/compatibility/2.3/versions.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 186.715

+ 327.6775

+ 373.45

+ 338.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER94': class PDFDictionary 

+100 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/webkit/WebView.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 171.7

+ 314.4275

+ 400.96

+ 325.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER95': class PDFDictionary 

+101 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.whatwg.org/specs/web-apps/current-work/multipage/) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 95.005

+ 301.1775

+ 307.1575

+ 312.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER96': class PDFDictionary 

+102 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://dev.w3.org/html5/spec/Overview.html#offline) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 159.955

+ 287.9275

+ 327.52

+ 299.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER97': class PDFDictionary 

+103 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://dev.w3.org/html5/spec/Overview.html#video) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 131.2

+ 274.6775

+ 296.68

+ 285.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER98': class PDFDictionary 

+104 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.w3.org/TR/geolocation-API/) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 172.045

+ 261.4275

+ 300.8425

+ 272.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER99': class PDFDictionary 

+105 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.w3.org/TR/webdatabase/) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 178.3

+ 248.1775

+ 298.765

+ 259.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER100': class PDFDictionary 

+106 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.w3.org/TR/IndexedDB/) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 170.7925

+ 234.9275

+ 283.75

+ 246.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER101': class PDFDictionary 

+107 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/practices/ui_guidelines/widget_design.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 114.5275

+ 208.4275

+ 374.23

+ 219.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER102': class PDFDictionary 

+108 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/topics/ui/notifiers/notifications.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 114.94

+ 195.1775

+ 346.2925

+ 206.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER103': class PDFDictionary 

+109 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://code.google.com/android/reference/available-resources.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 148.705

+ 181.9275

+ 368.8

+ 193.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER104': class PDFDictionary 

+110 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/practices/ui_guidelines/icon_design.html#statusbarstructure) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 162.8875

+ 168.6775

+ 477.1975

+ 179.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER105': class PDFDictionary 

+111 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/app/SearchManager.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 129.535

+ 155.4275

+ 371.7325

+ 166.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER106': class PDFDictionary 

+112 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/widget/Toast.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 96.6025

+ 142.1775

+ 313.3675

+ 153.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER107': class PDFDictionary 

+113 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/resources/articles/live-wallpapers.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 127.4425

+ 128.9275

+ 351.265

+ 140.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER108': class PDFDictionary 

+114 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/developing/tools/index.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 245.845

+ 115.6775

+ 453.865

+ 126.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER109': class PDFDictionary 

+115 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/topics/fundamentals.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 164.1325

+ 102.4275

+ 364.645

+ 113.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER110': class PDFDictionary 

+116 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/topics/manifest/manifest-intro.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 117.8575

+ 89.1775

+ 349.2025

+ 100.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page3': class PDFPage 

+117 0 obj

+% Page dictionary

+<< /Annots [ 90 0 R

+ 91 0 R

+ 92 0 R

+ 93 0 R

+ 94 0 R

+ 95 0 R

+ 96 0 R

+ 97 0 R

+ 98 0 R

+ 99 0 R

+ 100 0 R

+ 101 0 R

+ 102 0 R

+ 103 0 R

+ 104 0 R

+ 105 0 R

+ 106 0 R

+ 107 0 R

+ 108 0 R

+ 109 0 R

+ 110 0 R

+ 111 0 R

+ 112 0 R

+ 113 0 R

+ 114 0 R

+ 115 0 R

+ 116 0 R ]

+ /Contents 323 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER111': class PDFDictionary 

+118 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/developing/tools/monkey.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 138.7075

+ 730.6775

+ 355.06

+ 741.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER112': class PDFDictionary 

+119 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/content/pm/PackageManager.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 179.965

+ 717.4275

+ 452.1775

+ 728.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER113': class PDFDictionary 

+120 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/practices/screens_support.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 167.8825

+ 704.1775

+ 389.23

+ 715.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER114': class PDFDictionary 

+121 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/util/DisplayMetrics.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 161.6125

+ 690.9275

+ 396.28

+ 702.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER115': class PDFDictionary 

+122 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/content/res/Configuration.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 184.9825

+ 677.6775

+ 443.02

+ 688.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER116': class PDFDictionary 

+123 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/hardware/SensorEvent.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 157.0525

+ 664.4275

+ 407.5825

+ 675.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER117': class PDFDictionary 

+124 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/bluetooth/package-summary.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 119.9575

+ 651.1775

+ 388.825

+ 662.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER118': class PDFDictionary 

+125 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://source.android.com/compatibility/ndef-push-protocol.pdf) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 143.2825

+ 637.9275

+ 348.37

+ 649.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER119': class PDFDictionary 

+126 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.nxp.com/documents/data_sheet/MF1S503x.pdf) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 142.03

+ 624.6775

+ 336.2875

+ 635.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER120': class PDFDictionary 

+127 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.nxp.com/documents/data_sheet/MF1S703x.pdf) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 142.03

+ 611.4275

+ 336.2875

+ 622.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER121': class PDFDictionary 

+128 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 136.6

+ 598.1775

+ 326.68

+ 609.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER122': class PDFDictionary 

+129 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.nxp.com/documents/short_data_sheet/MF0ICU2_SDS.pdf) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 136.6

+ 584.9275

+ 367.1125

+ 596.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER123': class PDFDictionary 

+130 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.nxp.com/documents/application_note/AN130511.pdf) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 139.9525

+ 571.6775

+ 350.89

+ 582.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER124': class PDFDictionary 

+131 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://www.nxp.com/documents/application_note/AN130411.pdf) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 139.9525

+ 558.4275

+ 350.89

+ 569.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER125': class PDFDictionary 

+132 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation\(int\)) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 152.0425

+ 545.1775

+ 474.6625

+ 556.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER126': class PDFDictionary 

+133 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/reference/android/hardware/Camera.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 161.2075

+ 531.9275

+ 395.47

+ 543.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER127': class PDFDictionary 

+134 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://developer.android.com/guide/topics/security/security.html) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 220.3975

+ 518.6775

+ 429.6475

+ 529.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER128': class PDFDictionary 

+135 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (http://code.google.com/p/apps-for-android) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 129.955

+ 505.4275

+ 269.1925

+ 516.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER129': class LinkAnnotation 

+136 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 379.615

+ 0 ]

+ /Rect [ 460.615

+ 290.115

+ 504.7975

+ 301.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER130': class LinkAnnotation 

+137 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 366.365

+ 0 ]

+ /Rect [ 470.995

+ 107.49

+ 515.1775

+ 118.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page4': class PDFPage 

+138 0 obj

+% Page dictionary

+<< /Annots [ 118 0 R

+ 119 0 R

+ 120 0 R

+ 121 0 R

+ 122 0 R

+ 123 0 R

+ 124 0 R

+ 125 0 R

+ 126 0 R

+ 127 0 R

+ 128 0 R

+ 129 0 R

+ 130 0 R

+ 131 0 R

+ 132 0 R

+ 133 0 R

+ 134 0 R

+ 135 0 R

+ 136 0 R

+ 137 0 R ]

+ /Contents 324 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'F3': class PDFType1Font 

+139 0 obj

+% Font Courier

+<< /BaseFont /Courier

+ /Encoding /WinAnsiEncoding

+ /Name /F3

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER131': class LinkAnnotation 

+140 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 353.115

+ 0 ]

+ /Rect [ 336.2725

+ 709.9275

+ 380.455

+ 721.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F4': class PDFType1Font 

+141 0 obj

+% Font Times-Roman

+<< /BaseFont /Times-Roman

+ /Encoding /WinAnsiEncoding

+ /Name /F4

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER132': class LinkAnnotation 

+142 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 339.865

+ 0 ]

+ /Rect [ 350.19

+ 633.9275

+ 394.3725

+ 645.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page5': class PDFPage 

+143 0 obj

+% Page dictionary

+<< /Annots [ 140 0 R

+ 142 0 R ]

+ /Contents 325 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page6': class PDFPage 

+144 0 obj

+% Page dictionary

+<< /Contents 326 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page7': class PDFPage 

+145 0 obj

+% Page dictionary

+<< /Contents 327 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER133': class LinkAnnotation 

+146 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 326.615

+ 0 ]

+ /Rect [ 381.61

+ 664.8025

+ 425.7925

+ 676.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER134': class LinkAnnotation 

+147 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 313.365

+ 0 ]

+ /Rect [ 307.5925

+ 391.8025

+ 351.775

+ 403.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER135': class LinkAnnotation 

+148 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 300.115

+ 0 ]

+ /Rect [ 183.8125

+ 359.8025

+ 232.165

+ 371.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER136': class LinkAnnotation 

+149 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 286.865

+ 0 ]

+ /Rect [ 122.125

+ 346.5525

+ 170.4775

+ 357.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER137': class LinkAnnotation 

+150 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 273.615

+ 0 ]

+ /Rect [ 108.775

+ 333.3025

+ 157.1275

+ 344.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER138': class LinkAnnotation 

+151 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 260.365

+ 0 ]

+ /Rect [ 343.435

+ 312.5525

+ 391.7875

+ 323.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F5': class PDFType1Font 

+152 0 obj

+% Font Helvetica-Oblique

+<< /BaseFont /Helvetica-Oblique

+ /Encoding /WinAnsiEncoding

+ /Name /F5

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER139': class LinkAnnotation 

+153 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 247.115

+ 0 ]

+ /Rect [ 110.4475

+ 301.3025

+ 158.8

+ 312.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER140': class LinkAnnotation 

+154 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 313.365

+ 0 ]

+ /Rect [ 160.4575

+ 141.3025

+ 204.64

+ 152.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER141': class LinkAnnotation 

+155 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 300.115

+ 0 ]

+ /Rect [ 183.8125

+ 109.3025

+ 232.165

+ 120.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER142': class LinkAnnotation 

+156 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 286.865

+ 0 ]

+ /Rect [ 122.125

+ 96.0525

+ 170.4775

+ 107.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER143': class LinkAnnotation 

+157 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 273.615

+ 0 ]

+ /Rect [ 108.775

+ 82.8025

+ 157.1275

+ 94.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page8': class PDFPage 

+158 0 obj

+% Page dictionary

+<< /Annots [ 146 0 R

+ 147 0 R

+ 148 0 R

+ 149 0 R

+ 150 0 R

+ 151 0 R

+ 153 0 R

+ 154 0 R

+ 155 0 R

+ 156 0 R

+ 157 0 R ]

+ /Contents 328 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER144': class LinkAnnotation 

+159 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 260.365

+ 0 ]

+ /Rect [ 343.435

+ 730.6775

+ 391.7875

+ 741.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER145': class LinkAnnotation 

+160 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 247.115

+ 0 ]

+ /Rect [ 110.4475

+ 719.4275

+ 158.8

+ 730.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER146': class LinkAnnotation 

+161 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 392.865

+ 0 ]

+ /Rect [ 125.4475

+ 642.3025

+ 169.63

+ 653.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page9': class PDFPage 

+162 0 obj

+% Page dictionary

+<< /Annots [ 159 0 R

+ 160 0 R

+ 161 0 R ]

+ /Contents 329 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER147': class LinkAnnotation 

+163 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 233.865

+ 0 ]

+ /Rect [ 500.1475

+ 730.6775

+ 548.5

+ 741.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER148': class LinkAnnotation 

+164 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 220.615

+ 0 ]

+ /Rect [ 515.1475

+ 580.0525

+ 553.075

+ 591.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER149': class LinkAnnotation 

+165 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 220.615

+ 0 ]

+ /Rect [ 55

+ 568.8025

+ 63.34

+ 580.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER150': class LinkAnnotation 

+166 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 207.365

+ 0 ]

+ /Rect [ 313.045

+ 461.5525

+ 361.3975

+ 472.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER151': class LinkAnnotation 

+167 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 194.115

+ 0 ]

+ /Rect [ 448.06

+ 429.5525

+ 496.4125

+ 440.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER152': class LinkAnnotation 

+168 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 180.865

+ 0 ]

+ /Rect [ 124.615

+ 418.3025

+ 172.9675

+ 429.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER153': class LinkAnnotation 

+169 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 167.615

+ 0 ]

+ /Rect [ 132.535

+ 354.3025

+ 180.8875

+ 365.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER154': class LinkAnnotation 

+170 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 154.365

+ 0 ]

+ /Rect [ 217.9075

+ 181.3025

+ 266.26

+ 192.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER155': class LinkAnnotation 

+171 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 141.115

+ 0 ]

+ /Rect [ 73.7575

+ 117.3025

+ 122.11

+ 128.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page10': class PDFPage 

+172 0 obj

+% Page dictionary

+<< /Annots [ 163 0 R

+ 164 0 R

+ 165 0 R

+ 166 0 R

+ 167 0 R

+ 168 0 R

+ 169 0 R

+ 170 0 R

+ 171 0 R ]

+ /Contents 330 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER156': class LinkAnnotation 

+173 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 127.865

+ 0 ]

+ /Rect [ 499.5925

+ 581.24

+ 547.945

+ 592.49 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER157': class LinkAnnotation 

+174 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 114.615

+ 0 ]

+ /Rect [ 257.9875

+ 560.49

+ 306.34

+ 571.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER158': class LinkAnnotation 

+175 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 101.365

+ 0 ]

+ /Rect [ 373.0375

+ 560.49

+ 421.39

+ 571.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER159': class LinkAnnotation 

+176 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 233.865

+ 0 ]

+ /Rect [ 493.5025

+ 560.49

+ 541.855

+ 571.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page11': class PDFPage 

+177 0 obj

+% Page dictionary

+<< /Annots [ 173 0 R

+ 174 0 R

+ 175 0 R

+ 176 0 R ]

+ /Contents 331 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page12': class PDFPage 

+178 0 obj

+% Page dictionary

+<< /Contents 332 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page13': class PDFPage 

+179 0 obj

+% Page dictionary

+<< /Contents 333 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER160': class LinkAnnotation 

+180 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 378.895

+ 538.4275

+ 427.2475

+ 549.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER161': class LinkAnnotation 

+181 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 127.865

+ 0 ]

+ /Rect [ 207.1

+ 433.99

+ 255.4525

+ 445.24 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER162': class LinkAnnotation 

+182 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 69.925

+ 127.865

+ 0 ]

+ /Rect [ 239.6275

+ 398.24

+ 287.98

+ 409.49 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER163': class LinkAnnotation 

+183 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 742.865

+ 0 ]

+ /Rect [ 98.3425

+ 362.49

+ 146.695

+ 373.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page14': class PDFPage 

+184 0 obj

+% Page dictionary

+<< /Annots [ 180 0 R

+ 181 0 R

+ 182 0 R

+ 183 0 R ]

+ /Contents 334 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER164': class LinkAnnotation 

+185 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 392.7925

+ 666.6775

+ 441.145

+ 677.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER165': class LinkAnnotation 

+186 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 716.365

+ 0 ]

+ /Rect [ 258.0025

+ 600.8025

+ 306.355

+ 612.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER166': class LinkAnnotation 

+187 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 703.115

+ 0 ]

+ /Rect [ 462.835

+ 246.5525

+ 511.1875

+ 257.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page15': class PDFPage 

+188 0 obj

+% Page dictionary

+<< /Annots [ 185 0 R

+ 186 0 R

+ 187 0 R ]

+ /Contents 335 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER167': class LinkAnnotation 

+189 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 689.865

+ 0 ]

+ /Rect [ 259.42

+ 321.8025

+ 307.7725

+ 333.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER168': class LinkAnnotation 

+190 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 689.865

+ 0 ]

+ /Rect [ 381.79

+ 246.3025

+ 430.1425

+ 257.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page16': class PDFPage 

+191 0 obj

+% Page dictionary

+<< /Annots [ 189 0 R

+ 190 0 R ]

+ /Contents 336 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER169': class LinkAnnotation 

+192 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 689.865

+ 0 ]

+ /Rect [ 304.7875

+ 704.1775

+ 353.14

+ 715.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER170': class LinkAnnotation 

+193 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 468.19

+ 581.8025

+ 516.5425

+ 593.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER171': class LinkAnnotation 

+194 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 676.615

+ 0 ]

+ /Rect [ 382.21

+ 361.3025

+ 430.5625

+ 372.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER172': class LinkAnnotation 

+195 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 676.615

+ 0 ]

+ /Rect [ 382.21

+ 246.0525

+ 430.5625

+ 257.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page17': class PDFPage 

+196 0 obj

+% Page dictionary

+<< /Annots [ 192 0 R

+ 193 0 R

+ 194 0 R

+ 195 0 R ]

+ /Contents 337 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER173': class LinkAnnotation 

+197 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 663.365

+ 0 ]

+ /Rect [ 297.6025

+ 148.8025

+ 345.955

+ 160.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page18': class PDFPage 

+198 0 obj

+% Page dictionary

+<< /Annots [ 197 0 R ]

+ /Contents 338 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER174': class LinkAnnotation 

+199 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 68.335

+ 666.6775

+ 116.6875

+ 677.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER175': class LinkAnnotation 

+200 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 650.115

+ 0 ]

+ /Rect [ 162.1075

+ 483.1775

+ 210.46

+ 494.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER176': class LinkAnnotation 

+201 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 636.865

+ 0 ]

+ /Rect [ 194.605

+ 394.4275

+ 242.9575

+ 405.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER177': class LinkAnnotation 

+202 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 623.615

+ 0 ]

+ /Rect [ 289.645

+ 394.4275

+ 337.9975

+ 405.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER178': class LinkAnnotation 

+203 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 610.365

+ 0 ]

+ /Rect [ 195.85

+ 381.1775

+ 244.2025

+ 392.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER179': class LinkAnnotation 

+204 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 597.115

+ 0 ]

+ /Rect [ 286.7125

+ 381.1775

+ 335.065

+ 392.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER180': class LinkAnnotation 

+205 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 583.865

+ 0 ]

+ /Rect [ 226.705

+ 367.9275

+ 275.0575

+ 379.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER181': class LinkAnnotation 

+206 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 570.615

+ 0 ]

+ /Rect [ 320.92

+ 367.9275

+ 369.2725

+ 379.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER182': class LinkAnnotation 

+207 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 510.745

+ 313.1775

+ 548.6725

+ 324.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER183': class LinkAnnotation 

+208 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 77.5

+ 301.9275

+ 85.84

+ 313.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER184': class LinkAnnotation 

+209 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 331.5175

+ 245.4275

+ 379.87

+ 256.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page19': class PDFPage 

+210 0 obj

+% Page dictionary

+<< /Annots [ 199 0 R

+ 200 0 R

+ 201 0 R

+ 202 0 R

+ 203 0 R

+ 204 0 R

+ 205 0 R

+ 206 0 R

+ 207 0 R

+ 208 0 R

+ 209 0 R ]

+ /Contents 339 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER185': class LinkAnnotation 

+211 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 557.365

+ 0 ]

+ /Rect [ 304.42

+ 357.5525

+ 352.7725

+ 368.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER186': class LinkAnnotation 

+212 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 544.115

+ 0 ]

+ /Rect [ 436.81

+ 107.0525

+ 485.1625

+ 118.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page20': class PDFPage 

+213 0 obj

+% Page dictionary

+<< /Annots [ 211 0 R

+ 212 0 R ]

+ /Contents 340 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page21': class PDFPage 

+214 0 obj

+% Page dictionary

+<< /Contents 341 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER187': class LinkAnnotation 

+215 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 530.865

+ 0 ]

+ /Rect [ 218.395

+ 309.4275

+ 266.7475

+ 320.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER188': class LinkAnnotation 

+216 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 530.865

+ 0 ]

+ /Rect [ 476.8375

+ 232.3025

+ 525.19

+ 243.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER189': class LinkAnnotation 

+217 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 530.865

+ 0 ]

+ /Rect [ 369.7225

+ 132.6775

+ 418.075

+ 143.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page22': class PDFPage 

+218 0 obj

+% Page dictionary

+<< /Annots [ 215 0 R

+ 216 0 R

+ 217 0 R ]

+ /Contents 342 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER190': class LinkAnnotation 

+219 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 530.865

+ 0 ]

+ /Rect [ 102.1

+ 719.4275

+ 150.4525

+ 730.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER191': class LinkAnnotation 

+220 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 406.115

+ 0 ]

+ /Rect [ 334.66

+ 164.99

+ 378.8425

+ 176.24 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page23': class PDFPage 

+221 0 obj

+% Page dictionary

+<< /Annots [ 219 0 R

+ 220 0 R ]

+ /Contents 343 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER192': class LinkAnnotation 

+222 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 117 0 R

+ /XYZ

+ 66.25

+ 406.115

+ 0 ]

+ /Rect [ 326.365

+ 719.4275

+ 370.5475

+ 730.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER193': class LinkAnnotation 

+223 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 138 0 R

+ /XYZ

+ 69.925

+ 517.615

+ 0 ]

+ /Rect [ 199.5475

+ 469.1775

+ 247.9

+ 480.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER194': class PDFDictionary 

+224 0 obj

+<< /A << /S /URI

+ /Type /Action

+ /URI (mailto:compatibility@android.com) >>

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 205.0825

+ 147.0525

+ 295.2175

+ 158.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page24': class PDFPage 

+225 0 obj

+% Page dictionary

+<< /Annots [ 222 0 R

+ 223 0 R

+ 224 0 R ]

+ /Contents 344 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page25': class PDFPage 

+226 0 obj

+% Page dictionary

+<< /Contents 345 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page26': class PDFPage 

+227 0 obj

+% Page dictionary

+<< /Contents 346 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 320 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'R228': class PDFCatalog 

+228 0 obj

+% Document Root

+<< /Outlines 230 0 R

+ /PageMode /UseNone

+ /Pages 320 0 R

+ /Type /Catalog >>

+endobj

+% 'R229': class PDFInfo 

+229 0 obj

+<< /Author ()

+ /CreationDate (D:20110222144351+08'00')

+ /Keywords ()

+ /Producer (pisa HTML to PDF <http://www.htmltopdf.org>)

+ /Subject ()

+ /Title (Android 2.3 Compatibility Definition) >>

+endobj

+% 'R230': class PDFOutlines 

+230 0 obj

+<< /Count 17

+ /First 231 0 R

+ /Last 231 0 R

+ /Type /Outlines >>

+endobj

+% 'Outline.0': class OutlineEntryObject 

+231 0 obj

+<< /Count -14

+ /Dest [ 47 0 R

+ /Fit ]

+ /First 232 0 R

+ /Last 314 0 R

+ /Parent 230 0 R

+ /Title (Android 2.3 Compatibility Definition) >>

+endobj

+% 'Outline.2.0': class OutlineEntryObject 

+232 0 obj

+<< /Dest [ 47 0 R

+ /Fit ]

+ /Next 233 0 R

+ /Parent 231 0 R

+ /Title (Table of Contents) >>

+endobj

+% 'Outline.2.1': class OutlineEntryObject 

+233 0 obj

+<< /Dest [ 117 0 R

+ /Fit ]

+ /Next 234 0 R

+ /Parent 231 0 R

+ /Prev 232 0 R

+ /Title (1. Introduction) >>

+endobj

+% 'Outline.2.2': class OutlineEntryObject 

+234 0 obj

+<< /Dest [ 117 0 R

+ /Fit ]

+ /Next 235 0 R

+ /Parent 231 0 R

+ /Prev 233 0 R

+ /Title (2. Resources) >>

+endobj

+% 'Outline.2.3': class OutlineEntryObject 

+235 0 obj

+<< /Count -8

+ /Dest [ 138 0 R

+ /Fit ]

+ /First 236 0 R

+ /Last 252 0 R

+ /Next 258 0 R

+ /Parent 231 0 R

+ /Prev 234 0 R

+ /Title (3. Software) >>

+endobj

+% 'Outline.3.0': class OutlineEntryObject 

+236 0 obj

+<< /Dest [ 138 0 R

+ /Fit ]

+ /Next 237 0 R

+ /Parent 235 0 R

+ /Title (3.1. Managed API Compatibility) >>

+endobj

+% 'Outline.3.1': class OutlineEntryObject 

+237 0 obj

+<< /Count -7

+ /Dest [ 138 0 R

+ /Fit ]

+ /First 238 0 R

+ /Last 244 0 R

+ /Next 245 0 R

+ /Parent 235 0 R

+ /Prev 236 0 R

+ /Title (3.2. Soft API Compatibility) >>

+endobj

+% 'Outline.4.0': class OutlineEntryObject 

+238 0 obj

+<< /Dest [ 138 0 R

+ /Fit ]

+ /Next 239 0 R

+ /Parent 237 0 R

+ /Title (3.2.1. Permissions) >>

+endobj

+% 'Outline.4.1': class OutlineEntryObject 

+239 0 obj

+<< /Dest [ 143 0 R

+ /Fit ]

+ /Next 240 0 R

+ /Parent 237 0 R

+ /Prev 238 0 R

+ /Title (3.2.2. Build Parameters) >>

+endobj

+% 'Outline.4.2': class OutlineEntryObject 

+240 0 obj

+<< /Dest [ 144 0 R

+ /Fit ]

+ /Next 241 0 R

+ /Parent 237 0 R

+ /Prev 239 0 R

+ /Title (3.2.3. Intent Compatibility) >>

+endobj

+% 'Outline.4.3': class OutlineEntryObject 

+241 0 obj

+<< /Dest [ 144 0 R

+ /Fit ]

+ /Next 242 0 R

+ /Parent 237 0 R

+ /Prev 240 0 R

+ /Title (3.2.3.1. Core Application Intents) >>

+endobj

+% 'Outline.4.4': class OutlineEntryObject 

+242 0 obj

+<< /Dest [ 144 0 R

+ /Fit ]

+ /Next 243 0 R

+ /Parent 237 0 R

+ /Prev 241 0 R

+ /Title (3.2.3.2. Intent Overrides) >>

+endobj

+% 'Outline.4.5': class OutlineEntryObject 

+243 0 obj

+<< /Dest [ 145 0 R

+ /Fit ]

+ /Next 244 0 R

+ /Parent 237 0 R

+ /Prev 242 0 R

+ /Title (3.2.3.3. Intent Namespaces) >>

+endobj

+% 'Outline.4.6': class OutlineEntryObject 

+244 0 obj

+<< /Dest [ 145 0 R

+ /Fit ]

+ /Parent 237 0 R

+ /Prev 243 0 R

+ /Title (3.2.3.4. Broadcast Intents) >>

+endobj

+% 'Outline.3.2': class OutlineEntryObject 

+245 0 obj

+<< /Dest [ 145 0 R

+ /Fit ]

+ /Next 246 0 R

+ /Parent 235 0 R

+ /Prev 237 0 R

+ /Title (3.3. Native API Compatibility) >>

+endobj

+% 'Outline.3.3': class OutlineEntryObject 

+246 0 obj

+<< /Count -2

+ /Dest [ 158 0 R

+ /Fit ]

+ /First 247 0 R

+ /Last 248 0 R

+ /Next 249 0 R

+ /Parent 235 0 R

+ /Prev 245 0 R

+ /Title (3.4. Web Compatibility) >>

+endobj

+% 'Outline.5.0': class OutlineEntryObject 

+247 0 obj

+<< /Dest [ 158 0 R

+ /Fit ]

+ /Next 248 0 R

+ /Parent 246 0 R

+ /Title (3.4.1. WebView Compatibility) >>

+endobj

+% 'Outline.5.1': class OutlineEntryObject 

+248 0 obj

+<< /Dest [ 158 0 R

+ /Fit ]

+ /Parent 246 0 R

+ /Prev 247 0 R

+ /Title (3.4.2. Browser Compatibility) >>

+endobj

+% 'Outline.3.4': class OutlineEntryObject 

+249 0 obj

+<< /Dest [ 162 0 R

+ /Fit ]

+ /Next 250 0 R

+ /Parent 235 0 R

+ /Prev 246 0 R

+ /Title (3.5. API Behavioral Compatibility) >>

+endobj

+% 'Outline.3.5': class OutlineEntryObject 

+250 0 obj

+<< /Dest [ 162 0 R

+ /Fit ]

+ /Next 251 0 R

+ /Parent 235 0 R

+ /Prev 249 0 R

+ /Title (3.6. API Namespaces) >>

+endobj

+% 'Outline.3.6': class OutlineEntryObject 

+251 0 obj

+<< /Dest [ 162 0 R

+ /Fit ]

+ /Next 252 0 R

+ /Parent 235 0 R

+ /Prev 250 0 R

+ /Title (3.7. Virtual Machine Compatibility) >>

+endobj

+% 'Outline.3.7': class OutlineEntryObject 

+252 0 obj

+<< /Count -5

+ /Dest [ 172 0 R

+ /Fit ]

+ /First 253 0 R

+ /Last 257 0 R

+ /Parent 235 0 R

+ /Prev 251 0 R

+ /Title (3.8. User Interface Compatibility) >>

+endobj

+% 'Outline.6.0': class OutlineEntryObject 

+253 0 obj

+<< /Dest [ 172 0 R

+ /Fit ]

+ /Next 254 0 R

+ /Parent 252 0 R

+ /Title (3.8.1. Widgets) >>

+endobj

+% 'Outline.6.1': class OutlineEntryObject 

+254 0 obj

+<< /Dest [ 172 0 R

+ /Fit ]

+ /Next 255 0 R

+ /Parent 252 0 R

+ /Prev 253 0 R

+ /Title (3.8.2. Notifications) >>

+endobj

+% 'Outline.6.2': class OutlineEntryObject 

+255 0 obj

+<< /Dest [ 172 0 R

+ /Fit ]

+ /Next 256 0 R

+ /Parent 252 0 R

+ /Prev 254 0 R

+ /Title (3.8.3. Search) >>

+endobj

+% 'Outline.6.3': class OutlineEntryObject 

+256 0 obj

+<< /Dest [ 172 0 R

+ /Fit ]

+ /Next 257 0 R

+ /Parent 252 0 R

+ /Prev 255 0 R

+ /Title (3.8.4. Toasts) >>

+endobj

+% 'Outline.6.4': class OutlineEntryObject 

+257 0 obj

+<< /Dest [ 172 0 R

+ /Fit ]

+ /Parent 252 0 R

+ /Prev 256 0 R

+ /Title (3.8.5. Live Wallpapers) >>

+endobj

+% 'Outline.2.4': class OutlineEntryObject 

+258 0 obj

+<< /Dest [ 177 0 R

+ /Fit ]

+ /Next 259 0 R

+ /Parent 231 0 R

+ /Prev 235 0 R

+ /Title (4. Application Packaging Compatibility) >>

+endobj

+% 'Outline.2.5': class OutlineEntryObject 

+259 0 obj

+<< /Count -5

+ /Dest [ 177 0 R

+ /Fit ]

+ /First 260 0 R

+ /Last 264 0 R

+ /Next 265 0 R

+ /Parent 231 0 R

+ /Prev 258 0 R

+ /Title (5. Multimedia Compatibility) >>

+endobj

+% 'Outline.7.0': class OutlineEntryObject 

+260 0 obj

+<< /Dest [ 177 0 R

+ /Fit ]

+ /Next 261 0 R

+ /Parent 259 0 R

+ /Title (5.1. Media Codecs) >>

+endobj

+% 'Outline.7.1': class OutlineEntryObject 

+261 0 obj

+<< /Dest [ 177 0 R

+ /Fit ]

+ /Next 262 0 R

+ /Parent 259 0 R

+ /Prev 260 0 R

+ /Title (5.1.1. Media Decoders) >>

+endobj

+% 'Outline.7.2': class OutlineEntryObject 

+262 0 obj

+<< /Dest [ 178 0 R

+ /Fit ]

+ /Next 263 0 R

+ /Parent 259 0 R

+ /Prev 261 0 R

+ /Title (5.1.2. Media Encoders) >>

+endobj

+% 'Outline.7.3': class OutlineEntryObject 

+263 0 obj

+<< /Dest [ 179 0 R

+ /Fit ]

+ /Next 264 0 R

+ /Parent 259 0 R

+ /Prev 262 0 R

+ /Title (5.2. Audio Recording) >>

+endobj

+% 'Outline.7.4': class OutlineEntryObject 

+264 0 obj

+<< /Dest [ 179 0 R

+ /Fit ]

+ /Parent 259 0 R

+ /Prev 263 0 R

+ /Title (5.3. Audio Latency) >>

+endobj

+% 'Outline.2.6': class OutlineEntryObject 

+265 0 obj

+<< /Dest [ 184 0 R

+ /Fit ]

+ /Next 266 0 R

+ /Parent 231 0 R

+ /Prev 259 0 R

+ /Title (6. Developer Tool Compatibility) >>

+endobj

+% 'Outline.2.7': class OutlineEntryObject 

+266 0 obj

+<< /Count -7

+ /Dest [ 184 0 R

+ /Fit ]

+ /First 267 0 R

+ /Last 301 0 R

+ /Next 302 0 R

+ /Parent 231 0 R

+ /Prev 265 0 R

+ /Title (7. Hardware Compatibility) >>

+endobj

+% 'Outline.8.0': class OutlineEntryObject 

+267 0 obj

+<< /Count -5

+ /Dest [ 188 0 R

+ /Fit ]

+ /First 268 0 R

+ /Last 272 0 R

+ /Next 273 0 R

+ /Parent 266 0 R

+ /Title (7.1. Display and Graphics) >>

+endobj

+% 'Outline.9.0': class OutlineEntryObject 

+268 0 obj

+<< /Dest [ 188 0 R

+ /Fit ]

+ /Next 269 0 R

+ /Parent 267 0 R

+ /Title (7.1.1. Screen Configurations) >>

+endobj

+% 'Outline.9.1': class OutlineEntryObject 

+269 0 obj

+<< /Dest [ 188 0 R

+ /Fit ]

+ /Next 270 0 R

+ /Parent 267 0 R

+ /Prev 268 0 R

+ /Title (7.1.2. Display Metrics) >>

+endobj

+% 'Outline.9.2': class OutlineEntryObject 

+270 0 obj

+<< /Dest [ 188 0 R

+ /Fit ]

+ /Next 271 0 R

+ /Parent 267 0 R

+ /Prev 269 0 R

+ /Title (7.1.3. Declared Screen Support) >>

+endobj

+% 'Outline.9.3': class OutlineEntryObject 

+271 0 obj

+<< /Dest [ 188 0 R

+ /Fit ]

+ /Next 272 0 R

+ /Parent 267 0 R

+ /Prev 270 0 R

+ /Title (7.1.4. Screen Orientation) >>

+endobj

+% 'Outline.9.4': class OutlineEntryObject 

+272 0 obj

+<< /Dest [ 191 0 R

+ /Fit ]

+ /Parent 267 0 R

+ /Prev 271 0 R

+ /Title (7.1.5. 3D Graphics Acceleration) >>

+endobj

+% 'Outline.8.1': class OutlineEntryObject 

+273 0 obj

+<< /Count -4

+ /Dest [ 191 0 R

+ /Fit ]

+ /First 274 0 R

+ /Last 277 0 R

+ /Next 278 0 R

+ /Parent 266 0 R

+ /Prev 267 0 R

+ /Title (7.2. Input Devices) >>

+endobj

+% 'Outline.10.0': class OutlineEntryObject 

+274 0 obj

+<< /Dest [ 191 0 R

+ /Fit ]

+ /Next 275 0 R

+ /Parent 273 0 R

+ /Title (7.2.1. Keyboard) >>

+endobj

+% 'Outline.10.1': class OutlineEntryObject 

+275 0 obj

+<< /Dest [ 191 0 R

+ /Fit ]

+ /Next 276 0 R

+ /Parent 273 0 R

+ /Prev 274 0 R

+ /Title (7.2.2. Non-touch Navigation) >>

+endobj

+% 'Outline.10.2': class OutlineEntryObject 

+276 0 obj

+<< /Dest [ 191 0 R

+ /Fit ]

+ /Next 277 0 R

+ /Parent 273 0 R

+ /Prev 275 0 R

+ /Title (7.2.3. Navigation keys) >>

+endobj

+% 'Outline.10.3': class OutlineEntryObject 

+277 0 obj

+<< /Dest [ 191 0 R

+ /Fit ]

+ /Parent 273 0 R

+ /Prev 276 0 R

+ /Title (7.2.4. Touchscreen input) >>

+endobj

+% 'Outline.8.2': class OutlineEntryObject 

+278 0 obj

+<< /Count -8

+ /Dest [ 196 0 R

+ /Fit ]

+ /First 279 0 R

+ /Last 286 0 R

+ /Next 287 0 R

+ /Parent 266 0 R

+ /Prev 273 0 R

+ /Title (7.3. Sensors) >>

+endobj

+% 'Outline.11.0': class OutlineEntryObject 

+279 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Next 280 0 R

+ /Parent 278 0 R

+ /Title (7.3.1. Accelerometer) >>

+endobj

+% 'Outline.11.1': class OutlineEntryObject 

+280 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Next 281 0 R

+ /Parent 278 0 R

+ /Prev 279 0 R

+ /Title (7.3.2. Magnetometer) >>

+endobj

+% 'Outline.11.2': class OutlineEntryObject 

+281 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Next 282 0 R

+ /Parent 278 0 R

+ /Prev 280 0 R

+ /Title (7.3.3. GPS) >>

+endobj

+% 'Outline.11.3': class OutlineEntryObject 

+282 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Next 283 0 R

+ /Parent 278 0 R

+ /Prev 281 0 R

+ /Title (7.3.4. Gyroscope) >>

+endobj

+% 'Outline.11.4': class OutlineEntryObject 

+283 0 obj

+<< /Dest [ 198 0 R

+ /Fit ]

+ /Next 284 0 R

+ /Parent 278 0 R

+ /Prev 282 0 R

+ /Title (7.3.5. Barometer) >>

+endobj

+% 'Outline.11.5': class OutlineEntryObject 

+284 0 obj

+<< /Dest [ 198 0 R

+ /Fit ]

+ /Next 285 0 R

+ /Parent 278 0 R

+ /Prev 283 0 R

+ /Title (7.3.7. Thermometer) >>

+endobj

+% 'Outline.11.6': class OutlineEntryObject 

+285 0 obj

+<< /Dest [ 198 0 R

+ /Fit ]

+ /Next 286 0 R

+ /Parent 278 0 R

+ /Prev 284 0 R

+ /Title (7.3.7. Photometer) >>

+endobj

+% 'Outline.11.7': class OutlineEntryObject 

+286 0 obj

+<< /Dest [ 198 0 R

+ /Fit ]

+ /Parent 278 0 R

+ /Prev 285 0 R

+ /Title (7.3.8. Proximity Sensor) >>

+endobj

+% 'Outline.8.3': class OutlineEntryObject 

+287 0 obj

+<< /Count -5

+ /Dest [ 198 0 R

+ /Fit ]

+ /First 288 0 R

+ /Last 292 0 R

+ /Next 293 0 R

+ /Parent 266 0 R

+ /Prev 278 0 R

+ /Title (7.4. Data Connectivity) >>

+endobj

+% 'Outline.12.0': class OutlineEntryObject 

+288 0 obj

+<< /Dest [ 198 0 R

+ /Fit ]

+ /Next 289 0 R

+ /Parent 287 0 R

+ /Title (7.4.1. Telephony) >>

+endobj

+% 'Outline.12.1': class OutlineEntryObject 

+289 0 obj

+<< /Dest [ 198 0 R

+ /Fit ]

+ /Next 290 0 R

+ /Parent 287 0 R

+ /Prev 288 0 R

+ /Title (7.4.2. IEEE 802.11 \(WiFi\)) >>

+endobj

+% 'Outline.12.2': class OutlineEntryObject 

+290 0 obj

+<< /Dest [ 198 0 R

+ /Fit ]

+ /Next 291 0 R

+ /Parent 287 0 R

+ /Prev 289 0 R

+ /Title (7.4.3. Bluetooth) >>

+endobj

+% 'Outline.12.3': class OutlineEntryObject 

+291 0 obj

+<< /Dest [ 210 0 R

+ /Fit ]

+ /Next 292 0 R

+ /Parent 287 0 R

+ /Prev 290 0 R

+ /Title (7.4.4. Near-Field Communications) >>

+endobj

+% 'Outline.12.4': class OutlineEntryObject 

+292 0 obj

+<< /Dest [ 210 0 R

+ /Fit ]

+ /Parent 287 0 R

+ /Prev 291 0 R

+ /Title (7.4.5. Minimum Network Capability) >>

+endobj

+% 'Outline.8.4': class OutlineEntryObject 

+293 0 obj

+<< /Count -4

+ /Dest [ 213 0 R

+ /Fit ]

+ /First 294 0 R

+ /Last 297 0 R

+ /Next 298 0 R

+ /Parent 266 0 R

+ /Prev 287 0 R

+ /Title (7.5. Cameras) >>

+endobj

+% 'Outline.13.0': class OutlineEntryObject 

+294 0 obj

+<< /Dest [ 213 0 R

+ /Fit ]

+ /Next 295 0 R

+ /Parent 293 0 R

+ /Title (7.5.1. Rear-Facing Camera) >>

+endobj

+% 'Outline.13.1': class OutlineEntryObject 

+295 0 obj

+<< /Dest [ 213 0 R

+ /Fit ]

+ /Next 296 0 R

+ /Parent 293 0 R

+ /Prev 294 0 R

+ /Title (7.5.2. Front-Facing Camera) >>

+endobj

+% 'Outline.13.2': class OutlineEntryObject 

+296 0 obj

+<< /Dest [ 213 0 R

+ /Fit ]

+ /Next 297 0 R

+ /Parent 293 0 R

+ /Prev 295 0 R

+ /Title (7.5.3. Camera API Behavior) >>

+endobj

+% 'Outline.13.3': class OutlineEntryObject 

+297 0 obj

+<< /Dest [ 214 0 R

+ /Fit ]

+ /Parent 293 0 R

+ /Prev 296 0 R

+ /Title (7.5.4. Camera Orientation) >>

+endobj

+% 'Outline.8.5': class OutlineEntryObject 

+298 0 obj

+<< /Count -2

+ /Dest [ 214 0 R

+ /Fit ]

+ /First 299 0 R

+ /Last 300 0 R

+ /Next 301 0 R

+ /Parent 266 0 R

+ /Prev 293 0 R

+ /Title (7.6. Memory and Storage) >>

+endobj

+% 'Outline.14.0': class OutlineEntryObject 

+299 0 obj

+<< /Dest [ 214 0 R

+ /Fit ]

+ /Next 300 0 R

+ /Parent 298 0 R

+ /Title (7.6.1. Minimum Memory and Storage) >>

+endobj

+% 'Outline.14.1': class OutlineEntryObject 

+300 0 obj

+<< /Dest [ 214 0 R

+ /Fit ]

+ /Parent 298 0 R

+ /Prev 299 0 R

+ /Title (7.6.2. Application Shared Storage) >>

+endobj

+% 'Outline.8.6': class OutlineEntryObject 

+301 0 obj

+<< /Dest [ 218 0 R

+ /Fit ]

+ /Parent 266 0 R

+ /Prev 298 0 R

+ /Title (7.7. USB) >>

+endobj

+% 'Outline.2.8': class OutlineEntryObject 

+302 0 obj

+<< /Dest [ 218 0 R

+ /Fit ]

+ /Next 303 0 R

+ /Parent 231 0 R

+ /Prev 266 0 R

+ /Title (8. Performance Compatibility) >>

+endobj

+% 'Outline.2.9': class OutlineEntryObject 

+303 0 obj

+<< /Count -4

+ /Dest [ 218 0 R

+ /Fit ]

+ /First 304 0 R

+ /Last 307 0 R

+ /Next 308 0 R

+ /Parent 231 0 R

+ /Prev 302 0 R

+ /Title (9. Security Model Compatibility) >>

+endobj

+% 'Outline.15.0': class OutlineEntryObject 

+304 0 obj

+<< /Dest [ 218 0 R

+ /Fit ]

+ /Next 305 0 R

+ /Parent 303 0 R

+ /Title (9.1. Permissions) >>

+endobj

+% 'Outline.15.1': class OutlineEntryObject 

+305 0 obj

+<< /Dest [ 218 0 R

+ /Fit ]

+ /Next 306 0 R

+ /Parent 303 0 R

+ /Prev 304 0 R

+ /Title (9.2. UID and Process Isolation) >>

+endobj

+% 'Outline.15.2': class OutlineEntryObject 

+306 0 obj

+<< /Dest [ 218 0 R

+ /Fit ]

+ /Next 307 0 R

+ /Parent 303 0 R

+ /Prev 305 0 R

+ /Title (9.3. Filesystem Permissions) >>

+endobj

+% 'Outline.15.3': class OutlineEntryObject 

+307 0 obj

+<< /Dest [ 221 0 R

+ /Fit ]

+ /Parent 303 0 R

+ /Prev 306 0 R

+ /Title (9.4. Alternate Execution Environments) >>

+endobj

+% 'Outline.2.10': class OutlineEntryObject 

+308 0 obj

+<< /Count -3

+ /Dest [ 221 0 R

+ /Fit ]

+ /First 309 0 R

+ /Last 311 0 R

+ /Next 312 0 R

+ /Parent 231 0 R

+ /Prev 303 0 R

+ /Title (10. Software Compatibility Testing) >>

+endobj

+% 'Outline.16.0': class OutlineEntryObject 

+309 0 obj

+<< /Dest [ 221 0 R

+ /Fit ]

+ /Next 310 0 R

+ /Parent 308 0 R

+ /Title (10.1. Compatibility Test Suite) >>

+endobj

+% 'Outline.16.1': class OutlineEntryObject 

+310 0 obj

+<< /Dest [ 225 0 R

+ /Fit ]

+ /Next 311 0 R

+ /Parent 308 0 R

+ /Prev 309 0 R

+ /Title (10.2. CTS Verifier) >>

+endobj

+% 'Outline.16.2': class OutlineEntryObject 

+311 0 obj

+<< /Dest [ 225 0 R

+ /Fit ]

+ /Parent 308 0 R

+ /Prev 310 0 R

+ /Title (10.3. Reference Applications) >>

+endobj

+% 'Outline.2.11': class OutlineEntryObject 

+312 0 obj

+<< /Dest [ 225 0 R

+ /Fit ]

+ /Next 313 0 R

+ /Parent 231 0 R

+ /Prev 308 0 R

+ /Title (11. Updatable Software) >>

+endobj

+% 'Outline.2.12': class OutlineEntryObject 

+313 0 obj

+<< /Dest [ 225 0 R

+ /Fit ]

+ /Next 314 0 R

+ /Parent 231 0 R

+ /Prev 312 0 R

+ /Title (12. Contact Us) >>

+endobj

+% 'Outline.2.13': class OutlineEntryObject 

+314 0 obj

+<< /Count -5

+ /Dest [ 226 0 R

+ /Fit ]

+ /First 315 0 R

+ /Last 319 0 R

+ /Parent 231 0 R

+ /Prev 313 0 R

+ /Title (Appendix A - Bluetooth Test Procedure) >>

+endobj

+% 'Outline.17.0': class OutlineEntryObject 

+315 0 obj

+<< /Dest [ 226 0 R

+ /Fit ]

+ /Next 316 0 R

+ /Parent 314 0 R

+ /Title (Setup and Installation) >>

+endobj

+% 'Outline.17.1': class OutlineEntryObject 

+316 0 obj

+<< /Dest [ 226 0 R

+ /Fit ]

+ /Next 317 0 R

+ /Parent 314 0 R

+ /Prev 315 0 R

+ /Title (Test Bluetooth Control by Apps) >>

+endobj

+% 'Outline.17.2': class OutlineEntryObject 

+317 0 obj

+<< /Dest [ 226 0 R

+ /Fit ]

+ /Next 318 0 R

+ /Parent 314 0 R

+ /Prev 316 0 R

+ /Title (Test Pairing and Communication) >>

+endobj

+% 'Outline.17.3': class OutlineEntryObject 

+318 0 obj

+<< /Dest [ 226 0 R

+ /Fit ]

+ /Next 319 0 R

+ /Parent 314 0 R

+ /Prev 317 0 R

+ /Title (Test Pairing and Communication in the Reverse Direction) >>

+endobj

+% 'Outline.17.4': class OutlineEntryObject 

+319 0 obj

+<< /Dest [ 226 0 R

+ /Fit ]

+ /Parent 314 0 R

+ /Prev 318 0 R

+ /Title (Test Re-Launches) >>

+endobj

+% 'R320': class PDFPages 

+320 0 obj

+% page tree

+<< /Count 26

+ /Kids [ 47 0 R

+ 89 0 R

+ 117 0 R

+ 138 0 R

+ 143 0 R

+ 144 0 R

+ 145 0 R

+ 158 0 R

+ 162 0 R

+ 172 0 R

+ 177 0 R

+ 178 0 R

+ 179 0 R

+ 184 0 R

+ 188 0 R

+ 191 0 R

+ 196 0 R

+ 198 0 R

+ 210 0 R

+ 213 0 R

+ 214 0 R

+ 218 0 R

+ 221 0 R

+ 225 0 R

+ 226 0 R

+ 227 0 R ]

+ /Type /Pages >>

+endobj

+% 'R321': class PDFStream 

+321 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 1786 >>

+stream

+Gatm=9lo&I&A<G1rrL0KdieGHa/tAm\=&0o-WZEPH@\XY7SAjN7+mcRT*6[c,V,!2S<:f9;cj%3n*Sj56kOtdD>n-?K\jr"lZX%?L1YKp"VteF!PP%pSpY>1F?<_7`#+L\f^tb6oSW(.iL"T,,^MR9JQ_^l.#)@h:*PO,bO*'KL0HOTdOe+\QX-7kkc\[n0:Mjjm,1h6rjM^nBt0ib9efA_pB5CM7rIAT421[30TiHEHi:+QbJ1)>bYg0^GH$ZQTi&\4*+i5Z)rF);bTi-#Wb)cs]nEr$FE<%l4N=c$EPM,sn+rNbn!o`J\cWGP4RcFL31B?'@R6^j];$@dghdNtgkMFE3f*c<RG5mF&0?kWX5ut(k0=[<rf/W'gm"Zo<B1--@(2(gU=4s1k@6UAoB#4.$(iCmA-142;$mtW\URGKgS'hH#O9.2o4msSR`0]7raCs67O\'Q>uoLMd-,nG@<>NaW#;g/<j/oZcoGt`GFl:E\TtJuN;cXjoIrCE`pVIM$C=F3k/db7N"Zf"rs+m!(@ep-*&urPZ\+XS>jT$d;g7/52$])`>*np9)cI%L,cN/c>o3SWQJcimA-<l_ET^1$j`+3;_fr43U]=+kkL"tI'72"Bkm2WD/16gGMc:'G`P@Yj<r")sB1*9sVkFNoc[&l6Co5foj#BN;e\$?1<ekW!#XC^aiM7Ds81mShB5DiP1F[I0G;Qb`-T-+!JEU==;D!!Nc>MM5F_EmjX::nbfjmVW#W%A?67R:TV^-$+d>R:a7s2s6n1jXT6Zfk6)5mOFa4W*Cg$[i,R+uAe2![$gI=fPaiUCGhMB(G#X-U?JG1)%&.0WoIEo=b++Q+Gq"Mnmjr!3Wc%,*oaM`mGN0aAX0q&pgP'2VRH;d[J<?3Uan7=5efk8_I'?NrPN!:f['C36mf'dcjSkI(YA@*/+UIXKMnRX@a*SC%uRY(8FqQ(!q2B-i(D[ShCJf(JPB::#Z\*/Cb1TV)]-Pl$cE^4[+Q*D>'uM'rMu)F/YrcdbjJk?!*+i[j-s$'rnT49]g64@B0p!pVZjJ,Z\e/f>c[?]9G]?78rDc:;Oj?QN%h_ZJ!XZGo0N8aNEl]WZ+hJ\aHafcW"7I97,H([fL:`q.&Sg*CPKif1ZR&#QY4GRgBDC[<QI0h,N/XZ*K*Q-/MhWLpM!K$dqc3)7rh**.D@KqRH9lOk@FTJ5b/@F.N&V[!kag#\gkKi1_3p"QDJg)1gW6R<iW19?2(gWP9_%=obC`3%#mRSH4D^<fgO1NBF7?.EQ$/\@5,h:Y(ES)$jL"Dsc2:a[W'KIlrWC<'CU'J$RPfY:/09p4G@ih-ENmulBdnPL_"d?o#Ps"XSZlaB,=.f3!n9Y'XgBaF"SVPqa;k=3-ER;'fqlTmb'S!1?`3Y+gh1b9iTOLQpbpJ<[p,_U\b80J"8ksU$_S'SB#Ui(1rFZ,[bDX`,ML!IJAr&j$KfZrDll!j_2cSi>5ctAa'k.o11nU*:pK7]+D$R/smLNUgno\R]+89tr>aIe[Q:tdSpK.\Vb3tTO!)1;OMq*1.hh:9cnZW`5?boGNY8Ds#/l%7<Hp[L?.J@ZP/]dhNUUrjZ_>.(q#LDW8?>T/'ddSVQ>\gG9qZ3D<TFgj(k*=.@6f)0+kFHHYo3Y(IBK^4)::)=PP6?J]"X\3m44#`(WSaJ5l<f_DT\C.cJ8:\DXG8ZY\O;7S/akP'T<S;]@;XF/Qd2G!jX/S`mB*?bM?gQI&cEaOup5%fU;\L4"S_EtKK(,CqK$AG\C/[3N1'`j\#<Y>N-U.U:Muk@~>endstream

+endobj

+% 'R322': class PDFStream 

+322 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 1514 >>

+stream

+Gatm<hc&8h&:S8Hs'[#(RmC[YQ@D!u%1I;J9:KnpdMLpLU8r.-Z301&^Qf+^9nTPTL;8>F)gQYBDnfR+"SbF?T6U`^14qg;-r:,S>G*,G@J2WRAqpUUgDA\5M\$^MYs=r<3JA^SHq*+G;^UG]n,P[qCI&8u`?^9Cbf\2&G_`si-Gj(.ZsVr*5-U)%q[[:gZqp2!IJnQmjm1(pMGia73)=IA4$Pj++;>@kKEVYd;aMCdZu]'ZFNBRjB`7!_3I4/rF#N#N@si4T9+qpcSYHeKLkO*`1/(j6Uil#LgBL/>6jHXbgJl4H&PCt7\\?IZRCA%1(;cB1Dor?5f%!Wm=8;n]BD:[DCQu!Agc4O8_[j;\a#lZi1OD]a)_!:6eT04<lE^^;0>J1?mVqRURg5L3a-`X[olQtr.'T<g_b<a8<GSog"/F8"7/03'J3[2E"^X`5g,U&P?HdV<7opJ1cIj%JfbX#_68I@;N&V0UK6r.E[oV7i&`4))Bb4Zd]VnQP;oF.7%RQsum)Ns4"H*N,SOBXAk*FfCGqKJ=F=A/CL5Er&__8@.8iCSLM!+B1l'N3kq0[%$Sa3*lZP<U<1<500YY-OC.G_(8!`ocs(g)C07R*nN2<t]_I2ImEj3?tH#+4T;IJOITi`"E=E2os2k)Hsmn9j6$IDE0&opBUL)>c.X#:/56Wf;$P\0nV:'lE*Pm&4bi"2#Dn]o:%u)7"S!d++]hp2,r@(R)rDP.$LipCI;(1\L_,QlC)CUf_%Qd*6%D(30"MB'/;Na^U:o.a(hgnlG3LZp(jU^JpIJ=!`;bo:X>=36dcBN@I',)>HmYIDm!JT^TcXN:&MQV9+*!5K*$"%_%Z1HrfAmhbra['V5m(-\379RLDi^qg9nF<PGlnb]6_>D5o<!8ms`$AouT$Sell/2B6(0^kl=Se@SL9qHi.3l\eWGC0m=-a3fJRIf$KfB=s&*pH_"noVF+H=[Q67@G5CYh<c'\`^?M`\);?o)0pj4+;;V#:su]sMc3gCY3EJBW:,]'4C0Xu9nS/a+uAdafa[^\;1mm%?6'^B[-Qt57i4?`]V[:W@P>dbMd8V8HQYV@FC6i$mMN5#V_km:PZa8EX/JZBp1p,,o1SJ&RBMPi>;,YS(1XN-=iGRNfi1!^KZduK>t#$)HQn-28f^>+?+[LT3'%H!ENS+&OmqB'EQpu9W'RC/3u5/%FZhVnV3]lf(SBE!J."n#lP_Bj?&\cT-+2`RV@$J0lUI3.(S^aG(Ut&W=X.AGLu<!:b+uUM."EW/OjE+*C#[aKqh2hTa6=/-*4lP1o.\_(bl`.34sP$*XrC>bNu2$Z^"mhic$j:Gl/Ois8JLs9S)I>6%)EnW/+/d.`:pGqL$;2eK2RGqM"]<N'`O4ah5]G9*3HcBjDLfV[O$)2cj-3pN;SDVg>=2:ENWSSB-J>%!\]fFEB>'5IfLBKf+'<T]pr_0G#QI65mFAt.u&+bQ8`bGfNGFBZC7ga3/43a,5DA$[^44[ql\XO3&j%q+4@nm"o~>endstream

+endobj

+% 'R323': class PDFStream 

+323 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3279 >>

+stream

+GauHOgN)%.&q*PUrW2,+fORVZn"Q2Y>fOCT8p2tuG5SStRY"($_Ls*M!jptcqX"J?+r/k,Cmc"ck!3IPEDGP92kb5I%=]AhDnI7Sh4.R`%WP`/?P:DW5+-mE^Wp3#phkPNqY%]PY"QY4T';4rjP4IhBP;aQ)j'I1(LXYa_kAb"db-H"o1f1U0F,lAdK$2Qc(AH6??r`rr%Bi*]CFg'oCKZ+pjM%nd$[cfi<)9[CnC#iUHPO5Y=m]N(KN^gF?0eFY?^(3'Wq'KF"$jOks?_.XG+k>E3o#nF;E9FHOOfc:sA';Th$BfEl0\-GQtnjVR[msbt5adQ_NF5&IpKh2Pni4_9%FI+u1@#KGS/J$aPm&O`HVgAVL^g]IB/9S8#6YnZC/Rnhs,J.2(W<Nt02Q#`lfpF'7=Cq2^jq1(r:@#8ik,5<uLcQ@R]$JWsF,Eu\&eB*a*ZP_p-b,\ID/fqeI=123n,&/2]WCR1jb7<=5fb;)e8=1]g\5la-K*o=-U1W$GNSB2bgLo"_eaNK,8,jXKoo*_9Lgq\fCJbN0]QQkGrP')'?hK>?Er5X1e/JAq>ad"E8R&^O5g5i8ArV$Shgu+;W4UUkk$:-W:dbPJ+&4XqXINr;s`$S8SnFGQI6C")6#2gYZi$jM&$pQ8.M>o:uQ@K"-b$8I-\7Z7qDHXe--'oN'LluIdmOQF2K:?&O]+Ifprp5HG^?8-P-E8Zl^gp%qIdpr.01"ZYaih?Rq3_j<%7&8B+tt0aihOTXIp^Gd@R+FP;PCb]$45KBs1Y'iUdEt%%iFa:btM;A6l)\3@`Zc2gIP1L+dPPL;=>-<,8eY3"J<#f*s&Pc<:W6^hQA1c1RC.$&ct;*-FjWE)8TlGAn:.tk<4;eB/YVcjArmui'fP`U><oio>b,0dn)g<+o12F%1(NhZD@U)*gphS)A8"K)cU'u7E+A[-s^hV.Z%[(8J5nT"f]LXp!#h)8m-ad_$ij^#*S*^,':/b+C9)I`]?:KV/c-?KkR4bEYm&$=mY]\oq[FNr^/)nOgGq1P['S5_P@?J+=Rs[9bZm.jZFbh7V0].6N..HHUrn)I2U&D/0rGHXf.7X9EqWR\J`C-f67[*>e<:1GO-t%6kD3[MN_kAhSREFE.Y4-%-DN+O@q3`T=-.qMS?0"[7DVEUTo?jV,Cp/9AH)Np$Sp*@1LR@B;A]WJ=F=UDO<s4hS1W&jq)'f>d(ER:i]Ks"18@$j-XCgI@C=&>`0F3lRcjJ_=No1YRj/A94>(CppsCXr=pK$H,1Wk&0eLa,n[.C"_%sZ@^&CZJNH2E.j1rI0Q4j!jT<o9(<3,/KUWUZ>`-$b@4<;Q#jnkd2q>LK(Uq#T>aAuZ27jGC?0PWlC)j9)JJQW3H7,MhM?t-4Q1,0RljN(uftAkhhML6m$^'D:-<R59W\BBWTc%\,QBl:]6C/Fu36+M*qLP;c"P1G>jJdrh#(3)">_jX+dMKCkPWi?2IF(.W;7Z*Yg%4Q=ZM,[,\6!iu4IDS!H(e2?m4q4!("p]h4Y.^<;W\9QK<cY?6FLYAYOVFt?TsVeb5m\q8k^,[R6WBtC]Gd:`=ik\D[COkc(/LPSF:!&EW[e"(s<;<+t"o0./=4X0>fK8m-_]N*5a[@\VB4c)>a"`\L9<<nUA;rhPh,;Bi[rFeT8\D#&5a\$E8@&)D1G1"h9F7il)AkFIX,nV5+k$iVqLWkT4^3mZt$iU(KH:\oI0Dd%VG^d&$W^(!egHm91pi`r[U#^PP"OHT1mre"^19C-M1pUKkLcY7T8gkAMne]A6B$oo_WBD\^G4s.Th"J*=^6HaDBR.(b73%Vu-O"1%(im,=p/DDkFCo0[t4'l66dK+2rJq"?nQX8&Nm/gk&U>.s94$0YB=d'_`+_k@V>")iohL;%jKIG!)t[.g"3K"W29-\hY]ioUNjLLWDgkW$rcLS8i8OOB_LGkR*mZ]ef*$$"R;<#%o%6C<qr5(oE&]'+_#<nUO!ibqZjW?^HWT8f]'_19$*TqUh*+3`s8FPtc%rIl%,W,)kC/V9#e^)j[GZV2pD%&J5brCAQREJTu'-Gi6'l0SK^BK-S3%?+34GGRiodnq6QALnmZ]BbEPmGWTl"e9T/WHHe:[3sW-=J\?&,e*P@W@gu?Ob?'ph?rCQ<X"sn;d^\=!%@1nps0.Xd$08jo_kGp'i#D:>JBkZ1qi%05G3rYE=/95;a\=*C"5,&_r$H*Z'%@oO9"18[b\"A"/t+0;jE[KS:CMP4B/.qTip0R9V&>,*\0YPSE7;eiY"<19V667n]fdPW>7K>gu3C94*/GVP3`2NmmEu>TcCX#E/.oh;/E1I1/EY?:#p>_MN!adjijZWi"#uRh0K9T%-#(,?o9gV$1)#6HO]Q/*Hr""0V+3"p<MW?24RRRf;gsZUH]D"2^74DBXW3ooZ"u4J.I6o<8JM>^d>#7qu,+L!M0&(/'[+i\$!F=AAr+0Wu$]h@dHAqWb@c,>+LGoi?@N,f_b)MY@n.4Y:dNplU('fE;H*GK8(aI1NQGJ)#;HEO$qf``drM&?g@hON;E"^>U+pJ#Ppr<c,,YTmtO3d54V7[EKqc&q;(H)#lsn=dMq_9r#lDQZBT`KnJZHrC2nSQnYU@SAPSV:-W6LfWsN4',fZ@>aB1S8;s4BTK(O"l)FRDtK`1<E?eCl2MVmRl[7F>'+'Fu79$!&oF$?M';Z(6`YZu`Wd[9qgiC^3J0*dN3`0j&hWVPM5'f_'JY-(0CD"J-moNtMb%d"g"MjCo0OV96$VP%(oYA0h.THp%f_oL^G2M,ISpU>rK:L@&;%S:HkG%X;=Z%?^Y=&Q2!DYRnVekR=Akh17/(jc<'dmN$Q4<5T#4'K[Z$"c?Nnm1HnUM%Z^=.8AOOa!lL+uV)sDBVH9n3<J*&IWH"AaC4Ek$>2Xl(X-KLSr0)k=6aC)u"<8*;VM]qAX-@6gknWm>A4o?:1a=fSUJ@I20]kgo;pV#+r,^]]iOd`]`*.@rlJ\CY3#a]d(gG#;\-%9HBW"ms$9oo"AUn4b3a7Dan0nE8)ADeG&hK6kCNfd(=]=2k4-Z1sHneqt4&<l4d^4!otkcM\PNKDd.Qa@)J#Eat<%3<][PNXFCj)c-2EM-KMK25+e,rm@ROEYHRH]3%S2tbJA3^+\At:?XH#Ejm9_2CuIeINmmj"pk&8\M6-ea35gi`J%?WIl1!`(iT44u%^Q!O=UObS-2\ZsIf'e!YBF6<=i(U9knEd;bSr.7*'SM">&b=2I80=4CHk1XDiTV_,>W#^2RT7Pi`tFA\T80(jQ2=""8;IE49~>endstream

+endobj

+% 'R324': class PDFStream 

+324 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2992 >>

+stream

+Gb!#^CNJ7A&cJ;hr!1I5LH6F^,5;l@2r?T/4h]#2NH@7QWB2/iKHrB"_#TQ2s8+FaLIaWt=d%<1*'Z]/Z.sDDpFIbF/GM`ZpGbP(QPg]i-A^;f2Fk^)/t2`r50_s!qej,=Fh6`[gW"dLf6#RM)NoCU#F7_n%rL1<"09Za"N+Dna1d=@=nO0/Tm$sMVmj(X5I!HimKYTG&"<I9Gjr?@qHj3mqdYB_g[4O0jbC0cTs\s?4__?Sn\BkGA)iu#X*'o.l*#Sbs"6fO#7c8G5'FUor6174=kN;7KbR7*"ieABS7J<rdM&A^cbIj4Uo76D?Qd=5qD0n`Q$2g\9;RN<8#(a?C!$f5E0M`%ZNS<2)_G)AU%L,o1"%E0-o6&:;IsR%_Q`.O1Pe/F"5H'R)F6"p"Lo'?*AkV5PFr*+WURDK6]:pZM.@8+ME]K[XTXpQ=!lJ`TFl9@"jLO<W`DVEcP=^TW5qFe;>`"Lcq0J>GB#T=IQ5pQEu(RkrC@M>O2lDK.`]N:F)mqNX.nOh,gBkb.TW>Z9k-J'/e:OH6:A(f0pNtd)S)'n#"Kdl4qfJU5:i+]IF<hgL%(*u%SIhqQ!u2V@^8P"LC$t4`NOsVC%>r$UTV]`^^8)mg5TV0;;ab\5"_=7(gH^'iDW`#%$_9OjS>;t<[(G#kGKeL@!L0UHj!L,pe8BB+a^#JN@h=AQ"OU1NS_cl*7Q,a:s?I@=<8oKA.cfQ=GW8CD]=u85HQdT%S+S4cIIFb],)M1P_.L%DN9A,!h<WG'a:_9QK[o%qH-;VCLa-6e-/4Mb-FPXU#:==4qB&:^R>@`d]ID1k[5bt3@8+95(,mZ/%J&,Jh%nW/>a_#M3rH_Jc>mQWdC$eoe=N%3Zf,FC04H4E08?T6\:9Cena&i0EQ&ND(*D-#eY_QSm6cZr;$^o5*MsY3WFI5M9TXbo,i[;+Q;i?K5)Z%8Yi(B\YN2a.K_mFO2'eIX+,BoQf/I8%=`=jpq>$<>D(R<Z7":CLECW2IsN!f"Q-fip]if'p?)4h6Q_!EM0o72s![;S$7=gCg2\S3p?NnUQS@pb4c-q%2nbY$Ne-YiXnqc&k[U`U*joGfO2JHDiUR@r/<@G!"eq_^=_u*4]::B4Wm)NDK%B/K!MOu_s.=i"Sd#>l(_@fJBBfV;s3McQ-[%R"\0T#,rrtpVA!Bh&+YFU"ejT-E6UNZMQ0->in0^e-oo.t@m;BBL/6B;&%KjuLc\'k6ZaZ"_7uua4B_V.O6ll%``4-6G>9J)+.&?>1c0933+1_cc3%+(P'"HS<hs^[FPf>3SK,T?oU)PR;-7(?OU*f/\49ej!?nhq<b'<O$iCLLfGc&L@p(-/6DEOK(6X3=%2lLtf73U'K$WQ*X&f<?!-sgl,8?%06ctu8_iQ>S_cB1tRHH=q:]k?f;*U'/Fq.,PqU6@!T5^\UAP"H't/Y>F%UgH#+<3S5S:r3?p<=7mq`:E&o\_rmiXpuqeZ%JoTIik%'fW[2$pCtkRH)upQPen_3l<HUk:QaZ!;O0[dZa'h@*0qeF:&J/FEPA@d5l&nF?0=b**(LX3gajVXi$'Mqa7eO+F@G@DB>uFrX>fDcT2>plXI+U/A27<oWi\"`2!9GmW3bla?@L`]"T-6$lu7.M_A00e.!MPLXXT"gkSL8h1,nru:_g67U-e?,S=c$i9t,73_Fg?$oV(K?YGjg^Ac;V%4@,;M*CU6R&IDHHaL6)8.3NlUC[ajD,Sh`eh/saJ"X;/$TC<@PK'bWca["3-g5b-bNJN3E@llMh0UhRCdbSSTru@Y=_u4*9VrP-o@:u3n'$OOT#Ap4mLMPNbFV(JmNCRU;VC#JOah`-\2oMXr+]T_.cP)LrOq3*h.9uJ.KQ-j":-rt902Wu(:Tht>$mZpjU7&a,!IR9'LFnX)0#_M$P6:Z9=fTTA%I*"nG1R[uqj?a!F9?eX(S].%c?%'XG%3l_Zf,Oj"djoN"*4MLSC2N_Y&1_PXfiubNJlMnQq&k7eh3^TirV?UU2'r`/1XWPUm+925Gg6C3Ksu:R1P]7;nfH."IZ6^bb"2BmS@`@+a]=*nm$Z,IS+Jc#@YSg+1J4Td\b3(K$e,PKPi*igKtnsZp&tdakgpLY2u&]d@*#LYe7*)]'nqtUh9Yo`Dr/*fsfp'eEl8i"/8"F`Y^nfI*Df?23b\,C30j"oSWp\VFq]&[,&)dMqs-@oXQ3XZ3#6V9YZL(#hMoBp&ZoJ-`ZR6P^FgGWs^5`>B"Odk<do(,Z]1smU7Zs\,24XqmL[s]4qD,F,'*^4ZRjc'c4QS:4p.Tk]TcMdQl]FDN1cNRVoP1co7Q\e`^A$K[A=S!=Y(E*%F8Qp\riWHhN#,mH.Q-aZ^n\=,aol2FBT:b/EF>78<ko';QE!^c0@NH201a!L1ece#teOZ1CZU#Gj+0jhJVek<iR+!W"%<KrUr+/838i\i<#VK5Z-9,I9bS]HZ]cJ&a`]fOm:"=.uN7.++2jT[=ef*SWTSB24ZC)p%P\6cl3VQHdKA)i^@;A!B(`Z;H:P5oN<SB]<sOXpl6a86*dZ!`7G/7e\6^TC-mLJH_#YLt$c"3Lf45e-MmsW&&W1(h[XN\d`=joVLt@1!LrZq#4rh:k+4<[sg>7$aNENF[Z6Q0[KDPq_hnV/,geC3E8c_m5-FOZ\Agum9nZ`;TV#+%.`+_+5d[[>Hs+sGn-7P'jH=%S=;.('q(p7!1Y^N3iph=/ZoiCJ\P0+P%?2("Iomr;6o"e3^(D00(:7O8s>J(BdhQT?ZfP@mL'GjWBK)]l.VT2XUH_bfX-O)_22T=8)TY1X48J=2mA6-s*Rk7<I%UU3/:$]@b\*6pWl(7BQ;4Eat9/%+O=4%D"dQ4P4o^:Fd*^4E#<nW"E6[R]mQmY!,8cO[+D;S+r,5\/3cjB\6>$?^pk\r)*(]mT`iBERpN'=[NXCcXtYYakUo<_4])pW$WkiR6,V87Q&12m-M@@<p;9;GTbpHCOXc&f>M7L:a\]tjRdQmhHN3EJh;ush~>endstream

+endobj

+% 'R325': class PDFStream 

+325 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3266 >>

+stream

+Gb!SmlZ:gj&c\Gjr!sXjI;iAH&kP7X9sNfMg;N^,b0@<VlO?6K(,(%`Hs"epoj*(n#_MMEENcc+0hL^aITYqhFr)VH_QV,]2]RM-D:%317B2)#4/@n$&__UtbK]?S?e@S#+Wlc,VCBtKnDq<aW3<)UPj)"G[4s_VIK`V0KrVqtWA9s%dDeaa@1G?a<#O/!L[<WB6C6^kB_+=>r.Q<hM>d=755ZZ.RVJU968U5^UD;2?M?^iZ?"DV8]#R!X84`ZO#%J_4A>Uhnn\p.HpTIr78-;%m$K&7Z1*=hMN=OCEYqd4*T5=.]'2Z);IAl@H<57*"ZuAasZV7a9?NnMk%6H<O_T7_,/b+t46\ab.+a1a'GqKGTKBZiaUSmZ8E@aHH!eokj+lF#?,/_DdJ::o/0h=A(RKQsX)^OX@#p5%er<b@>&7M12VNA;70i@-XP6?VYD$e*g7(uIP&3`9^##Wae96]Xki-WccXFjuk!oOT9a<B3Dgo"FgUM"C5,XC#O4b+:=,Ki+"_uWaU>/8^!F+edR'=9'oG>+8(I&:UT)JgXj"JK`ON$Hm!cLW&Me[;0U!D00s1OR6VAaCoo7NXiXCaa<R7qlgb.VuLV<9MKN;FN@Q(u2pjOSQI7G^@N5;hl9P<Fn"UWNtWk_-rOGNSF7EGGfVBd`1;`K6H?:F9c"GH)rddQ=n0:ih<Yn.6fK;&$*<HA\J#G>WaRLBi:KOPBdDOjc<m'dO-.L_%Di`XP$F<d3t<0@1b$!E6qeSf^oT7(L/0SUt"Aj;kJF`7MLG5oC*Kb^s/Dk3%9'WIH4eFmh9Lm-][!q_Sk:<d*<gHhjLD0nM:3t-0Zu1Tg<YaZs8tiG*WM%aE$U`fMi>j/cD%'^h>o4e1TKs<eG_.rd-#&)U7nlk251RqX1cm#?u!KHsa,Z)])W+5i@"rpQfak&(hCg#TjPbA[%O1dFa*Sk/R#'9MNq!$'CYhQ^=*S77GP*-TFS`0qik?CXE*NiFR.Y[9e;ehJO)N\lm"VUCI7dO81>&DeD@oA4qlp(D%C":MdZ(!uZ7lc?nm!`QXoUF>siLg0"X;n1Dft]3/Q+13$1%#SlB0k&bsZJJ86-NIDR,#Qcbl>.Ye`fajQ:5Ro\.622=%2GS',Os^B[I\<>;$;Uo2Bq'R-1%SL\d0'WgRFL@*@Mt'1a>>::;&o*%OJIQDB7gu)qZM4$!>$XaBT>&;$nTJI+tiCO-C71Z`?`m._CAZVkBaAJ09P?Pc1>HqeT^#^H-e],P'f..+cMUS/'P!;NGP(nVUC9A!7+Car8ZnX`T*F?4pe*_bV]9PIIc4M@X[(S$[)D!#CSP_RqR\ZT%!?FF#m=4*f[<dc,05-2ilIER*"G8QM;EF";Y.Ri$E#$UL3(udYB9i6YPcd&4,NBpaLGoV!O:k5amF1/6FEBiN-H9EL(uGqcbc>`P^5@Ktogdfg@/0W*#ZS75jiOq0MPp3Tfl(7kE">rq-Zes0:efF4d*8^#/\$rq2&)6BTj<&[XQge1^7rlc!^"8'n-N(HIL^ee)/cU(W[M-=V5F!P>6N7(ObEF8oWn997aX<5K6UH\d?0!cd$`:`Z$f6%a7(9pu^X"mY.q>hn0+,IQ5+`*`]E5!'ec7Guj2CY-X&U:cDW5G)^V8T`g0[>es,07R;6FfP^(odgDs$\oQ0gTBag-Nib-=AP&$BCB5Q`COj;+9;a1LP1s\!jGAQ#*67o$]\nLJ8M"PUF@=]$7YTH="IEc?k1oSAaT/&Fo-Wu^0e']2t^"4nPl-A7SH_VS/AIkR?dDrLT!F:L@e"5o+rQA-HacfaL/`M`'.aHF:]BkOt*Y%o^LnsV[qC!/V!rL"ku(0aUP"T#.X8@g9kH8T^Xqn&=;90A]lFn_rE%)=s)W1i:28EGQ$c@'>MJ*jmgT"Ga;N/0u5?u.Oc?IY0B3!'@P.brPRY7fiFM>d)qf)`RMlM+_&>4"6UAFhLJT?QBD/p$cVmK\\=M-#J**j^STJ@8[d$q+='8*s%H0Rl)`BaGG'HF+(-%@WZc536P0G6%bRF/$2`?\=W+X$+V,RDO56@Nbuo+D22r8d,J<]@8_acr6tJZAMe'N`'9=(r!Ho]O(KXrfd\@QF+aV'T\==TI,)@O)?sJh0JnW&SZkt9`he;rIPUput+DkVUGhCS9R'Ihj)CcE&i2kfpaS^;Wck'KY,>m"`P)/\r@3^7N1KPpjd_b.F!(Q&RTjSkIhPO(F+M5Tt%[Ak:>LqV.F$cnAd5TS2>[mI(HT"do%f:;_,?f5j35uW.K:0Jf\`&DTR`6<tUis#$+)oUIHt'u*,a?nl2TDMK!TV;(>sO;a+WkIJK'\&*Ml.YWdk36tLj"<n@\#IJSr\';Gl*ET+'J^4a[K77#<Cb*J-l?r(XhG3^=a6C9CLq&KF=hRmts''kH@@^ibe>^op:_`f?8%pj"t-??`ZY/#8CB[?"KUHJW5&#]qZNR1D"GjM4\=uc(0Lpj&4ND*d;1:=D6mLs%Gc#(2,Q;(Y-'n0+[_\ei1!?b<e@YGa;C2LAj[:rcd#/$2p89q(KF&Uc*4g=-'ST&GfLudt*K!AZtIKd:Jg3Lh+VO8is-8Bb\_YUT7o5"@WVH?)/_ma2Fo5:6hO#``cG#N$T\s8gm&j@hR2MfZU\O3+7.C8YYKl<(Fn5dX,n&U_`K2"@WWbN[1Xs[1Z22PDs5m91DaB:kg=;<7nI%m5.Sj?:0mS3ZZaJ;$)3Wm"j-m*eBt4Ja5k$iieV\MOJ?L6WjPDU4b9Y3MsZReSD(&_Y+n27+LM"QAQ9M(Vbu$/`OkXM@qZb8Q=qi-(:PT)pp@*N1_Sm$r)aRhQ[:P1eu\06^"B/*S""a!e*`)LsuJIJY4EBlU[c0YE`dYRVYAZ=Tj>NKJGAEVS\ADCSu0hp)9)^e``rtMA#F5/4ZKOn-B.c$!]t5'n<>R;q,>&)Tj68'IB!;aYCn!etASR$/95d&lk^%=t3"7$7CTkbZNA"jN*Nq3g-GkdMQ8ja[S+G7Erg%Ai)LpH,gi1dl:c_%8!;ZFAtb!$'Ipb8#-mHnDPQMf2%DRH)X2/e6i@cb.rdjgdMnY6Xbc8[F$[.>E.^^<9g9BJdo_Z=XTsX&Yt%7B;US,7Jp%<]<&-gfbncj.!$/:(Wb^/W*+Q9,jdFM'2bla.Z1_IV>V#S,85ufA5)./C)):BI]f&@ekk2HEH)kWaaAf11ZF#KX&iRc6`ZK1!ijgX0eTmfKTGrc"Wu[g9uhu'ZUfD@R"\EIMq#:?@[^bUTOKbn,+DVtZ3b<(qaK`AX+(4FL7uH~>endstream

+endobj

+% 'R326': class PDFStream 

+326 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2764 >>

+stream

+Gb!;f>Bei3&Ur%dq%%OgqV\^n_i$-jqW-:#epEQl2c:^*Fk["\OG'"1!2R$fYO;mE&P7fl[<5a/<s]^Ojr;MEpkH)i`,A<KFT[0'1O/lT!m?>O!j&(MK\8k?2gbA[]Df'Un^.nagR*q=9Wd-&JQ9&p'@X5Q&Zf?R^fa;:bJ:QCEBYG[/BH_C%amBm7\nVbhf9$9j&[r3#.$O0$\$Vjhhr;c2@USX6^iq?(GfaLYMTl,1,U,bJu0CL&.Im[CdQP:k$]qjN4K$uTdM)D)3H]2VS`(d?bUp%rd$F`J?NF>4W8#Z7l5-c1J`:!LLbSGF:%]c:H>qc8F[8R)b=!L4FSqg%O-^W*q1lB'&4m/Qj?-j/0q_I`RJ&+57:W0+X0dE6hY+hREg=Y?`,]IF',7>$O;hNO3N+0LO#>=:tp8i"@DNsV3htr"p>hUHJF,V:4=kkR`r\c8/7K6J/PB.:hY8D_*W+u/*AG4ndmAtNPH6%#'5pBjn.j##&muo@#;MDek3YMI3sOF*_Wk+6t%h!lh=05_6`"5rkSg=\K(P'**a?ZIh2PSQTt/M>fFs#7^pacU=[+5SD@`RYn9+1r%L8cHnG4=_m]ie\M2$(VjMV%+CG;j@jY?1J`.!%kf%1-FZbnP(#&r[,*aQ'_8@]U\5T*,.%"fM_#&ohJ^N[Fo[6QmA]VR!a62]m<scQ\^01fZ*t,c&Z>Bk6*a:ia!)9NHH64g>DEb`q/cL43Oi<V73B80KVV(JQ&TF"C/5W:I<u>FYTKqSLWKc1"`Sk=M3.LRRs6Z0%*:>e5D?pbn?F<'<gP46q)sDNgWL1;,Ypku9VBN'PR:LQJ/]9E`SV6Pb5I0kPT5@MPqU=W2+0T+lmdZeRbHjptTIQ.6'W<tu4fp?Z!bWf>rnYN0ANj@2CJrdc2>uf73E;-#[iXotpcmMPqK0CDGZ`^H@.0Dfh*[e-WV?17cI_<m0.3U3^bea]ZMqm$W*+&2)c!luW45l*(r4C=&U=0>m2:)O1l29^%T;'K.t,4LP(u.]*DsD,L,,pB`.5Y\0Z'[dSdMI'7:Blqfs@1\0&='WmWsib.gM<^j!7QZJYclFDkH]b(T+oBB%(QYLm&:H6rHq<T(RE=YDraB%6p&K^S(bMoJM3^s">J8\_=<^p/XFb[Ifp_0W!?_3RmHg^Y32FjMdcc8@R>BHS2rmZIW`NlpbWajiH)&SJa<;&#8?(Ki/Z,?FN2R[CTX"aVK<LEBBVu_H"iN>]NA&-fieag9A'YlRmUX%8*=oik2<HC5]^XY@$bMg@38dX]dLKC5glo\s7,Y]+s^al+8(@%WB>!^L)1r2n,HEW[]Xt)WS9)CBE1YrL+[S3M]f9(4D0^]:(7u4!&<-I7Q^QjL#<JZ+!;$Vj$;8g#sS^VimCsh@b6:^tIl,Y3)U*%V[7mVm76^e@ZOQnTm:^6Q/!/Y>3H!]qp4*(cfjCbhSIIH5*d^Tg]>\RCgm)/X];]S#p@-VEBU3(fnJ[\)(aY]Cgj;"\<]Qn^64,4un@73!S/7#q:G+.#@D^4Vth'2VmeOB]F&Jm^].%(tkb2@<T<[j[9,fFXfnSLf,pN,ri1A5=4AiD[(*D,2)L.SSX_CQoRsn**El3@inj/VA;1_;;B\G*`oKYF.Bjc!L2BcDN,NXaZYDs6RiggM2o=@Pm+iLN0*rM#A`n66M9(BoPu[^0nKa]&9&EIQcBm,VA7$)\ecDo=2U1_>p=rK>XQ)1::[0?Fj'@Q.tV7Kae>2:Nb'A]R[a)u>_HGG;g_Ln<hO/sRijWMHNKI/l&hb$bDEoeB0)1s$7G#r&OP>00\Z&GJ%6#=,)3[5C@8'$+-6;fdFL`F2G\G'%/:[=!bVP9r&7d`O"Wo"f.p$P3NaCN&XUjE_n-F/`<B]r(9`OgH\2&up&S;T%m<CcW/C!%!mdY*Xq*guOQ+2BgQ38kJ;TEh)0!i9+]Sh?"eRDsUY:gU>[mD3eZFA08C.X"YRk"m:%*(`c@O8iG:'(ToD;>2)YXl(IZlj4O6p'olMSoj+`YrMekkG,=-R0_bLibjM?PV3T(Dd,"^JXElu6"5UV9R7HXHq&Gp8>[DQToXKKG,b$YtFf"u2=OA(28%1HuZC*?(ZHE-];-NJ;rH_:ef5DFoUPjSR>n2QiLn`7iUG$=-AQY0MYDF4<Z*4K-B:kmkiR*^[4U7`G336;p3am5V_c-5151=nD\)(pCK]K.B0,n%(lobp2QKAC8,Vd9:PC*U9n(r5g.rb.$c`;!j2"Oc.pl`p0FGnVU(,HbNF?Hlc,U1UoNnn`75-laqZR^H57S<LtS`&'W(`<d./I&,4WQT*J=[RPTH9R<2Ndn_30P''r,SL@4>[e&JhV?&Y@+ek^D.ljhOPSnY?&Gs[S!:Y:.iW&n;9\3$%*#_mTjZ3qjurR@SiUJaLZ.LQFY8u7&%4q]))eE%Ao(,TpY]f;SCN;=DB4kE#48aHL]KbX,8g![`DrbV*6s#lBQ_S$unCdS@<2Q%&qBVj4Q*u^JAMkQKYPkVbq%Efgm?OBVuXs!u(m&RVVUn#S&e`YmC/!PBa.%j@["\de384N'b60<'p(Q:sK9qQ>%Sl+h=e'-U<$g&trlaPB81@A<K#0U(T1WA-]c"</6>T$^m=J/9.o=@f@GF@/N>["R)hL1fQhHh9XR;Quko]MgsOn:?Cfm`,7MB-P,qcBTOGnC';4d'k>id&hV9M,\ed[1denE*PnX]\LL6B"+s8&_qQ$S^US]lH3HIKg$?5'`+HZX&lh5GO8bDDI!U??l;*^E4nH@f~>endstream

+endobj

+% 'R327': class PDFStream 

+327 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2591 >>

+stream

+Gb!;f>BAOW(4OS'rkk/<XO>g]W4R8GHqWbUZ.hlrfH&:[+;0hKPCN^bEn+OSEr_At0!QfP3tmT:[R:_C\UEAG:a%[c-Zjj5']<F'Dr66[[U:qCYS2+dF:6]qf<7BMh_;gYgOWBUk]_$kg@Z"P_r=kHDmmPa(S4sJ_Hk>H_>pe4K0c[KUGRIYB@*XVTM*<`h2e-oU]1NfT4%;dPMgZZqmgtAqkcWlr`OZ+%XD3>^'WUr4jhRbSBG"b&VDdQ,k/Q"QUZoI%eGA,M:1Vp`-`^P%O.Gk4QY"3D;`=Pi<WPKW$gLSR_]G>Q58W,il;ZgT5`%d`,T8n6QTC(,d`2)cjiCH$H=(8JnlstQqJ8L_9R^o:ZkF+ARWmhS'M`[0j8>o(sP$NF(7(?BdpKZj)UnMN<7D5qLg5AYmg#5B]kaY=I.V>Hs)NBHdp#<d_j:S,ZoYFM1nLqPT,e:/</cU::^?-R6b+*GT=a?lZOs0TJZ)U(NcpV,#l%%M,l'aKoC_UdW%t#^l6B5H64SM[7XIi'RQ$4:d``Y-H:X\.Ksot9Q:"W=eZ"m,`>N^EG!>;;HZOY.P*Uc%uZ-Mj2@LI#6*S%VNg'9#?"4T>!-Q:ctZ?4J`\CUbPgU7)kN/=a4rjuoL4Y7(22WK%Em:uLbi!Cn"Q?]9/d:r4G0UB5]tB_a*2SP[ThJdnIaLc$M!O\<&7$kR/-kB42EiXr0e+d0^+3J:k&(Bgum(90t/]"'rc;XU^pU?@A]jK`n_g6;dg"AljKpt*&1q^_]FG_!X]7qr,Qn#Is4f%rUP>XrVleWs#OO9oY-&M^'$h]/O6J3J7)]Di(&l_]`WMi(8dfqTg^EW9=08`=tj2$4gHL@2bB(o8<fX1nFfM>Sh_boFq?+p/*6U/9-r.@oL']]D*0Q>&/t*+Lm=_aZid*ii#B:lPj9Qs4(uAWWU9uHNd0BU24p@?U8BD]FR7eNEuZZ^=UKUd$O-p$du95,,tOZLG\_'f%T'F^rkFXh-eO<dqP;OK^UfA+PJ#][g,30B4,%C/R7;Js(6sNqo;.<Vf9W*tE`M?k`.=;c#Ycb*,KpHmmkrg2`cV-s0Q>FQ7STt2c/h9*,mbEb3u^3>:C6P>%ok8HfB:4X$/rhG0\o0_MhOQNl5##BJOu/83l`)U3e1A)(BECa\Coh#+PAHh7Tt`k]Lpl@`8T7M&?@3(WBJsN41[4-$[Spf4WOaODPoE1CcO@h#5tmBpM)>uoZN'7ICpVbR,m[3\-7ZZheq@-2l0'`WZ^%LD*&0[hlaV?;7?@P<&*K&s-O==-=oro="IL17u38HW@jpn"s_K1m-[;\01>0Kd:K"OHpb^3O"_/Ff!md:qXtp47eo[kG50r.;80>pS9UUUbFiH.RUHL<fh>mr_a;!c$522h9P4YHY?9`&/jjo`146!`,q4P'@#,a_PXdO/O<Bl;Abs<M=%G^Z".>uqar1pQYGcOd,h'rE4Qn7X!tUC_M];9WVD(ECj5&7h-cIs@\6Jn)?+Y&B",#CA^&79Xl1lEf5G-pf_nc7_o@llE26`U>TNmuZ3%N(aK&\4eB;iBdJQ+XkO]jK$Lo[gJ=;_$bs7,et[9L2"$XpftQ8[r$9$L-:!"r/:#EW;\rgpGj;9GAE5$-ILLnhO,f*RFg*jYgKX\HDlfVctTV47^_#@U'n1K('6s,.sU*l>Y[PtA'jM"aAB*Ol@I`:HD4=LHF$%8[>+3CQo1#nd/3=uaX)5M)i9X@s5A^=pZ]Z31Zsk*N]LLGu7dN8m3)7&GET@1qEeTY!SV)nP(+EtFsYH/=N^POV"-"A!PhcB,XfkXLH'<d3ntBRN04V&7U)QNOF\1MHbJ',l:cLp=s"KhJDJoh_f0lY\3Y%uC2QcIOP(16"9udtHj9i5lUWlu#c#>,6JVk!3',$D)E9?m1na^W#\2CSjdEObk=nOR<(dc*fU'WegMSBFe?rEjW!jmB:%eG#ZHbXso:C<De=D0ulgj?rojiaa:L8P$r,D]%&s"n%U5;k6W1IArMjbX1[f^Iu`fN:i`9R$Y'(@?m9$t._/u3c4Ee'B8A2rkk9eVcG$O^l;ec)7F=qlCf)c-&Um1C_^dY7I8)m;.Iq%]?2`3F2<Z#3I:Dc'O9@4p/@%n%qpk*nO-ZeBgD&15).q>6B\r+u/U)RR;PYjHWsgY2qPh3sS^,X6AQY2"k4nU,``E(piJkN)<B3(Wj#\0n*YRgJs-R6o2_+hlr9oM[bmbC,LM2a*lWBj@>/prL+"np57>+&V+1XR#q=&4h&F4[Drr)6WE"W(pq17[,%ukoeDVj9foao!5H&*43K4Dp9ZU/HV"KfR8d+_d=IEs7MIXg\Vcc`rU$mtR/THAb^GB/L2]&>@W_^?n1Ra#J%P;0)Of%?Q80dDe?LPU^#)ITL!m#u>Y)%+PrTo.RfOD)GlkD2-mQt95_;H+&U_RD?\IXtMgi+&UC@AQ0]I,S\uX!_,,NS(8.f_Vh%G!L-HV*;HXI/$H>m[N')7ZUg<JL+t$N-K[PK@EG57B9FY7I/E5(<>j*1q"#Ri7[iIK>)*,q(T^7b=WV0ok6?7`Y,EE>_>N@X%30bBPDnS^SLaW\aMRB2dM0iYPnR-Fl`;~>endstream

+endobj

+% 'R328': class PDFStream 

+328 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2812 >>

+stream

+Gb"/(D0+IA&cSAir.k6tR493\(>hNjl#aq*SVqi<gl%EPAEnVo-qHZlOU=BHnbr=P!['qZZ;'SR]1]&3a,rUg=?QKI.idd3O/)_E$\6\<*5-@-EFC[-a(ISp0&_3Mr7Mnble'ek+'b.d!RB@:GMo;rNj5hO3Gni_kKe+tl4&O-=NC^F!(I@n(&+A,6Pe%W4oLShTJLfnU]8-n03Wt"o^A.;_bX!X6H<SQ"kkOIr]=_PdmC9_4I7Q!;*(C8M^<fmb?3o9+;I:c*lfIma^iEL9q"@3a3dS"PpTdu3N.4,`"Nsq**`iBM[@,7F-qcKN!.5@1):7[j<@O<1BATDhgY]mB5',ZDa>XG>%E"MZVi39^r`;RW`(J=7DTe0<D^+\;34Q;4c&2Zj-^Sg5:P<SO&J.IXu$sb&f4V<ei4=i5RZ<rkRTf<4j47go`Dlm(u0hZa26l`@,GULd":_PR]+-m0qZ;.@LTI+Ejce5%2`fo*EUJ&pHLciQ@S/l=l07pa4q_m\,\0-\adpZ/;E,3>e?&?^4WJpT\U>YDM]Y`:7%Ch$0lH>N+HObS-^H3RV5EV`LO+Wda)Z7_fPIi/!oY]ln"D8[MIoL11uF+7k*$_[;,FG6nqaMrhU\RM+O$-66Qd_Tt2qV*Z6^4%9(Mt+Z&+j#*QJYjn`PRDXl9Fg7TrI$C-g+PXLH6n0gq,NY<X[PMZe'EZnqa`OB.2H<r.Cd=hbXBU/W>'#qGsR`%K2`JGInM>)[_?$'RF,dmE)+A4OM_;MD'RMP@m&&T!N/rC$Y"<:I@'TsLL59+NFQRjr7@4h)](9]LYo'e-"k%f&Jh+D.N6:2Z<o!bBpbMZsMQ^gl?%+]Y_`(2&8<0YM0+BK8TlTOUIk<ESApJH@*kBHAMSLiRD2Qk_QR%4J1B+I(B@AdFmH#;QlBL=5Y?A\l?g/OLd8!YU+?TdJ3(`+riTZ/[%J;t]).p#YuPmoN/'bR?GJ_M=GP;J%D"sbt*MF+hBoe"aF1,6go5_1O(BTB*S\^74u[5i*B<OYNO7<`AEe"j?J$IhsAE[mgnUW8),:l#<c0p"s7pOL8$(W&^iqq(Opkb7m&Qk9#ejVjN,V"RF4pHIfr3+8a3,I&<OfgFFjg[MH%8cAI(?aS;<TiW:VKhfP*RDAE];l\0BF./q`SW9c!CY^K0%7@2EA6e7O(fA^lQEr1Qj5#GT9'!pZBote/)qW1J3C+sc,,6eiq%]g[85snu]:N8Ko]/ps=m8-qN'QVoraLq+"%C>[/RVo$4C+`DOB9C$XbpfKS?A!$G<H!Kj,Q4]Z^%b1O,J0]agA=[E`.6km:1`'B^Mj)13+I,W+.9RX6@E^%!2d!HIIgncgblNj;#A8&!0t=$_A=/VR+i&I$O[Tj-UnlX9U\T9:6K$?bqM!'o2d1e%rD:G]E]Mk/AkIG'X&_jRV)T\[jsd^V"gmVo5b`*'!n9EHua!!f'N)T+XW<7u#_VSKB;8FtmM+]^\Z[M!/o;msd/Ks2[\rY#:3T!eu)[.CPZ#1ob^[$c5()<26786<@1A"O"L0AK,?3`T':Le?1<s,XJDG*>\E::dU=H'?P(ZF^(hS>&hb=b2/atSt?G;gY2jFAl!e5V;\n?"\l)QQD2",0"G:t4a_VTiURCCNA8],03o!i.FVOq<GMP%G[jm58b&p^C<;a\4IHpt\R#0Y/s;&?3ABJ'dFFt0at'7&-)Yd<'dQOL0fW6$REV>;K(/Dn33DYo!(rULK_3kh[`<KnjQF.je9^M[`:W'U+@,[Jk_9"GWjnr-i<BQ*[2YVIh_6VfpUJPdYVt"t5TJ;5)V"mF'a&/:&_oEu1.bB_P!Z].$5?P.R/*D$FNO>Ta5H_f`rKa*Z+QudKY`pIjFU;,]-TltT;oP!.>?\lHdk(,)^kZu^l2-i1m5GhVQ4DUR40o6j0c'4]YN:>/bQi7q:+*U\-"X^nNQOH6O'("SGm+gF5bLFCTY&K&V;NndciTcb*;`uB)DZ]42%M[gEZ+[p8ZWV2:DGb2/m^?k*+=Y$.-W1^M+QH.le3@q=o0Tq<UCtS\kJO_oGq?^F?s3=`lP5Yb$c758CsiO]"O:-tD'\!VFZ)GMjRqEHVQhk'I..c]0S4Sqm<:5#u/fLVF!Do$e2Z!f#/k2qB`h[&rsq-51)#nOL68'f1[;g)V:6m(K9N&f/]5X[/!E5ok5F*Gso94.!-;`<@%*?cD*mo[-tBjt<aZ*eGkgGaIR0>i"%+KA'eCLUJl?01s6jM1T_.Th?35cH.l6-k-q</XT+*q$Q0F7^R8k)>48rmLJKd3i;UmPabmMZ+poF4l8q\.3tbIRuiWGNl/6Fl!C:=TXKPpqaLX`*X?gd%n]&[TV`QDl>Ajr_*@^P&#2fNF8McWpa/m9G?]8*-=Y,UfUf]iWYA#UPU^G\F+HXh@XOBM^/^p3oEu%/8T*6`Wo3E<hA'n@#Ag"')t_9Y#,e?)IpfJ85sOtQoZGqEX;F<^OjV]>lcBIpT/2T8]$f")-@=RT<r*GpEnMH`>b-8rl=TTZ`V,T#EY6P0N#]0.8<FJ5\DrE_!]#")G5^oK!cj09aRo3>9K77=M.V\*9tJ+16E[]_9&=-F;Vj)^Fh,^C0:+erL1pO+n4r`/S>1'=KP!"S\u,nt&uIgGqN%Kfq_3F'="]pe5m=:!eFs]hhn#T9BQO--$+._rh0gLCI<g/MK6#<Eb5O-]qbJ2smid.NOuJs)>\J"nFnMf\^$U(5R]::Xl?(4f1?O_M&6@oI[Gm`lm<>NITma%F$*5Fg?R/Nmogd0+s*'C>j5(h_h#Gu^HfH(=s%qO3n%M2kiJGn=q6U)&UPg=-~>endstream

+endobj

+% 'R329': class PDFStream 

+329 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2771 >>

+stream

+Gb!SmD/\/g')l41s'a8-QPPTrq'C3-%u3g4m;<G_gPtq;LWb+=-/)r]M(0r7p&4`8L6O!p[M,K='\aft@T+I2S9a7b(P^G[:[%dI.FF=s4anGM32"rV_GN"]fh;0UG5pD(pD[/:O%2#D"HtS&m#6^A)K*TI8UhQe`cQY/*`fE##Qp#[K'CsUAngoQHgn2%@*IC!h2b^ean\;m]qa7*-c*"SpVZ^BYFc.Ykmr$@DA)c#^\rQ[?:KS31`-\Bp`H#eV`7XJ_r4`PiK*Y66C11Y(ls<s#k*E[]\jS3qnlgq%"(+JV3!kMqn]Lp2D3uk'hW*_8N&_hj]Y*9<150iQ!#:*Oel-o?d?`YH*0k-`CeQ3ZWAg#O8h(b9%S*$$Z3g[d`'rWoH0u90*Es.S$]a`OgI7YL\3I<om_<6ZC!7oH1UpVB8;i2Rd/s&(<_aoIeMjR>t1IS&s+&Xr-Z.?rQ/h\88KOY'%UoU;t/IOU2rLVf`I<C'3gpk=@l0&@"JuYFimV8OpXnkZ.=XJdI^V2Q9om&UfWlCa';)fN-U,fN-$O@OHCVWAMAr/\^":]Q!o&;(+$E/_A<$3?I2+V)m/,X"r-MmphV\k_OE8"#6")UCc^B>;:lC+k7\B$Z[b@)E&?4!Wf<f_0FjUqT#d1!/#XSaV`5,>1foM`2Vf[6UC96U^_-U7oY(9p"f'6?6;Z"]YT@cOZ[:Et+:L@,bRB;q=,4/!'.KXjs(<ab#)Z+bbZp^7+p/>7*a-0)HB^]1C["\,Qs;eM['U"&K%5E'>Hlea<O$QPj[Lku@8-%!j*%1Q[tTqgh'/R_S'GSgl5]qak]];H9cgY(Q2t8H-nSi,(+Ne[$[9gnD+u)NTt<n6EH$(W#^8s>F*Yq/kA65`cD(nFY/8<!$-#kkJUm:7O^c:]YM[PP>)@&ESIr:a+T,CLHP\/P\e6lUJ0<LKSQ.O2%r_'k,H1Qm]"1IM?/9$eD^$VqOK>lY/S)5F'$5H8^3lZk>Sqi;'4ID$nY"^R9@=SK?Cf^]c3Jl+9#LQ!kTYVJ!MM['O&Q!]UXpu]VBKJQ7)@EkmO">q*;P#$kWO[Q>aeVpN]<Z-UA]kbd;@`i(jl:$G/I!*k(q1\)422e2q*IJO-(q!c<\VDpnaNH75Kde02%!MiTfLglk2ut@*"L2bD\Fn=sM<n>]s*:ELqtqThS/S;tC'"i!sPrBO2HL#UEY@P9;j<GSMH?cG?0:UftBj!:2q=+?='<a#7X@8/3',%71+uh1^Nk4sU:'>dH4q?flR'm:Uo>3beu%/?Q8oEr9+'NhPC=:l1RWJ(I<J[Okdg,Xfs9i.WUC1'076&<T8?dsCUk?%WGu7=,O.ScFcIUYop`5A*1YGqDqH:r)6T98Lj)f0.0%U+7g6NO-u'U9?`F+RXSOiAi]N&n0`HgJ`'/ZA(L^e76$c))@BN`_H=89[>0-dYKaAUc8C_PZS2d<MT1/1mNnnfr0$kGTu]@J[+#p#GKd(==W16W#OT>KnVOT:6DG-[duL/8G3Q6OF:3:['hu,I5otEK,KZGh^&6:K8kIQh2_lBr^J+QTCh/LN]IGak(Q%e8SsmOjdc;6/No%Wm6O0@lukV[nGM$'.9JA#r6t'uR#JWNXUZlCApN8TUL'3S8K$EZ1`VNnCU&:\jj)iAR>Y7M-6G2<EfO7gCq(:W/Q@P=!U3=eP<@Ck,_E/Aff?ige4XAXdP4fu5#cTt,e-R%\B1^_'2sla;>FUgHP&\34_LI!'&2h7e<%;&hk?0;??,N([W0FuV.-`=[2j.tYd&Qsmn1o3pt+ZJ>S6dT-L*)SPIafq5Hdf".FdT?D/)c/$8TnG%O%[\f`pWWn'\[gdQnJcLNOpAbI5qHBK:\(AJQJigr=[DJ+ESM?(pp'A`KoqeWt"5f.!Tk@omVuQAtU1NVd(tBYL,Ea&Mkbb>d%M2_5>8\p@+;[8gcYb6[2XK=rm'+8gP`@eg!q]6TGu%lPh]6'WI,@^ZZfJ6p%S\2p^6I]Z=l>BSjmVG(;tZtcV\;f,2e>RAcA!djtRk,h-DM#t**/d*qlSE^Nog*$Mn&-*>23Pl>K'J],]RR48G\;/.<]uINbm=82Z/V3l46RnV_+o:*Xisq[#K=c5up/T4`)jRkYBo>k,>g?KCOkRBepE<76WirHi'T2LQo'07FA581&?]%PUcY;2m4'H7V:)CAHDZg]rkG5&HRo?\jf#pGcO'KG$V2BV`[7ifJ_nj[e*?\o\Ym-j'](Bq3%9rLE]1Gs#[PmaJ]=L"$df-'HdXZKolkK3]%c5oV'/A7m1$Q!JE5ufto'O/nn($/LND^;F`YS0WLitC%ZGplcK't0%2)iCfL>$"=3K9]?\,In.%:W0<#-1d&$?k;"NN.oJ@=;#I=#Y/O=7'_0Z6/mHokFrF'@8XM8]mp'@u/QHG-UQ2D,o$dHJsSp-a$"$$k'qGQ^c0&gtffq7cDrHkSK#5%`IEt1Mo)[@GGhZ;eNCR;!rHjWnqD&*habXOW=`X?^-CWd7'Hl*c]uNE?;R+V7h%OXJUn-s'@kTm<(+`?K,-k<E+WYf02I5lU&kXZ=7L;"/8uN<^kXiMulebR-YaEei0]B07"lfKV,d6!R,D+4D3)B(70:p@e2ZLl*,[:Q25RHj`K#``ebo^3kW"B7c,M8nY,[9G+Xe;"Z(WHm#Lf*Ie8V-/)<\=CcT,08f::(El.&qP#Yb&n&Rt;I6$K=F-V#,XGecu/'gZ8Z]a3\[k$\=MN69!>@]M&m7udOolVV_rDT,Y'FDGcd7RuUo=['<^\7u$S5#:~>endstream

+endobj

+% 'R330': class PDFStream 

+330 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2785 >>

+stream

+Gb!;egMYb:&q(:PIjk)'S;"lr.I&h_jD;+X!Ks"3Q(8qSpRt0eUgB7$VRpPFIm6rX4"VnG'*MFi80kJoeQ&MBSSGbj_&q;.)^YQgfC8Na]&7n=hLOoR5-3YZg\&`+TBrac%\NRTH-TlRF#qWQ(q\<SB/,gch@0*2?f7sW#hQn*$YMJl_)a$[iZ>Jm_O8f['DnQ5E:$D,_>8YcrgPe(=8VloqXA:XU4qb@2lV&tgQ+!pUu;,+a7XH;h!o#Mr'(4320GAV1#-p^0c>:f2uGsp*(5t/4Q38J7`\QHLQAo[d!:pKA\dXlD"9Q?2_9Chp[Im=LUghZbi/!dc.i9R]n50MGUOdH3ocpdLsW:,/<-Z$rt`c</;=Zdgkc^Mnq<i/KGsis/hH?9PCDOqjsoG<"R`@?=.&klkD[0fcCQ[pB;i"pJ*crO3cV$(i6].k44'\\*5@.]di,p<,@DE&*f2usK2`E*rA_Y+_AnFEKJMA>D6A-F7O*K'YseV4?j:)cZiPCMiAJ[cY*;J"TJ7G">^>V'AQ`8-`.?,!gPP=#[L/#TO%-BokNN/YHG6ep2QggOFDUoB`0k4mF/'C&^%nGV!nZD=$[+'IghK6[[7O^*S=/\:c_mc.9P49O\U8uAGN(/SMZP5HLGI?<`2c/P7`s4`3q-!f"n,@,eV<#`rumR7cPD<Rh)a>#GNR,_B7R[2qoWp7!=3$W*SdHQOs5K/AnE8f![8*64Q79d9K7`aa"kQ-h>Hh=(EoS6m@-&'6GAZS*iJ!FiY[*jL*r(H917m)PDCO/eL8<%V*_Is(,-GGD30.4MW!O,_?dbJQtmrD>EFF6:mj3cbk"=e):DIe!C#6K#L@5JgTY$iG)eAepXK-E)qTYu7C;/G%lXno4WG];i\R2@`Q)1DX1J-YSOr^@/O1[!^eY>c<Qn]/;nr.bTCshYXhYeD%>IOY6Rk\`R3G\I*&;ET&E3dp!1u_)h%Cpudo^F2GR.g9_Ph@9OG,-X6#'R-Y&:PHnGF#cW9(OJ`RF'4<l<FX5H/;B:8a^?T#.V#"c@6.ii2lEeB+1"A+6)OBt2&T>G`0+W!@H"%_P=R?(@%)5fVPE`7%R?Jd9-dNNM7_Kl$U9k#I2fYYgcO1il04?5/@Wg#9+MNr'fj)F.Xnid1rZp$%..M!BfA")W_5N=@_&nO8=a`T*;9D?<^_s6a&MaA=Hqgq@adVDYh$Wo<ZLT0L&>;oJun>f:5*db<TDg-Ri;3IG@G=p"1m8?2aA'tB2K*04MR'G!ocYXMpO3a(4jZ+dZK3<a\#-GkuuHbuL!cm=%7;`+W].G0noEMeSIUS5&)^SKmV<^pUl4pZ6A6]%0bbNLO>2t.51Za:he>%=ju908Q``(OBX!MUD%c\[@Z_"XGN6FEs;cMG9D?XR30[(R>4]K^11pN2""-$;#&^5)!1MYq5O3j0E!El=X[.uI[2DHd\m7(I9>RohdahkP#7L1*.q40%"ljO/RUj3b.`6dZE=0,2H^n*s,D7[d^$-p)U*eRuKM(4iDb9WfOHC,kj_bLHboUE/)<p5Y=sp_1[u6gGtDqD>L,G-7La=-dT*HGDs?XQJ[K_3`UD9b[p))EG,HOKK_-H4X(s)_uP(ob#qZ<C)01)@6Cr@"X$45tnfH-?QJI/L)=i:m\P&Tm.&Fb<D^kd*053;6:H%Rc0`t5[k3/fPOCY3k+m!+C:1oCY%j<0$DRC4h)-5Em`:gGh#flKZR8e5G8"T+oeG-*Kqr..("e;kL@ebD!C)=ebZt;#6$$T"J[g<$rr9W=Q<'j+D"oA/;W!<b2^#p4a#\K1Y&_JkO!<gB?KcK=tlMTP8FNb9DWlgM8*Xd*bF^pB_Ed$1nWq*FuuV(6gH@%F>Ro;+$FoJ*JtkL=?X2acSh'iMlVlEfYW1]H--j6$rJsq7jJ_r#ZSL9.gkj@gCBqh"KEbt<%0dX7QF>I2;V7Ip12QJ3DrD>:H>6u*[;:9>L%k=l+ubQlQSo'4V-;8ilKYp8rl)(ajOlKCbUlp<q4s+9'E^3Z71!O[i8n7%[HpUS6G^!8\cRO;^,H6[3enj)8!-Vo=4@:YsY_<+.P$V^V$6)4hI2NH!c#M>"SZ.7Wp24UFoT-q?''M=]L(c;k1g:,H/Rp5se[_`-tbApm'=7gsiJhDd2n=.<?lCZ%\T0YQk3,:=cUW)D84f0fB6'M#BLX'n41ne\+jh=s+nq^Ve3Jh$Y8mjXE3p5\6.%`RmRJf[me]EHc_!C2$(ndOgKaC0DPiG&O^ZiqATsWlA\h0KgQ:48'f$+IAX-@/X6j2=,Tb)ID1<dk0CG=4q/-@rp?3;Q.6sr&3/\Va=*0pJ,8,6o^;8a>uV)qV<r[*Sp+Vo<d<"ol*;r_'i9fcAa!$D1`Iq_?k$\,%.9j_1=Y&d]15:IE2*up#eWto/:hOMC!X'ebuGV.]6?j!)G"5Lh)n)7ii]nG;]C)>/eO>+dp(&$IPFA(YI9h.dl)5<g,tMS+Oe?q:G$\g\FE\0:7[8Ps+Gu%EmRMfqM?Fc7'O<Y?8#%BVhZaO_@I#3_$]Rb%;@Y]^B,8Q70[SLb;(/YROT]"p%d(%?NK79j&e%5Z"&cp9#tq!a&]X4LqgM\$r3NhTFS;ffTOGrcnOd.Rh$l!A=?82n81@3UiWoL#8"n1Ia68\:Kjco<&lk=C!tG=Vn+0"etJco[4XZ,au)i*4tJr[XEp:"7S*jg#.-O]@,QI[PG-f,aCjFQm%XE[Q2n_&M^]1$,bIsctSHbN(liB0ST9FN!c`RjKX5JjJ[L7d>02QZtu)+G:.jJ.`0@FIfY^11^s~>endstream

+endobj

+% 'R331': class PDFStream 

+331 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2270 >>

+stream

+Gau`ThfI79&:S8Hs'^\LdZ-==960Ah8m5U0,ph]Qdtb8OM@Uu'\2u"t^[LT^,Y*"`+p73XPLuf1Z+&W"hsMtG3W;GE2lcq-h8%Ls,D[,>.3M5N!h7g2gZIII:])/Se'eF8$ZV?hRaH?_:SN;3SBU#,Oi#Yd#Is(R,8)tZ,$)l$2HBJdc_+346qYMFq8ZgWj!aaA2BQ>u$_-W%s*j5tr,l]#Ek)f]/\:,c)]+p[1(dA?i>+)Cc**pCTH.R?Fui]*jcISRDG(/1!38_OT<H)>Ffjs;..sEg.p80tCm9(8$d]qre2.8Hr,BXaY-d(PD=Bif^%<3R!`MJ6eermuV=rLsO<,Yg-QS6*iOsR[(KOSZ9!<ttA:BC4.Zd)m1=(:b^JbnYe!)m$-O=rsN)%k[i$?tJ=3b@B7Q6HPrmZlc!H0*edd:XCag*jM2V:J_CF]SRF/GJ&HTs`A&%K_^HEZZm2!.E`)3(kE4LDN?1=^XCBka`#Y6T/6o[Lst0daKGM9;r.#^GJ9dh!)`=]S7rB&F(=E<oeqYCSfd'Ak^JL)7$:&p#gNJcG4MY<I;RJ5nIq5dkAG`bR6cok6G*#*H*KkBd]76"G`9pmq&0Fh(A0Vn9BON:g#TV:TB3gOc;Ek<%=r!#2tUHj-r"S^C_N^PK(JT*rTb#M'mdKC(t=3n&@_Y\h%@\0K90JimAr-cef/)m-"Am]!eI),c.WXUpQ]:1'iRgLDHKjN;%7Din=GCN/#'bI?qITC-nd>V+h,F8)mgA:::ig_#Cle)=M)Gk:o^"+S&@ggS-C5j"22Y3o$gkiI&\/D%p5/Au!8T*-^r@37sK!DtBR]+H.l#2c"XE$hoPnq-f>gf+`CD)J<JACK"k<%pV8d4%2*pYt.a)Nl?Xko.U/,"]oA$Bk'KXHWTR$0MQ&SXB)a5W]0Ef?TTXUPptncg':(S\lZqRu`W'cm=E/,(?5#QLc*)f,W>%UhorR,`F0DjiTJo\`7>".!2=t3UCp<q?QrCD@ED+<UZ/.Xj'C%(\-uG=T$Ke\th%fhst);?d-p6jOqLEX?3=5dR_<uIY=7u6QE5H4<@:XQV.poO/=6Y<XnZ>BPOhVMH-)dbakCXnQa#]+a1>)9S&%hL^=*HAk=;1#iId18Ie%S%=#UL[4[^8GHO`&f4171Q0"kALb/*H1V()4LZiE,I<f7;,s@S"Y0D,lK3ZOaO;tDs>NX:7F\+@LG6[Y,TQ+C7eJ"O+]]2*^DJ#uhZ6WtqOE\!*"&PEWi8.ri-".5Y4.+Ts4f\o@!G\.\2U5fh<#qW!H69dS@oLC*`cHWMd',JY9Tq@5@uYW_cDt]+X<d*FEHe4+04@QY]V4&P;Rr+f<7<*qM0O&6nD/`]p/ifu&im6nF/5AWrhe#e?@=Qcp4CIk3L!>D'sHXl-n_eE8TpcX<akA5aO2C58h&*)_4[caonH+C,kON`,q.2Hh9=H__)2$CP"I:k4iW*u,:bD#g0>RNX`%CXYGX_j3cL(A+1ZUJ.@E+V>582%4(IrgfJ<(tW(a6l.*FpPll.@36Mr\JcdQF8=rgOd/l't<K2IYI&3-n&bhi[Dgl[rMQu$0C>5[:N,idPKMo]n^/["'F6s1LmG%!ug#>rMFA<=mYOI-;85"8E8QXX$H4M0+-n-O59G\Rrt3ZOU;mGG.V;,btWOTRUSH)@#.F"6FHS9$T=1M]1I=jr3?a6To?ji<1t)+BOZ.QTC^:j4qoKeXAi4UC;=]=4+DapoX5rN%<EIYH1#nVrO?6@ZP^2n[TO$uM!'U91lZC3!UWD>p>nemf4@WT2abh2aLb#rOSl3MGe,$\`@%6Zt44A::6M6X+n^$1kg+`gshO1Tqhl$Y7j4i63&+K6(j=K:pSJ\?hl5LXYtfd@W\%iR*Osbd\\#l;ObJCq^>O'Ubt,T?0I7/CgT88)9,p.J%KC2AYW?J'X5d>#+N!PRE?WH"af^NI$KqR;&ap@B2Q+5j=e(%X+?p.YH1ur_,fd!?:_9]nPD_m!dc5bNSZ>8dsqm]pc>GK'9.0dHm!mep]l;CdE?d9HpUYFOt;"B2Q-V,o_/5_*o$#.DWcsk51S&D>&CqJ/FS\FcOMk4!1QG0Or=QWt#GY:gr1E[[k.b;'FXTX1KgX)Dch`1rD)M2j7T&OTH<RoQHPnNpkgm9rH>n'jp?0^JdlGZI11'cZXV@_R`K9DbY^lAf<.XqNc^M#P2ml-F/e:=tn(/l3V&%NIn%N/K@H4Fn=c=^%m5C*Y2Hb8M+IAJ).&UbgqncW86p1Pi1MQIfV^;V2k~>endstream

+endobj

+% 'R332': class PDFStream 

+332 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 4195 >>

+stream

+Gb!#`=]aB<(4ORiq%%csdpQ_>Y3!mNA0XZA8E`m@mYAHB.RVu?gU,.TAq'\lYr5fa8O1gWE'fiXG8K(^-#9hr!:dgkrkGN7GdROl-S^Dh=BpG;NDd"U#i72*5PprL`]ZFW!CG0j_`V+J%$"e'(/83MUC>pAItjd,6lb0kBf);i?r?T(Yn!LN)J);gV#T.!E"Jc\@.>%8r/7$5)u]`)J,!ko;)4aU@736p5uf#!U`bE!6:e'ck=eE0&;iL:O9FASJfljK#)t/)o&m#h*;*1"KI.g-F.s\5j`grZ1?8Wbe!U607Z%eAGS9DPg7Rr9E7A&gMm@.`-G:k>]NfCQX@d*pI]PRZf>[:GVT-'p712kZ[`UZr)gO,G&gcR-H%.=R:%IDhfAP]Tj,],)TV/#n*8nQ5+#V6*Gr1@@9L!CZk4lS>g7eU@m,t,25Zr`P^>i3R=>n\u=m')De=a>TRkCmGH+O+oAI$r%.n%Z&r4E5>"6'Ui5;')t=NChco'1O,elMo?3P\)2h%iEgAqV=urHS@WTYs4HBbUeo9cad3ZRG@#Fn4te%"(-mP,mne05)(rcecAt8kE0.SK<ZG7TGn,HP(g)%G:Tk^2DX7>W+2-fIao7,%-cic^3Nq"=5poc$#].n)#0p4)\S51&Ud4:^a25Dg&gJ#[:E\ht).sXMB6Xc-g:rR*Rck%rqI-kgQT:hBAHI-bhP)@baY)H@_:d-;>:FLp^OBDQuG+,8)lHOm^&h>&+P)H@ga[OS_NGO2.]hO@SS'j$%)r34Ndo$;;YtEL5MOL?&D.U0/h;hj98.^qG,754$,G&',!CmaSPkZQpq2ijibUZ&^9&3[C(5,maJdG6l?)TI(n6%X\$EX"X5[LnAB?H!BDICGDVJ^r^Ub1(/`K&l;]%lol'K@@[Ou83GRRLN`OQc%iMc8Z**FP6[-mZ.36%G?s.qA4RD)i6B;`n?lpgGgn.i,,RaBJNlq+f[-V.^]SuT2%lR'Fg-NhNa5R"j9m%(b:NRs==cWWIp)\p#X0nJ*`?G.BsDPVG<rbTB48]B7r2e;]4aBoX$[Hs;dJD_/,TX5*CY*XXu?e$FXH=\laerC[bX1*?;N#J,Kcn,8ZC\a_GaKZTc'Ibl3,GkL!Nh%i+peJPb'[,T(P0(%#!`i?5uBXHZ^&A_g&oe?L-tNBit.>s"=;EA";3aCL`PQ11A.Cd3<K02Agei1j`Mp'o([mmWUe6^!5:UnEI=kGQ74(lW]M\\+u#mF[Z7O*mLSHgj`XMT-]s;<IX%5g_qa.`V=.c?dH&Wa^X+W3mR[aN(A@=Z,26/r/0\;6.s!hX"Ns;n]Q(0>d_O_;r2aO2tfhU(CNBQfKPNZGDSc#2<iqPPFtJ7`Mg!gd8Mg"&)BWi61!t6o-paEmbX\BTKO0>qM8_3SJq+b1i/k5a6&&olA6@q(5q\RI((%K?cuF]YX+UN*=m3AOZ^g0i]&6J,\3?jYN=gN9u>IpG&L;]C@9q"IJ;b7:Yn7tD.3h5EAQ/Y`\_KiZ?r>JB9PXYmLPj2D;!="1Q6tUGTXa-P+QushBhlmi4L=Ne)7<ELn-gLYTG[=P$gL4N>o7Z8-FAfQMcFO:WUir%0(d%7uX/HeQ>D+cpXftL*pd8QSga87#9%FTTnB-"4-2*a=0>>;arSm&]?CO4):RRfpAsEMB$:UWuGQ6FL"OgFrl\62M3'dW+8WQlLhM=*u1hSl"?2TG,3-tX$D"]`V3=jY=,Cl>VA1<j"Hh[H`EQ:,#q[UO55uTITCa=I^Ti.4CQGYWtHhd-^dEs6s=7"fuNn<VZa$f;oO(KF?6!)fa/LJ=G#['-`7+D38H$LTK1EA.=jZX+?KY!Q)Xs:Au8Zk$l:;>qT_D/brI(HFe'^79W+-]Kl<VZ)#A>*dcFE:0iOLD)KD-H<_`tn0aQ2@)3q/$>!kn9=$`#=-Z:4XQ\;=qUEg'\#Pg1lLHp`n,R5+jq(r_>5_fjrQcY"0!pn60<.2\a*D!WITdZ1ZL'_@1XNJLJWe6Cr]4NZ%gZDUn5`.t8O0rpufJ^c2"?Lq/Eg_>h,=6k/Tb=%te-VR@W(-0hpc)I;Pt8l4K'MJuTKZ+p9;Yo3SEf6:TKWBq96U28j#-_e6&,;f66u`9W_KBd_&><S%ON3)d'sgllHFA8`N<PH6Ers=AOr_*g^;Uc**\)7n[ZYVn[Y2!qebgp7U9#`aQ,16<N4*E\_0?Dng[JdQ\k&3m(<tq(C%?ZMGIb1@-<eG^C[n$]D\i%Rf.%IauQS)9Q?;)jkp[lQg6HgEAT)c_8S](DKZ;]=A!UQEKH5s*<I6&P[";4>$QuD+_!0hKbQn49nAB/r+R:%YS7,[^;iJuJ^@:N[O5up.!D)\^(Q=n$>mRK":hBilUWBb946fA3$l]Se]k.GeMNtGfdR)#aTS\Ah7OY.9c9.Uh3-TC*q7n]]EJAY`\`$!$qUTY'5bT$1B$DY$AD\O.o,KR>IXjb59*m\':,6&Kj,\u6aB/U(8!,4-D+L5Yi!L(GdJ2sS73,/db*aMmT92e9^s+#\bIFf]?=J8$'s%FHkNpEbq>D:J#[lcIp.]'LY#-)N0`5f4i#+Og@Je7GY574oFN+Rg8,B0V:^'>LlXXbdd19R4M'F/c@d<ONCalt5aiSH/rJ+dM"Cp,hf[>WT`rJMgXNHekDEEDR**Tp4PTm4pKe&Vns$&5RAYfgOlI-;O$kF5.8M$-Blq$JOn/T0O$kF5#+sSFg&7f=)#\%m_L<<*'!]m)T/+/O,#oiam,M?9;Za?m[-T$=S.b&GBW"rjR$R])Pu@a4SF.*WoW?8MoW=D"gTOXK:sb57A02VgIDO#!d)Eg$4ta7#,"UqW?iV8b>")RW`AnW>NOIukKaP=O2n[,,?LeXt0M<e"g%[r>*bNZpCfd4!3U)T1om?>r`dAQ\Z3Zs9X"joulXdCP>0jMk`(C_^ZSM#E+R&Q#bF@Lg>S_i2`Me[*UT]Yq_"mlR^OLV5b'LVt\LKklf8%*$PA`^Of6?<"IJ:DT's2KU_@Kb8S$#kU=45EQ-%,rf3$sXkf6+FQPS`X0!q2W5ihgB"_5=1Gkppaom@\>XXQ;qQ2FY<Qmh:6e20FP:jrIReb9(+p[,dq^cs.5Yq-(E5n8HHGdPp'L"aRA-/"m)T2Ea2-DTHfXX;?fF2'.@4<KCjjqW+[^V#&9I.b]7`!K.=]Im79O$#P5n.cfGpU=/jXfsIfc^*7JO&<4l1?Bn4(Wn8lWnq&ldcoUaO*k3WLc#)O6>S*?1RbE5:$1tpkjLcm/]Vg1^kk,X_WJ>Wm=d(PpIP7&F7D,kbmr5Bo;jA@pT8Pf!pOQEE.ii9naoQCYpJ!+NoTUt+_;W;&,,-HW/>k@6*)54M"JR;e6W0:>a8f(Y#,Y6e%_SM!akXB-ZRFL^8RXQ\^e#7/_l<ss\<:;?kPMLR[:oN1LCm[Tc*O<jcN?hI3S`@\cd=T\iW1=^lOUMfJYhEK]Gg9?Il'S#asN@<J*un`aeCecV9.(`G`SVcpO8kuK76h/$j,WpV&r-_i)SmED6CX;pS>b1O<!:d'plE>F4g"S_U[T7`i<mu<Q*jY'HuGPWWP0Q0Flt/_g!CXaiRJ;O54'e<b)#s9HUUuGj'PqXEA-=HQL.Tkj.2fX#YjFknP4HGVt8(h*0bS%b?qi*eF4DcbYbH4mGDr0eW!*$1\5r%eH5tqIDt*dn;k/7X'1[qGstd;EMPGWup>S]oDRGDa0'3kkBCSr][MU4rtdnRBkAh^'kg(Zr1c>@XrY0Mih,;*D7*b+_OIu</WbhMF)>H$SdlT6-nId+bkY>Ss[]dA>j4t@M`8E7/T^c)DBF1aMb".=p<="%L`'U.2gZtMpWC:qA/,V&Ru\JHW2?B,)s8K'=AC"2<X6:@i;PK98AKXdb$')0+?60F06Q=Q4[oDFP+YYNSTgXgU)7fO"SA=5@t<c*RQP7.]$t-G)Y&DKE@MIF(;8UjcLlT`G4'nW?^9)"TiP^;-VneFmpMPlA/Nb9Ed2U?q[*$Fk"jC#$rkpm87h7#:CH*$s0]hRO,#?R#SQ8#2Lo%n6I5@8p;1$Eg`IsZq,6<'?Rsk[-IH@'Hhp0*cS.)CU??<(h]?^+5Ao%(cbUZeT+B>N%M9rK3LjJ3H`EDjdKNjX=.Xu==mKn9d+2rAm:j0UG@;dCIEo4-;H/X&n1'4X:]G%i80,6:+bH<@Hq&:IWd+V2uKq(aj.06Fqo9$m/Ia2q=4~>endstream

+endobj

+% 'R333': class PDFStream 

+333 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3161 >>

+stream

+Gb!;f>BAQ-&q8/#rkjb/cA^5p$qZ;eoK9\/c(-,&A%-mV$Ud;o>2DT-;KRBdf`cU8.>^Y3:Rkr.#?WMm]AMHF>%$?.9E"5^!'fAYb;U2=2V]t$)Asd0Ih/aOT0N4Sr`D1k1BQ;h-4[1mN*C74'k>8%**TcQS*/+ZCIqqP3&WLg@gDFSr4f`Hm5csAg=B6<P9jI;_\[:l2r+G+7/1'dq-<jeqlW?4A;4nj>(D3]gAL'%&QknkP$L.GZ$&YcR>hZ&Cec@i7oGQ5iBs$kF<&A>+6Y%Z97GemF]FkT_f8N2OYN@eZh'%(U$#d$?bbtUQ#/S%n<'N81Wb-*PA$A'.E/lrhM11FYT?A&kU4da7@H4jEfBP83<<QLn71M.Q8pZNX2hcSI31Sc(2diM9+f*+%sXJI<(*F5%tEBj=-K?DB-%:!\rk#H$&^2\-drfs*!CNkN<_#""(8F)^CIq&&g#]F&9:7JakIa@l&)=Qin,'MhS#G&=U5mc:SVr$!K%&j%9!*&[[^IjO=)SJ+b\/f6jlhS<H;te/rc'bG<@aaP:Z\j+M@YtRdWFt:d$rdGLl4T,hg^68!qu9iAXI8IgV6,V^6u%Mq+N!GF/UGjkYr5n/,W*L8[TSC&%Dq(*5)fiA,k,Tu4lY+cZ"[Po.H4pc2+[k,tL,>a^=<^T;@E0H+RGg\l0..i&(m2t!_KS;6?4(_/7,_MTYrL*[gAk[FHmL_*L:^aND6K9pM2`D2ana*j^bAS<]RZmO0H7&MRp(.f4;eUe\]8m0N+Wcf#kRf'Tb<JM3=rn3$5a`N#rq<?K6G5qO5QHZ$r&M!_`A.(m2`>SGi8)oUi;D[r`F3^KhMM7KmNSDEs8WG\d9k2o:4YheI>pjE+ZGWSu@#&rViP@:h/[Cqp!+"/6g>$j@K3]Yt8k!<NAPB"ZTNeNUK"]m_%p)WjiY2JBC>>nj_(M_ZU)HT>QdY:R\oOGr<DW4n%bc>]HuVU+`GM78Fr&]+m"pa/gQs%_aL\laNLa:\>uLA!B<U^?>psi:ZPkq"_I5+,ejMA$FWZ='eqj%r8W-ka@0[haT;:j'44@JU2+Y<kUq]T/8DWa+4(NYWNNA%B_adn;SPo/JC<u8T7+KAi\2AZ07GB8&0;S<sIQpN<Uhm<k=kntd#B<W&j5'6O5&SXdc,W?6p&7*3[CKpUA)DmFNUA#.417c_!cu]a#+d=hZNJ$6E-,oo_U.G:oaT,G6tQZrO'q)%:'Ec)4mO&sXGE=.oSB$Xp?@.NMEq]>S[YRVp3+DllL?C]e!c4-R\W`CE>&EF4@-(QU_2/9<FP;'R;rhj4Bh>BIN?sR8+,74p;d&3AQ@&CT_<P.E&$9\P]GTe&G'8'+NB[fiJVdcYGan;Ro:-=@$.9g;JQD3%%7kC@\8>t8qTIA.i'ao-OqO%F!_MG&5?G,MfE1@]kW_kTIu0/Qc(;0Bg:aTaABYIRV+)1X\X5-E4HRp%s)&nj0a6/q6gtVEcK9_jmr'\<$CX%rE.-"\J"K\0$0Op:ug,i!-rHJVV"g!rN/+OQE[2d7)4*%<^ZI`/Vs_*qlMHK_hCr[#@qnjEJ_`aPgpV]%C9nP4G57l-HsqjOCe1Mi:(:Z]"r(B)"qolcj_PDF@P<T[,XL'R*6lqk@8!_.IVk/eCUCSgDFn#Gp7i9gl2pJ7"6YVR5(-OQEng?n>p!crtfAdIAqDQMTri1X&`#14#^re)\9G+R%]P>:YCKhp$E2+9r9I-&/M9BgF;M4g,KJ#H+[ZE?3(6BY'K,62BlE-BC;e4kXD#DfNL\"r2IHfLJq]'"<@p\QOdH2,L8p,V/l<*>Wu8RM3<h93lC:;a%/aY*F@kX$cYd!dS!6C*.V/LIo.Y'3[chBDWhBuT'2a'5+"d!!V<p'cukXDlC@p@'Q)VR`'ELX;)sqj1q%e@b.1#$cWr6V!WTIB&?K2IP3@fhc#Lr6$_JJQcl#8E)41JE-=K1h!Ro#RdUg;NPUD]R>kq`g0mCT'5L'\q_&cfQm)pPs57_^AV!:j&pHONJ,?+Qn>NNcUe<iC)4At5Q@>qSoU/,64ZDN:V@8LFQPo0c`r?MS''9rbWatWb4d=s%,o/6:$iUZF1rPK#38^MuYCM?5S<cHr[nEIh2"\+8:WV3U:=(GJT<VsL^OhN3<e,6sQ6"a0l+l2n;H+1P9W52T8YtR'i#WYNhlmY9sTA2c3iOfrEWX`H5>4st?A='!q9;2b^L$1%&8gB/U+"^^An_AB-7TZL!1(/c)7.D`6q$Dcm>>I606n)0T(asta`+Y*l2N8?7ZRY/`/61YdXlk3-6j_:OV,V:XA]V&S@sccH+"[`CgG<t7.oJn/;nK-bX9@)#.pfF!&XccokfruQ<TIZOV&Cij(L"Kg.Kn8$p-J^j#s+QOl=Ho-QFM7;Dg+`uVBI_:p]t^Llt_Ys?S7kR9kk^?h_[sPClg,hJ%J1lSr=8RL[PVre0kca7d3&;'l/X)19(jic?H1kp\i`.-)(54']^G/,[qf=6pH\]+!d>3&F6)K,7palN^hcF1gm>XP2m]RVhG&XSPqjAUu]cr'[nun83TkK<d`?$P2#Rc%q'gO;)sC.01DgN.QJC9JV@4Hq+OEZh+[cG*8DC_+V2-#OI`"DE:Rg5WOic[J!#K]=/cHbnAU!kGQq0dkdmT-WdQYpkAN;geFWuKR."NMO8!=d''J[e1eOA[BNrYMjGH;dLuc*;q(lcdl9-(emZ,"*e2J\:]D=L2*:%A<+.0!_l>^o[X>qJA1$hC%`>H&>Tnh_5#'eX#f+A*SQ@gRs.0]Ejp!$EZ&)H.-Xm,VF9>^)uj04TWd:!OE/;YTSI$dp5Wdh?m3MW@d5)ib<_Mrr(^nW@r%BKqp+%=sMhjX/?#p%:#;2,ADM7NB0[(7M2U;mblj]86@:_uH>g/3+/Fu.["TQFMIU"]c;QAs%M"9n"-9"Xern'a0@H>)eY9SlmTUBCdCFjik"(/!k(8YS_?V&seb7)bY6Ou#cR?M(_-H2Q(KM:e)2MaWq$R676eKp67VXAsBfShDHA;R'%okVD;e+3Y)^C+FKlF<tsqk7G"jN%'ruRB)E(W&4oNG,Uli7gs'-&P.3eGA8V"D1.WB,`V,:70@gYT<7!rf.=KEM(EOPoObg>X*CXsB]Zf_en`)e+D4"@RB5t$BQuN(e0l?_)8"l'Zi:+KM`9G~>endstream

+endobj

+% 'R334': class PDFStream 

+334 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2922 >>

+stream

+Gb!;eD0+IA&cSAir.c;BWRHu4OeU^d:JQ>ib?TF]4"G`IVB6onP#.>B"-?F1?f,/Y?(tl`n_H/<?d9f\@.E1.h.INV%.TBorsiLg[gVu[pF`rs/6:^*NXq'BnD3*sX3^L[/V]=7n2t>E`c#&,?+=puB?kTYEkO3o?GF?[WtDLec_f!(1585&r"I\T<N"-0Q6"[DH4?4Drrs8=KuG.9$,>,bcfHgp**P1A8'Y7q)J7oWF2rF*%?74IA4j9/aVU;9h!*=W7WpXIH>_(%K',(@&La%SRAnD\O@ba)`)84?r<3H/+^YPt6V%qC3UAY/!lLXT.C`'fW(_r=JfrMHT835mFMkr!3/KTt8o&;W,srj-1eG8ej_&c188Pi^k@Z+9Q^ZrYp'[03OU,&=P_?/H+Ar:BMkVL*mK^7j^bof9ODdS'BhBPBr]F4)5BEWucL^8MAH"FZ%JqpLUTsUP:=rH]Gn.HZD4<i!3C5PlfI\'ImXFs,j80eR?T)@B;W'+YJ6L>GL-q\8_K@?<q/^HS-<%*,SZ@0%,Fb=j[Xj<tKN[$e/cjo@LCf@l&dJ.S6N]qJ`/X#Ba*@<nWP;P+G"frIOF/>urqI'Kmj/"_#]dtipuAQ2A`V7mh^0u>40>ae4Kd_i^JQu%F!6)iIO7aK?Ap92H*?MYp^cY?+o&2r3RRoan[<pF.F7TR"-q&!Ib"@;-FD#]eq#"q$M%H@1o>Un9(]p77@oet@"nA\b>9]$K'/'sG+QIK35P6p'Tkr\E)U=.4.<u89/E(I-%VbFR*LnOa]s<pl6+_5\`Q>P6eu^$qseQDiP:&@KeS/=:!7(Q;'iR^Mb#$K%"fiIF0YHHR`c_C1b##*QLG`]jo3>/#JU'Z9PT7h$67037II<LEbY3-cIs%qF[m5*S9r1S/%L]6J0\*^B'W\O`LNi3gMH?FaQ<MC(-gQ+h4@RpD36CpM^(kn<_lQ0h)[;An?QT,=dY[FVg<k[DiY`^mK7I8S)a=S?iTirQ%Y8YEb9BW]2K\'_fQp:BStd$T/N90E-L#-7RLh<-T8VAiIQ2f0mat=_bisa+c.p_d'*Pn=1GsC(Cj'%7N%^BpA`)08F<S&=MqF@Vu[J]+';.Q'k`2@FYXaa5:U<`FGLg,48)=F1"V+Zc1H!AL/CBonm`#PBW[K:c3I>!8?lAGnS`hLq&j.d3:Lk`-ARY4q3@_Jf?!L`Ggkq`%bcEZjWtLk7sj%kWhJ"EI2mbT.W-dr:U1s;7$i\$IU;YuZ9KN2fu3DNk;=?%A2Np+o-5<eaLV\+9MCm:'-^`pE3Z\kk-aD0EA7B/Gsj\6(.q$_i7Qq!J*+u1Vmt-2qXhE:giO>Wp-?c!TJJ4\:j\7X$BqTbfHFd@gtg59%br?m&1^$]*jVVeF]Co(W+8Z.gl``_.3,W,l)&sTit##7:*(S8l=f^HEhsZ#gp-%Pi6@ef3"KZYE9R(,**>?c$tnaV:M4e8O9"s!/[I=IeKVpOqs!ZXWh#rucGJ\@2od*#>V$^4`WH$UHX;,&KI#c;>2f&)LfGdSHic,]<'`uPStO`1MEb/HH.[1lORX/T;c.RFdM.l'P1uFV(p1&VB3CH/XJ3La0dRSt`PdlVY-1rXa;@S!R$3OB-FQK&dh7m-E1HbIqF@d;AH#snpmq4Co::^s*OdGV"k.kmgCj@;79ab=^j)nVB4>bgj4Y-L60p:abtDG&g!N+Q4QlHIp9j-H.<;\'C_uUHXj#L?qT;Ir$t"5e*-t3@+2o]lmiZ)^YWC;q%;[Hhd-%jU39;=d)l0DTH%`O!@qYENBDG8j\4pW+8']3M>&&5@2;Gj:Q9E^lm;NX/M0lsd*:YCP,JK7*P_FB3R4epuc!nCcqL2gfV3p([&pA*76t@e\>7oHR?UJfGq=)>O4aQEgk78p=a4/qCF;8EZ?CcjUAQ!b+AG5,"aUAg<lqPX_]WHXR:c&'9"[]*/CoV^/l!@$Q^Y0u+JWs.DALu);L]p+$=<Np.`<K?n@5X+f4VU>)>^578.c9'\Sb:$-&SPb*.YW?X)607,X@W(W0%ijb:3D_s`kFT(.YA8UF"dTDO0=3^lN207)RSTcYD.6[q50./Gq*8Q#-("Y?8eqmo$r?9Uah+[GAiCNNEu:o9]skD3)d\&R?kr%c]B>NGM1Il%gYpf5DS7l&GsUl4G2\.4rJ7oV3n.66+JMa=RG<W_bsH<YJ:K?@YIrcj2JA_"8_Bc(JRo&+tJe[j=1rlMe\NplTI-\ro]&&p&!VMDEIUXo$MPELb)Q;_0Z';DCar<`4*JsD$/8EZT[2qTJ?IO7G?7B+,](SM<.kmIt#H3?:Sf\^!C#G@:<EJDRa5":"?*aYtCe`+JC;#AmS*dGi1<X0GUYJ[L\5(''i6S!?)\D>2K3dW(50N\p_]PSJGp<(f[iNA%c`CE==:M.c)p4W%2)\3pc^N33'8R]$W!3Dd"pTqSPCY$ie+V=gL1W]f(F5W4n!kZA=)GlB?>1\ZDI.KgrbMl9[2f5?T-i%rEhqmBg+:lC$T:@ImaOUQi:MNk#V`U.4IHDW4MH0u*(5pAI.q7I!"^kBIs]T@?9P<<;M-&uJS>A.d;`#uaR%,[E312HUiAE1r4<CVp^TUCOJ@P'mGp60i9q*U[-/Xa6>;7'i'3jsJGafr;D1/T,3BCgrP#_dY0V+^`^^0#m$V2#c"ULkL$Uh-REhG#]RKP"XVXW>]B*18sOIn#=n%h[FM<iBsm8"lJ)H-lB1)PHoIbN`r2`4;Fh9NsI$t:7oOgr5%$9;,h@GE=\-RlgSJ8.#69,*:1X2Bt=6%*<NM,)n$JR<t2W.N3fuV;I-9?L/Lob(gi\.Gue'&ZU+51"#fnEa&HM$#qp=GPc>Z;(-$#G)`f`AmVH$jQ/NZ9.`ETKF0HZWHK-k%3jWah?RP@f1*%*kQoV9A=!0D0V-n$_hq%i9Y@%5MOrR(F~>endstream

+endobj

+% 'R335': class PDFStream 

+335 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2889 >>

+stream

+Gb!;eD3*F0')ipps'ah=FUl$@,YNRmXp*7LBnKaG[-Q^j\@iE[7,(B\;'@64h-]%WP*4p4monT/J/#V8]TbeoT,BiabU<H5Iff50j8e)`iVArCJe7';#U1pRq7kjCq9p^`b\uEWO!=otD\D(d#NGhi#0iMonOGk^_tN=.S@-$Tn8N4'9uf!4F8%&b6*!bnR$REiO'9@RLnDN]"3gdR9_cm1IVQUpG2&`_(nE@[@u%h.TsOBM9PN+npVQD\QqWHQAChXMkf`^=+m7BZVAe=iEA`MYI[rj6<cSTG-K/M^A>,]Y'r3UaF'_g.KuFO?iGeJdkB<*;N=TE?049",NFuo!pG`6LDrq3hTC#"R.n.<1gb$^mN.Y@:".eq5.3W-3k).W"2$_)beO"90XThglfa`Zn5ZBl+j]WE]5WE*Nhs^\XJZ'<M1s@-))j,)fiF]s=1uu'I@)5.UZ4:!6)[M4V1G'!C5a)P#.80($7X$ug+,-B$n+Ror4t0krRWt#6NfUk%T&OQHN2C)<M"W&2>Wi_mf*796cC'YI'7VQ)C;gb3*<KP><OF'UAh)UloLC*`V-)+f4pRfa8sS0")o7J'$s(^3N1./0.pcNKFN*j<)^[=loaPP6Xgl(d?9`M?\#'Xd'kr;EGFCD<FrL,Ip$etZU0&G*U,c7fekqWM#pi%*iGL+J_(0Tq4\IuE'n=72r)@m<9JWKQ#QHY_/F%oOmp+%>R/dUBm59gps8%MqaS3^5K5hQLIN4?Fe%=cP,AoEEXri!)*QIh^'*qn4:V=Jqf0YfAgC_a#ULN=g,eCI]nT8lqdaJdLqBO>\EBM$-pMG_AESui9cB*nQqa^q])YN)llY$R;&I*$6eLB+SA;SAq,rea-_^M]=8O8;?KV?`?%n$rH1,r`0)a2N(GS%)Dh?%.6CWf(;Q:fdCK*T62RcPKa)[X1([@o9ZUKS%j?C"8b]9[(j95%.E!F).,'XJ3+8:eG-&LAJ_HMYHKSDK8ooXa-MHd^#TY)#Lc*pD#sm;p+qCa5amfpKcR<HrV2HS1)*%MhsHjp>2>T-306BO^UM%H/C'X5R?N;iG4N?R:S>/pML=>(8?'cjP/Tq+3Bg+QAafJJoQ&NVV;h6qhKp\D\=$!q4W\hZ^Q0,>q3?0"grh=c]%j(lMND\&aO6M=X19h1p4js/)fr!RAVDk'."V_gGc6"iNe0)!:T8Pj=kuiZf1SKulL\/cOi0&b;itio@(..&@bIDRkBri;8V%U,NA*/37p>^KM34QnVeiI=^@3(6&L$[R;*[!_+EE*_%ePf?XjO#2WlG_i\@)@cg'K09i?MWJpXQUQdgM;"8(%a@ra[6r5>/,;""K-q\uh.74u=l;+]kAF<b4i\M4d3F<<DNl02;l`I,:VJ%^+L'X/KQXDm+=Vc%1nRdup7bUlI^q@U":_-p#paRP(O&XKE84P59$6(K\Nd4hb[I[dd'0Ae7VW+F]3T!I%nWn1(A.>YA=%Ie"58+_H\-Q1"6r\]0lXW`#hX-$\&/KEZ&T\:^f<BuMo&-X8eiEUMQ*<k,@G2H"7uU)d,#%8W0[QSO</SsC<bWt`h_(II>-^2i@/llWgu1uR;Y48e60ku*\D#PZ>G9Zg<K_k\<kQ%*D?A?.V;^"5-Hi9LgOd)_Zq%cFLkH*C[)q+PB[Bi+hkWDZ0]su7dF_X0W^Y&;P)eaZ2S50S`,p-5FVY*gJ#P;o`W'Q[6fD,`!k3%a_=]/CM1!6B'W06#qW&&N17CU\><t#hIoL.kRLTOna,9diDKblPa[+HXJh0Qo.8o]G'H"Z.d-*3HAT]U47_K20eL<Q7-$R5PLm2Rr<[-E[)nmH/%mf$\].lSH1;FTpF&iiaK2c:g@]<k!*FL(8TGMab^ek6Yjt*Ua$ls+"`sa^3<i08am.MeIk):]s_j01Zcm:Je#6PM9D&QEa10/6pbq2LukZ+@VKrikm&arC_PhODPc^LHT&ujUG'OfZp&Mp!:a"T^CR!cSrI+aWom7FQLblrA>&K8&1M43shYGM1*+g8JdH12%:kW4_p[;@tCa.oV`1IW-d88Mk.;'??)p:PMlh?De?0kf!gP4`RL$$JSFE:>i"h74@tc`'-Uka]?rPDB!ePRqDW>BQ>#jU[rj%)JgQPJ]QfBbnp_!`Nk1^spm1k-jB?@fdFq%^qsFEBe8h=?h\[Ep!UoOANN+HHO_RhAF([_PST1eGGXKf.sDonr;uBr2F%0^a,^O3h70VXgkTPNa#db.g#G@XeR?WO&"$C6SA4,DE4<\MoH6jd`nf$)EKip?)34U2B4U-b/lWM"jnq0VZmthC[-B^I5HNDQLrHN9>^5@)ZL1%@`!Q*nK"g_3M"/D3nY1[VnErCB]5oE5EFg/(XUe2)sEpI[\4ge:%Lj+\nkc%Q=VYqj;*MO%jBK\gRlJ&brc5=(VbUJoL"VRfptT?J,Fq_U>QC^aG=AQOteGB>g)QXSs/#c#*\T;>10&!>jh<(ASFdLC8r$u%<L1)"Wm816)AFnY$lp/?^^i@N!pZf\o^Xu48Rcq=!e[%`WF=FE5KF'_E3uJ9B6`S-I6'K1>W^6qaU"Y5^!`u>?T.$_RHl!D[amc[gqUQa,OG6BW%TM/Ua?d=)Ao*23ID^Z*5D//W?i=s4l=Ln5?TBYQjVXh1EZOCXfeXIoYLp2m7d^%ca,sZ;KP>qZs6(D9cm&N*;9$c:iEcb;"dqrVh`qmRB7Nft]_*M2E?O9N39i0LMZt@:cLT3`C,g_#>(*;7rHDY#b(\^>+1FDmUr@\ZT3*UV"GW/NgJa"$LddH2sjmd.$J#R6KhE\Al>`22^W',aajnH'@$jPNgVs[-*'BFaX=b]1"FT3llQ"\o]*6:c]&'iCd*.]5B4FAVr7@2Pm&Y@B;?S<r'e)f;sB-6$W7e0CFW1_>~>endstream

+endobj

+% 'R336': class PDFStream 

+336 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2484 >>

+stream

+Gb!;egN)%.&q*PUrh84=R?8)D]$T/Zas<"2RTq2EVREAQ>>l(>98H/k!C1AkpX9RX'j207gH&odYpf`fFItaFd-tFn?_7-4-31g+i:1k!4<J/oi/Q@pB!:-%p@,mgp[+6LO%8.*//[E7XlgaqH.=\d%#1?<L@rFh3,AJIa7*6Ic6m+h-0:c/#-AfJ0eGJ+?[;`9Dt40G+(4fK1Z=o%r`K-imSf#FDofLnFLQ8bDot2GK4WBI8qt3ulT_OaTLG`b"hPH[.]l-Q@E%83^l?e1C#n.MaZu6Ra/K6=-2tre<,!H*99G*sd-rb+pcO.njDGf1,HYLp6Bt`%SS;Nb;jH4\7BYHKet/d[<Nd=LP%)\-8X%,@_\U,'D-jsE>sIVL'qfLd%8VG&C"NGfDu4f8rOgJfmL6_BleI#9Cs6;^$naE`Q81;d,Rd*mMHtEbF>Wq95jYh+3+0WVW%G4S1<F!f<$!]d@e.`Oj_Z?m9?aIfnCXBEg`VD:k#,^]k8P68-Ue`cB>YoWn/UI'Q+4.nDB\0$/U<2^S-)EeUG^X)-`mthe;^;;T@a;3B%mlY"u<;]12?0s1LmiN8So#u34i)!`]a=(eH^ahK0=RqHL^]i=3mmPfCh%ZqJ:*Pn@[\k-2>YZU\EhF:l-_I#IX*Pf)?+O[<>+mDsAI?2cYH>XGH^ajR,LVS$t83+;2iU10s6d(gLVrPW(AYEP1PbML==R";(`?_lNV5e_0EOl/YCPhjrj\a%jb([<M@od(B"'^tD.GI>&"p#YoWe(C4]s,.R'/4C"&=/!b>$4aoSr#59`W?!MXW@a$@'0a^=7j\,7R4\163Wp'<,:'@W]'DZQ,^:V,^TD$dbh[QBrU;IN;^2"4@G>eY(9#/or:Oi2:E^puQa'mEg0ac'2[9IVgo6Dn&.c=H16n"@BMT9'Sn*+V"<53_:]0F]bpuLH*(&i>8(gkELXf1T82YK0fe'X%tLF9@l,I\M038H)5O)'tL8sioJmM6t<M@br?F!$\]dMKDqUMP28asq>:at6Yg&%TMK,Ropl$,.CL+$o\2.Eudq'ub(Ej]/0dS4CG4V(NrG7YWL.'G7<"qNVm6N2,9)0bM!+;\ecl',aiR[Gl+oCQaBCL?d#[ODscD>HI"oV(eW5Abd1A9\W9BO?9O3)C^)8c+CI3d\p-u/JZ[i,&X%pK"?!O=M!D.3h3l"7;_?,Rk9Qp/kfs8"$:Dr.oMY9qtkZK'*2V4gusJr\ta3YS29Uf$rI^u8!EQ9>obY-_)*P_2dtl8X_(3+DX1Gt_94[YD&GOdh8JiF9fcq0k>4ej-"Ta]:6=V[*7YHI`'d$VQ<%ID:gW4;6k4'G0,V0_DY&</??o1TdZcA;.$b968NPCDpWh-0Y5aeX&K_N.n=/(S'aj9pQ?iHaBRO=Eme2'Q;)^TZ*4,.T:`0a[-&$7l371'TFg%>;FPQUqo0f[F^-r(.`hOhP_)PJ2+t'?7aLJYt!ih&VL)$&21W8=7]jn(#F<OS9o@Y!P-5b)YX/=+q&i$=V&FP[b-uKUagbtA&k'WeC&)1W8%.a-nN4VWGR89E1"\7sQ;W1jcQ-2?k2:juC(AL#3E^GGd?4,;li9m]$)Fh)c,rN)A\`i,#irj^YrJ>18$MZ`@A0FbZ3jX1p)3.NlrMVts4/VG%e3<-b")iQbZ@-MK/Co)rq=$ZWra<Z65"sUB9I;+EO*qcHpgWnEL8uu(<B<\lE+G[+k`FcA-]1%I;p&as;I\NUpm#;eOBS]Thc>'D)kC3,gQI-fFcVD#P25S\EP3e`<t5K.B>pJAf04>kqp37Yfq7[8l1nu%^aZA4!liN@rcJ&qC]>GUJs,\a9$aT5G/bK8P)IeXUOFmXQJ_^TL#W-jeEknCW2/`-V0/$FdpsDX$/\],XQJL/*-FgpU9feK%\m/!7!o&(rHl?;D8$qb'0J"Wp^3!jhWQ@pSY@\G?Gu3#09<G7\t)locTBsXG0_Y`Q^*V8lX=>66#f6I4W[h$bI1f(35c%\*2t+oiKC+e,di([+ta@ZF;Y:71etW$j[K)aql\+m1XWRFBpX0(HIL$(*P9`*'cL>$KQt[l`]B;Vlh43tLl95rmq1u]I<QGjiO[8u<,9/8;JV#g<FMj&GF+F5dSTZB`bA_nOiJeSYXgKuTb>b.f-8H[P('7sguN2%[*S5`JV]F:T^g7X^4C(=%ZcB-P)JC?lQbAte7HRn8:-2n]j4"1>fPk*+pRiaXA"F8[a.%;:*^Z]8<g6of&UC8DVd.I]LRu9B5fDE"ESAK>rR#gm^'?/YO0IAj]HY<fS>/7eC(*]]u+m1;h:c:fT>c?<d3Z%MT27Bs.#7"br<Yu9H)s^PIsX7;9_g+%74&@^<gHj\1@%E&tlr(W49c`DR_EJ]-i\qSFmW/6lhL%2%HW=BoK3/Gd%L0&R;(e0q!4$7,o^]>D!NY;8Ij`47j<U\84`_S!q;D:s*nV*Cs[n80bd7:^^.K?=sXuo6Vi[iSfE=!4#`7o)~>endstream

+endobj

+% 'R337': class PDFStream 

+337 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2589 >>

+stream

+Gb"/)?$"c/&q/)"rW=KCC<&f^%uF3]PhS$3k9dZPXZgjlFp9-6#qZH;!%:A9p"]dBMNSs;;XGa$\RWZ)OT_o@O)rTu$-3[,!r"W*#l2f*4F\*-+=+8s$"=g:fk^0Gm-0^XmPh'd+2oK6Bek8p44aRT))TrY15pg(6uJS[JQ^_T!XdNl3Z4""XJinN)RsNK8%@p4rTGOF"N_Hjp*Z8VktLlorP!&2r3UB>'#mF8lI[iHg<`uKMPdcHJ+1J93_6ntB\,C`oZ]$j1U:J*:)L798lm@iSBF!;^UJ?QrfQXH`NOaN>hBeC,\88pKb\PqBqi-M`dKkf/)s4LgF'h%#/P^L`D?L)G>Fi%'#mk=9HZQP"J3C>"UV(?)T:A\3Ou`UWEUm"jHJ`&d[#DfadV<+3-7HVQ-Wf+c&_siR8tN,WKNQ?9>TZ\)^Q;0=_VK%P4aWSOTG:&?1MUd@R"q/.\1U$6)%e7cPuF:=L#qmC5#oU<,%`6<&2@0<]SXqVKA-_B2eA#/4A2[GgM:.;:7Ukn[1o5ru=S(`sN/ThuEJpl^,OhV2OB.b4?&S1?0[95LRD-X',98cUb#<KMOr<K_K$/EV0Hh'NK$>RIg.BF1caB0956U][Oh#*KK.LA?tA-pc#"j2"A9s;_.t4N3MhGf,Y0W.(S?cW"TR]9uk;5lU:%3O#n+I6Q5V(h@![l,bu$j/Bt5S)tN"U%u)V8f2rCA@^$1Ve>=#:DQj>(gRTi$6chufl%Xuq@TGb0>s0+3jH=;5aai<K$K5aTn9R&>!AgP$C+V23%9uZ<dV5asU%2IEi9I2.)_=aOQBE=*@#ZhCXiZNd9O!W[3R_:2?p\H+\abO4\qWqj7I<_2lk2g,E)rR2dUhXNM"c)Dg?6h`^#rJ6=^a$=.Fhl;qso(XNM!C\rg..FXkMGVGm-\,pC-5q\:$g;<W>HZ7P6ni-'365,Ru":9Z`[A,L7\+(aM?T%lTaoRJ\R$!a1C+^`h/f>Z*ni\P+#.Z[)MSa^%G"Y2*SXRAMP!><jjMjDUE=^\X%+d[V1GbW?(X9_JdjImh?90kg>uWM/Hu>A6ZrC]d+H:eNDX*qH!uR]rjs]0.\d;<ne?-+EljCRF@4E;daa:`te:LdE4,'\oijFoiXR+F$ZNq1GWOHP9M&mZad7bUCTq:aQ\,o:.5,AS\etW.-s4FQ$oIWPdn`OKMhG/Q`K2Nf[EGI$\#E88hNoiG]qVBoW/:>$dF/"dJ.BLf7S?#b@=_8.SN8;HZiFH1#Y.>LMC$ZXQ,b@X""f9QN/Lf=LpLE1>9:),?1_iD%\2d5eo#Y]"g2<cojq\Ujefj.2kNfFMfR5XY(LkFn>!TMSlI"ZWL4U0V5Z$,G58oG.k\\;'0L"f\[/'$6TkhO]RfpfI\^N$,Z/"lBn/0$%WL@C*c<(Jr<!BB+kf+E8[p(Ua[_!th5,5r*'*<`_Nj/*YKj:bYa*irQHh#N,AW2iX&@:'HCnYe;-"iGccI^e)ha7*<(/60`_=")CbUTS[Ecg_C9&7HF2id3eg(a!Sk6c/2O<#eQ?mj_A:ui:;%]r<!H/3?f.Y-GZr_d\?#KYQHpnX/nq`?ib!BIAp'*4Ymj]X+5FZ,>A/U<[(gXY%(_-kjf9rI,pF!Kre6bo$%>h^oSO)1[N<cqH?;W&&\&dhn![oJ[d][mEXK4)!VC#16MG/9V"ie@-,DM6"kr`'7DLe^"jdo_7G6O2X_Op1tgDD`6bsbYMl5V(*:I.H_#\M(VU*HE]Y+fe@]HMI:.Fc;M9140bRctpQ/1P]8aKf@qQ.)=9gNt*tKs+m4[4hn`4\J4A=FRNX\.]/-dj5&[;OiTaW'=+o2+UK]"/Pnjt8c)BDJ5O4qiH@7%l)e'3D_F>U_`D?f>IED"m6%U.@%OXd1n"/4d2)j!XFD`96]q-ga8900udSYoo4IWKO]KSndY,cU]%AhG.e@e'T^J@[G"7^R;A@\GehTMhpbG7]"O@'J.R_!D7F)_Q^,>A56$jP(E.\]dHm!Y4jG:=_P8l@brD-_J&*s7\/P-C8cSeW29L]"W:833'_<K$iT_`VN;cZ(Mu&c5`6s!g0M!68)&fF9ljVh#%bUjdh$niA<_ah474;+XM'Z;K@+.o7n\N(E\5(Mp<rJX9I_8i@l>=5_XEI_!TY/S_u?e%nG"pVmqLlrnq&D&*'G=p&E89+O&`X^BhaIj!Ld3l?Bq2J(LC!/&Z32_/fk^Zs[og=-1iJ[,;c%aS&T8lSITJ<uq@7%<Nik].c5@;X3jsiI,]o3#k,"(d*N<8)u]NO.6N/fi]pg\/?R@'4)fQ9DB)Fhn?_gD/g+7kIoFD^u>.gE'EW=BV'7?W`-M,mPs;&rL"+d>V;6nTFfi+RqEien2*5EiQm>Akt6hWPlm+785Y2X\XPT\l!Kd%qu_pGIg?OE6h!6l4bg1ZZneU1qcED]$M7iIIbAP4;0`06mZk%A#Wt)^D5[0dO0`&gWO]R&3B*gVC3SEp&>!%1go+hZm*=t`]\77i4&&m"=4s3)Ujf6un!qZ^#Ino+%[-2%[fYbT'24kXL8RXU&8HD]/F\-/i#A`kU@<)ZK8\]-#jqqBk5L@E+*$K6#C61,+7/VE%0~>endstream

+endobj

+% 'R338': class PDFStream 

+338 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2437 >>

+stream

+Gb!;d?$"c1'n+D%rkk9hGrlcm;W$l*@lkW*f1@ku]'V>&J4N5J/kI_s.'NL5HS7oVPU/DUf%Eg<*a9hFMu.M^\H`P9Ma)di)l3P<B5mAfJ09Nu!eNW%_sAb\RD""<`Vg"kj+BOK+WCl0c-Gt^3^J1RNOleG*5MNr(MM>`&MUjU@cQDIAngoQpRke^Cd?`uh2bmZ=YTgUB"u4L0@#9Dh=$^,_p8iV)MS-n\CC#C]Chl&on6T?q`fDeluOj!3S2?UB*e.tdrYe8!IUIEYR4j%aL0A;efqF)\:pU1Kt%'cV.$>,[mE<AR0RHBXhWntXS>u7\20J=#IOOQ7>9mOL,+l@/P\jShQ>b4HP2XV#6P;,!u\?b)_cN][7\Cm[2Y.;cfN`/r*G;hN!.3Y:IL(*j&W2(^tn+e5\<kk`!Ao$f1s6H1W]b%T$AWG$s[Pg[4nK)!fY3Zdd6Q9E/QS?r#W(I)`:?jk90/!gZP=rTn'j]0L+7MK+f2OfGf:S)0,&gA+?D2QjHQN1kZUfON:\0KX!:$!+eg]M3ShgFED9kDZk]r!9kA)I`,X&&ir1]km*ufV.59Fm^V$;ZJH\aJpCd5qY'lcT<@//qcSOilo)AB*3;\PTt,$b$*cf\n0[H@SMa(S6\*'H._$]B]Xb?\NWm!nD/f1,'8,%S#ru6Diu(T$1>H-Yd.;J(P#6$]]99&^)senADiJri(5,FNBoN&&%55%i.iC^qH>r]=emPHDM`_:E'EESa.=3WF&2VYpfr8I/pO5>s4,I4FlkWjn_s1"2rKJC6`jPYKVUB?il?mF8@"3+u-QU5/rI?'O4]c?FJ5m38p\3Ou_p,lC8hGGjnI3qF<tX,sr<uK,kp86agPMEjC8?R)Lj?7tV)a$5Y\NTP)CnOL_No?Yfol#K'*D++N18=$X69.&\]0c-2r6KM2@u=;M"V[]@GBa%',3```oe:R%6m%I`.i6bMr\3u<J0#JJD;p&XnU2K+\@bD6J3]V&6W^I/6A\&aC.lUZ/UO$fTm(C]5\mR>!F:`=o2M2#:t,2)$8A0oS;Js*nUQoo93%.p)tB9I)f:?hsK)\K55?b>cB8!,crf,eo(3$'@pqn.Z\^b0O[8:mX-DK^!aY]e8Q-q+'/WJZ$M=9e<rS/@6<F(4Fr3*_p4gGWi<tq:@RV!,nk9)e[o<kVli/8i)O:+0g]%r1V&SZ8!pK*;Rk#N9Jo9b/N0G$H(NsSN^,;;Nt=t;q8/F"SEd<lS46e?%A#V;m+U<=Qh.7@R!QY))h-gUgLgP-N^s:1G^BFEPMc_u:AhU8dBML<Cp/4?YDDk5UZ.`G*pOeJDc`B070OD6$b$Zc99l9D-e'E`L&eR>3kctDC6A"CG4UAW,js9A&42GD#*E2#\j!fsH@VgtF1t%qXX-IeqJggOe8f\[G6qF**"79>8<]Z:YYCT906mj'A]bWgjZNB6fT&6)NE.6HULN8pAjPcX4C@:lVa.S,-u/2]K%7qEBVu/6+JR'0*$@`-a0QGIjMALV$b3]#'WE0h5*js)U36AP=0o"%j-B9@o):1tbk209C2._\ERi\l`l!I>UAs@"Q^P*@M``ZZ[B0f=WIXP1jf>NA>,p9[Nb!]rgV]lZP=UU:l*BnfnVWQGJ?Wm020k=,b,QoQSXRmMdDure,Xd-Lp%t"&"[3Za-7n:d,Y=,;>pn/k8<mm)d9!80WJ(6?C"3/Q:MS/BF2p(62CF?`MLSo[@c_Q8CG2;Vhh2Gue?k'L*2td8;Nj@bnm]WlonP%[.2h.ZG4ntmMmYXL[8_e'me,FReV%9:M]t`sm(%aAh3nW9l8,!c7't*9U6_9pe81u7+maY82\02e*M",qh\f\U;7S[g0&c"iQpDln`m)a;N4U7=4J&'lO`0:mB;Aoj3,KY+Uh?-pH\?+5pC;>>RNN^n?0OuXSiQrBJ^6!8(]4=lYcuLeY95rDRQHd(%j@-E&Li]5PcJh.eM32PDP-W"hs&X/$]Z9\f-oFU_NE:'[GH`AV0q^kO"XjNaH[nfG4Bl4_C$b['U;I\9a6SM#u&+eCTIapinHkOeN>X*>j4aiC<[W'=^RnuH>SMcn6l+fk3Dp$?"_H>Vmf<U_N7CZ?l*N;hnE0\?N8h3W=ks*G,EDm:m`>Y;2($D!;8a/Y=uc^*Y"miJql"Z0X4)9miC6\L8VZfl6tH''[_fn]F:u.i2$.ga".)^rq4N#bMJstW:dR81GQS[XnfNo[Iua;r]cCk)>\YZbrb0#dnCSddm@6C4a9KPeFP=k<,/M2N'Or*LfC)5*G""*A]8k/c+oB2P^?N)m9Q6m9g+Z:796%OW"N-".`"DhmtL70hXOGh_WKs%6<T)XQU2]E=SEQl?]ep<9lu\rXd=kt%ip!+*jQ=dalY=k\,-eh-O*"$2s$Nj<KZjR'5PO9f'Ead+aP2dR&&IH`%Q2[amsYcHjUn`o#:V//c8$I~>endstream

+endobj

+% 'R339': class PDFStream 

+339 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2629 >>

+stream

+Gb!;f>BAOW(4OS'rkj#G3tfCl`I1[$X*#@CDPXYq=nMeB+UJTr+Xel;pNlmt'P1QDC?/ZII$7-R39U1a'n?c4Id-.,*s$a/_hXoq\cLh?kSCF2r!BOHn)&Ophtm1hgB,88Y)Qr"Y3XH`bA5&H9\lp]q>MDK[<b.eGg.O_a+eT@rYOaZZb")@dq\.uRmBR=/n"SfN.4_Lr3!cKQQL[+.ZnLK-]+Yd(!"rAa!CusJNH?-hN5&tJBK3q(,>PtcBD?M&U%AVa(k_4+ea%>k^!=BYLk)o)=T$`=iB=4O;17"I/a!,$@(omMgth^4JT1N)1Q07co?Q7Kf!ECb\7hDBuXPLA;>;_8`su93Op8O1W>[aq^.">@22>(Eb6:lc-_5mc=5`-^RAZsB[:(3!4<_IScl5`m,3lK7!Do_R$;>M7E%ArIX_;L#2LQ%BnJc(]8n.*i98+AT?8Z-N:o5$;ds[[NlK.<RUis^9p1eg4<Pr;,bFidAMdabo!0N=:FZ*(%*e?kST:*i`&TSAdYQ[Wru7N6>8lPj$stDP/!7/O=M/IuR9Zh#;i0%ULun4R+;MZk;4e37Upsd!8/@W>6l-9@\lYj$GB:>I3FPjp/&sgufr#$17FqVDT;M6(A<9KI4<!^6VVH$VnQ^OW]=K%-Q9l_d!Zj@%XA+m49U=s-\r4XL"L9R^\;=WP7.$rc^5S]6-H&U+dce/;UqQnj$H,fX1JG)CUqgQp#Djs#Zq1Mk#AhOm$u$5&"mY7'SG@4Db!HXgoD*JKeLFeC-e3j_nYgZNB0<*NI?rrNT7f@uBTn?1&uBluj-bMeKoOkEV*#3Hr,1d1&F5h5BAKjEZY'd!Tq[D/[c]L@mFS<4a">P#[aDa+b'1U+eVC+"Y;[\F9\o#;D)?IE2lu]p"ll91Nb>fJg32>WPM_2WMP[07b1^&sDOGFqc)[?hVDB'm;G>M"<]")9]3ld/LN:U1!:AVu[H<&"8U9k^k\W-*3dId/,N<uTej11;4c'"hTK1hl=&[,E?CpfMhbA]&A(,QqDNSgRh0l?$W4]=;Gt)jd2=h94SPPk1mfBJko/N0"Bl>p;NNUQ`K^6@(ihLbs\oH;+Jj8qZ=gr6W3<qY/Ftm71=SE1XLU)_k,L*6&T%pEuOPRV5=Dp6Z$Qlu4\KjR1m$\]h>_YL*<1Qu$-8U[=EB32!ja#7="^LiE,Kj+!,lo786*siIn@Uf`f#qk?#@LY$,[Ila1;d)"Uu1YOcfaSJn2&'ne`K&eL>2,Zo4Z[&L=M;Uk:XlQ@Pij^nIT_*>QK8K4B._5jRG0.1h.(EH0r1".&f#r&m`9Uf2[*E;fllak5p#`D2pe&TVP<#_]J]"`&e&&K-9)M9(\0EGQ38.[0jP>T-ooLOp<OCo`CG6aU7^R]bq<o>]7/TF)s&4rPn[$jh,7Wb*sGl[&kJ.GDTrs>p,-C0J29dod>a55s4VW;JN7W<oA9A;B`P'=0hk;LYJLd_KtIedF;Pe9atAcc@'T#rH)9Pj#(->27*?f9NiA!D\Is;VAX`:e;:4FgIu?MF3[D=f+>QOOO*'7`MIa!q,KXOM6i783QsHDChG'+%?lhB\nH2JSLoUR$m]JX6TR-qN7ro]D@sd79)+6"Wqn9'@BX#JmW;C6p#BTVGKEhEXCoOuB4,fTL8DY4[b53G6*[$a"u1s;mdCH!gu!oC]a@g%'"NO4FO+iqR`'M?\(0W2Bf'b6?<ufmb1m=5Q(.^tbEtha=DcfW81SB8p-RaljJ/2fXF+K!oikqM%+"bLn'ok)Jq^=nMqM0UnU\R5/^G]&FSG'ho(N5>:nZEL"XXWCGb@$=$ae^VoTP*L5>i-a.K*UkINAeJeR$\ljsOu82kOUYO5HreY#`"]4'LrO<5iNj@c>Y`Y'MfF9c;4*7Mm<\bL*kZUO+lU<c_=e?Uil6je[O=URe<tl5dmVcRiBd`i*&s_PbD_[`LrX14eL1:SC<;D\k*;0uJU>fJ-WT!d&K[!i*5snHY"&4>%%10Yb=bfn,aM>=QAQE]W:=Y![$]h22c@@?J9N3'Q\r"%EI#dAlC"j!Dh[p)bkPj=>*MLA%1Ck3"'`XC!T)*%O^+@n%%3p8"WjqH*NgL";6?,!`geD=6&fkF?'*-Qd+ALr,'\r'<LWL2:CWg]_M?>F^u2KiJ3Hm-$)2*BVmoN;ee(/jZ>a[R-%qfS_Q`KpU?X7.jMfJ66,H2"0!XGAksFb8M.,.[%#+H2;5)0<NTk[u@kV%-eZF&rV7.>&aqYZ+2u4WI!J>SPA%.a#mNnE6%N\P'qsU\LGHaT!+SUCDnSRjuMGJJR`g+[sKMr@O<O^P2[`m,inB[18;8Y!7M:+;7XD`Csf1F7qHK/\Zh/$)&9]N<6\9?'"+i#6dpL2i;!W%-;q-PL;ng"$a+tU3M@()CH5Hr-j#)6doDNd1A6.4ZbhYoV6@(O^>?B80;JD1(U!f%?%)--?SaA?bj^+hfF7H@!mCNXeu:gAqg%=+FF`Eu8hZ6!VXp'LVhR)DDNLH3<-<rG=K1]K6C)fC=jr="1g:^M@/>\;KO-89('VRX&T+7eSRANX+rn3_,#j9$7<fV@.15QAX?ZNB:G/*2mX"%*#mYH>b9$Sn()W=?T[C_N:$FL"c]je[@^nCp$+tc^?]l29.K~>endstream

+endobj

+% 'R340': class PDFStream 

+340 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3172 >>

+stream

+Gb!;fD/\/g')l41s+0C#Et=,YP3po4qijgDh;I"agUIEEc(^jW.d!lbW?gTDpZla0-qa&7/@F`9M[#09Qf7G%[qCHh=WdY=oRFAYm,ohpl-a3n^nrjXLYe+e?aEh_kKglhO'b(7)R:LT`Zo_@mCLW(I<WpTpBQ.$@e\3@J^irkhh,]SDfRUBdma'[XF[F4]b)mOVgmulon*092Z8h6s%+^<7R(88LYk!I)Z-ER0)15t^=OG9:F;9r9)3mRHoe]NSTp?<WE8#BCha0SHL..TK];h?*S2#g3U)a[G+]lR\@$m]n"'5*@(d+E)%%],Gp4"J2;H8(ea2GMlOU0PQqYDnL]la3$*K:u*m4,8Ks]GV`m]aW3W%<N.TT\eefXM9foDDeeF7_Y3QXU*7-(T<ALTEV_6a?5=\PG4X(I[\R?g=pCJs=%?i:rCi!'<*0aYT1r(^q&6]o6h;Gt`h%V\EaOaj(U7e'%/^3S.'HH0>A%<lLSf$\M[Qg.iE;7[BN<k/WaP,qcZ6(Z3bB';+^U5kTn_Dqs\1W>Za7)m(pNJ.uo.TpJ@G0t=R'A,4ho)tkP<PA+_3U@gpT<9=XD#57XNpj7IkT-!*kOUR$&*jO155=QFkNcWr@okD?Lis)D0Bt^J--a2.j"NNbGUJR,C]EN9HTjk,Wf?J\dC](l@o<dogPmo:K[p.<q/A-$F2#"(l7=@i+:'*GO[O/*=MP^3Np#t!,jgf^BJMX0*^;D2V1T@66:)Sen6&3S>QIZTac>C4/0KR12UGTC2Qk["#0B9ejA]`[8BE.`]BqoH96Ca5V$?Nc,?[tYDdTr.HQ4$J)F$"4=NUp8(q_CL5m2"2?!L_<<oUrO1]f3QOde?lB.QIah7ftLdN5>pe/>3rTKaSt?$HN=fp5ZTd"6r:3TWSL_XiokeEN%^+5'PO+'HGs3MW\Fp3Okn!\1TdpN)aQZkRe@b%0Qngc[18H`&"4MYhInTedbh<EJKc)kK@tSjVn8$'@Q;\Wb`4iM<d(SP$F-!-M=.1'W>,Ul!I,E&V8/jbO0>>8epA,3?-6.s@chXLsAb*3M=sI_$LYW-Xf6cYe41r9!k8e`X7Ldqa9*!G)d)YIqC:V<bVFYAe!9S.u6r&([;RpDm(8_$AW-hQcG6:D"M+^!2@F5lrrcTK>Cq1h6t#M'C)-I[V.+A;,<(VE+[TP&kPBaM]&cimB9,HJrm?"32Vj\q0sQ&?2C684I4!``doi+H1[AZGYnN%CIQHc)BF3fcNC8e(DQo!fpV"p&$jC1n4sa;1\1+M->!'m0M+"=1^2]iCS!e^\XX>d:#N:nWu&5i3&%>b5O)boU2OH*NJfe(j@T%K>'9hEi@\lTR,i<#\*IWenMT\<@sVpH'&s/WZ(Qpm+mrIV@MGeH\*3XVp9)n@Y$J2JtR/sb#jBp4ePGJ,d0gp4-nL,J_h7O\h8HaiQ8\ufffu!``rg7cnh&4)f'O3PsR+#`"L4dN2^s.Dc&\N"dM6QeZjNL*VtE'Fmq8o=:?S[p_lKDFl,pY>r!4)64\kp?ZKhkJIA-%[X1&pDaSs]Th&B_IKQD^j4\[nmIBT<s8MClVW<6CF_Td-7%=5k!4)6M`thRP9ECeC:dIla\A8L0#36+_@%JTpNk:Q5i5gpKOsIZkm>JqkI*s/AdT1A%pc[kdA%f\YVlTKBO+Vee2Kd`TYX%8o:*'b=A1#Y^<G#on25@^Gg2QZf]P*'u9?@M70GK@?)=^3BW=,:5eH7'_VKlTf?QM)(DjbPoMG687`86q$QJ_1e"P-k99le@m6;b&r&%bQD&"CD>hdIM/;/O%.RI*o@IsM#EA\mlc)[=M._gTb#$Po8Lk:r!lh6hpl4ROP5b@Bc`%aRYV)^W3466#3.W#MZbA/UPD7d!2#,Rb]j1u5=cB4(\9Kt4E3YA<adp.?sDetr:>QgD_347@_F'e0oZP)'#$T&&ZR%"*2h7;G?)Poj&P]BP@cpN(K77aOW&fYKL.Z*<n;qgC62or"*)r>MS4pJMA,nm6E`P1c/2%V`s]C>]tZO<')+:$B$(p4LYeo)G*32ekpB\nRi`#jq.I`!uDG^f"'WC;A:5H]_spTF"paLC_Q4)8\Ip+G&Qm8`R_jZ?Q_U]4?p@6"1Y9L"M"ZE>;Q;Z+njh@fj]+SP#.s7'!",@>9o%?=hf+.C2?.hH:pVGTAi6?uka9i.n4#8GsL)Nhnn/b)qWP?j[2Xes`Er$aTKRlb:`elP8d]8sh1GdMVl26:?pE[E0*gr$n)CDk7q2Oa*UGahV\6D!Yd8?*gUoYJ[shN]S6!54uPk9jM&3Q6u0[`,&Il79?%Z%Ei7]7US7/0=E!BF-`5>fa1PT\YJn4c\;OOe@Br'VNb5,5#7e)ERp@lELTqci<MgS(8QAbjD%)?[&!%@/i*ZY(n-]=dG&8_Con!P\9SXt0)Q_"B<2g9e+r?8I3&UkcSt=6Lb@F[6I/Yd;8#2MgXerFEptdWBa6c:+aZDhG\>d<DPjU!*"fF?BE4f^MP1ti-]&dt39-c$+<)os,eG_S?^]Xd0I?m3ZdlFfAO^4cZLH.?7f<5jbIQ1\%KKGr>-6/+`J(&X5N#H$bATTL4qhXt72Y*/aa.8nksURm)V,`4F`<tgn!jkW_)IV-5mR-uk>\iMhf@*4GRU>Al(]=[45]aFX92FumK'ak/"Au`.A"jsW4a]4hC]On[-\oiNa+Q@R^H#P3]GN)oDeZD%eO_n,)?-AA0T9U>mOgToGnd3a2-_rBe[Vm\f;\T?^@"Z+p8BI?VHTnd3@*d%N]nH551d+5UF>gKHMnjbAZ0PN)K1:W5PD[pq;$M44n0!7A=Y'E%&)e[)ZK=+(5]_`$E=O8d<k"6EPO<XoTT=DeT2,=3.V=IA%=h&DBi4?qHuDfk.PUqqBJcNpXXo.n6!qU'ho^_aA;MD[6W<`i9`N"B=I?;IuOErihF!=,$J$c#FOTf:6O`-6O%tE8mFKlqCmp);[kle[<Yi`aa+kD0b?\[gGD#]K+ZC_/K"3M5Fq@>l4i\P-CmSSB'b'roP1%3<N50-qSN\SAhRD9$6VIG06A1XaTB-qGopPcdO]]]g<'^E(D?V76@N(c4ogU<kDN8!F`SG)V/<BfJjT61:9+ETpI0Lmh'B4'2Hs>^]E_5EAt?]6^/#"jb[);.7X&e/*V&UDL$I4R;i+,q@W1.c_(.HMQUR"~>endstream

+endobj

+% 'R341': class PDFStream 

+341 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2734 >>

+stream

+Gb!#]CMt0$')`jos+/7X.YYR`l=m#cSChNXjOIAKm0*n4e1N&Pfd2n0=,Qk?mhp/VX-Zi.EA%A4[Oa(e_`;@Ac;662j"#:;PFSnE,PL,>bi0*O9j$2/H>N5>h2Iphq<G]SlLB=aFZRpSO#7mFa6YnummY-;2t$=ko'$fiXe1Co]Jkd%#(8DPX$<iom5g4&Zu+QG'iW]K`6[-#0/i[[\a[6.rYf,@^?s<%mRG6CFND#f15b*:]M#XdN6g\?MHS1NKi[np_@roG/E+,f\G:hQFMXb.QE*ED0sM:IfpOIj1R;fdpF]pSAkH9>b5#9YQLWDgM,$ZaL8BK-I=-YpZY[jL08AR7X;EIoN/^73<pSFlIhCp$7`L*Q$98l9F<Hg;E?''*%uK<q06^khkT(K2CU&tX?o"?e+rACB/%%/!h<3N).n$,09)^CZ="0VQL"Hd)bh/F%#d"gF;tu?69V`:M7>J3;4*3%&KM3E'(U(GZo+nDB>,K]+([7)!,'r@$MEV6N`iWG9\&FMh)ZV34%^T'0U<$@<E\J-a2=?$Pi3n;Mp;SaVrA!Vn*S!&=;.El`D91Za0buRZ&<6a`%Rg^5@'?q@^g3))cIeg]^AfmeieQtLXMu$9VcCeH!c&2G$20u.3[8GS]t;kOoA']3Il!WN%Eeq!F-ejUXIY,AfD+p8pdK!Uj-E8%Ql_&^N<[glgdn[Po@=l/RD=EYIgmEakp<b\]%1j32NdK0k<%7^?-S'`+dqBi,M22*DH>bVW##VE585lkl"E$Q_p3JWS/pM!mAPA*PBdIl<JB'K;$^KEQ"66&o0O:alc_^R(<?sLH"`$6TF6=@Be2n'Qst#`VEOS.%X91qi6G507sZ,N=U=\a=^+<lX3ke7/6pJ*kGTn`1i+ME'YVKS$HGlXkJ8S`r%fg@<DRTuirLVEi%gq!SfCp,#p=Y?PBaGG;iipO`mh0Uoh'o_-n7SH>;u,2%h&1dD/B[2U>GHg?GMt<<LGS+dS#.-_JdSKJkN`SbjjKWpGu1G0_sb-h<te*0(o[(Fu6iOH3t+UMd`.V'qmNa?kBSe,1gdu=EJ>$JLDW/CO6U%3r`"O18;L8cGX!gbNO(X/'_JsP0"8"U)G.)9'$XYHi]092@s=e+hj8JE;q[W%q*M8`)@<rOWq_5T&N%RS$H^TkZesG+&S1ulamC_k(TC*B0Dh"]o0Tlo%u'UK.$pGUlp"kIh+2YrU(!k4pEYMiT`jcAXVHf)0+j!h+N@.6A[A*bkO.2Pp0UC7%m$2c<V?1_DtBp<>JF`%@%WmLo74om))`(<](aEe#>kEHS79l=d8,tY*C6!.3\=[2%#pII9(XS>:[k&'*kZS3>LZJfU@R[3?_f=SXi$A:Aj,Rdr0S@PZHrTS`.\LjBImN2,'68":Rr6j_L<?,#`3M7Rk(aLN[eYP_o(S"Z1iN229DIj!3;!?9G;'5)L6i.h0ej'JM`%$ZW?g]`%68kI9't./`oA%,PbMJsqcq\"1Vil/4FcLs'ir;WVt/%$ck+L:cMSGu]);Yu'(Yf-f[p=l/VLiGLhF3iFK>>G2[8P1+<@>_iSd7*08a8a5=S9ar:&F:PQb3FB=m"#C)PNspf@jMcRXR7UU_p]IZ?c^o%ST:5bo`uZ^ITm'r],E7t!AP0I;l_V`\LXP>m_(7^i)bl;9<>nq%e*o3!Jk\KNisY%1R8*$7'%RU[AN?2&Pee[Q>H(N2OD.:7T8^+**u+m"0c9O&J/L"JrjYZQqN"53mbQ1UdF<elHiI]uK,jV\-kY@c`B+[DC+s,+82"t/([kV#d`!;S?$</4kfEt;)=N$Q6JJfgUV6=31_uH&d[g7&$=&;En^)C_5>pAab%`erduoaX#.(GlkIPb&hO$^PKU3Q'^h:6c@C.!>DpR]qS#s)`g^#5bY:*RmV(06RIq$a[Ao#ftKm]fS]&((S$+aV'A]>ZHX*guL/'Fab6GmYhr"_T2n\e=NE6_r1PKKHsEp)uu!a-o_4k[CUgFmTa>nNrk>T.?Dd=4?n);Y49o>g(We,-2TJ)62LI(K1IArdM'Q[#0;g2V5e*c.QI70622K$m*>;PO)APKQ9r=%C:f26>AmeFsD8[Tq6#7";9uHSe(ZjmWL@kj#oh2q=ol.&(dS@,*\90L/t.Ko8J:['Ns+F*9&H;@V4h(Gs2GX&68\$Z1r!(@Jc_B1i]Q4tl+\Nb/]1P?XK\],$74HLJK/NIE\XeC##5-fVrkUZc2Qn>X.A$.TDikOa)d0F3/Sq!,3N$5fq=3cgG-\<81_e!i_L?[H4[$KM0K%aFZ(eL%4qqD<j>@>W>ifRCP_#uq+D_(c)g*C`??7KlkJ>2%"`>Fh9>\]"j&pF=*KB_::tE"!Y'S;*A5<^LR`U/LdM7U*IoF@guC3Ds12j+Mu'I>742-1h0_"D#Z_b5u92Zl^,BGf39Vqg-b\H9YX2=Q/r'ka]`1/_/!ODlr%YZ>FH;G93R)"_ZpGAW+jhr8?uDeul[+q`=(=p<#sJBn"Cu@G!E)4-AFOcF=GeBf=<(9'A_nL/7[Wl>EE_B"m`?L3oET>mk8)n%lE_g1o_LDk>9U#5oZSY$sE`-ZmCdZN^AB!*c1oLoC/ljd=O7?9Tnr*kNlrbF2&QjC!Y2B=l"pb/kd1Tid9<,(H*[mK1J5X3"3V5WQ"PQX$H:B1Fa:BtBa<T?b;3'`Zt=+Ht1Im:l+5Qb&6l//A^D.T(8'XXqKUn@=Q$[kP??c6_q%JFR%A?r*Em&#RYZ]D~>endstream

+endobj

+% 'R342': class PDFStream 

+342 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2699 >>

+stream

+Gb!Sn>BAOW(4OS'rkj#'3tff-8?)LI`1(&AnMIB/mW:@8J4[gK9bIe!g<m\(3T*?%9i8.HaY`<o&d^Mt%R-E+LBBVGiu^ek)l3OQ<cIo\!QToE)B@Z*@J(]@\U+5>PQ'mti\MZ]f*Z.MVUt7Oe7mX<d.SH'#5><.iN0/7@prSTc%?n8deYJs6*#akN0^mETDSmg>k^<^r<]On[0j\4^Rpr*^HC!oF;>WD322UHfeYj[cNf_UCb&bDQ!/_r%r8l67`hfFTbUaM[<sd)?XL?OiEO..E\@FF3PQ4>#E`m;T(8sjKoh`!_-G11di0CVnuujLN>A<uX4G+IPE/HUC?8!miVfOB)/oQGC:W&:*Z1FZ7#A]4'8U1bnYfjI$&:juSK"O8\/3*g^T2rt1!=(lR%D,pk(Pg7JUQm0^EMNm%>V8@cD??US6qUAn0StA%0q1!F,eqp';co7.a#^fO$R<\6u:9'+T2#*3GO"VH2fhc7]6nW.8pS58`gEn;d1<"[>;1;::/t+M7c?"e#$1c,smDN1dPAl0Zc`qa,-`,V$^HnJR%O0V^d_J;"%pmVVE//cT`0fs3>R:s8DQ>qf=/#f-$k5b,#;i/b9\-/4.DY/[,>P'(HXnYnp40@7iQ*9B.f0eUG1VVKqks3b=P?0h50cA2\;")o]2cQmQcX(*M2$,\Y(r)mO6HA#,l3`4#Ml[)1O77<VTIBSlGS_H(1[-UHd0<boK8Gtq'#SB%DM=m0)]UY4MsCd2#1B7&6N"0YJo\55-AHeM2?JBfbA^iQe<Q6B^UA\(<s^(uPRG/cV4\MJ#@,iB-d_&,-#Cs+X)T18#)&OCp]cOY8tb+,63OEi*54BR=uFLt94k_2<^`pFm%1GjVE7g$PF4]AA^8<:^/*Q4--8R#';R?AF*:hpd"%\dVi3k\pGKGu@Mo(*jrB9^71*H;IAa\??J.Ha\2^;WOQe#'e!7AM.UbM&cS=s!+)JYUbnG))Hg793tWR^/Xrf,V]:3Kq<YhB-l]#5[gaht]f#28=;rm(+)#&Zp4]Dh)-Z2VWm;c3>Jm3tN\p3+dMX6K]k6f(HH$-Kf+gPLrQ+cWbcc7FA*U(6tS2[/A]$,!GsqAcqIM[eF$OccRfm^e1!"L&/.mZ_<>&:t7;&S^8p/XjH+ZOuO(#Q[\__a>/Sqd@4j@Q@_csWAW?Q2MF6#T!VL];`T4>?]Z9G*qu./hIFM%!Kr<t@^L2=gJ/20ZUQ,1L)ApZK>Qa3noT/fm%P%T)2,dC\cdLE+Ij`/:Z!KS]'\Jgb`$P?6g-)*T'-#Iq=k6:^blW:<@H5N%K^>Q;@K?T0sKs"<60Y;D4o6RaA",R-bR7BP/Rl_`LP8sUa;odGaf7gaR/23T`mK>BMqdpH>J'3JNSVAE`KI(]V6_@794klD(b'J2ebdD#//dbQ:89)D%p-$+$=2XS[`MAr,t*J9IV0S,dXsNWX@3?Vb^(Bd?dTk99CEa/E=$8d)eXNF2Otog%=<P&JKQ)2qr.is4QlMBR^)cW1T_@m#HlGch7UF%@"mHUqbCDMb\%*YQW9)hG',+B@sRM]M@0mlN0(#>1<`cRc]<9^/eJpG;?[gVj#rX>hk-o,nI?D',"dq"hol5^pluhr()bGM/*:e'>hZeJ,L2JTlnFiH#Em9*iZ>--*XJ>D/?Sk9dF-hP,p_!V?:nj6uubq[cd.INnAu,S7$6?NYZDV%Zfk1FU.2s4>/CZ;2[>\A)fV%h4[1ANm0S=@W1$ENanV[DG0_5SJ@X.Z#P+N'<i"N8$YkHfXSVb);O9DP'k_?5'ASn#5e2>j61[,%cBFs<V^d@Z0U'FdLUa&+O#IZPE^Jt]';0SoAE"^Boe7P"AF>-37U<JRLpR!#"orMF8W`=jXP3WMr#;nS4M>0N-Y!<,+L`E6n")Ih^UWY13<YjjXi/@cE5'%Y5Q/T*JJspC"'!u1(V;X0O_V("gIEqQYKo#2,"Sh#t5@1<?\Nc2\T6Uo(dnmqK8^<K!i*5ok^&7#G.h[.BPq^f0#r\*Q0]_[2S_'r9V=TK)b+%eWsno^N(XD*3&E1I(/LD2Yfj)Z;r^BG<D!l,XTc2HJdcU5ZM^6[H8-b+W!q;MH7hVDDt]oQ+3Lsp*^n(6oF>$Ik!lnEAcNq*"2%%5.03bq_[;X;*F=ihd>P%e\]9p:mi?'^YnCAPrKq=LS)tES(F;Yg$N\YqatC)7I>#f.W)QU_^"5e6DY4Lhhnj[K&a#3Wd9\(L0Tf;JdCjjD>M5CcPMnBlfekAk"=>t+/f]pXmb8Oh@"[Jl\Dq1/=u%3VH%gB/+%[oa/t)DdD.W2k&7AUSFin(=C[q2[(u'JL=bk,Wi^j`?\M)+jnV]#rVchcm-g/*n9P0l'h*[tV>X[J_>=aKT(!5M^+/ZZ"W%^B3r>KGo72lskgFl,@U@ls1Oe4]qr/UakiCh4=T.kh/'TQ"Xm[EC.9CaI2n_,CPrdl#mJ.-8P&%lKmXqM@+0,/=>UWa/3cg;:_#2f0Ni,FonZC07@ZKR%^?/kT[)7<Mp9h*d<S^le6E%'KkK:E8Q36k#J`a%N\grS<F%$khTZk?PP/C9H5#51`_a*$CNh]`mYDQi>a(3O2HAlkYe.mK922/W+V9fS8.[#5t]/]7^G4j_C)nG^;>UtJ>TBr5mGuR-tTcu/S[gsef6)L.D@5uq)0?tOp`^Ok5*W?5ua0X]p8@[@s6V7f/'"i\d(YN2N_u~>endstream

+endobj

+% 'R343': class PDFStream 

+343 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2695 >>

+stream

+Gb!Sm?'!aM'n$USs1l*=$AWE=haLBbbp9n/A=Mr>MoDF>#?mj=mcZ0sj;I^DpKUU\AWQ6+ChA=.a<7]4P2\Y!gquK/@"%q\m/Kr*f\[M3S+cpk6FL"$@*"+>nU\AX]R98&rWRH9d?'&*T8_.[i-rIJ#Q>d:oERZA@WsJ4@+;&B^i=;0VrJ@nV"H%j6#W=`&\YVks62DQ$4!cei]"=@Z^nsop@#?fn`0.u-Gb4VSPe^NC\Q;e04/7+38jlWoAOA?fMXUHi?qh)3shCK#UYr/+QsB][G7cQ16iW39P%7^;WX<T5Q!WN0N/]TY"Mf5,^Y`o3`e%?WC/KR7FE#R8=_5?Ckjj.A\s+/Z!=8%`_9r6=#A')7[7$9Neo<!TD%)(U/tO$Um;m1oM9h[KgZUQ8Xd<?G]/WP_rd?pia;UM8e1GISdtPR1.ME&*t?9>kt.$@I6O&n*3`pJpfh8r%s&]E)'<nm-7Pe:6n-g$HUL[!Z?Ou&kr^3':%t%d`fJCB1m]h7IaI81/u1^%P;g6#[8Bi@P3FGH<@XDQ"c&n3P"?TPBN#V%MX%@0;;%D+*'J==6f[@0]Fu3MR[#Y^A9j?AG;Op3cF$3OlF(+.?;afJ@B#&@TG[>'b%`G0"=eHc?%+01;YRudBZ!6%"kdGF@%rtVs7j)hn$LG%La`jZD`i(]d:nVclL-X;b#cBrPTi[aHJc1PGL'9CM6pI_\kn+cU;p'fEI[c\f^QM<@Sc&GdktgS+Z2%.id*'"`JegR9*LV4G7M+q[tKdfi-U-?9T6Ud7mOkkJU6`,A$bTrN@*V6$#%76TXE>p.hQ/@W+F8]QT56cU($670Pa<uQBu:Y\WWiF.r.<GT8Z;4#Ebu#Rdg22EN6]PU&g=dfSa\)&,`N4rbCn,<CWG/q\Qi5J#cd40j_+!7>dG!oEbg@"ah<hd4=i8cu!%LTbIP$<8:):&nGOl<`50I50e[+C-*)B<,,uK?jsA/6ILL[T7@?7Gl!2BQZL4fe7MXB.+)UTmjaL,Gp+E?6=`Znqb-[nY[@[%1O_NT<X^dAW<qYPK<(JL19m%<R@QeU-Lj_/Rt(2&k7?0Njsf,@9$9Qq8OU$s/Q$li?_\(X65Do:#Y2C6W1,<L4t7uA#F/<``'DS]^W*Z4,C]6a1X*bipbDXCO24N@!X6([@L>S:+aHUQZ[lPhj]SM@fO%HQ`:;dAX)e"1JoP45GXbpk5l:dY&M;1Q]5ds:=K_tnmBop:Wcgrt+&Gaqm:o"DnQM^NDOlZeOmFq5Oh?`c6!Fbg=6n+FDpU$lL0d^>]Ijp<K2LrnVAi*4>)=_?pCr[#s(;D`j<kO>#4Ho:b"^2bN?/thPJ3fW719di)J`Q>B<a%_][#^iF8(>sC*EQF@5rN`%:@_U3UhQ]K5V9h`R+V@"*7:";uq\R>Bm<Y[$7uV<cAP7Zo;&Icc_eZG+a#t1dt8_]0!BPg#sr][m3Jh'XuXsg)qICL"#OfoK1"2X4Ba3V-#![cWV'D[[.!-.U>e'#h=0j%<T+F3u0>F@d&uWY[9J2[e(7N3`h&bVm=fGb)WuuVP?^F+U?umMtcBTP;EWYM8LtcR<]+IEdkMI4&Z.TZ4tBE-"2ImJ:aog%IY_^Cltm6A*XSo/\JVk7.MZlXYq_o14EWH)a=&AOF@)`7R]44ZjfEg*Jr:`RA&!_hVYQH,*c@(fXIL8hHKScW;W5]YAu,1Ro:8oKu;WPUGtO^GRlK-/E'D:MAK9-lQb?Sqc/!8einIhEA%3m%PbpMJVlhrPFe^N8^j1JUa""GLu[:+2MM?G@dR#SB,d6q3V,C6M/E.t3$47eo$j+"9;J)oU*uZ!X2<PONuls[K%YeUE'-36;]u[lKDHR*`lIJ!\:Kp^K0m@#K['Jkdb?l9&;int`tjh;ADM\!UG8Bhh*ZiaX7/:g14)0.<UiZD^L;WWV$u)iTiGEMH7gP+0i)V.D5C:6SP.O*R6s,OC!XL!R07n#IH&jhhbpKdi&OYm?MH(l=s:11m_03\k#9RfbRh`A*ElU[5FA5p&[U<QOT_d9Ck^\rTg[9F[0:I:X\pW0*"[i?Z"(GCG$s?!4*Y&\l5HG=/4*5hE9u-E?q!^gVU?r*=d:V9FU_l<a^.6gMB#W%MiTIRjq+*-EFCNB1*>YA#4\e3/r,:c:l3^V>#,[Y^.#VF<]0\DjUnTE5W_R1Dmq%>b1nb!*/Y<f.O%&/X*(P&&^Vu/1M@LJ8K/[d.8>f0]Z]uM$N]LB_MH-_=VW[&5J_[Ndm45TH)>Y43qD2VA;8>Zon8kBfZXTV?![>k;)j+RNnLY__nQ"_1^F>63^h0RT)ER!oNE.;I/Kf_QE4u2$$He//E(L`o:&gJ^'6aq)"\Z/fqEfe*is&=V_X@YCfF9AY8$ub7!fTjfpas%'G_^GSM'R2YfQ9spQ^#'MmY?Y:NM$4mA=*&.B2%Mg=,hsGGjaB=(kF\P&Z8S,4f2WO.IuS\uP3#=kf4c'eSu[*[_=Y$DC,-LH4miY4cN%P=oOt:IF"-IL?"s)Gc8?7BZ!'jYdk#c)()!P[HQDM!V#cTB6[L<a(/=&"M[S;,X[j^'RinqIU@#;FT3QRmX,;3A8!&`Y.Nq!Aeg^?aXtsF#pCUC\iFYgh)@?Pu^JUO<`h$X,PA%HSQ:j9X+.[Qe7V@T3Kd*C,-BES\p!TDf'C_Xhq)TYk=!X]i.iXb#fE+&f]t+`*b6*r!,qUm%F~>endstream

+endobj

+% 'R344': class PDFStream 

+344 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2495 >>

+stream

+Gb!;e=``=e&q5%is$N,Z,&^>b"F,dFb:9rA<3=c/8Z+$QmDBJPQt$48G\/(Qs*hS,!:\D;3DQ(rWDk,s7iu)^J),uiLd)LO9aZDhQgi>i,)B]1Ae9s@(mb2VQcl:&54WXA/>%kENl>gdHOcW;E"TM(`,%DjiX'Fm5/C10'p6:E1N>FG^p7XfiZ3.,9MF[(+og2=E#t(4_=B`?s1ooWbeG7S%mM./1`OGV=?hrA5)+2u^46!TKQn8h&W.@KE5<hM=MQ>RLrjnMpFM*=rT]AsI)ps:]m@:m67&0)^K+/JkJ=/dPoah-FkW'f14F@GVUjrFSsuI;?E\IRr>(\+2_8_2'jR@q?S8LRJ\7++Q`FABoXrZ=6FE_el:*-.FA_/"^g$:R;h!iDRETTF`Aas-pN^4]Pujs#Z^80>cc>eW(H<,bqI:+E=/pq-W@d!!P;Vf/io)g[2HYe-I\Rl9E!(p.=2?0^'rXQJT19&*'XHL(?r_P%N<bm7KD&%QdZg]P:2X#->aHoD?/cJ23&O9%b)1P=FGQ^V//HY35`3L!17hfYhWk&Q-t`'RE;rlK@+bL!$\j'4i7_;;Y.lBc1TbJC1#pAC@c!.>c[jjf[mA+:"$/.P;=*m+W8CTQ,<F4b+KI!D#pUg[::]:*FeHA14Pr=GaQYJ%lP*X9d=*,0S:j2kIh%57a>+3/]dd`s2m?1flOm6&OKbl"<+%1eV)O^s'%A&)bCgRlI'-gd$mi2)eDY"CJLAkE&nLB(+mHVnio=JJY"mO^'92_A=h9!i")!@4-aLO'=[K#YB<:D0c,jP8JGLHR5Olu:eI<[jTb/_IiI`a]8)_"E2Plp!B\\AT^c[7[W-o9%M`rmr0Y)`25fHlhE7A1G=g^>2ZdoEbA.+ZBLb\W59;YAFAXSW2jFAQd2G4U<jNf)K\[!WV<u0E`]:dBIDLZXk%RIZlF=5ZPZJ/s,>+(Pf[eL$RKd`*G3tT7gEuh"QL!"M:BaMFc;B!3ZqN[0,53T#`6h"2VBMV435GCW6@euq,a@e(*gX[G\&;hR2C7V9C%\VH;c5-Sg>@YI6\PWEW0H3%T_\$=T![d_&oJ.VDO*A1N&r(2=`LXb)ggTU3eJ.fDpBp@")$E06$Ia2j"6c390#i(7Z](O9H@gn%2]CMaO]s2@J]HcQ"<kH!gg6Dd0qER6E>dbr&::oFgplL8N0mB7Kkk3d.2Z3D(WBCdbH&0>0rPqm/33eVFTBQ3K&K.K3n9HKrs4Pm0?%:!:.GBB-o@/4s'LJS_q+0+meCi#-hH'P6q;c;\8s8_nn`?.#&6YrPT5jS4?"5UL39T1#`Pc8Z`N]KrDfGL*h^f&X1G4fS2BZ`]^s,<FYoSmCa@XR9KX5S"7;\;nK]gYBHE(WpRPI^SljX,oQC5"Z82VRaMeU24Zb@SIAD!J3ao/h9g'ACEBAZEe_V]4&,bX39%MVW]4M'7>MB.jP4jP!hh6que]1itbV<YkHa4X>VlDN)9eaV_*o_P53u8HdiUsNIg\18.4R_/GIVMisPf*R&.b(1(d()O_\E;MR;JUQQp*uL;-03Dm"1H_Do7k(.BJ>u,Z=o^DEn)7ZUH,dTU\b?Cl8T]BVt8Z,0t,``;3R"&@_/1l8)0+Ek2T"JgFAJ[6*b2#bl6Ts0]@LZO)lfG>XZs]Ci#PlM%m6la]b"a($$-g@3Lh"%<2Wi*V4C%Tn`!.l``a/ZeJb8F<o6BlpT4h"e=]N7\+ZZ^TQErR3G;:\7k^/@)lZ;5'lM0)]IAKg*>MeO8itl?6LIZhRk`q[8nPrNHA_3Pr1Lh4#L'&)mB,jgC>ebX-hi.3Dn^TDpffe]*%b&A?abC(!k1T(qA.)"J`4\)Z'quSp+=)`>d8=+SlmSN$:!(J6W&Ee,=&mb84in$`P^)qq'#llXu<J9plrg\r`mcQI32GC'o"Bf34oN<lXpk<f6(X#;Q!t[aNhAd7alBX>'d"EbIFW]D/hnlEI/%hG;JpRq.8_r#Z%(lubS4c6@q"()^?c)n\!3au!-(6h+KM)_MlN)_9h=Y7q3g4+02^4D<*fSED<H2bNMd4f,_d8m8gT)Mj!ee3nd9@e@/Akn9:V!WOmgR?`"\dWqm(dBTh0lo#P*Sn<XS]@=8jXdEjCB%+nnjL5&Q,9Fj6oYm\g5A$^fZI\Mq0Jdjn"(-=8`<;UVTLO\@H)22u/Q\+JZ)Roh`80.20r-TO6P.F,=skA3SLL/)[f`[q`]cgQA0scHkM`/\in^F$Y/.e^jrgq(:OG+DhC[Y8V/:NE'DCfZ?S]-6P`P+scV$UDAG^?0Fb4aTBs>-XnEmTH8i#:Zl;]<1d2dbof9j\lAVns<a"WKd3dYNCn/5@VNRSCu*t@bKJ);>VPL+fhHI/]fL15BF+8jkA*Y1[Z4mLooI<3T8VIiUMNK+F'Fs\VQbTo$\no3*o*^K(!1*BNRe"^N@4-1_SQKM1ts&..>%`EC2WgHCmkA&PSDd*p4K':+G0W@p]J'APN9rKu,#9.pajF8QSTnE~>endstream

+endobj

+% 'R345': class PDFStream 

+345 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2066 >>

+stream

+Gb!;f>BALX'RoLEs218;PjEo:gXndKP&*5I9XDEcmSdGF/O5:I\WRrT^Y^9hQtm>P&oTgA(a@Y]dAM'"oBG7$(I,)$N`(DN&cDI]"kSCS"PfTtK@)&k2gYGfVu:\[a+GFXT$n5>SW.Y+3ps;tl$%R-$Xiu1't.:/iAt)lG6VIUUU9q8q_5_WS\T@%[3%D_Q5?(/kQd(GYU4b*Im98a^2@0)G=0FEpkVf"S_rgg_nB*]T&YNR^G'KfKS+_fRKp"aR$K\4]>ubMA+g9_TECNP::1XZ"s^-)I$#VIEA$K#"5'tE%/WfGY79aqT0#F2]8g5'l-YI,Pt3^*fpF'Z08a2nj@iK[4A,13.YrntD`o<`,&pC)N/;!ULl=rR;/d'[XJKmP@jtLghqh^g^:mpkk2OQS#<mr(`L#>PY[P+Db7p$a?EHboC!Kjl)ci%lTg^4>(fNSqPXA.5=[Z7/(`Gb$(E0>^Ose?Q1tk]7(bYknd.UfM1?Y1t.A3*IF?N?3fnb8JkDK8_.G)\9?'YObZ\52X<gZ]dG5_AO"=-hG18:!Rn17?Amh@`ha/^AOY)Vh&1LSBUP&+rNUPY@"otA6RNqA?;0-<6X>LOn,bf:%,)+X!)6Sn(DS6*]V'JY+=ag.b``;!i[+V5gR;'M>40/i][7Q<JmiXD42<ZOc%$mpt;bsd>53TG&DK8'M@KD6&**i>el:kf1M$CM,L>.8CaDlkgmm@OKVc._e[N+9mZ7\AE'PEeo_N0Tdo3C3/S3D3i._SeeR$+1?QL0_h_'X<ojSIi(sd&ZKJ)!*S!nmV/]+t8?bE6#qfQ[hLN#q!"g#ej_(!i^ui!Y["\MtI#"`mi:%5s:c66'D]`C;jn"78Hi*ij8Tc*&gg.[GgTd\i;T4n"C$1CDaf".[>Q!nPW#uOPUAV4KJDVb_!J4(W6dC5=:$1pG?%&B?J"3ekcD'TGJ(Bqt[M_oS97K#b?)I:ggO<^^\h>Ar#l<.nu2f^e$qG)E_Ho8I<O^:.S0IQ=i*rJ4$V(\7Ys$Uu[Q%)*tqb6AP%[&!SLc_RM)j^HQ16f*T:u+nJG8=m75Z5V"Xj%>9`JKV^T+ND+7EGgc+XMN$F@1>Aet876UVK>Ea#mppfS7J07nU?pCXB\EXJ@RATeOmb4ZCei+lT1I8&fp6l1@$]P$T<VpBOUs<;0L<_a\:E1Z1*=58f(b"m2H^`G@NS-+)&>ll\\saG,$CVi"sH]]:,?0dhH]#\F*ns-:!?-PVD_$+M];+*M<n!>O".!2A6^[u$'Ri6R@JZ4^4`RN,$Zf$`_!]LY)UsLfEa;!1*]^l6)h-S:U;-f^N%u@2I^38H8Sr:[k\Ac'JdWq#NK%\FPFsgEhRVMH%(*h!-U46l,ufFT-#7hKgd[]ITcL";W]'QUQ*b3UUHhls!WJH06Fd"qJ#D_=Plrn_X/8i:'E8I;Q:G!/chdoRT8PjeF'g:K!8CNFDOMnMG#<iq^F"3M$<a;KbTQD=WRuH$0>/2']$)e[>+pFr5ru`BcYZk?kQ/d@dAY;Bj"P\e#JJ'2]O_KSDbnor6B.iY'Jl=(W:W()clK65(IEXNCCuTI3_S"[5IY6)U]5@/^83G%i\g@04k:O&:rg5HHr`d1&<s;%*s-e?.(ir^t=e3%Hn2G*AkC<Gn,8-POkDF?lZqJi,s[i2oo@%^A'phKfaCGA\dJp((V&9L:4T;d2dh*;0,9AN[Y-*W@iD:TcdAcO+_M^2KYS@Dl:jJhe8o-7/a5=fC(Z13'(b/`"=BCP7Ls&fBbidV"sN!&C!7n410_/P6(6%2_P(FR_H0s-=[_qjX#Tu\MknH.4t!lb\%=b1MDs2UeMS5e)"rGUghn&"dJ_g]ODe+VQQ3oRtG-j7mbW`k:trL^9T;l:+/PC=slmMR2GrP%cGR6/(2r@A8PT<-u@7bj5r\bWRZA2+Y]Nc%Mu!&VAUs:U;+!e782Gt)_u![?D"`ER3SMB]<X20K1O`C2A&LnF=tS$RbbDicYq,;1sELFfsIL/ZKrE8RnA7lhsR4Rfq@T&Ap@tdZio1>$UJF4f071g1+H.cUhD-$N99'kX+(/do.1[~>endstream

+endobj

+% 'R346': class PDFStream 

+346 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 210 >>

+stream

+GasJJ9a\`k&;Bk0gu0ici7NlXj''fpS&1]2[Yfbk=r1N&,d^"PW6?q@DgpQ`a?spH<<o#sq[8#cj:8V/+]k1&X$.hjj3GLYnh0;,k_pNX)Ys<H`o4%"\2mD>"jPN$E0+u8#*8!5a[OrH`UH-)M@HA8C_K.'ZC`3"P/nU>#ALc^7e?j>_e!u^WeT]=WG)NL6,Pm(8*A6O<Z`u"7:u~>endstream

+endobj

+xref

+0 347

+0000000000 65535 f

+0000000113 00000 n

+0000000263 00000 n

+0000000469 00000 n

+0000012253 00000 n

+0000012440 00000 n

+0000012682 00000 n

+0000012912 00000 n

+0000013142 00000 n

+0000013371 00000 n

+0000013598 00000 n

+0000013826 00000 n

+0000014058 00000 n

+0000014289 00000 n

+0000014521 00000 n

+0000014752 00000 n

+0000014981 00000 n

+0000015213 00000 n

+0000015443 00000 n

+0000015675 00000 n

+0000015907 00000 n

+0000016136 00000 n

+0000016365 00000 n

+0000016597 00000 n

+0000016829 00000 n

+0000017060 00000 n

+0000017292 00000 n

+0000017521 00000 n

+0000017751 00000 n

+0000017980 00000 n

+0000018211 00000 n

+0000018442 00000 n

+0000018674 00000 n

+0000018906 00000 n

+0000019138 00000 n

+0000019368 00000 n

+0000019600 00000 n

+0000019831 00000 n

+0000020063 00000 n

+0000020295 00000 n

+0000020527 00000 n

+0000020759 00000 n

+0000020990 00000 n

+0000021220 00000 n

+0000021451 00000 n

+0000021682 00000 n

+0000021914 00000 n

+0000022127 00000 n

+0000022865 00000 n

+0000023094 00000 n

+0000023325 00000 n

+0000023555 00000 n

+0000023785 00000 n

+0000024016 00000 n

+0000024246 00000 n

+0000024477 00000 n

+0000024706 00000 n

+0000024937 00000 n

+0000025167 00000 n

+0000025399 00000 n

+0000025631 00000 n

+0000025863 00000 n

+0000026094 00000 n

+0000026325 00000 n

+0000026555 00000 n

+0000026786 00000 n

+0000027018 00000 n

+0000027251 00000 n

+0000027485 00000 n

+0000027719 00000 n

+0000027952 00000 n

+0000028185 00000 n

+0000028420 00000 n

+0000028655 00000 n

+0000028888 00000 n

+0000029122 00000 n

+0000029356 00000 n

+0000029591 00000 n

+0000029825 00000 n

+0000030060 00000 n

+0000030294 00000 n

+0000030529 00000 n

+0000030762 00000 n

+0000030995 00000 n

+0000031229 00000 n

+0000031464 00000 n

+0000031697 00000 n

+0000031931 00000 n

+0000032165 00000 n

+0000032383 00000 n

+0000033052 00000 n

+0000033288 00000 n

+0000033525 00000 n

+0000033760 00000 n

+0000034014 00000 n

+0000034282 00000 n

+0000034527 00000 n

+0000034799 00000 n

+0000035090 00000 n

+0000035367 00000 n

+0000035641 00000 n

+0000035923 00000 n

+0000036202 00000 n

+0000036470 00000 n

+0000036734 00000 n

+0000036991 00000 n

+0000037242 00000 n

+0000037493 00000 n

+0000037790 00000 n

+0000038083 00000 n

+0000038366 00000 n

+0000038682 00000 n

+0000038972 00000 n

+0000039257 00000 n

+0000039546 00000 n

+0000039828 00000 n

+0000040108 00000 n

+0000040383 00000 n

+0000040944 00000 n

+0000041227 00000 n

+0000041525 00000 n

+0000041810 00000 n

+0000042101 00000 n

+0000042398 00000 n

+0000042692 00000 n

+0000042990 00000 n

+0000043272 00000 n

+0000043544 00000 n

+0000043816 00000 n

+0000044084 00000 n

+0000044364 00000 n

+0000044642 00000 n

+0000044920 00000 n

+0000045238 00000 n

+0000045525 00000 n

+0000045811 00000 n

+0000046074 00000 n

+0000046313 00000 n

+0000046533 00000 n

+0000047020 00000 n

+0000047198 00000 n

+0000047424 00000 n

+0000047610 00000 n

+0000047833 00000 n

+0000048138 00000 n

+0000048411 00000 n

+0000048701 00000 n

+0000048941 00000 n

+0000049182 00000 n

+0000049424 00000 n

+0000049666 00000 n

+0000049908 00000 n

+0000050135 00000 n

+0000050333 00000 n

+0000050573 00000 n

+0000050813 00000 n

+0000051055 00000 n

+0000051296 00000 n

+0000051519 00000 n

+0000051931 00000 n

+0000052173 00000 n

+0000052413 00000 n

+0000052636 00000 n

+0000052968 00000 n

+0000053208 00000 n

+0000053450 00000 n

+0000053684 00000 n

+0000053926 00000 n

+0000054167 00000 n

+0000054409 00000 n

+0000054651 00000 n

+0000054892 00000 n

+0000055116 00000 n

+0000055508 00000 n

+0000055746 00000 n

+0000055983 00000 n

+0000056220 00000 n

+0000056442 00000 n

+0000056768 00000 n

+0000057042 00000 n

+0000057332 00000 n

+0000057574 00000 n

+0000057810 00000 n

+0000058047 00000 n

+0000058268 00000 n

+0000058610 00000 n

+0000058852 00000 n

+0000059094 00000 n

+0000059320 00000 n

+0000059652 00000 n

+0000059893 00000 n

+0000060118 00000 n

+0000060440 00000 n

+0000060681 00000 n

+0000060922 00000 n

+0000061163 00000 n

+0000061388 00000 n

+0000061730 00000 n

+0000061956 00000 n

+0000062268 00000 n

+0000062509 00000 n

+0000062750 00000 n

+0000062992 00000 n

+0000063234 00000 n

+0000063475 00000 n

+0000063717 00000 n

+0000063959 00000 n

+0000064200 00000 n

+0000064442 00000 n

+0000064678 00000 n

+0000064903 00000 n

+0000065315 00000 n

+0000065556 00000 n

+0000065781 00000 n

+0000066087 00000 n

+0000066377 00000 n

+0000066619 00000 n

+0000066860 00000 n

+0000067086 00000 n

+0000067418 00000 n

+0000067658 00000 n

+0000067878 00000 n

+0000068200 00000 n

+0000068441 00000 n

+0000068680 00000 n

+0000068919 00000 n

+0000069235 00000 n

+0000069509 00000 n

+0000069784 00000 n

+0000069926 00000 n

+0000070170 00000 n

+0000070299 00000 n

+0000070505 00000 n

+0000070662 00000 n

+0000070834 00000 n

+0000071003 00000 n

+0000071216 00000 n

+0000071387 00000 n

+0000071616 00000 n

+0000071775 00000 n

+0000071955 00000 n

+0000072139 00000 n

+0000072329 00000 n

+0000072511 00000 n

+0000072694 00000 n

+0000072861 00000 n

+0000073047 00000 n

+0000073271 00000 n

+0000073440 00000 n

+0000073609 00000 n

+0000073799 00000 n

+0000073975 00000 n

+0000074166 00000 n

+0000074385 00000 n

+0000074540 00000 n

+0000074717 00000 n

+0000074887 00000 n

+0000075057 00000 n

+0000075220 00000 n

+0000075415 00000 n

+0000075644 00000 n

+0000075802 00000 n

+0000075980 00000 n

+0000076158 00000 n

+0000076335 00000 n

+0000076494 00000 n

+0000076682 00000 n

+0000076909 00000 n

+0000077120 00000 n

+0000077289 00000 n

+0000077468 00000 n

+0000077655 00000 n

+0000077837 00000 n

+0000078009 00000 n

+0000078230 00000 n

+0000078387 00000 n

+0000078572 00000 n

+0000078752 00000 n

+0000078917 00000 n

+0000079132 00000 n

+0000079294 00000 n

+0000079471 00000 n

+0000079639 00000 n

+0000079813 00000 n

+0000079987 00000 n

+0000080163 00000 n

+0000080338 00000 n

+0000080502 00000 n

+0000080727 00000 n

+0000080885 00000 n

+0000081070 00000 n

+0000081244 00000 n

+0000081434 00000 n

+0000081608 00000 n

+0000081823 00000 n

+0000081990 00000 n

+0000082174 00000 n

+0000082358 00000 n

+0000082524 00000 n

+0000082750 00000 n

+0000082925 00000 n

+0000083099 00000 n

+0000083248 00000 n

+0000083433 00000 n

+0000083667 00000 n

+0000083825 00000 n

+0000084013 00000 n

+0000084198 00000 n

+0000084377 00000 n

+0000084614 00000 n

+0000084786 00000 n

+0000084962 00000 n

+0000085132 00000 n

+0000085312 00000 n

+0000085484 00000 n

+0000085708 00000 n

+0000085872 00000 n

+0000086060 00000 n

+0000086248 00000 n

+0000086461 00000 n

+0000086601 00000 n

+0000086961 00000 n

+0000088892 00000 n

+0000090551 00000 n

+0000093975 00000 n

+0000097112 00000 n

+0000100523 00000 n

+0000103432 00000 n

+0000106168 00000 n

+0000109125 00000 n

+0000112041 00000 n

+0000114971 00000 n

+0000117386 00000 n

+0000121726 00000 n

+0000125032 00000 n

+0000128099 00000 n

+0000131133 00000 n

+0000133762 00000 n

+0000136496 00000 n

+0000139078 00000 n

+0000141852 00000 n

+0000145169 00000 n

+0000148048 00000 n

+0000150892 00000 n

+0000153732 00000 n

+0000156372 00000 n

+0000158583 00000 n

+trailer

+<< /ID 

+ % ReportLab generated PDF document -- digest (http://www.reportlab.com) 

+ [(/\(,h\315\262\327\227]MM$\306\353\011\335) (/\(,h\315\262\327\227]MM$\306\353\011\335)] 

+

+ /Info 229 0 R

+ /Root 228 0 R

+ /Size 347 >>

+startxref

+158909

+%%EOF

diff --git a/pdk/docs/compatibility/compatibility_toc.cs b/pdk/docs/compatibility/compatibility_toc.cs
index 183c0de..056605a 100644
--- a/pdk/docs/compatibility/compatibility_toc.cs
+++ b/pdk/docs/compatibility/compatibility_toc.cs
@@ -7,7 +7,7 @@
 <ul>
   <li><h2>Getting Started</h2><ul>
     <li><a href="<?cs var:toroot ?>compatibility/overview.html">Compatibility Overview</a></li>
-    <li><a href="<?cs var:toroot ?>compatibility/android-2.3-cdd.pdf">Current CDD</a></li>
+    <li><a href="<?cs var:toroot ?>compatibility/android-2.3.3-cdd.pdf">Current CDD</a></li>
     <li><a href="<?cs var:toroot ?>compatibility/cts-intro.html">CTS Introduction</a></li>
     <li><a href="<?cs var:toroot ?>compatibility/cts-development.html">CTS Development</a></li>
   </ul></li>
diff --git a/pdk/docs/compatibility/downloads.jd b/pdk/docs/compatibility/downloads.jd
index 61bdfd9..27a2109 100644
--- a/pdk/docs/compatibility/downloads.jd
+++ b/pdk/docs/compatibility/downloads.jd
@@ -7,12 +7,10 @@
 <h2>Android 2.3</h2>
 <p>Android 2.3 is the release of the development milestone code-named
 Gingerbread. Android 2.3 is the current version of Android. Source code for
-Android 2.3 is found in the 'gingerbread' branch in the open-source tree. A
-CTS release for Android 2.3 has not yet been prepared, but one will be
-available soon.
+Android 2.3 is found in the 'gingerbread' branch in the open-source tree.
 </p>
 <ul>
-  <li><a href="{@docRoot}compatibility/android-2.3-cdd.pdf">Android 2.3 Compatibility Definition Document (CDD)</a></li>
+  <li><a href="{@docRoot}compatibility/android-2.3.3-cdd.pdf">Android 2.3.3 Compatibility Definition Document (CDD)</a></li>
   <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.3_r1-x86.zip">Android 2.3 R1 Compatibility Test Suite (CTS)</a></li>
 </ul>
 
diff --git a/pdk/docs/compatibility/ndef-push-protocol.pdf b/pdk/docs/compatibility/ndef-push-protocol.pdf
new file mode 100644
index 0000000..2300a6b
--- /dev/null
+++ b/pdk/docs/compatibility/ndef-push-protocol.pdf
@@ -0,0 +1,471 @@
+%PDF-1.4

+%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com

+% 'BasicFonts': class PDFDictionary 

+1 0 obj

+% The standard fonts dictionary

+<< /F1 2 0 R

+ /F2 3 0 R

+ /F3 13 0 R >>

+endobj

+% 'F1': class PDFType1Font 

+2 0 obj

+% Font Helvetica

+<< /BaseFont /Helvetica

+ /Encoding /WinAnsiEncoding

+ /Name /F1

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'F2': class PDFType1Font 

+3 0 obj

+% Font Helvetica-Bold

+<< /BaseFont /Helvetica-Bold

+ /Encoding /WinAnsiEncoding

+ /Name /F2

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER1': class LinkAnnotation 

+4 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 14 0 R

+ /XYZ

+ 55

+ 511.3263

+ 0 ]

+ /Rect [ 70

+ 613.115

+ 132.5125

+ 624.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER2': class LinkAnnotation 

+5 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 14 0 R

+ /XYZ

+ 55

+ 439.0138

+ 0 ]

+ /Rect [ 70

+ 601.865

+ 109.5925

+ 613.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER3': class LinkAnnotation 

+6 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 14 0 R

+ /XYZ

+ 55

+ 344.0763

+ 0 ]

+ /Rect [ 70

+ 590.615

+ 120.0175

+ 601.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER4': class LinkAnnotation 

+7 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 14 0 R

+ /XYZ

+ 55

+ 307.7975

+ 0 ]

+ /Rect [ 85

+ 577.365

+ 158.365

+ 588.615 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER5': class LinkAnnotation 

+8 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 14 0 R

+ /XYZ

+ 55

+ 230.6725

+ 0 ]

+ /Rect [ 85

+ 566.115

+ 124.1875

+ 577.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER6': class LinkAnnotation 

+9 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 15 0 R

+ /XYZ

+ 55

+ 667.0475

+ 0 ]

+ /Rect [ 85

+ 554.865

+ 139.6

+ 566.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER7': class LinkAnnotation 

+10 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 15 0 R

+ /XYZ

+ 55

+ 518.6725

+ 0 ]

+ /Rect [ 85

+ 543.615

+ 144.1975

+ 554.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER8': class LinkAnnotation 

+11 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 15 0 R

+ /XYZ

+ 55

+ 328.7975

+ 0 ]

+ /Rect [ 85

+ 532.365

+ 121.6825

+ 543.615 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER9': class LinkAnnotation 

+12 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 15 0 R

+ /XYZ

+ 55

+ 219.6725

+ 0 ]

+ /Rect [ 85

+ 521.115

+ 118.765

+ 532.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F3': class PDFType1Font 

+13 0 obj

+% Font Times-Roman

+<< /BaseFont /Times-Roman

+ /Encoding /WinAnsiEncoding

+ /Name /F3

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Page1': class PDFPage 

+14 0 obj

+% Page dictionary

+<< /Annots [ 4 0 R

+ 5 0 R

+ 6 0 R

+ 7 0 R

+ 8 0 R

+ 9 0 R

+ 10 0 R

+ 11 0 R

+ 12 0 R ]

+ /Contents 32 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 31 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page2': class PDFPage 

+15 0 obj

+% Page dictionary

+<< /Contents 33 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 31 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page3': class PDFPage 

+16 0 obj

+% Page dictionary

+<< /Contents 34 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 31 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'R17': class PDFCatalog 

+17 0 obj

+% Document Root

+<< /Outlines 19 0 R

+ /PageMode /UseNone

+ /Pages 31 0 R

+ /Type /Catalog >>

+endobj

+% 'R18': class PDFInfo 

+18 0 obj

+<< /Author ()

+ /CreationDate (D:20110303200815+08'00')

+ /Keywords ()

+ /Producer (pisa HTML to PDF <http://www.htmltopdf.org>)

+ /Subject ()

+ /Title (Android NDEF Push Protocol Specification) >>

+endobj

+% 'R19': class PDFOutlines 

+19 0 obj

+<< /Count 3

+ /First 20 0 R

+ /Last 20 0 R

+ /Type /Outlines >>

+endobj

+% 'Outline.0': class OutlineEntryObject 

+20 0 obj

+<< /Count -4

+ /Dest [ 14 0 R

+ /Fit ]

+ /First 21 0 R

+ /Last 24 0 R

+ /Parent 19 0 R

+ /Title (Android NDEF Push Protocol Specification) >>

+endobj

+% 'Outline.2.0': class OutlineEntryObject 

+21 0 obj

+<< /Dest [ 14 0 R

+ /Fit ]

+ /Next 22 0 R

+ /Parent 20 0 R

+ /Title (Table of Contents) >>

+endobj

+% 'Outline.2.1': class OutlineEntryObject 

+22 0 obj

+<< /Dest [ 14 0 R

+ /Fit ]

+ /Next 23 0 R

+ /Parent 20 0 R

+ /Prev 21 0 R

+ /Title (1. Revision History) >>

+endobj

+% 'Outline.2.2': class OutlineEntryObject 

+23 0 obj

+<< /Dest [ 14 0 R

+ /Fit ]

+ /Next 24 0 R

+ /Parent 20 0 R

+ /Prev 22 0 R

+ /Title (2. Overview) >>

+endobj

+% 'Outline.2.3': class OutlineEntryObject 

+24 0 obj

+<< /Count -6

+ /Dest [ 14 0 R

+ /Fit ]

+ /First 25 0 R

+ /Last 30 0 R

+ /Parent 20 0 R

+ /Prev 23 0 R

+ /Title (3. Data Format) >>

+endobj

+% 'Outline.3.0': class OutlineEntryObject 

+25 0 obj

+<< /Dest [ 14 0 R

+ /Fit ]

+ /Next 26 0 R

+ /Parent 24 0 R

+ /Title (3.1. Protocol Versions) >>

+endobj

+% 'Outline.3.1': class OutlineEntryObject 

+26 0 obj

+<< /Dest [ 14 0 R

+ /Fit ]

+ /Next 27 0 R

+ /Parent 24 0 R

+ /Prev 25 0 R

+ /Title (3.2. Header) >>

+endobj

+% 'Outline.3.2': class OutlineEntryObject 

+27 0 obj

+<< /Dest [ 15 0 R

+ /Fit ]

+ /Next 28 0 R

+ /Parent 24 0 R

+ /Prev 26 0 R

+ /Title (3.3. NDEF Entry) >>

+endobj

+% 'Outline.3.3': class OutlineEntryObject 

+28 0 obj

+<< /Dest [ 15 0 R

+ /Fit ]

+ /Next 29 0 R

+ /Parent 24 0 R

+ /Prev 27 0 R

+ /Title (3.4. Action Codes) >>

+endobj

+% 'Outline.3.4': class OutlineEntryObject 

+29 0 obj

+<< /Dest [ 15 0 R

+ /Fit ]

+ /Next 30 0 R

+ /Parent 24 0 R

+ /Prev 28 0 R

+ /Title (3.5. Server) >>

+endobj

+% 'Outline.3.5': class OutlineEntryObject 

+30 0 obj

+<< /Dest [ 15 0 R

+ /Fit ]

+ /Parent 24 0 R

+ /Prev 29 0 R

+ /Title (3.6. Client) >>

+endobj

+% 'R31': class PDFPages 

+31 0 obj

+% page tree

+<< /Count 3

+ /Kids [ 14 0 R

+ 15 0 R

+ 16 0 R ]

+ /Type /Pages >>

+endobj

+% 'R32': class PDFStream 

+32 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2055 >>

+stream

+GauHM=]68"&:UO7s3Qg;.k&i9p:fX=c#/ZFPB^$6<I#1b^lu0=]JF%:rr%"5F*fNA!%?htI=,dXC39mb*5@4,^"<=tS&:^g!Q'Ha%1%_L0Y`3tq<?#9qF>)UXok!/Hl$p?ir[Lp5/qtf$d47Akm:N.Kd33a4;[-!&;&jtg*_qFF3,`[hsi:gM,uD2$1hN2pFlC+hu(BY-5^+BX;?h'%ej/BTUp'8(gKgj`<+G;nhsam;6Y`"+"f0S[S'XTMk`+46u2S+<K#c^=NE=T_B-X<\=PWfp-A6sraa/7!aPP'_f"/OSrstKV8Ms%Z5$'@q:[%,X#ND(@,ad4cR^]e3Od9cCHQVV"&4f%@r9oSnYX@C[[?1<J>^V\pgqN`7U2o9T$-H-K'3Eq7q&F71`;;$SN+Xc3-q%8YJ6X"KXCL)KM>b#hLLZo,b\ZQGJ$^Opc)nc?&,shX"lN)l7jZ-lFDi]^DtXYPsD(Jc'dC;LkIcV%)/`iTJuj[OJGa$YCfp[RDN*a>7CMdX*>_b6_Baji.F]L>Xn6QVT4k;q]f>m*k+?l#L=lO/@_ea;%3+$)-'s>7X8_k'LMu&%VJi)Q.T+9ImC3SV?si(qBO[HWYIF;*YNcMRj^bf3\eNth..^4LC#\e9R&s.RJF.9P4TCk)>-kKV2G/hOAS'L?A*#W6Z(s>Ge9VbMeQV!#2Hg!^*0,(gj9IdY6.HQO5R<"iBt0RW=i[lBc[H,YulJ7Ef1j\RnF]]OhU7cb%4rLK5PtPMoH+s$m3(Jh3QgP3kju;2N:q$nAWSD_CVV)6*fnB$UI\4+qD'Ab73k;S23oIip![1Y[fiP^6c\.cl+:daHlr%HPiQ0>XP$PC=\HnJj0O^:\<u#QOh>j.K:'s"'l#a'X_&#E6!@UaZn;C2u.PR7P_VTf$"msST`7ugMH%/h)_B3duWuFU\p3Y51?W48la@r:U]YM[Rd_">b>=O=&J=?@%Y]X-s$"Ein-%uQr"a';P?Oj_1g1=[b<&WhCWTA`rrZr&4uFV%3mPRE1Nje,EutC@ao]Ao8.25?D(tFf(<I0"l&S#FJqJW;r?NR)Lb11YJ8l:g:rnflaVG7I@e]4]Rh7,#t_AS@ZS%D-a.a13X%'qdV):Ej42]W)&u\n@R]ii/dAeY>2h)Laf#W-LQ+n=H)ojMN]*i<:i[X/'ZnHN8lmJp1:)^hrYB7ZM\QA/U=M86SCA&>*Yk!>IM7Aad8#;_[cShi?6h(D`Mn8NU5N!PC^\Q>R6n46DPK0c!*9T$rq\MX\OIAA`4JiUT?R^F`klNYrmTW:[7En%7+KL[M>FGS+[UsL9TER)pG,k:c9$psKDCCV]j=26"<YU%*Lnd8=Qq:TD_J5qmM7;jhA55$fsOE_8njC?U6:)nX\-BfaY.Ts>+4,!#d&q#7`\lURnShSEop.RJ0(cN1C'WaYI!I3"k.XL?p<rL%_k,jVmeXO`3YI$M:<\pDLrEamB`W#km_bX0U+GXffU9,4G(M`K8c-'/>CBiV?%;$&>Uh4f%=8?'MjP<aD]b=80/.Nk*@s<,_^#VA.b59f\7]oI`Y&'2[sFPaK$gY@q^ZR%\AeZ*C-(%F[9k[hNoQ-70*jO,K.>)rs>Gf=OSAtpK/js<3THa:QgDjdIVFdhWBm8-2_KWMs^Ol4sp7\l!,U#qK0lV*@d8UhG_)m-FG2"N)N(DR_">(hpLSioYQ%t^G=cRa#;Yso/;Zum`5%-=c`:#GTP_cRdTO1@9qZ*nT)N.iO`@``]aCdp>9@3YF88@1@g2`OZYk$ibmI7j9b"sD>"'MX6I,to2C<D!MsQ0[iA'Q%Mh'lrai0kYGAH>]M`c8YBh?kCIl+gP3S["MNY5nq=-QG]$RJ70)SJWf%$.@4jfM:>ne)NrJ'6VATqZK2u:/?@'qe*8G<sAgic=cMnG\d'M=dXT!@jSg_4gX,<V*Udir/nPY"k<Q1CeB*+dYWM,&th.'496%?I>T9,tS1%`YeNClRT)9Y'gklb5I*pbb*AX#$nqQE-!oX6%KnJ^kFMG"_KTh`9PM`f#Du'<u^b]s6gL07_N8rrBb=mfr~>endstream

+endobj

+% 'R33': class PDFStream 

+33 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2836 >>

+stream

+Gb"/*=``=W&q3VVr^/nr[N($W%Vso`5'CQha_'+mXdZ88@7WpUL5/)lp?:CP2o#Nk5`/NDW]\4CC^Fc3)BW.BrYg^t2L[aYG7XlSZ@qt5%QH'l=5ZcR#qS<V_t*2aDt:pt`2=8f?#)XC0o^>]hDo/:27G`hS\iS)2lP9+-CS-tZRIG8E#]7t;*W;b\#)!Y/\eVL>e*)8ngc9k+_UgLrd65'r73c<2Rb8L9W:9PqYnkEa-KA<[=shI4^*EGYe7l-a=dAB;Pq?ti`ML(kuj#Vi7tl);4i%%(R@@uJku+OO2-o@j%KlfdR3oY'Qeob2BI;"=9MAQEsA`*(VY@=P*#PIlk7.d#n);33Eri6JmT19AsqRk!qtN[;m,Kpf:6arLb0#0M?eTj'%bdS"[)\0Nkl*a,4M?DIkT^fX2^hGq\iYQSSJoGr1.5W-IEn"C&EJq6]d$2:pnqm[qV/7cl*0F+ZZrBmUWS)SCJ@Okb#sFs1F.j-i<!egTp(e3Q3utQ9'*1)<-C[+P=.D9*.R).!-XSWfP\_1>d[2<r5bEZ\MPLJI`n;6,pC^>mfc5NnD[=\;C[oVT!u&"jH1G%dh%2r?j0l/hE.9`qXIAp.+U?D,Yd*>Np(^mZ?FKJ.e"3DV6X2gS;+cB6MbfW8>S)8[ClfotErP@>Be)VSs5i*UD+!j\+X6g;\?\7UeeVF$tA`8l2.^#E_d#$ETu&3Qe>/CAeCDp41tuqDbY3cjjTG]sUAqD7W6gm70=fLp_L4P-GO.)`&n)p3mmAmF%n?Yn,p'SLQ_gK0AM8bH14>B&t-E2.I+RYt[fFT$fWb4e9f7D@Y^&D9Wl<'e!_Gc+JjsDAbA*=Qrt[<<pSCYfKT53E)pQHn"6^EQg,%aB:o^3Ju6$SucK[hCq14A1:&Z-<0E+KmRVLrYdk)GeO4@#Fi"jSmM:<QK-'t^*j\RT*MQHMAo0G3[q\++4XFSUg6=h[a3X*eD]a0h:IGHW3"tEL->Ho#q(#7s!Yu/OT\G)b670/qfcX^DX4*DeF%URJW>a9,7T"U)p9100ICs>(k%0/MZ_[1A9:iF2jAJ6E`!9]OGl#)n/Cqn#hIlLq7V;Uo(\&DZHbD(]M*%Q'W^FD[nAi;P*3`7?@q-<TMWHJatl_o[lBVlpr@V+FW(1()7t"?c:gK!0onGIp)?Dk0gCt/P.#eWAre:#o,E"NE_5r8Q"N#oosE3kXX0c5F;L1\TO&j!jtVY@Z(-S)n3QYZ<3:M+M=Hlf;$K3dUINZ-`gLL^-\?b-qbTD7S#`mJ7*`uImP2-!0n?mu+h=nVHV?#6*83T9,[:!8NN;0$6eeNF%n1o:!QUca'klT!8=Q^Il5<T[*J_1H/s7ctH:HFo6U:'>9%%9`n&S[O#gg8"HP+du)DLRC;R*^YW5i4sF=['._J@Z'(H`,S>4LYZOI_:$6AKQ6<]2r>>c4SsKE`2c-4BPL`KH).TGN7(#*\;qOK3P(90+lZ`NW&/DO4ocacVuf![9'c`CJWM7GXBECq-R1pk^t$>2\H0:J5.^gFNf<8JP"q$@!%"5K"V/!2_k%XKjYe+1Alpr0]k=Y:]M[c<alN,cn`;g8bPi9rHa!r(QZ<[*>M%)(?7^V+!G!NA45uAO5R`CBCBteV4Rk+Eqk:%=6gk]8SV6,/A:4#-kpuOKCK>bV8,-k!qI?6=HrD#1#\dJ?Y':K_FHn+0GK8_YTiTfu%QkTt7=F(YPXcE":qrBf607DrG"4n6;^ZWEbUH*;I#M)&"QJ7M*YY<bc-#fcqj2`F45QX<e!`]T&!a,3GL^K@H*Al[!6-jtp<cK\BQ,#.(EVLc>a"&MSMGN2+RYj/Or6'\Tiq3Mt)&hRfE9^/M(rkI9fQ*ZM''OJUng@,^i[:=:fdLK0Nj>-]#jN)^t@UW;&to$dicH/Dp#W/e6jME3FY\nE7dN;2:=&a@dAgK-!>:!,#7E^1fq`n\0Xf:jT]I5U\9lI8t)8`%6l-RJ4AVS?C@0Zb9W$BpYM%+3TPs5l&UEe4=kDJe3Cr?rog-mSX<,@%=/i7[f%rcq-C;gJk3(rP9:hjmN'ff&E3:4(Wql;BfU6+3dE.V!6HEdYoK_4jq(j@P.4$kbd:`,%!#6<VGu/(ned/].E9j<@,lQ2`-SVH#h0nPfq10=poI3D8s#80\LkhklX%"cP[0\6gOugRZt2H!6rJNfZgaH->1kl'(L,&IY*#edm?h$`,^0M=D?_/8juSL<5>o,hFTJQ,tPlqGp`nrE#/rW&YTrK+4]JP411U`DB'rq2$LHHJ'u08`V+U0BI:>:ZI?9[9*N^.ORcNKIJbukD3"jL5`aIGFE08`l8\6Fn'P&fH\A@j_@+HpF/&!f<P>jRF&B]L5HVkegj@qiJU>VcAf3LJmoLD#2E^sc)E[uiDl_Q=-X_K9SmM"DI6L=\dln/]7dUVC"?u&mtS1</eEME(>ML2L>+SV?`moa5P)6"9]R$?\Cea,_s%N;!'WR&]t8dhXR5#TW`rLMP[]i`B?9;)Y8DJuP`r@>`eBLh5%R#YBFbMQSl'IJ5Hi"t5Crk$o8'--](X`TN-LB,nRdOe39a8.+.:TN=qGcj?C`*<NcI7faLim8*sOooGGc"M+Sk!6*IbZLi%LBHYO@DK_h#X#eF-qOL5c#0a?6^O'U*V:90K"O5P'GG8q-u7C(I>G)jVkp4iP'(q/@N%)%<]?&SR2Q&]D=`78+cqKf^FXRQld<pd)su`\Q!81I\?UI0Rg/KBj/?4MZ^e7LP(`\?/_7a(Vnno^Um384A!Y$qMXLA.p_mi-@d(k*aC+LhbEjbNQ\i"E_MRkaJK\Qsi`400b[["mQSrcBQI^WWu^Pqr[o_[4AE~>endstream

+endobj

+% 'R34': class PDFStream 

+34 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 266 >>

+stream

+Gau0;_+qm%%)#a-5J/3`&aHH#G+QWIgL7sH5Y4+>e0V3@5l5oV^l[Ki%GA%gp[%Wj6C!.CFU)<r\6BP9K6Ntle_i=Q\L`b$l"f)(crsS9G(/A&>In4b<\r/.mq%V\l.a:Z`S>tS+B"%kqNI[SB!SLY%*uGP?%ZM"2q`VKo6=uX^Q5Y2rnhL905u=e5%=-Y^^.Y=@hdgpENolm0!mAXm[K#E&@Ab/]X6mM_?@&0Lr"cdD_d:#ph<F_dlEVa]'>?+;&16&d9s?~>endstream

+endobj

+xref

+0 35

+0000000000 65535 f

+0000000113 00000 n

+0000000234 00000 n

+0000000399 00000 n

+0000000587 00000 n

+0000000814 00000 n

+0000001041 00000 n

+0000001268 00000 n

+0000001494 00000 n

+0000001721 00000 n

+0000001945 00000 n

+0000002173 00000 n

+0000002401 00000 n

+0000002615 00000 n

+0000002783 00000 n

+0000003140 00000 n

+0000003410 00000 n

+0000003681 00000 n

+0000003819 00000 n

+0000004065 00000 n

+0000004190 00000 n

+0000004395 00000 n

+0000004549 00000 n

+0000004720 00000 n

+0000004883 00000 n

+0000005077 00000 n

+0000005236 00000 n

+0000005399 00000 n

+0000005566 00000 n

+0000005735 00000 n

+0000005898 00000 n

+0000006028 00000 n

+0000006154 00000 n

+0000008352 00000 n

+0000011331 00000 n

+trailer

+<< /ID 

+ % ReportLab generated PDF document -- digest (http://www.reportlab.com) 

+ [(L\026\316.\265\347\223\365\204y\010\361\341\344\330\360) (L\026\316.\265\347\223\365\204y\010\361\341\344\330\360)] 

+

+ /Info 18 0 R

+ /Root 17 0 R

+ /Size 35 >>

+startxref

+11712

+%%EOF

diff --git a/pdk/docs/index.jd b/pdk/docs/index.jd
index d8f1739..f5a9344 100644
--- a/pdk/docs/index.jd
+++ b/pdk/docs/index.jd
@@ -3,12 +3,12 @@
 @jd:body
 <div style="float: right; width: 35%;">
 <h3 style="padding-top: 0px;">News</h3>
-<p><b>Compatibility Definition for Android 2.3</b><br/>
-The Compatibility Definition Document for Android 2.3 has been published. 
-The 2.3 CDD allows device manufacturers to use the Android source code to ship
+<p><b>Compatibility Definition for Android 2.3.3</b><br/>
+The Compatibility Definition Document for Android 2.3.3 has been published. 
+Android 2.3 allows device manufacturers to use the Android source code to ship
 a significantly wider variety of devices, including devices with extra-large
-screens, such as tablets.  A release of the Compatibility Test Suite is not
-yet available, but will be soon.  For more information, <a
+screens, such as tablets. Android 2.3.3 adds enhanced Near-Field
+Communications support to the Android APIs.  For more information, <a
 href="{@docRoot}compatibility/index.html">visit the Compatibility page.</a>
 </p>
 <p><b>Source Code Available for Android 2.3</b><br/>
diff --git a/samples/ApiDemos/Android.mk b/samples/ApiDemos/Android.mk
index 7921120..abaf798 100644
--- a/samples/ApiDemos/Android.mk
+++ b/samples/ApiDemos/Android.mk
@@ -10,6 +10,8 @@
         src/com/example/android/apis/app/IRemoteServiceCallback.aidl \
         src/com/example/android/apis/app/ISecondary.aidl \
 
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4
+
 LOCAL_PACKAGE_NAME := ApiDemos
 
 LOCAL_SDK_VERSION := current
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 71c3a06..c570322 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -36,6 +36,8 @@
     <!-- For android.media.audiofx.Visualizer -->
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
 
+    <uses-sdk android:minSdkVersion="4" />
+
     <!-- We will request access to the camera, saying we require a camera
          of some sort but not one with autofocus capability. -->
     <uses-permission android:name="android.permission.CAMERA" />
@@ -44,7 +46,8 @@
 
     <application android:name="ApiDemosApplication"
             android:label="@string/activity_sample_code"
-            android:icon="@drawable/app_sample_code" >
+            android:icon="@drawable/app_sample_code"
+            android:hardwareAccelerated="true">
 
         <!-- This is how we can request a library but still allow the app
              to be installed if it doesn't exist. -->
@@ -73,7 +76,7 @@
 
         <activity android:name=".app.DialogActivity"
                 android:label="@string/activity_dialog"
-                android:theme="@android:style/Theme.Dialog">
+                android:theme="@android:style/Theme.Holo.Dialog">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -149,6 +152,23 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".app.ActivityRecreate"
+                android:label="@string/activity_recreate"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.SoftInputModes"
+                android:label="@string/soft_input_modes">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".app.ReceiveResult" android:label="@string/activity_receive_result">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -156,7 +176,8 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".app.SendResult">
+        <activity android:name=".app.SendResult"
+                android:theme="@style/ThemeDialogWhenLarge">
         </activity>
 
         <activity android:name=".app.Forwarding" android:label="@string/activity_forwarding">
@@ -182,9 +203,12 @@
         <activity android:name=".app.RedirectGetter">
         </activity>
 
+        <!-- This sample doesn't work with the new action bar, so use
+             the old style theme. -->
         <activity android:name=".app.CustomTitle"
                 android:label="@string/activity_custom_title"
-                android:windowSoftInputMode="stateVisible|adjustPan">
+                android:windowSoftInputMode="stateVisible|adjustPan"
+                android:theme="@android:style/Theme">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -218,6 +242,283 @@
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
+        
+        <!-- Fragment Samples -->
+
+        <activity android:name=".app.FragmentAlertDialog"
+                android:label="@string/fragment_alert_dialog"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentArguments"
+                android:label="@string/fragment_arguments"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentHideShow"
+                android:label="@string/fragment_hide_show"
+                android:windowSoftInputMode="stateUnchanged"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentContextMenu"
+                android:label="@string/fragment_context_menu"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentDialog"
+                android:label="@string/fragment_dialog"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentDialogOrActivity"
+                android:label="@string/fragment_dialog_or_activity"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentLayout"
+                android:label="@string/fragment_layout"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentLayout$DetailsActivity"
+                android:enabled="@bool/atLeastHoneycomb" />
+
+        <activity android:name=".app.FragmentListArray"
+                android:label="@string/fragment_list_array"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentMenu"
+                android:label="@string/fragment_menu"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentRetainInstance"
+                android:label="@string/fragment_retain_instance"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentReceiveResult"
+                android:label="@string/fragment_receive_result"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentStack"
+                android:label="@string/fragment_stack"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Fragment Support Samples -->
+
+        <activity android:name=".support.app.FragmentAlertDialogSupport"
+                android:label="@string/fragment_alert_dialog_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentArgumentsSupport"
+                android:label="@string/fragment_arguments_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentHideShowSupport"
+                android:label="@string/fragment_hide_show_support"
+                android:windowSoftInputMode="stateUnchanged">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentContextMenuSupport"
+                android:label="@string/fragment_context_menu_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentDialogSupport"
+                android:label="@string/fragment_dialog_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentDialogOrActivitySupport"
+                android:label="@string/fragment_dialog_or_activity_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentLayoutSupport"
+                android:label="@string/fragment_layout_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentListArraySupport"
+                android:label="@string/fragment_list_array_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentLayoutSupport$DetailsActivity" />
+
+        <activity android:name=".support.app.FragmentMenuSupport"
+                android:label="@string/fragment_menu_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentRetainInstanceSupport"
+                android:label="@string/fragment_retain_instance_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentReceiveResultSupport"
+                android:label="@string/fragment_receive_result_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentStackSupport"
+                android:label="@string/fragment_stack_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.FragmentPagerSupport"
+                android:label="@string/fragment_pager_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Loader Samples -->
+
+        <activity android:name=".app.LoaderCursor"
+                android:label="@string/loader_cursor"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.LoaderCustom"
+                android:label="@string/loader_custom"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+<!-- BEGIN_INCLUDE(loader_throttle) -->
+        <activity android:name=".app.LoaderThrottle"
+                android:label="@string/loader_throttle"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        <provider android:name=".app.LoaderThrottle$SimpleProvider"
+                  android:authorities="com.example.android.apis.app.LoaderThrottle"
+                  android:enabled="@bool/atLeastHoneycomb" />
+<!-- END_INCLUDE(loader_throttle) -->
+
+        <!-- Fragment Support Samples -->
+
+        <activity android:name=".support.app.LoaderCursorSupport"
+                android:label="@string/loader_cursor_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".support.app.LoaderThrottleSupport"
+                android:label="@string/loader_throttle_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        <provider android:name=".support.app.LoaderThrottleSupport$SimpleProvider"
+                  android:authorities="com.example.android.apis.support.app.LoaderThrottle" />
 
         <!-- Intent Samples -->
 
@@ -228,6 +529,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".app.IntentActivityFlags"
+                android:label="@string/activity_intent_activity_flags">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <!-- Service Samples -->
 
         <service android:name=".app.LocalService" />
@@ -361,12 +670,16 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".app.IncomingMessage" android:label="App/Notification/IncomingMessage">
+<!-- BEGIN_INCLUDE(no_task_affinity) -->
+        <activity android:name=".app.IncomingMessage"
+                android:label="App/Notification/IncomingMessage"
+                android:taskAffinity="">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
+<!-- END_INCLUDE(no_task_affinity) -->
 
         <activity android:name=".app.IncomingMessageView" android:label="App/Notification/IncomingMessageView">
             <intent-filter>
@@ -527,50 +840,6 @@
             </intent-filter>
         </activity>
 
-        <!-- Preferences Samples -->
-
-        <activity android:name=".app.PreferencesFromXml" android:label="@string/preferences_from_xml">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".app.PreferencesFromCode" android:label="@string/preferences_from_code">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".app.AdvancedPreferences" android:label="@string/advanced_preferences">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".app.LaunchingPreferences" android:label="@string/launching_preferences">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".app.PreferenceDependencies" android:label="@string/preference_dependencies">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".app.DefaultValues" android:label="@string/default_values">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
         <!-- Device Admin Samples -->
 
         <activity android:name=".app.DeviceAdminSample$Controller"
@@ -612,10 +881,136 @@
             </intent-filter>
         </activity>
 
+        <!-- Action Bar Samples -->
+        <activity android:name=".app.ActionBarMechanics"
+                android:label="@string/action_bar_mechanics"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.ActionBarUsage"
+                android:label="@string/action_bar_usage"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.ActionBarDisplayOptions"
+                android:label="@string/action_bar_display_options"
+                android:logo="@drawable/apidemo_androidlogo"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.ActionBarTabs"
+                android:label="@string/action_bar_tabs"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Application Updating Samples -->
+
+<!-- BEGIN_INCLUDE(app_update_declaration) -->
+        <receiver android:name=".app.AppUpdateReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
+            </intent-filter>
+        </receiver>
+<!-- END_INCLUDE(app_update_declaration) -->
+
+        <!-- ************************************* -->
+        <!--       PREFERENCE PACKAGE SAMPLES      -->
+        <!-- ************************************* -->
+
+        <activity android:name=".preference.FragmentPreferences"
+                android:label="@string/fragment_preferences"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".preference.PreferenceWithHeaders"
+                android:label="@string/preference_with_headers"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".preference.PreferencesFromXml"
+                android:label="@string/preferences_from_xml">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".preference.PreferencesFromCode"
+                android:label="@string/preferences_from_code">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".preference.AdvancedPreferences"
+                android:label="@string/advanced_preferences">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".preference.LaunchingPreferences"
+                android:label="@string/launching_preferences">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".preference.PreferenceDependencies"
+                android:label="@string/preference_dependencies">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".preference.DefaultValues" android:label="@string/default_values">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <!-- ************************************* -->
         <!--        CONTENT PACKAGE SAMPLES        -->
         <!-- ************************************* -->
 
+        <activity android:name=".content.ClipboardSample"
+                android:label="@string/activity_clipboard"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".content.ExternalStorage" android:label="@string/activity_external_storage">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -632,6 +1027,16 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".content.ResourcesWidthAndHeight"
+                android:label="@string/activity_resources_width_and_height"
+                android:enabled="@bool/atLeastIceCreamSandwich">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+                <category android:name="android.intent.category.EMBED" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".content.ReadAsset" android:label="@string/activity_read_asset">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -697,6 +1102,126 @@
         </receiver>
 
         <!-- ************************************* -->
+        <!--     ANDROID.ANIMATION PACKAGE SAMPLES         -->
+        <!-- ************************************* -->
+
+        <activity android:name=".animation.AnimationLoading"
+                android:label="Animation/Loading"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.AnimationCloning"
+                android:label="Animation/Cloning"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.AnimationSeeking"
+                android:label="Animation/Seeking"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.AnimatorEvents"
+                android:label="Animation/Events"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.BouncingBalls"
+                android:label="Animation/Bouncing Balls"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.CustomEvaluator"
+                android:label="Animation/Custom Evaluator"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.ListFlipper"
+                android:label="Animation/View Flip"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.ReversingAnimation"
+                android:label="Animation/Reversing"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.MultiPropertyAnimation"
+                android:label="Animation/Multiple Properties"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.LayoutAnimations"
+                android:label="Animation/Layout Animations"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.LayoutAnimationsHideShow"
+                android:label="Animation/Hide-Show Animations"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.LayoutAnimationsByDefault"
+                android:label="Animation/Default Layout Animations"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
         <!--     ANIMATION PACKAGE SAMPLES         -->
         <!-- ************************************* -->
 
@@ -830,21 +1355,50 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.Tabs1" android:label="Views/Tabs/Content By Id">
+        <activity android:name=".view.HorizontalScrollView1" android:label="Views/Layouts/HorizontalScrollView">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs1" android:label="Views/Tabs/1. Content By Id">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.Tabs2" android:label="Views/Tabs/Content By Factory">
+        <activity android:name=".view.Tabs2" android:label="Views/Tabs/2. Content By Factory">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.Tabs3" android:label="Views/Tabs/Content By Intent">
+        <activity android:name=".view.Tabs3" android:label="Views/Tabs/3. Content By Intent">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs4" android:label="Views/Tabs/4. Non Holo theme"
+                  android:theme="@android:style/Theme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs5" android:label="Views/Tabs/5. Scrollable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs6" android:label="Views/Tabs/6. Right aligned">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.SAMPLE_CODE"/>
@@ -942,27 +1496,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.Tabs1" android:label="Views/Tabs/Content By Id">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.SAMPLE_CODE"/>
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".view.Tabs2" android:label="Views/Tabs/Content By Factory">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.SAMPLE_CODE"/>
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".view.Tabs3" android:label="Views/Tabs/Content By Intent">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.SAMPLE_CODE"/>
-            </intent-filter>
-        </activity>
-
         <activity android:name=".view.Baseline1" android:label="Views/Layouts/Baseline/1. Top">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1054,63 +1587,63 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List1" android:label="Views/Lists/1. Array">
+        <activity android:name=".view.List1" android:label="Views/Lists/01. Array">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List2" android:label="Views/Lists/2. Cursor (People)">
+        <activity android:name=".view.List2" android:label="Views/Lists/02. Cursor (People)">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List3" android:label="Views/Lists/3. Cursor (Phones)">
+        <activity android:name=".view.List3" android:label="Views/Lists/03. Cursor (Phones)">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List4" android:label="Views/Lists/4. ListAdapter">
+        <activity android:name=".view.List4" android:label="Views/Lists/04. ListAdapter">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List5" android:label="Views/Lists/5. Separators">
+        <activity android:name=".view.List5" android:label="Views/Lists/05. Separators">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List6" android:label="Views/Lists/6. ListAdapter Collapsed">
+        <activity android:name=".view.List6" android:label="Views/Lists/06. ListAdapter Collapsed">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List7" android:label="Views/Lists/7. Cursor (Phones)">
+        <activity android:name=".view.List7" android:label="Views/Lists/07. Cursor (Phones)">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List8" android:label="Views/Lists/8. Photos">
+        <activity android:name=".view.List8" android:label="Views/Lists/08. Photos">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.List9" android:label="Views/Lists/9. Array (Overlay)">
+        <activity android:name=".view.List9" android:label="Views/Lists/09. Array (Overlay)">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1152,6 +1685,27 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.List15" android:label="Views/Lists/15. Selection Mode">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List16" android:label="Views/Lists/16. Border selection mode">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List17" android:label="Views/Lists/17. Activate items">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.ExpandableList1" android:label="Views/Expandable Lists/1. Custom Adapter">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1217,6 +1771,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.Grid3"
+                  android:label="Views/Grid/3. Selection Mode">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.ImageView1"
                 android:label="Views/ImageView">
             <intent-filter>
@@ -1320,15 +1882,55 @@
         </activity>
 
         <activity android:name=".view.Controls1"
-                android:label="Views/Controls/1. Light Theme"
-                android:theme="@android:style/Theme.Light">
+                  android:label="Views/Controls/1. Light Theme"
+                  android:theme="@android:style/Theme.Light">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.Controls2" android:label="Views/Controls/2. Default Theme">
+        <activity android:name=".view.Controls2"
+                  android:label="Views/Controls/2. Dark Theme"
+                  android:theme="@android:style/Theme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls3"
+                  android:label="Views/Controls/3. Holo Light Theme"
+                  android:theme="@android:style/Theme.Holo.Light"
+                  android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls4"
+                  android:label="Views/Controls/4. Holo Dark Theme"
+                  android:theme="@android:style/Theme.Holo"
+                  android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls5"
+                  android:label="Views/Controls/5. Custom Theme"
+                  android:theme="@style/CustomTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls6"
+                  android:label="Views/Controls/6. Holo or Old Theme"
+                  android:theme="@style/ThemeHolo">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1455,6 +2057,13 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.Focus5" android:label="Views/Focus/5. Sequential (Tab Order)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.DateWidgets1" android:label="Views/Date Widgets/1. Dialog">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1469,6 +2078,38 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.PopupMenu1" android:label="Views/Popup Menu">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.SearchViewActionBar" android:label="Views/Search View/Action Bar"
+                android:theme="@android:style/Theme.Holo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+            <meta-data android:name="android.app.default_searchable"
+                       android:value=".app.SearchQueryResults" />
+        </activity>
+
+        <activity android:name=".view.SearchViewFilterMode" android:label="Views/Search View/Filter"
+                android:theme="@android:style/Theme.Holo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.RotatingButton" android:label="Views/Rotating Button">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.SecureView" android:label="Views/Secure View">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1476,6 +2117,30 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.SplitTouchView" android:label="Views/Splitting Touches across Views">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.DragAndDropDemo"
+                android:label="Views/Drag and Drop"
+                android:hardwareAccelerated="false"
+                android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.GameControllerInput" android:label="Views/Game Controller Input">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <!-- ************************************* -->
         <!--           GRAPHICS SAMPLES            -->
         <!-- ************************************* -->
@@ -1572,9 +2237,19 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".graphics.HiddenActivity"
+                android:label="Graphics/OpenGL ES/Hidden Activity"
+                android:theme="@android:style/Theme.Translucent"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
         <activity android:name=".graphics.TriangleActivity"
                 android:label="Graphics/OpenGL ES/Textured Triangle"
-                android:theme="@android:style/Theme.NoTitleBar"
+                android:theme="@android:style/Theme.Holo.Dialog"
                 android:configChanges="orientation|keyboardHidden">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1646,7 +2321,8 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".graphics.TextAlign" android:label="Graphics/Text Align">
+        <activity android:hardwareAccelerated="false"
+                  android:name=".graphics.TextAlign" android:label="Graphics/Text Align">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1667,7 +2343,8 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".graphics.Clipping" android:label="Graphics/Clipping">
+        <activity android:hardwareAccelerated="false"
+                  android:name=".graphics.Clipping" android:label="Graphics/Clipping">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1681,7 +2358,8 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".graphics.UnicodeChart" android:label="Graphics/UnicodeChart">
+        <activity android:hardwareAccelerated="false"
+                  android:name=".graphics.UnicodeChart" android:label="Graphics/UnicodeChart">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1695,14 +2373,16 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".graphics.Pictures" android:label="Graphics/Pictures">
+        <activity android:hardwareAccelerated="false"
+                  android:name=".graphics.Pictures" android:label="Graphics/Pictures">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".graphics.Vertices" android:label="Graphics/Vertices">
+        <activity android:hardwareAccelerated="false"
+                  android:name=".graphics.Vertices" android:label="Graphics/Vertices">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1779,7 +2459,8 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".graphics.BitmapDecode" android:label="Graphics/BitmapDecode">
+        <activity android:hardwareAccelerated="false"
+                  android:name=".graphics.BitmapDecode" android:label="Graphics/BitmapDecode">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1800,7 +2481,8 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".graphics.DrawPoints" android:label="Graphics/Points">
+        <activity android:hardwareAccelerated="false"
+                  android:name=".graphics.DrawPoints" android:label="Graphics/Points">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
diff --git a/samples/ApiDemos/README.txt b/samples/ApiDemos/README.txt
new file mode 100644
index 0000000..30a5672
--- /dev/null
+++ b/samples/ApiDemos/README.txt
@@ -0,0 +1,19 @@
+The API Demos application includes a variety of small applications 
+that illustrate the use of various Android APIs. It includes samples of:
+  - Notifications
+  - Alarms
+  - Progress Dialogs
+  - Intents
+  - Menus
+  - Search
+  - Persistent application state
+  - Preferences
+  - Background Services
+  - App Widgets
+  - Voice Recognition
+  - And many many more...
+
+Api demos is designed to use the compatibility library "android-support-v4.jar".
+It is available through the SDK Updater in the "Android Compatibility package".
+Once downloaded, copy the jar file into the ApiDemos project libs/ folder.
+(If using Eclipse, add it manually to the project build path).
\ No newline at end of file
diff --git a/samples/ApiDemos/_index.html b/samples/ApiDemos/_index.html
index 399ef86..ffe5db5 100644
--- a/samples/ApiDemos/_index.html
+++ b/samples/ApiDemos/_index.html
@@ -37,7 +37,8 @@
 "    <li><a href='src/com/example/android/apis/media/index.html'>Media</a></li>"+
 "    <li><a href='src/com/example/android/apis/os/index.html'>OS</a></li>"+
 "    <li><a href='src/com/example/android/apis/text/index.html'>Text</a></li>"+
-"    <li><a href='src/com/example/android/apis/view/index.html'>Views</a></li></ul>");
+"    <li><a href='src/com/example/android/apis/view/index.html'>Views</a></li></ul>"+
+"    <li><a href='src/com/example/android/apis/support/index.html'>Static Support Library</a></li>");
 
 }
 
diff --git a/samples/ApiDemos/res/anim/animator.xml b/samples/ApiDemos/res/anim/animator.xml
new file mode 100644
index 0000000..2432f19
--- /dev/null
+++ b/samples/ApiDemos/res/anim/animator.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="1000"
+    android:valueFrom="1"
+    android:valueTo="0"
+    android:valueType="floatType"
+    android:repeatCount="1"
+    android:repeatMode="reverse"/>
diff --git a/samples/ApiDemos/res/anim/animator_set.xml b/samples/ApiDemos/res/anim/animator_set.xml
new file mode 100644
index 0000000..cab24c5
--- /dev/null
+++ b/samples/ApiDemos/res/anim/animator_set.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<set>
+    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+        android:duration="1000"
+        android:valueTo="200"
+        android:valueType="floatType"
+        android:propertyName="x"
+        android:repeatCount="1"
+        android:repeatMode="reverse"/>
+    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+        android:duration="1000"
+        android:valueTo="400"
+        android:valueType="floatType"
+        android:propertyName="y"
+        android:repeatCount="1"
+        android:repeatMode="reverse"/>
+</set>
diff --git a/samples/ApiDemos/res/anim/color_animator.xml b/samples/ApiDemos/res/anim/color_animator.xml
new file mode 100644
index 0000000..08ca017
--- /dev/null
+++ b/samples/ApiDemos/res/anim/color_animator.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="1000"
+    android:valueFrom="#0f0"
+    android:valueTo="#00ffff"
+    android:propertyName="color"
+    android:repeatCount="1"
+    android:repeatMode="reverse"/>
diff --git a/samples/ApiDemos/res/anim/object_animator.xml b/samples/ApiDemos/res/anim/object_animator.xml
new file mode 100644
index 0000000..863d423
--- /dev/null
+++ b/samples/ApiDemos/res/anim/object_animator.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="1000"
+    android:valueTo="200"
+    android:valueType="floatType"
+    android:propertyName="y"
+    android:repeatCount="1"
+    android:repeatMode="reverse"/>
diff --git a/samples/ApiDemos/res/drawable-hdpi/apidemo_androidlogo.png b/samples/ApiDemos/res/drawable-hdpi/apidemo_androidlogo.png
new file mode 100644
index 0000000..088181b
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/apidemo_androidlogo.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-mdpi/apidemo_androidlogo.png b/samples/ApiDemos/res/drawable-mdpi/apidemo_androidlogo.png
new file mode 100644
index 0000000..11cb47b
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-mdpi/apidemo_androidlogo.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-mdpi/ic_settings_applications.png b/samples/ApiDemos/res/drawable-mdpi/ic_settings_applications.png
new file mode 100755
index 0000000..745ff2a
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-mdpi/ic_settings_applications.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-mdpi/ic_settings_display.png b/samples/ApiDemos/res/drawable-mdpi/ic_settings_display.png
new file mode 100644
index 0000000..85af393
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-mdpi/ic_settings_display.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/magnifying_glass.png b/samples/ApiDemos/res/drawable/magnifying_glass.png
new file mode 100755
index 0000000..2592ae0
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/magnifying_glass.png
Binary files differ
diff --git a/samples/ApiDemos/res/layout-h420dp/resources_height.xml b/samples/ApiDemos/res/layout-h420dp/resources_height.xml
new file mode 100644
index 0000000..115a731
--- /dev/null
+++ b/samples/ApiDemos/res/layout-h420dp/resources_height.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Part of resources_width_and_height that varies based on height. -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
+            android:orientation="vertical">
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#8000ff00">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#80ff0000">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#8000ff00">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#80ff0000">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+    </LinearLayout>
+</merge>
diff --git a/samples/ApiDemos/res/layout-h670dp/resources_height.xml b/samples/ApiDemos/res/layout-h670dp/resources_height.xml
new file mode 100644
index 0000000..3130a91
--- /dev/null
+++ b/samples/ApiDemos/res/layout-h670dp/resources_height.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Part of resources_width_and_height that varies based on height. -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
+            android:orientation="vertical">
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#8000ff00">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#80ff0000">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#8000ff00">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#80ff0000">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#8000ff00">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#80ff0000">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#8000ff00">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#80ff0000">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+    </LinearLayout>
+</merge>
diff --git a/samples/ApiDemos/res/layout-land/fragment_arguments.xml b/samples/ApiDemos/res/layout-land/fragment_arguments.xml
new file mode 100644
index 0000000..e27df99
--- /dev/null
+++ b/samples/ApiDemos/res/layout-land/fragment_arguments.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:padding="4dip"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:gravity="top|center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/fragment_arguments_msg" />
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <fragment class="com.example.android.apis.app.FragmentArguments$MyFragment"
+                android:id="@+id/embedded"
+                android:layout_width="0px" android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:label="@string/fragment_arguments_embedded" />
+
+        <FrameLayout
+                android:id="@+id/created"
+                android:layout_width="0px"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <fragment class="com.example.android.apis.app.FragmentArguments$MyFragment"
+            android:id="@+id/embedded_land"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:label="@string/fragment_arguments_embedded_land" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout-land/fragment_arguments_support.xml b/samples/ApiDemos/res/layout-land/fragment_arguments_support.xml
new file mode 100644
index 0000000..9aa8daf
--- /dev/null
+++ b/samples/ApiDemos/res/layout-land/fragment_arguments_support.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:padding="4dip"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:gravity="top|center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/fragment_arguments_msg" />
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <fragment class="com.example.android.apis.support.app.FragmentArgumentsSupport$MyFragment"
+                android:id="@+id/embedded"
+                android:layout_width="0px" android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:label="@string/fragment_arguments_embedded" />
+
+        <FrameLayout
+                android:id="@+id/created"
+                android:layout_width="0px"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <fragment class="com.example.android.apis.support.app.FragmentArgumentsSupport$MyFragment"
+            android:id="@+id/embedded_land"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:label="@string/fragment_arguments_embedded_land" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout-land/fragment_layout.xml b/samples/ApiDemos/res/layout-land/fragment_layout.xml
new file mode 100644
index 0000000..c1ef203
--- /dev/null
+++ b/samples/ApiDemos/res/layout-land/fragment_layout.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the layout fragment sample.  This version is
+     for display when in landscape: we can fit both titles and dialog. -->
+
+<!-- BEGIN_INCLUDE(layout) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <fragment class="com.example.android.apis.app.FragmentLayout$TitlesFragment"
+            android:id="@+id/titles" android:layout_weight="1"
+            android:layout_width="0px" android:layout_height="match_parent" />
+
+    <FrameLayout android:id="@+id/details" android:layout_weight="1"
+            android:layout_width="0px" android:layout_height="match_parent"
+            android:background="?android:attr/detailsElementBackground" />
+    
+</LinearLayout>
+<!-- END_INCLUDE(layout) -->
diff --git a/samples/ApiDemos/res/layout-land/fragment_layout_support.xml b/samples/ApiDemos/res/layout-land/fragment_layout_support.xml
new file mode 100644
index 0000000..de31341
--- /dev/null
+++ b/samples/ApiDemos/res/layout-land/fragment_layout_support.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the layout fragment sample.  This version is
+     for display when in landscape: we can fit both titles and dialog. -->
+
+<!-- BEGIN_INCLUDE(layout) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <fragment class="com.example.android.apis.support.app.FragmentLayoutSupport$TitlesFragment"
+            android:id="@+id/titles" android:layout_weight="1"
+            android:layout_width="0px" android:layout_height="match_parent" />
+
+    <FrameLayout android:id="@+id/details" android:layout_weight="1"
+            android:layout_width="0px" android:layout_height="match_parent" />
+
+</LinearLayout>
+<!-- END_INCLUDE(layout) -->
diff --git a/samples/ApiDemos/res/layout-w420dp/resources_width.xml b/samples/ApiDemos/res/layout-w420dp/resources_width.xml
new file mode 100644
index 0000000..1edffe3
--- /dev/null
+++ b/samples/ApiDemos/res/layout-w420dp/resources_width.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Part of resources_width_and_height that varies based on width. -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
+            android:orientation="horizontal">
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w420dp Width\n#1">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w420dp Width\n#2">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w420dp Width\n#3">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w420dp Width\n#4">
+        </TextView>
+    </LinearLayout>
+</merge>
diff --git a/samples/ApiDemos/res/layout-w720dp/resources_width.xml b/samples/ApiDemos/res/layout-w720dp/resources_width.xml
new file mode 100644
index 0000000..8625c82
--- /dev/null
+++ b/samples/ApiDemos/res/layout-w720dp/resources_width.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Part of resources_width_and_height that varies based on width. -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
+            android:orientation="horizontal">
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#1">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#2">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#3">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#4">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#5">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#6">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#7">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="w720dp Width\n#8">
+        </TextView>
+    </LinearLayout>
+</merge>
diff --git a/samples/ApiDemos/res/layout/action_bar_display_options.xml b/samples/ApiDemos/res/layout/action_bar_display_options.xml
new file mode 100644
index 0000000..1718fdb
--- /dev/null
+++ b/samples/ApiDemos/res/layout/action_bar_display_options.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <Button android:id="@+id/toggle_home_as_up"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/toggle_home_as_up" />
+    <Button android:id="@+id/toggle_show_home"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/toggle_show_home" />
+    <Button android:id="@+id/toggle_use_logo"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/toggle_use_logo" />
+    <Button android:id="@+id/toggle_show_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/toggle_show_title" />
+    <Button android:id="@+id/toggle_show_custom"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/toggle_show_custom" />
+    <Button android:id="@+id/toggle_navigation"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/toggle_navigation" />
+    <Button android:id="@+id/cycle_custom_gravity"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/cycle_custom_gravity" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/action_bar_display_options_custom.xml b/samples/ApiDemos/res/layout/action_bar_display_options_custom.xml
new file mode 100644
index 0000000..b7f5bd9
--- /dev/null
+++ b/samples/ApiDemos/res/layout/action_bar_display_options_custom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+        android:text="@string/display_options_custom_button" />
diff --git a/samples/ApiDemos/res/layout/action_bar_tab_content.xml b/samples/ApiDemos/res/layout/action_bar_tab_content.xml
new file mode 100644
index 0000000..c0aa7fa
--- /dev/null
+++ b/samples/ApiDemos/res/layout/action_bar_tab_content.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@+id/text"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content" />
diff --git a/samples/ApiDemos/res/layout/action_bar_tabs.xml b/samples/ApiDemos/res/layout/action_bar_tabs.xml
new file mode 100644
index 0000000..a51f46e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/action_bar_tabs.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <FrameLayout android:id="@+id/fragment_content"
+                 android:layout_width="match_parent"
+                 android:layout_height="0dip"
+                 android:layout_weight="1" />
+    <LinearLayout android:layout_width="match_parent"
+                  android:layout_height="0dip"
+                  android:layout_weight="1"
+                  android:orientation="vertical">
+        <Button android:id="@+id/btn_add_tab"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/btn_add_tab"
+                android:onClick="onAddTab" />
+        <Button android:id="@+id/btn_remove_tab"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/btn_remove_tab"
+                android:onClick="onRemoveTab" />
+        <Button android:id="@+id/btn_toggle_tabs"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/btn_toggle_tabs"
+                android:onClick="onToggleTabs" />
+        <Button android:id="@+id/btn_remove_all_tabs"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/btn_remove_all_tabs"
+                android:onClick="onRemoveAllTabs" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/activity_recreate.xml b/samples/ApiDemos/res/layout/activity_recreate.xml
new file mode 100644
index 0000000..d55dfbd
--- /dev/null
+++ b/samples/ApiDemos/res/layout/activity_recreate.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/activity_recreate_msg"/>
+
+    <Button android:id="@+id/recreate"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/recreate">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/alert_dialog.xml b/samples/ApiDemos/res/layout/alert_dialog.xml
index 0097e7a..9855605 100644
--- a/samples/ApiDemos/res/layout/alert_dialog.xml
+++ b/samples/ApiDemos/res/layout/alert_dialog.xml
@@ -29,6 +29,9 @@
         <Button android:id="@+id/two_buttons2"
             android:layout_width="match_parent" android:layout_height="wrap_content"
             android:text="@string/alert_dialog_two_buttons2"/>
+        <Button android:id="@+id/two_buttons2ultra"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_two_buttons2ultra"/>
         <Button android:id="@+id/select_button"
             android:layout_width="match_parent" android:layout_height="wrap_content"
             android:text="@string/alert_dialog_select_button"/>
@@ -47,5 +50,11 @@
         <Button android:id="@+id/text_entry_button"
             android:layout_width="match_parent" android:layout_height="wrap_content"
             android:text="@string/alert_dialog_text_entry"/>
+        <Button android:id="@+id/two_buttons_old_school"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_two_buttons_old_school"/>
+        <Button android:id="@+id/two_buttons_holo_light"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_two_buttons_holo_light"/>
     </LinearLayout>
 </ScrollView>
diff --git a/samples/ApiDemos/res/layout/animation_cloning.xml b/samples/ApiDemos/res/layout/animation_cloning.xml
new file mode 100644
index 0000000..de51880
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_cloning.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Run"
+        android:id="@+id/startButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_custom_evaluator.xml b/samples/ApiDemos/res/layout/animation_custom_evaluator.xml
new file mode 100644
index 0000000..0d6285c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_custom_evaluator.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Play"
+        android:id="@+id/startButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_loading.xml b/samples/ApiDemos/res/layout/animation_loading.xml
new file mode 100644
index 0000000..de51880
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_loading.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Run"
+        android:id="@+id/startButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_multi_property.xml b/samples/ApiDemos/res/layout/animation_multi_property.xml
new file mode 100644
index 0000000..de51880
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_multi_property.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Run"
+        android:id="@+id/startButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_reversing.xml b/samples/ApiDemos/res/layout/animation_reversing.xml
new file mode 100644
index 0000000..8d84d43
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_reversing.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Play"
+            android:id="@+id/startButton"
+            />
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Reverse"
+            android:id="@+id/reverseButton"
+            />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_seeking.xml b/samples/ApiDemos/res/layout/animation_seeking.xml
new file mode 100644
index 0000000..afe4a4e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_seeking.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Run"
+            android:id="@+id/startButton"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/seekBar"
+        />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animator_custom_evaluator.xml b/samples/ApiDemos/res/layout/animator_custom_evaluator.xml
new file mode 100644
index 0000000..f3699d5
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animator_custom_evaluator.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Play"
+            android:id="@+id/startButton"
+            />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animator_events.xml b/samples/ApiDemos/res/layout/animator_events.xml
new file mode 100644
index 0000000..b015ac8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animator_events.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Play"
+            android:id="@+id/startButton"
+            />
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Cancel"
+            android:id="@+id/cancelButton"
+            />
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="End"
+            android:id="@+id/endButton"
+            />
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="End Immediately"
+            android:id="@+id/endCB"
+            />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Sequencer Events:   "
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Start   "
+            android:id="@+id/startText"
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Repeat   "
+            android:id="@+id/repeatText"
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Cancel   "
+            android:id="@+id/cancelText"
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="End"
+            android:id="@+id/endText"
+            />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Animator Events:   "
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Start   "
+            android:id="@+id/startTextAnimator"
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Repeat   "
+            android:id="@+id/repeatTextAnimator"
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Cancel   "
+            android:id="@+id/cancelTextAnimator"
+            />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="End"
+            android:id="@+id/endTextAnimator"
+            />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/appwidget_provider.xml b/samples/ApiDemos/res/layout/appwidget_provider.xml
index 373db8f..559b09e 100644
--- a/samples/ApiDemos/res/layout/appwidget_provider.xml
+++ b/samples/ApiDemos/res/layout/appwidget_provider.xml
@@ -18,6 +18,7 @@
     android:id="@+id/appwidget_text"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
+    android:background="#ffff00ff"
     android:textColor="#ff000000"
 />
 
diff --git a/samples/ApiDemos/res/layout/bouncing_balls.xml b/samples/ApiDemos/res/layout/bouncing_balls.xml
new file mode 100644
index 0000000..e5d7da5
--- /dev/null
+++ b/samples/ApiDemos/res/layout/bouncing_balls.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    >
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/clipboard.xml b/samples/ApiDemos/res/layout/clipboard.xml
new file mode 100644
index 0000000..645b1ea
--- /dev/null
+++ b/samples/ApiDemos/res/layout/clipboard.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates clipboard.
+
+    See corresponding Java code:
+    com.example.android.apis.content.ClipboardSample
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/copy_styled_text"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:onClick="pasteStyledText"
+            android:text="@string/copy_text" />
+
+        <TextView
+            android:id="@+id/styled_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:textStyle="normal" />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/copy_plain_text"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:onClick="pastePlainText"
+            android:text="@string/copy_text" />
+
+        <TextView
+            android:id="@+id/plain_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:textStyle="normal" />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/copy_intent"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:onClick="pasteIntent"
+            android:text="@string/copy_intent" />
+
+        <Button android:id="@+id/copy_uri"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:onClick="pasteUri"
+            android:text="@string/copy_uri" />
+
+    </LinearLayout>
+
+    <Spinner android:id="@+id/clip_type"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:drawSelectorOnTop="true"
+        android:prompt="@string/clip_type_prompt"
+    />
+
+    <TextView
+        android:id="@+id/clip_mime_types"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:textStyle="normal"
+        />
+
+    <EditText
+        android:id="@+id/clip_text"
+        android:layout_width="match_parent"
+        android:layout_height="0px"
+        android:layout_weight="1"
+        android:textStyle="normal"
+        />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/controls_1.xml b/samples/ApiDemos/res/layout/controls_1.xml
index 1aaef3d..e280188 100644
--- a/samples/ApiDemos/res/layout/controls_1.xml
+++ b/samples/ApiDemos/res/layout/controls_1.xml
@@ -23,23 +23,46 @@
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
-    
+
+       <LinearLayout
+           android:orientation="horizontal"
+           android:layout_width="match_parent"
+           android:layout_height="wrap_content">
+
         <Button android:id="@+id/button"
             android:text="@string/controls_1_save"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"/>
-    
+
+        <Button android:id="@+id/button_disabled"
+            android:text="@string/controls_1_save"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+      </LinearLayout>
+
+      <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
         <EditText android:id="@+id/edit"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>
-            
+
+        <EditText android:id="@+id/edit2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+      </LinearLayout>
+
         <CheckBox android:id="@+id/check1"
             android:paddingBottom="24sp"
 	        android:paddingTop="24sp"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/controls_1_checkbox_1" />
-    
+
         <CheckBox android:id="@+id/check2"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -116,6 +139,14 @@
             android:text="@string/listSeparatorTextViewStyle"
             android:layout_marginTop="5dip"
         />
+
+        <TextView
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginTop="400dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:text="(And all inside of a ScrollView!)"
+        />
         
     </LinearLayout>
 
diff --git a/samples/ApiDemos/res/layout/device_admin_sample.xml b/samples/ApiDemos/res/layout/device_admin_sample.xml
index 16b08ce..374b87f 100644
--- a/samples/ApiDemos/res/layout/device_admin_sample.xml
+++ b/samples/ApiDemos/res/layout/device_admin_sample.xml
@@ -15,132 +15,280 @@
 -->
 
 <!-- Demonstrates implementation of a DeviceAdmin. -->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:padding="4dip"
-    android:gravity="center_horizontal"
-    android:layout_width="match_parent" android:layout_height="match_parent">
+    <LinearLayout
+        android:orientation="vertical" android:padding="4dip"
+        android:gravity="center_horizontal"
+        android:layout_width="match_parent" android:layout_height="match_parent">
 
-    <TextView
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:paddingBottom="4dip"
-        android:text="@string/sample_device_admin_summary"/>
-
-    <LinearLayout android:orientation="horizontal" android:gravity="center"
-        android:layout_width="match_parent" android:layout_height="wrap_content">
-
-        <Button android:id="@+id/enable"
-            android:layout_width="wrap_content" android:layout_height="wrap_content"
-            android:text="@string/enable_admin">
-            <requestFocus />
-        </Button>
-
-        <Button android:id="@+id/disable"
-            android:layout_width="wrap_content" android:layout_height="wrap_content"
-            android:text="@string/disable_admin">
-        </Button>
-
-    </LinearLayout>
-
-    <LinearLayout android:orientation="horizontal" android:gravity="center"
-        android:layout_width="match_parent" android:layout_height="wrap_content">
-
-        <Spinner android:id="@+id/password_quality"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:drawSelectorOnTop="true"
-            android:prompt="@string/password_quality">
-        </Spinner>
-
-        <EditText android:id="@+id/password_length"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:hint="@string/password_length_hint"
-            android:inputType="number">
-        </EditText>
-
-    </LinearLayout>
-
-    <Button android:id="@+id/set_password"
-        android:layout_width="wrap_content" android:layout_height="wrap_content"
-        android_layout_gravity="east|center_vertical"
-        android:text="@string/set_password">
-    </Button>
-
-    <LinearLayout android:orientation="horizontal" android:gravity="center"
-        android:layout_width="match_parent" android:layout_height="wrap_content">
-
-        <EditText android:id="@+id/password"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:hint="@string/password_hint"
-            android:freezesText="true">
-        </EditText>
-
-        <Button android:id="@+id/reset_password"
-            android:layout_width="wrap_content" android:layout_height="wrap_content"
+        <TextView
+            android:layout_width="match_parent" android:layout_height="wrap_content"
             android:layout_weight="0"
-            android:text="@string/reset_password">
-        </Button>
+            android:paddingBottom="4dip"
+            android:text="@string/sample_device_admin_summary"/>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <Button android:id="@+id/enable"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="@string/enable_admin">
+                <requestFocus />
+            </Button>
+
+            <Button android:id="@+id/disable"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="@string/disable_admin">
+            </Button>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <Spinner android:id="@+id/password_quality"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:drawSelectorOnTop="true"
+                android:prompt="@string/password_quality">
+            </Spinner>
+
+            <EditText android:id="@+id/password_length"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_length_hint"
+                android:inputType="number">
+            </EditText>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/password_minimum_letters"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_minimum_letters_hint"
+                android:inputType="number">
+            </EditText>
+
+            <EditText android:id="@+id/password_minimum_numeric"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_minimum_numeric_hint"
+                android:inputType="number">
+            </EditText>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/password_minimum_lowercase"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_minimum_lowercase_hint"
+                android:inputType="number">
+            </EditText>
+
+            <EditText android:id="@+id/password_minimum_uppercase"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_minimum_uppercase_hint"
+                android:inputType="number">
+            </EditText>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/password_minimum_symbols"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_minimum_symbols_hint"
+                android:inputType="number">
+            </EditText>
+
+            <EditText android:id="@+id/password_minimum_nonletter"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_minimum_nonletter_hint"
+                android:inputType="number">
+            </EditText>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/password_history_length"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_history_length_hint"
+                android:inputType="number">
+            </EditText>
+
+            <Button android:id="@+id/set_password"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android_layout_gravity="east|center_vertical"
+                android:text="@string/set_password">
+            </Button>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/password_expiration"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/password_expiration_hint"
+                android:inputType="number">
+            </EditText>
+
+            <Button android:id="@+id/update_expiration_button"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android_layout_gravity="east|center_vertical"
+                android:text="@string/update_expiration_label">
+            </Button>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <TextView android:id="@+id/password_expiration_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content" />
+
+            <Button android:id="@+id/update_expiration_status_button"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android_layout_gravity="east|center_vertical"
+                android:text="@string/update_expiration_status_label" />
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/password"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:hint="@string/password_hint"
+                android:freezesText="true">
+            </EditText>
+
+            <Button android:id="@+id/reset_password"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="@string/reset_password">
+            </Button>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/max_failed_pw"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:hint="@string/max_failed_pw_hint"
+                android:inputType="number">
+            </EditText>
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <Button android:id="@+id/force_lock"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="@string/force_lock">
+            </Button>
+
+            <Button android:id="@+id/wipe_data"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="@string/wipe_data">
+            </Button>
+
+            <Button android:id="@+id/wipe_all_data"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="@string/wipe_all_data">
+            </Button>
+
+
+        </LinearLayout>
+
+        <LinearLayout android:orientation="horizontal" android:gravity="center"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/timeout"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:hint="@string/timeout_hint"
+                android:inputType="number"
+                android:freezesText="true">
+            </EditText>
+
+            <Button android:id="@+id/set_timeout"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="@string/set_timeout_label">
+            </Button>
+
+        </LinearLayout>
+
+        <!-- Encryption Status Controls -->
+        <LinearLayout
+            android:orientation="horizontal"
+            android:gravity="center"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" >
+
+            <Button android:id="@+id/encryption_enable_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/encryption_enable_label" />
+
+            <Button android:id="@+id/encryption_disable_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/encryption_disable_label" />
+
+            <Button android:id="@+id/encryption_activate_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/encryption_activate_label" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:gravity="center"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" >
+
+            <TextView android:id="@+id/encryption_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content" />
+
+            <Button android:id="@+id/encryption_update_status_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android_layout_gravity="east|center_vertical"
+                android:text="@string/update_encryption_status_label" />
+
+        </LinearLayout>
 
     </LinearLayout>
 
-    <LinearLayout android:orientation="horizontal" android:gravity="center"
-        android:layout_width="match_parent" android:layout_height="wrap_content">
-
-        <EditText android:id="@+id/max_failed_pw"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:hint="@string/max_failed_pw_hint"
-            android:inputType="number">
-        </EditText>
-
-    </LinearLayout>
-
-    <Button android:id="@+id/force_lock"
-        android:layout_width="wrap_content" android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:text="@string/force_lock">
-    </Button>
-
-    <LinearLayout android:orientation="horizontal" android:gravity="center"
-        android:layout_width="match_parent" android:layout_height="wrap_content">
-
-        <Button android:id="@+id/wipe_data"
-            android:layout_width="wrap_content" android:layout_height="wrap_content"
-            android:layout_weight="0"
-            android:text="@string/wipe_data">
-        </Button>
-
-        <Button android:id="@+id/wipe_all_data"
-            android:layout_width="wrap_content" android:layout_height="wrap_content"
-            android:layout_weight="0"
-            android:text="@string/wipe_all_data">
-        </Button>
-
-    </LinearLayout>
-
-    <LinearLayout android:orientation="horizontal" android:gravity="center"
-        android:layout_width="match_parent" android:layout_height="wrap_content">
-
-        <EditText android:id="@+id/timeout"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:hint="@string/timeout_hint"
-            android:inputType="number"
-            android:freezesText="true">
-        </EditText>
-
-        <Button android:id="@+id/set_timeout"
-            android:layout_width="wrap_content" android:layout_height="wrap_content"
-            android:layout_weight="0"
-            android:text="@string/set_timeout_label">
-        </Button>
-
-    </LinearLayout>
-
-</LinearLayout>
-
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/dialog_activity.xml b/samples/ApiDemos/res/layout/dialog_activity.xml
index 2b27d9a..4acdc64 100644
--- a/samples/ApiDemos/res/layout/dialog_activity.xml
+++ b/samples/ApiDemos/res/layout/dialog_activity.xml
@@ -17,8 +17,37 @@
 <!-- Demonstrates an activity with a dialog theme.
      See corresponding Java code com.android.sdk.app.DialogActivity.java. -->
 
-<!-- This screen consists of a single text field that displays some text. -->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
-    android:layout_width="match_parent" android:layout_height="match_parent"
-    android:gravity="center_vertical|center_horizontal"
-    android:text="@string/dialog_activity_text"/>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent" android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:padding="4dp" android:gravity="center_horizontal">
+    
+    <!-- Message to show to use. -->
+    <TextView android:id="@+id/text"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:gravity="center_vertical|center_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/dialog_activity_text"/>
+        
+    <!-- Container in which we are going to add and remove views, to demonstrate
+         how the layout adjusts based on size. -->
+    <LinearLayout android:id="@+id/inner_content"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingTop="4dp" android:paddingBottom="4dp">
+    </LinearLayout>
+    
+    <!-- Alert dialog style buttons along the bottom. -->
+    <LinearLayout style="?android:attr/buttonBarStyle"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:measureWithLargestChild="true">
+        <Button style="?android:attr/buttonBarButtonStyle" android:id="@+id/add"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/dialog_activity_add" />
+        <Button style="?android:attr/buttonBarButtonStyle" android:id="@+id/remove"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/dialog_activity_remove" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/drag_layout.xml b/samples/ApiDemos/res/layout/drag_layout.xml
new file mode 100644
index 0000000..909cef4
--- /dev/null
+++ b/samples/ApiDemos/res/layout/drag_layout.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Layout description of the DragAndDrop sample's main activity -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:dot="http://schemas.android.com/apk/res/com.example.android.apis"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    >
+
+    <TextView android:id="@+id/drag_explanation"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/drag_explanation"
+        />
+
+    <com.example.android.apis.view.DraggableDot
+        android:id="@+id/drag_dot_1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        dot:radius="64dp"
+        android:padding="15dp"
+        android:layout_below="@id/drag_explanation"
+        />
+
+    <com.example.android.apis.view.DraggableDot
+        android:id="@+id/drag_dot_2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        dot:radius="64dp"
+        android:padding="15dp"
+        android:layout_below="@id/drag_explanation"
+        android:layout_toRightOf="@id/drag_dot_1"
+        dot:legend="Drag ANR"
+        dot:anr="thumbnail"
+        />
+
+    <com.example.android.apis.view.DraggableDot
+        android:id="@+id/drag_dot_3"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        dot:radius="64dp"
+        android:padding="15dp"
+        android:layout_below="@id/drag_dot_1"
+        android:layout_alignLeft="@id/drag_dot_1"
+        dot:legend="Drop ANR"
+        dot:anr="drop"
+        />
+
+    <com.example.android.apis.view.DraggableDot
+        android:id="@+id/drag_dot_hidden"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        dot:radius="64dp"
+        android:padding="15dp"
+        android:layout_toRightOf="@id/drag_dot_3"
+        android:layout_alignTop="@id/drag_dot_3"
+        android:visibility="invisible"
+        dot:legend="Surprise!"
+        />
+
+    <TextView android:id="@+id/drag_result_text"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/drag_explanation"
+        android:layout_alignRight="@id/drag_explanation"
+        android:layout_toRightOf="@id/drag_dot_2"
+        />
+
+    <TextView android:id="@+id/drag_text"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"
+        android:layout_below="@id/drag_dot_3"
+        android:layout_alignLeft="@id/drag_dot_3"
+        />
+
+</RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/focus_5.xml b/samples/ApiDemos/res/layout/focus_5.xml
new file mode 100644
index 0000000..27c0a31
--- /dev/null
+++ b/samples/ApiDemos/res/layout/focus_5.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using nextFocusForward to explicitly set sequential focus order.-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="horizontal">
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:orientation="vertical">
+
+        <Button android:id="@+id/button1"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/focus_5_button1"
+            android:nextFocusForward="@+id/button2"/>
+
+        <Button android:id="@+id/button2"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/focus_5_button2"
+            android:nextFocusForward="@+id/button3"/>
+
+        <Button android:id="@+id/button3"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/focus_5_button3"
+            android:nextFocusForward="@+id/button4"/>
+
+    </LinearLayout>
+
+    <Button android:id="@+id/button4"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:text="@string/focus_5_button4"
+        android:nextFocusForward="@+id/button5"/>
+
+    <Button android:id="@+id/button5"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:text="@string/focus_5_button5"
+        android:nextFocusForward="@+id/button1"/>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/foreground_service_controller.xml b/samples/ApiDemos/res/layout/foreground_service_controller.xml
index 20ce103..076d4a3 100644
--- a/samples/ApiDemos/res/layout/foreground_service_controller.xml
+++ b/samples/ApiDemos/res/layout/foreground_service_controller.xml
@@ -17,9 +17,10 @@
 <!-- Demonstrates starting and stopping a local service.
      See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
-    android:gravity="center_horizontal"
-    android:layout_width="match_parent" android:layout_height="match_parent">
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical" android:padding="4dip"
+        android:gravity="center_horizontal"
+        android:layout_width="match_parent" android:layout_height="match_parent">
 
     <TextView
         android:layout_width="match_parent" android:layout_height="wrap_content"
diff --git a/samples/ApiDemos/res/layout/fragment_arguments.xml b/samples/ApiDemos/res/layout/fragment_arguments.xml
new file mode 100644
index 0000000..6541433
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_arguments.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:padding="4dip"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:gravity="top|center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/fragment_arguments_msg" />
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+<!-- BEGIN_INCLUDE(from_attributes) -->
+        <fragment class="com.example.android.apis.app.FragmentArguments$MyFragment"
+                android:id="@+id/embedded"
+                android:layout_width="0px" android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:label="@string/fragment_arguments_embedded" />
+<!-- END_INCLUDE(from_attributes) -->
+
+        <FrameLayout
+                android:id="@+id/created"
+                android:layout_width="0px"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_arguments_support.xml b/samples/ApiDemos/res/layout/fragment_arguments_support.xml
new file mode 100644
index 0000000..b218f82
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_arguments_support.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:padding="4dip"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:gravity="top|center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/fragment_arguments_msg" />
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+<!-- BEGIN_INCLUDE(from_attributes) -->
+        <fragment class="com.example.android.apis.support.app.FragmentArgumentsSupport$MyFragment"
+                android:id="@+id/embedded"
+                android:layout_width="0px" android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:label="@string/fragment_arguments_embedded" />
+<!-- END_INCLUDE(from_attributes) -->
+
+        <FrameLayout
+                android:id="@+id/created"
+                android:layout_width="0px"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_context_menu.xml b/samples/ApiDemos/res/layout/fragment_context_menu.xml
new file mode 100644
index 0000000..b5dac8e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_context_menu.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="8dp">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/fragment_context_menu_msg" />
+
+    <Button android:id="@+id/long_press"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="@string/long_press">
+        <requestFocus />
+    </Button>
+    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_dialog.xml b/samples/ApiDemos/res/layout/fragment_dialog.xml
new file mode 100644
index 0000000..f9dec59
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_dialog.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:gravity="top|center_horizontal" />
+
+    <Button android:id="@+id/show"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:text="@string/show">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_dialog_or_activity.xml b/samples/ApiDemos/res/layout/fragment_dialog_or_activity.xml
new file mode 100644
index 0000000..295f017
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_dialog_or_activity.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:gravity="top|center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/fragment_dialog_or_activity_msg" />
+
+    <Button android:id="@+id/show_dialog"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:text="@string/show">
+        <requestFocus />
+    </Button>
+
+    <View android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1" />
+
+    <TextView
+            android:id="@+id/inline_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/fragment_dialog_or_activity_inline" />
+
+    <FrameLayout
+            android:id="@+id/embedded"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:padding="6dp"
+            android:background="#ff303030"
+            android:gravity="top|center_horizontal" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_hide_show.xml b/samples/ApiDemos/res/layout/fragment_hide_show.xml
new file mode 100644
index 0000000..9f13295
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_hide_show.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the layout fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:gravity="center_vertical|center_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="Demonstration of hiding and showing fragments." />
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:gravity="center_vertical" android:layout_weight="1"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <Button android:id="@+id/frag1hide"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="Hide" />
+
+        <fragment android:name="com.example.android.apis.app.FragmentHideShow$FirstFragment"
+                android:id="@+id/fragment1" android:layout_weight="1"
+                android:layout_width="0px" android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:gravity="center_vertical" android:layout_weight="1"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <Button android:id="@+id/frag2hide"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="Hide" />
+
+        <fragment android:name="com.example.android.apis.app.FragmentHideShow$SecondFragment"
+                android:id="@+id/fragment2" android:layout_weight="1"
+                android:layout_width="0px" android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_hide_show_support.xml b/samples/ApiDemos/res/layout/fragment_hide_show_support.xml
new file mode 100644
index 0000000..e4245bd
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_hide_show_support.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Top-level content view for the layout fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:gravity="center_vertical|center_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="Demonstration of hiding and showing fragments." />
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:gravity="center_vertical" android:layout_weight="1"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <Button android:id="@+id/frag1hide"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="Hide" />
+
+        <fragment android:name="com.example.android.apis.support.app.FragmentHideShowSupport$FirstFragment"
+                android:id="@+id/fragment1" android:layout_weight="1"
+                android:layout_width="0px" android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:gravity="center_vertical" android:layout_weight="1"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <Button android:id="@+id/frag2hide"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="Hide" />
+
+        <fragment android:name="com.example.android.apis.support.app.FragmentHideShowSupport$SecondFragment"
+                android:id="@+id/fragment2" android:layout_weight="1"
+                android:layout_width="0px" android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_layout.xml b/samples/ApiDemos/res/layout/fragment_layout.xml
new file mode 100644
index 0000000..b693c96
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_layout.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the layout fragment sample.  This version is
+     for display when not in landscape: we can only fit the list of titles. -->
+
+<!-- BEGIN_INCLUDE(layout) -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+    <fragment class="com.example.android.apis.app.FragmentLayout$TitlesFragment"
+            android:id="@+id/titles"
+            android:layout_width="match_parent" android:layout_height="match_parent" />
+</FrameLayout>
+<!-- END_INCLUDE(layout) -->
diff --git a/samples/ApiDemos/res/layout/fragment_layout_support.xml b/samples/ApiDemos/res/layout/fragment_layout_support.xml
new file mode 100644
index 0000000..08c40bf
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_layout_support.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the layout fragment sample.  This version is
+     for display when not in landscape: we can only fit the list of titles. -->
+
+<!-- BEGIN_INCLUDE(layout) -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+    <fragment class="com.example.android.apis.support.app.FragmentLayoutSupport$TitlesFragment"
+            android:id="@+id/titles"
+            android:layout_width="match_parent" android:layout_height="match_parent" />
+</FrameLayout>
+<!-- END_INCLUDE(layout) -->
diff --git a/samples/ApiDemos/res/layout/fragment_menu.xml b/samples/ApiDemos/res/layout/fragment_menu.xml
new file mode 100644
index 0000000..7f0278c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_menu.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="8dp">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/fragment_menu_msg" />
+
+    <CheckBox android:id="@+id/menu1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:checked="true"
+        android:text="@string/fragment1menu">
+    </CheckBox>
+    
+    <CheckBox android:id="@+id/menu2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:checked="true"
+        android:text="@string/fragment2menu">
+    </CheckBox>
+    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_pager.xml b/samples/ApiDemos/res/layout/fragment_pager.xml
new file mode 100644
index 0000000..3867f46
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_pager.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical" android:padding="4dip"
+        android:gravity="center_horizontal"
+        android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <android.support.v4.app.FragmentPager
+            android:id="@+id/pager"
+            android:layout_width="match_parent"
+            android:layout_height="0px"
+            android:layout_weight="1">
+    </android.support.v4.app.FragmentPager>
+
+    <Button android:id="@+id/new_fragment"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:text="@string/new_fragment">
+        <requestFocus />
+    </Button>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_pager_list.xml b/samples/ApiDemos/res/layout/fragment_pager_list.xml
new file mode 100644
index 0000000..bbe7b1d
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_pager_list.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:drawable/gallery_thumb">
+
+    <TextView android:id="@+id/text"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:gravity="center_vertical|center_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/hello_world"/>
+
+    <!-- The frame layout is here since we will be showing either
+    the empty view or the list view.  -->
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1" >
+        <!-- Here is the list. Since we are using a ListActivity, we
+             have to call it "@android:id/list" so ListActivity will
+             find it -->
+        <ListView android:id="@android:id/list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:drawSelectorOnTop="false"/>
+
+        <!-- Here is the view to show if the list is emtpy -->
+        <TextView android:id="@android:id/empty"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="No items."/>
+
+    </FrameLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_retain_instance.xml b/samples/ApiDemos/res/layout/fragment_retain_instance.xml
new file mode 100644
index 0000000..0dc3985
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_retain_instance.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="8dp">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/fragment_retain_instance_msg" />
+
+    <ProgressBar android:id="@+id/progress_horizontal"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:padding="6dp"
+        android:max="500" />
+
+    <Button android:id="@+id/restart"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="@string/restart">
+        <requestFocus />
+    </Button>
+    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_stack.xml b/samples/ApiDemos/res/layout/fragment_stack.xml
new file mode 100644
index 0000000..1d12496
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_stack.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Top-level content view for the simple fragment sample. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <FrameLayout
+            android:id="@+id/simple_fragment"
+            android:layout_width="match_parent"
+            android:layout_height="0px"
+            android:layout_weight="1">
+    </FrameLayout>
+
+    <Button android:id="@+id/new_fragment"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:layout_weight="0" 
+        android:text="@string/new_fragment">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/gallery_1.xml b/samples/ApiDemos/res/layout/gallery_1.xml
index 9b9c4bb..d884c61 100644
--- a/samples/ApiDemos/res/layout/gallery_1.xml
+++ b/samples/ApiDemos/res/layout/gallery_1.xml
@@ -14,8 +14,19 @@
      limitations under the License.
 -->
 
-<Gallery xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gallery"
-	android:layout_width="match_parent"
-	android:layout_height="wrap_content"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout2"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+<Gallery  android:id="@+id/gallery"
+android:layout_width="match_parent"
+android:layout_height="wrap_content"
 />
-       
+<EditText
+ android:text="@+id/EditText01"
+ android:id="@+id/EditText01"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"></EditText>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/ApiDemos/res/layout/game_controller_input.xml b/samples/ApiDemos/res/layout/game_controller_input.xml
new file mode 100644
index 0000000..951c69b
--- /dev/null
+++ b/samples/ApiDemos/res/layout/game_controller_input.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Game controller input demo. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/description"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/game_controller_input_description"
+        android:padding="12dip" />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:padding="12dip">
+        <ListView
+            android:id="@+id/summary"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:padding="3dip">
+        </ListView>
+
+        <com.example.android.apis.view.GameView
+            android:id="@+id/game"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="#000000"
+            android:padding="3dip" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/game_controller_input_heading.xml b/samples/ApiDemos/res/layout/game_controller_input_heading.xml
new file mode 100644
index 0000000..297d378
--- /dev/null
+++ b/samples/ApiDemos/res/layout/game_controller_input_heading.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:padding="6dip"
+    android:textAppearance="?android:attr/textAppearanceMedium" />
diff --git a/samples/ApiDemos/res/layout/game_controller_input_text_column.xml b/samples/ApiDemos/res/layout/game_controller_input_text_column.xml
new file mode 100644
index 0000000..991f4a7
--- /dev/null
+++ b/samples/ApiDemos/res/layout/game_controller_input_text_column.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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:orientation="horizontal"
+    android:padding="6dip">
+    <TextView
+        android:id="@+id/label"
+        android:gravity="left"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
+    <TextView
+        android:id="@+id/content"
+        android:gravity="left"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/hello_world.xml b/samples/ApiDemos/res/layout/hello_world.xml
index 0282076..3d90a33 100644
--- a/samples/ApiDemos/res/layout/hello_world.xml
+++ b/samples/ApiDemos/res/layout/hello_world.xml
@@ -22,4 +22,5 @@
 <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
     android:layout_width="match_parent" android:layout_height="match_parent"
     android:gravity="center_vertical|center_horizontal"
+    android:textAppearance="?android:attr/textAppearanceMedium"
     android:text="@string/hello_world"/>
diff --git a/samples/ApiDemos/res/layout/horizontal_scroll_view1.xml b/samples/ApiDemos/res/layout/horizontal_scroll_view1.xml
new file mode 100644
index 0000000..167be4c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/horizontal_scroll_view1.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Demonstrates horizontal scrolling with a ScrollView. -->
+<HorizontalScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="100dip"
+    android:layout_height="120dip">
+    <TextView
+        android:layout_width="300dip"
+        android:layout_height="wrap_content"
+        android:text="@string/scrollbar_3_text" />
+</HorizontalScrollView>
diff --git a/samples/ApiDemos/res/layout/intent_activity_flags.xml b/samples/ApiDemos/res/layout/intent_activity_flags.xml
new file mode 100644
index 0000000..610e2dd
--- /dev/null
+++ b/samples/ApiDemos/res/layout/intent_activity_flags.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates the user of various intent activity flags.
+     See corresponding Java code com.android.sdk.app.IntentActivityFlags.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical" android:padding="4dip"
+        android:gravity="center_horizontal"
+        android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/intent_activity_flags"/>
+
+    <Button android:id="@+id/flag_activity_clear_task"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/flag_activity_clear_task">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/flag_activity_clear_task_pi"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/flag_activity_clear_task_pi">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/labeled_text_edit.xml b/samples/ApiDemos/res/layout/labeled_text_edit.xml
new file mode 100644
index 0000000..27568af
--- /dev/null
+++ b/samples/ApiDemos/res/layout/labeled_text_edit.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Content for a fragment with a text editor. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:layout_width="match_parent" android:layout_height="wrap_content">
+
+    <TextView android:id="@+id/msg"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip" />
+
+    <EditText android:id="@+id/saved"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:background="@drawable/green"
+        android:text="@string/initial_text"
+        android:freezesText="true">
+        <requestFocus />
+    </EditText>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/layout_animations.xml b/samples/ApiDemos/res/layout/layout_animations.xml
new file mode 100644
index 0000000..68f0e0e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animations.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:id="@+id/parent"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Add Button"
+            android:id="@+id/addNewButton"
+            />
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Custom Animations"
+            android:id="@+id/customAnimCB"
+            />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:checked="true"
+            android:text="Appearing Animation"
+            android:id="@+id/appearingCB"
+            />
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:checked="true"
+            android:text="Disappearing Animation"
+            android:id="@+id/disappearingCB"
+            />
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:checked="true"
+            android:text="Changing/Appearing Animation"
+            android:id="@+id/changingAppearingCB"
+            />
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:checked="true"
+            android:text="Changing/Disappearing Animation"
+            android:id="@+id/changingDisappearingCB"
+            />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/layout_animations_by_default.xml b/samples/ApiDemos/res/layout/layout_animations_by_default.xml
new file mode 100644
index 0000000..a5062bb
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animations_by_default.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Add Button"
+        android:id="@+id/addNewButton"
+        />
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/horizontalContainer"
+        android:animateLayoutChanges="true"
+        />
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:id="@+id/verticalContainer"
+        android:animateLayoutChanges="true"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/layout_animations_hideshow.xml b/samples/ApiDemos/res/layout/layout_animations_hideshow.xml
new file mode 100644
index 0000000..4215ac1
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animations_hideshow.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/parent"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Show Buttons"
+            android:id="@+id/addNewButton"
+            />
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Custom Animations"
+            android:id="@+id/customAnimCB"
+            />
+        <CheckBox
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Hide (GONE)"
+            android:id="@+id/hideGoneCB"
+            />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/popup_menu_1.xml b/samples/ApiDemos/res/layout/popup_menu_1.xml
new file mode 100644
index 0000000..6ddc76e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/popup_menu_1.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Google Inc.
+
+     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">
+    <Button android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:onClick="onPopupButtonClick"
+            android:text="@string/popup_menu_button" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/receive_result.xml b/samples/ApiDemos/res/layout/receive_result.xml
index a894612..5deb2ac 100644
--- a/samples/ApiDemos/res/layout/receive_result.xml
+++ b/samples/ApiDemos/res/layout/receive_result.xml
@@ -27,12 +27,15 @@
         android:layout_width="match_parent" android:layout_height="wrap_content"
         android:layout_weight="0"
         android:paddingBottom="4dip"
+        android:textAppearance="?android:attr/textAppearanceMedium"
         android:text="@string/receive_result_instructions"/>
 
     <TextView android:id="@+id/results"
         android:layout_width="match_parent" android:layout_height="10dip"
         android:layout_weight="1"
         android:paddingBottom="4dip"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="#000"
         android:background="@drawable/green">
     </TextView>
 
diff --git a/samples/ApiDemos/res/layout/resources_height.xml b/samples/ApiDemos/res/layout/resources_height.xml
new file mode 100644
index 0000000..1e219bf
--- /dev/null
+++ b/samples/ApiDemos/res/layout/resources_height.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Part of resources_width_and_height that varies based on height. -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
+            android:orientation="vertical">
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#8000ff00">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+        <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+                android:layout_weight="1" android:padding="4dp"
+                android:background="#80ff0000">
+            <include layout="@layout/resources_width" />
+        </FrameLayout>
+    </LinearLayout>
+</merge>
diff --git a/samples/ApiDemos/res/layout/resources_width.xml b/samples/ApiDemos/res/layout/resources_width.xml
new file mode 100644
index 0000000..a05a6e8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/resources_width.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Part of resources_width_and_height that varies based on width. -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
+            android:orientation="horizontal">
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="Default Width\n#1">
+        </TextView>
+        <TextView android:layout_width="0px" android:layout_height="match_parent"
+                android:layout_weight="1" android:gravity="center_horizontal"
+                android:layout_marginLeft="4dp" android:layout_marginRight="4dp"
+                android:background="#800000ff" android:text="Default Width\n#2">
+        </TextView>
+    </LinearLayout>
+</merge>
diff --git a/samples/ApiDemos/res/layout/resources_width_and_height.xml b/samples/ApiDemos/res/layout/resources_width_and_height.xml
new file mode 100644
index 0000000..8649dbe
--- /dev/null
+++ b/samples/ApiDemos/res/layout/resources_width_and_height.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Demonstrates using -wNNNdp and -hNNNdp resource configs. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <TextView android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0" android:gravity="center_horizontal"
+        android:paddingTop="8dp" android:paddingBottom="8dp"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/resources_width_and_height_description"/>
+
+    <FrameLayout android:layout_width="match_parent" android:layout_height="0px"
+        android:layout_weight="1"
+        android:background="@android:drawable/gallery_thumb">
+        <include layout="@layout/resources_height" />
+    </FrameLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/rotating_list.xml b/samples/ApiDemos/res/layout/rotating_list.xml
new file mode 100644
index 0000000..7213e07
--- /dev/null
+++ b/samples/ApiDemos/res/layout/rotating_list.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <Button
+        android:id="@+id/button"
+        android:text="Flip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    <ListView
+        android:id="@+id/list_en"
+        android:layout_width="match_parent"
+        android:layout_weight="1.0"
+        android:layout_height="0dip"/>
+    <ListView
+        android:id="@+id/list_fr"
+        android:layout_width="match_parent"
+        android:layout_weight="1.0"
+        android:layout_height="0dip"
+        android:visibility="gone"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/ApiDemos/res/layout/rotating_view.xml b/samples/ApiDemos/res/layout/rotating_view.xml
new file mode 100644
index 0000000..c30ed1c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/rotating_view.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    android:splitMotionEvents="true"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dip"
+        android:splitMotionEvents="true"
+        >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dip"
+            android:paddingRight="5dip"
+            android:textStyle="bold"
+            android:text="TX"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/translationX"
+        />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="15dip"
+            android:paddingRight="5dip"
+            android:textStyle="bold"
+            android:text="TY"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/translationY"
+        />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dip"
+        android:splitMotionEvents="true"
+        >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dip"
+            android:paddingRight="5dip"
+            android:textStyle="bold"
+            android:text="SX"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_weight="1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/scaleX"
+        />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="15dip"
+            android:paddingRight="5dip"
+            android:textStyle="bold"
+            android:text="SY"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_weight="1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/scaleY"
+        />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dip"
+        android:splitMotionEvents="true"
+        >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dip"
+            android:paddingRight="5dip"
+            android:textStyle="bold"
+            android:text="X"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/rotationX"
+        />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="15dip"
+            android:paddingRight="5dip"
+            android:textStyle="bold"
+            android:text="Y"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/rotationY"
+        />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="15dip"
+            android:paddingRight="5dip"
+            android:textStyle="bold"
+            android:text="Z"
+            />
+        <SeekBar
+            android:orientation="horizontal"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/rotationZ"
+        />
+    </LinearLayout>
+    <Button
+        android:layout_width="200dip"
+        android:layout_height="150dip"
+        android:layout_marginLeft="50dip"
+        android:layout_marginTop="50dip"
+        android:text="Rotating Button"
+        android:id="@+id/rotatingButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/save_restore_state.xml b/samples/ApiDemos/res/layout/save_restore_state.xml
index 4b489ed..0871dbb 100644
--- a/samples/ApiDemos/res/layout/save_restore_state.xml
+++ b/samples/ApiDemos/res/layout/save_restore_state.xml
@@ -17,42 +17,42 @@
 <!-- Demonstrates saving and restoring activity state.
      See corresponding Java code com.android.sdk.app.SaveRestoreState.java. -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent" android:layout_height="match_parent">
+    <LinearLayout android:orientation="vertical" android:padding="4dip"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
 
-    <TextView android:id="@+id/msg"
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:paddingBottom="4dip" />
+        <TextView android:id="@+id/msg"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="0" android:textAppearance="?android:attr/textAppearanceMedium"
+            android:paddingBottom="4dip" />
 
-    <TextView
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:paddingBottom="4dip"
-        android:text="@string/saves_state"/>
+        <TextView
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="0" android:paddingBottom="4dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/saves_state"/>
 
-    <EditText android:id="@+id/saved"
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:background="@drawable/green"
-        android:text="@string/initial_text"
-        android:freezesText="true">
-        <requestFocus />
-    </EditText>
+        <EditText android:id="@+id/saved"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="1" android:background="@drawable/green"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/initial_text"
+            android:freezesText="true">
+        </EditText>
 
-    <TextView
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:paddingTop="8dip"
-        android:paddingBottom="4dip"
-        android:text="@string/no_saves_state"/>
+        <TextView
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="0" android:paddingTop="8dip" android:paddingBottom="4dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/no_saves_state"/>
 
-    <EditText 
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:background="@drawable/red"
-        android:text="@string/initial_text">
-    </EditText>
+        <EditText
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="1" android:background="@drawable/red"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/initial_text">
+        </EditText>
 
-</LinearLayout>
-
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/search_view.xml b/samples/ApiDemos/res/layout/search_view.xml
new file mode 100644
index 0000000..4a9f7c0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/search_view.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<SearchView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"/>
diff --git a/samples/ApiDemos/res/layout/searchview_actionbar.xml b/samples/ApiDemos/res/layout/searchview_actionbar.xml
new file mode 100644
index 0000000..37736cd
--- /dev/null
+++ b/samples/ApiDemos/res/layout/searchview_actionbar.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+    <Button
+            android:id="@+id/open_button"
+            android:text="@string/open_search"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+        />
+
+    <Button
+            android:id="@+id/close_button"
+            android:text="@string/close_search"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+        />
+
+    <TextView
+            android:id="@+id/status_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/searchview_filter.xml b/samples/ApiDemos/res/layout/searchview_filter.xml
new file mode 100644
index 0000000..e72c17e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/searchview_filter.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+    <SearchView
+            android:id="@+id/search_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+    <ListView
+            android:id="@+id/list_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/send_result.xml b/samples/ApiDemos/res/layout/send_result.xml
index 34b3693..bdd927c 100644
--- a/samples/ApiDemos/res/layout/send_result.xml
+++ b/samples/ApiDemos/res/layout/send_result.xml
@@ -17,25 +17,28 @@
 <!-- Demonstrates receiving activity results.
      See corresponding Java code com.android.sdk.app.ReceiveResult.java. -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
-    android:gravity="center_horizontal"
-    android:layout_width="match_parent" android:layout_height="match_parent">
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent" android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:padding="4dip"
+        android:gravity="center_horizontal">
 
     <TextView
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:paddingBottom="8dip"
-        android:text="@string/pick_result"/>
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:paddingBottom="8dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/pick_result"/>
 
     <Button android:id="@+id/corky"
-        android:layout_width="wrap_content" android:layout_height="wrap_content" 
-        android:text="@string/corky">
-        <requestFocus />
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="@string/corky">
+            <requestFocus />
     </Button>
 
     <Button android:id="@+id/violet"
-        android:layout_width="wrap_content" android:layout_height="wrap_content" 
-        android:text="@string/violet">
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="@string/violet">
     </Button>
 
 </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/simple_list_item_checkable_1.xml b/samples/ApiDemos/res/layout/simple_list_item_checkable_1.xml
new file mode 100644
index 0000000..b405c30
--- /dev/null
+++ b/samples/ApiDemos/res/layout/simple_list_item_checkable_1.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<com.example.android.apis.view.CheckableFrameLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+    <TextView
+            android:id="@android:id/text1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:minHeight="?android:attr/listPreferredItemHeight"
+            android:gravity="center_vertical"
+    />
+</com.example.android.apis.view.CheckableFrameLayout>
diff --git a/samples/ApiDemos/res/layout/soft_input_modes.xml b/samples/ApiDemos/res/layout/soft_input_modes.xml
new file mode 100644
index 0000000..de47bc5
--- /dev/null
+++ b/samples/ApiDemos/res/layout/soft_input_modes.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates different soft input modes.
+     See corresponding Java code com.android.sdk.app.SoftInputModes.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:textAppearance="?android:textAppearanceMedium"
+        android:text="@string/soft_input_modes_summary"/>
+
+    <LinearLayout android:orientation="horizontal" android:gravity="center"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:textAppearance="?android:textAppearanceMedium"
+            android:text="@string/soft_input_modes_label"/>
+
+        <Spinner android:id="@+id/resize_mode"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawSelectorOnTop="true">
+        </Spinner>
+
+    </LinearLayout>
+    
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:paddingBottom="6dip"
+        android:background="@drawable/red"
+        android:textAppearance="?android:textAppearanceMedium"
+        android:text="@string/soft_input_modes_content"/>
+
+    <EditText android:id="@+id/saved"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:background="@drawable/green"
+        android:text="@string/soft_input_modes_initial_text"
+        android:freezesText="true">
+        <requestFocus />
+    </EditText>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/split_touch_view.xml b/samples/ApiDemos/res/layout/split_touch_view.xml
new file mode 100644
index 0000000..8758222
--- /dev/null
+++ b/samples/ApiDemos/res/layout/split_touch_view.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Split touch demo. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/split_touch_view_description"/>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:splitMotionEvents="true">
+        <ListView android:id="@+id/list1"
+                  android:layout_width="0dip"
+                  android:layout_height="match_parent"
+                  android:layout_weight="1" />
+        <ListView android:id="@+id/list2"
+                  android:layout_width="0dip"
+                  android:layout_height="match_parent"
+                  android:layout_weight="1" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/tabs_right_gravity.xml b/samples/ApiDemos/res/layout/tabs_right_gravity.xml
new file mode 100644
index 0000000..56e9ca3
--- /dev/null
+++ b/samples/ApiDemos/res/layout/tabs_right_gravity.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/tabhost"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="5dp">
+        <TabWidget
+            android:id="@android:id/tabs"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right|center_vertical" />
+        <FrameLayout
+            android:id="@android:id/tabcontent"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:padding="5dp" />
+    </LinearLayout>
+</TabHost>
diff --git a/samples/ApiDemos/res/layout/tabs_scroll.xml b/samples/ApiDemos/res/layout/tabs_scroll.xml
new file mode 100644
index 0000000..add7484
--- /dev/null
+++ b/samples/ApiDemos/res/layout/tabs_scroll.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/tabhost"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="5dp">
+        <HorizontalScrollView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scrollbars="none">
+            <TabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+        </HorizontalScrollView>
+        <FrameLayout
+            android:id="@android:id/tabcontent"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:padding="5dp" />
+    </LinearLayout>
+</TabHost>
diff --git a/samples/ApiDemos/res/menu/actions.xml b/samples/ApiDemos/res/menu/actions.xml
new file mode 100644
index 0000000..9f0440c
--- /dev/null
+++ b/samples/ApiDemos/res/menu/actions.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Google Inc.
+
+     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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_search"
+          android:icon="@android:drawable/ic_menu_search"
+          android:title="@string/action_bar_search"
+          android:showAsAction="ifRoom"
+          android:actionViewClass="android.widget.SearchView" />
+    <item android:id="@+id/action_add"
+          android:icon="@android:drawable/ic_menu_add"
+          android:title="@string/action_bar_add" />
+    <item android:id="@+id/action_edit"
+          android:icon="@android:drawable/ic_menu_edit"
+          android:showAsAction="always"
+          android:title="@string/action_bar_edit" />
+    <item android:id="@+id/action_share"
+          android:icon="@android:drawable/ic_menu_share"
+          android:title="@string/action_bar_share"
+          android:showAsAction="ifRoom" />
+    <item android:id="@+id/action_sort"
+          android:icon="@android:drawable/ic_menu_sort_by_size"
+          android:title="@string/action_bar_sort"
+          android:showAsAction="ifRoom">
+        <menu>
+            <item android:id="@+id/action_sort_size"
+                  android:icon="@android:drawable/ic_menu_sort_by_size"
+                  android:title="@string/action_bar_sort_size"
+                  android:onClick="onSort" />
+            <item android:id="@+id/action_sort_alpha"
+                  android:icon="@android:drawable/ic_menu_sort_alphabetically"
+                  android:title="@string/action_bar_sort_alpha"
+                  android:onClick="onSort" />
+        </menu>
+    </item>
+</menu>
diff --git a/samples/ApiDemos/res/menu/display_options_actions.xml b/samples/ApiDemos/res/menu/display_options_actions.xml
new file mode 100644
index 0000000..7c72de4
--- /dev/null
+++ b/samples/ApiDemos/res/menu/display_options_actions.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/simple_item"
+          android:title="@string/display_options_menu_item" />
+</menu>
diff --git a/samples/ApiDemos/res/menu/list_select_menu.xml b/samples/ApiDemos/res/menu/list_select_menu.xml
new file mode 100644
index 0000000..490e3f7
--- /dev/null
+++ b/samples/ApiDemos/res/menu/list_select_menu.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/share"
+          android:title="@string/share"
+          android:icon="@android:drawable/ic_menu_share"
+          android:showAsAction="always" />
+</menu>
diff --git a/samples/ApiDemos/res/menu/popup.xml b/samples/ApiDemos/res/menu/popup.xml
new file mode 100644
index 0000000..fc0e3b4
--- /dev/null
+++ b/samples/ApiDemos/res/menu/popup.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Google Inc.
+
+     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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/search"
+          android:icon="@android:drawable/ic_menu_search"
+          android:title="@string/popup_menu_search" />
+    <item android:id="@+id/add"
+          android:icon="@android:drawable/ic_menu_add"
+          android:title="@string/popup_menu_add" />
+    <item android:id="@+id/edit"
+          android:icon="@android:drawable/ic_menu_edit"
+          android:title="@string/popup_menu_edit">
+        <menu>
+            <item android:id="@+id/share"
+                  android:icon="@android:drawable/ic_menu_share"
+                  android:title="@string/popup_menu_share" />
+        </menu>
+    </item>
+</menu>
diff --git a/samples/ApiDemos/res/menu/searchview_in_menu.xml b/samples/ApiDemos/res/menu/searchview_in_menu.xml
new file mode 100644
index 0000000..09036a7
--- /dev/null
+++ b/samples/ApiDemos/res/menu/searchview_in_menu.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Google Inc.
+
+     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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_search"
+          android:title="@string/action_bar_search"
+          android:icon="@android:drawable/ic_menu_search"
+          android:showAsAction="always"
+          android:actionViewClass="android.widget.SearchView" />
+</menu>
diff --git a/samples/ApiDemos/res/values-hdpi/strings.xml b/samples/ApiDemos/res/values-hdpi/strings.xml
new file mode 100644
index 0000000..f2b46d4
--- /dev/null
+++ b/samples/ApiDemos/res/values-hdpi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="density_title">Density: High</string>
+</resources>
diff --git a/samples/ApiDemos/res/values-large-long/strings.xml b/samples/ApiDemos/res/values-large-long/strings.xml
deleted file mode 100644
index 7c392d8..0000000
--- a/samples/ApiDemos/res/values-large-long/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Large Long</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-large-notlong/strings.xml b/samples/ApiDemos/res/values-large-notlong/strings.xml
deleted file mode 100644
index 40328ea..0000000
--- a/samples/ApiDemos/res/values-large-notlong/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Large NotLong</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-large/strings.xml b/samples/ApiDemos/res/values-large/strings.xml
deleted file mode 100644
index c9fb189..0000000
--- a/samples/ApiDemos/res/values-large/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Large</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-ldpi/strings.xml b/samples/ApiDemos/res/values-ldpi/strings.xml
new file mode 100644
index 0000000..ebbcc38
--- /dev/null
+++ b/samples/ApiDemos/res/values-ldpi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="density_title">Density: Low</string>
+</resources>
diff --git a/samples/ApiDemos/res/values-long/strings.xml b/samples/ApiDemos/res/values-long/strings.xml
deleted file mode 100644
index 5d15048..0000000
--- a/samples/ApiDemos/res/values-long/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Long</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-mdpi/strings.xml b/samples/ApiDemos/res/values-mdpi/strings.xml
new file mode 100644
index 0000000..3034171
--- /dev/null
+++ b/samples/ApiDemos/res/values-mdpi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="density_title">Density: Medium</string>
+</resources>
diff --git a/samples/ApiDemos/res/values-normal-long/strings.xml b/samples/ApiDemos/res/values-normal-long/strings.xml
deleted file mode 100644
index 01a0487..0000000
--- a/samples/ApiDemos/res/values-normal-long/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Normal Long</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-normal-notlong/strings.xml b/samples/ApiDemos/res/values-normal-notlong/strings.xml
deleted file mode 100644
index bea3f8d..0000000
--- a/samples/ApiDemos/res/values-normal-notlong/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Normal NotLong</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-normal/strings.xml b/samples/ApiDemos/res/values-normal/strings.xml
deleted file mode 100644
index 16ff46f..0000000
--- a/samples/ApiDemos/res/values-normal/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Normal</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-notlong/strings.xml b/samples/ApiDemos/res/values-notlong/strings.xml
deleted file mode 100644
index a3e78db..0000000
--- a/samples/ApiDemos/res/values-notlong/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: NotLong</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-small-long/strings.xml b/samples/ApiDemos/res/values-small-long/strings.xml
deleted file mode 100644
index 8526f61..0000000
--- a/samples/ApiDemos/res/values-small-long/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Small Long</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-small-notlong/strings.xml b/samples/ApiDemos/res/values-small-notlong/strings.xml
deleted file mode 100644
index bc8a676..0000000
--- a/samples/ApiDemos/res/values-small-notlong/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Small NotLong</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-small/strings.xml b/samples/ApiDemos/res/values-small/strings.xml
deleted file mode 100644
index 56db730..0000000
--- a/samples/ApiDemos/res/values-small/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <string name="density_title">Density: Small</string>
-</resources>
diff --git a/samples/ApiDemos/res/values-v11/bools.xml b/samples/ApiDemos/res/values-v11/bools.xml
new file mode 100644
index 0000000..5ea02dd
--- /dev/null
+++ b/samples/ApiDemos/res/values-v11/bools.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+    <!-- True if running under Honeycomb or later. -->
+    <bool name="atLeastHoneycomb">true</bool>
+</resources>
diff --git a/samples/ApiDemos/res/values-v11/styles.xml b/samples/ApiDemos/res/values-v11/styles.xml
new file mode 100644
index 0000000..04c6f3f
--- /dev/null
+++ b/samples/ApiDemos/res/values-v11/styles.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+    <!-- For API level 11 or later, the Holo theme is available and we prefer that. -->
+    <style name="ThemeHolo" parent="android:Theme.Holo">
+    </style>
+
+    <!-- For API level 11 or later, we can use the magical DialogWhenLarge theme. -->
+    <style name="ThemeDialogWhenLarge" parent="android:style/Theme.Holo.DialogWhenLarge">
+    </style>
+</resources>
diff --git a/samples/ApiDemos/res/values-v13/bools.xml b/samples/ApiDemos/res/values-v13/bools.xml
new file mode 100644
index 0000000..1b8909f
--- /dev/null
+++ b/samples/ApiDemos/res/values-v13/bools.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+    <!-- True if running under Ice Cream Sandwich or later. -->
+    <bool name="atLeastIceCreamSandwich">true</bool>
+</resources>
diff --git a/samples/ApiDemos/res/values-xhdpi/strings.xml b/samples/ApiDemos/res/values-xhdpi/strings.xml
new file mode 100644
index 0000000..5757044
--- /dev/null
+++ b/samples/ApiDemos/res/values-xhdpi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="density_title">Density: Extra High</string>
+</resources>
diff --git a/samples/ApiDemos/res/values/arrays.xml b/samples/ApiDemos/res/values/arrays.xml
index 29c9d2e..aac4f79 100644
--- a/samples/ApiDemos/res/values/arrays.xml
+++ b/samples/ApiDemos/res/values/arrays.xml
@@ -38,6 +38,14 @@
         <item>Pluto</item>
     </string-array>
 
+    <!-- Used in content/ClipboardSample.java -->
+    <string-array name="clip_data_types">
+        <item>No data in clipboard</item>
+        <item>Text clip</item>
+        <item>Intent clip</item>
+        <item>Uri clip</item>
+    </string-array>
+
     <!-- Used in App/SearchInvoke.java -->
     <string-array name="search_menuModes">
         <item>Search Key</item>
@@ -92,6 +100,7 @@
         <item>Numeric</item>
         <item>Alphabetic</item>
         <item>Alphanumeric</item>
+        <item>Complex</item>
     </string-array>
 
     <!-- Used in app/Screen Orientation -->
@@ -118,4 +127,23 @@
         <item>*bzzt*\nYou\'re not very good at this, are you?</item>
         <item>*bzzt*\nGo away...</item>
     </string-array>
+
+    <!-- Used in view/Split Touch View example -->
+    <string-array name="cheese_responses">
+        <item>I\'m afraid we\'re fresh out.</item>
+        <item>I\'m afraid we never have that at the end of the week, sir.  We get it fresh on Monday.</item>
+        <item>Ah. It\'s been on order, sir, for two weeks.  I was expecting it this morning.</item>
+        <item>Normally, sir, yes.  Today the van broke down.</item>
+        <item>No.</item>
+        <item>No.</item>
+        <item>No.</item>
+        <item>Yes, sir.  It\'s, ah ..... it\'s a bit runny.</item>
+        <item>Well, it\'s very runny, actually, sir.</item>
+        <item>I think it\'s a bit runnier than you\'ll like it, sir.</item>
+        <item>Oh... The cat\'s eaten it.</item>
+        <item>No.</item>
+        <item>No.</item>
+        <item>No.</item>
+        <item>Mmm... cheese.</item>
+    </string-array>
 </resources>
diff --git a/samples/ApiDemos/res/values/attrs.xml b/samples/ApiDemos/res/values/attrs.xml
index 53f0034..35f224e 100644
--- a/samples/ApiDemos/res/values/attrs.xml
+++ b/samples/ApiDemos/res/values/attrs.xml
@@ -32,4 +32,24 @@
         <attr name="textColor" format="color" />
         <attr name="textSize" format="dimension" />
     </declare-styleable>
+
+    <!-- These are attributes used with 'DraggableDot' drawables in
+         view/DragAndDropActivity.java and view/DraggableDot.java -->
+    <declare-styleable name="DraggableDot">
+        <attr name="radius" format="dimension" />
+        <attr name="legend" format="string" />
+        <attr name="anr">
+            <enum name="none" value="0" />
+            <enum name="thumbnail" value="1" />
+            <enum name="drop" value="2" />
+        </attr>
+    </declare-styleable>
+
+    <!-- These are the attributes that we want to retrieve for
+         app/FragmentArguments.java -->
+<!-- BEGIN_INCLUDE(fragment_arguments) -->
+    <declare-styleable name="FragmentArguments">
+        <attr name="android:label" />
+    </declare-styleable>
+<!-- END_INCLUDE(fragment_arguments) -->
 </resources>
diff --git a/samples/ApiDemos/res/values/bools.xml b/samples/ApiDemos/res/values/bools.xml
new file mode 100644
index 0000000..cf85197
--- /dev/null
+++ b/samples/ApiDemos/res/values/bools.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+    <!-- This resource is true if running under at least Honeycomb's
+         API level.  The default value is false; an alternative value
+         for Honeycomb is true. -->
+    <bool name="atLeastHoneycomb">false</bool>
+    <!-- This resource is true if running under at least Ice Cream Sandwich's
+         API level.  The default value is false; an alternative value
+         for Ice Cream Sandwich is true. -->
+    <bool name="atLeastIceCreamSandwich">false</bool>
+</resources>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index e88512f..d7858f0 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -31,7 +31,10 @@
     <string name="activity_dialog">App/Activity/Dialog</string>
     <string name="dialog_activity_text">Example of how you can use the
             Theme.Dialog theme to make an activity that looks like a
-            dialog.</string>
+            dialog.  It also has lots of text to show how text wrapping (and
+            corresponding window size adjustment) can happen in a dialog.</string>
+    <string name="dialog_activity_add">Add content</string>
+    <string name="dialog_activity_remove">Remove content</string>
     <string name="activity_custom_dialog">App/Activity/Custom Dialog</string>
     <string name="custom_dialog_activity_text">Example of how you can use a
             custom Theme.Dialog theme to make an activity that looks like a
@@ -49,7 +52,7 @@
         orientation modes.  Often you want to set the desired mode in your manifest
         instead of programmatically.</string>
     <string name="screen_orientation">Screen Orientation</string>
-    
+
     <string name="activity_translucent">App/Activity/Translucent</string>
     <string name="translucent_background">Example of how you can make an
             activity have a translucent background, compositing over
@@ -68,9 +71,23 @@
     <string name="no_saves_state">This text field does not save its state:</string>
     <string name="initial_text">Initial text.</string>
 
+    <string name="soft_input_modes">App/Activity/Soft Input Modes</string>
+    <string name="soft_input_modes_summary">Shows how different soft input modes impact
+        application resizing due to an input method.</string>
+    <string name="soft_input_modes_label">Resize mode: </string>
+    <string name="soft_input_modes_content">This is a part of the application\'s UI that
+        can resize to adjust for the IME.</string>
+    <string name="soft_input_modes_initial_text">Text editor.\n\nTap to show the IME,
+        which will cause this window to resize as requested.</string>
+
     <string name="activity_persistent">App/Activity/Persistent State</string>
     <string name="persistent_msg">Demonstration of persistent activity state with getPreferences(0).edit() and getPreferences(0).</string>
 
+    <string name="activity_recreate">App/Activity/Recreate</string>
+    <string name="activity_recreate_msg">Demonstration recreating an activity, to have
+        it reconstructed with significant new changes.  In this case the theme is changed.</string>
+    <string name="recreate">Recreate</string>
+
     <string name="activity_receive_result">App/Activity/Receive Result</string>
     <string name="pick_result">Pick a result to send, or BACK to cancel.</string>
     <string name="corky">Corky</string>
@@ -89,6 +106,86 @@
     <string name="redirect_getter">Enter the text that will be used by the main activity.  Press back to cancel.</string>
     <string name="apply">Apply</string>
 
+    <string name="fragment_alert_dialog">App/Fragment/Alert Dialog</string>
+
+    <string name="fragment_arguments">App/Fragment/Arguments</string>
+    <string name="fragment_arguments_msg">Demonstrates a fragment that takes arguments
+        as a Bundle at runtime (on the right) or from attributes in a layout (on the left).</string>
+    <string name="fragment_arguments_embedded">From Attributes</string>
+    <string name="fragment_arguments_embedded_land">Landscape Only</string>
+
+    <string name="fragment_hide_show">App/Fragment/Hide and Show</string>
+
+    <string name="fragment_context_menu">App/Fragment/Context Menu</string>
+    <string name="fragment_context_menu_msg">Fragment populating a context
+            menu; long press the button to see.</string>
+    <string name="long_press">Long press me</string>
+
+    <string name="fragment_dialog">App/Fragment/Dialog</string>
+    <string name="show">Show</string>
+
+    <string name="fragment_dialog_or_activity">App/Fragment/Dialog or Activity</string>
+    <string name="fragment_dialog_or_activity_msg">Demonstrates the same fragment
+            being shown as a dialog and embedded inside of an activity.</string>
+    <string name="fragment_dialog_or_activity_inline">Fragment embedded inside
+            of the activity:</string>
+
+    <string name="fragment_layout">App/Fragment/Layout</string>
+
+    <string name="fragment_list_array">App/Fragment/List Array</string>
+
+    <string name="fragment_menu">App/Fragment/Menu</string>
+    <string name="fragment_menu_msg">Build menus from two fragments, allowing
+        you to hide them to remove them..</string>
+    <string name="fragment1menu">Show fragment 1 menu</string>
+    <string name="fragment2menu">Show fragment 2 menu</string>
+
+    <string name="fragment_retain_instance">App/Fragment/Retain Instance</string>
+    <string name="fragment_retain_instance_msg">Current progress of retained fragment;
+    restarts if fragment is re-created.</string>
+    <string name="restart">Restart</string>
+
+    <string name="fragment_receive_result">App/Fragment/Receive Result</string>
+
+    <string name="fragment_stack">App/Fragment/Stack</string>
+    <string name="new_fragment">New fragment</string>
+
+    <string name="fragment_alert_dialog_support">Support/App/Fragment/Alert Dialog</string>
+
+    <string name="fragment_arguments_support">Support/App/Fragment/Arguments</string>
+
+    <string name="fragment_hide_show_support">Support/App/Fragment/Hide and Show</string>
+
+    <string name="fragment_context_menu_support">Support/App/Fragment/Context Menu</string>
+
+    <string name="fragment_dialog_support">Support/App/Fragment/Dialog</string>
+
+    <string name="fragment_dialog_or_activity_support">Support/App/Fragment/Dialog or Activity</string>
+
+    <string name="fragment_layout_support">Support/App/Fragment/Layout</string>
+
+    <string name="fragment_list_array_support">Support/App/Fragment/List Array</string>
+
+    <string name="fragment_menu_support">Support/App/Fragment/Menu</string>
+
+    <string name="fragment_retain_instance_support">Support/App/Fragment/Retain Instance</string>
+
+    <string name="fragment_receive_result_support">Support/App/Fragment/Receive Result</string>
+
+    <string name="fragment_stack_support">Support/App/Fragment/Stack</string>
+
+    <string name="fragment_pager_support">Support/App/Fragment/Pager</string>
+
+    <string name="loader_cursor">App/Loader/Cursor</string>
+
+    <string name="loader_custom">App/Loader/Custom</string>
+
+    <string name="loader_throttle">App/Loader/Throttle</string>
+
+    <string name="loader_cursor_support">Support/App/Loader/Cursor</string>
+    
+    <string name="loader_throttle_support">Support/Loader/Throttle</string>
+    
     <string name="activity_menu">App/Activity/Menu</string>
     <string name="open_menu">Open menu</string>
     <string name="close_menu">Close menu</string>
@@ -234,10 +331,18 @@
     <string name="text_to_speech">App/Text-To-Speech</string>
     <string name="again">Again</string>
 
+    <string name="app_update_received">ApiDemos has been updated!</string>
+    
     <!-- ============================== -->
     <!--  app/content examples strings  -->
     <!-- ============================== -->
 
+    <string name="activity_clipboard">Content/Clipboard/Data Types</string>
+    <string name="copy_text">Copy Text</string>
+    <string name="copy_intent">Copy Intent</string>
+    <string name="copy_uri">Copy URI</string>
+    <string name="clip_type_prompt">Clip Type</string>
+
     <string name="activity_external_storage">Content/Storage/External Storage</string>
     <string name="create">Create</string>
     <string name="delete">Delete</string>
@@ -247,28 +352,41 @@
     <string name="styled_text">Plain, <b>bold</b>, <i>italic</i>, <b><i>bold-italic</i></b></string>
     <string name="styled_text_prog">Assigned programmatically:</string>
 
+    <string name="activity_resources_width_and_height">Content/Resources/Width and Height</string>
+    <string name="resources_width_and_height_description">The layouts below use -wNNNdp and
+        -hNNNdp to select between different versions based on the size of the screen.</string>
+
     <string name="activity_read_asset">Content/Assets/Read Asset</string>
 
     <string name="activity_themes">Content/Resources/Themes</string>
     <string name="activity_resources">Content/Resources/Resources</string>
 
     <string name="activity_pick_contact">Content/Provider/Pick Contact</string>
-    <string name="pick_contact_msg">Invoke Contacts to pick varius kinds of
+    <string name="pick_contact_msg">Invoke Contacts to pick various kinds of
         contact data.  None of these require that the caller hold the
         READ_CONTACTS permission.</string>
     <string name="pick_contact">Pick a Contact</string>
     <string name="pick_person">Pick a Person</string>
     <string name="pick_phone">Pick a Phone</string>
     <string name="pick_address">Pick an Address</string>
-    
+
     <!-- ============================== -->
     <!--  app/intents examples strings     -->
     <!-- ============================== -->
 
-    <string name="activity_intents">App/Intents</string>
+    <string name="activity_intents">App/Activity/Intents</string>
     <string name="intents">Example of launching various Intents.</string>
     <string name="get_music">Get Music</string>
 
+    <!-- ============================== -->
+    <!--  app/intents activity flags examples strings     -->
+    <!-- ============================== -->
+
+    <string name="activity_intent_activity_flags">App/Activity/Intent Activity Flags</string>
+    <string name="intent_activity_flags">Example of the use of various intent activity flags.</string>
+    <string name="flag_activity_clear_task">FLAG_ACTIVITY_CLEAR_TASK</string>
+    <string name="flag_activity_clear_task_pi">FLAG_ACTIVITY_CLEAR_TASK (PI)</string>
+
     <!-- =================================== -->
     <!--  app/notification examples strings  -->
     <!-- =================================== -->
@@ -303,9 +421,12 @@
     <!--  app/dialog examples strings  -->
     <!-- ============================== -->
 
-    <string name="activity_alert_dialog">App/Dialog</string>
+    <string name="activity_alert_dialog">App/Alert Dialogs</string>
     <string name="alert_dialog_two_buttons">OK Cancel dialog with a message</string>
+    <string name="alert_dialog_two_buttons_old_school">OK Cancel dialog with traditional theme</string>
+    <string name="alert_dialog_two_buttons_holo_light">OK Cancel dialog with Holo Light theme</string>
     <string name="alert_dialog_two_buttons2">OK Cancel dialog with a long message</string>
+    <string name="alert_dialog_two_buttons2ultra">OK Cancel dialog with ultra long message</string>
     <string name="alert_dialog_select_button">List dialog</string>
     <string name="alert_dialog_single_choice">Single choice list</string>
     <string name="alert_dialog_multi_choice">Repeat alarm</string>
@@ -327,6 +448,44 @@
         kipg naar mixent phona. Cak pwico siructiun
         ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg
     </string>
+    <string name="alert_dialog_two_buttons2ultra_msg">
+        Plloaso mako nuto siwuf cakso dodtos anr koop a
+        cupy uf cak vux noaw yerw phuno. Whag schengos, uf efed, quiel
+        ba mada su otrenzr.\n\nSwipontgwook proudgs hus yag su ba dagarmidad.
+        Plasa maku noga wipont trenzsa schengos ent kaap zux comy.\n\nWipont trenz
+        kipg naar mixent phona. Cak pwico siructiun
+        ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg\n\n
+        Plloaso mako nuto siwuf cakso dodtos anr koop a
+        cupy uf cak vux noaw yerw phuno. Whag schengos, uf efed, quiel
+        ba mada su otrenzr.\n\nSwipontgwook proudgs hus yag su ba dagarmidad.
+        Plasa maku noga wipont trenzsa schengos ent kaap zux comy.\n\nWipont trenz
+        kipg naar mixent phona. Cak pwico siructiun
+        ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg\n\n
+        Plloaso mako nuto siwuf cakso dodtos anr koop a
+        cupy uf cak vux noaw yerw phuno. Whag schengos, uf efed, quiel
+        ba mada su otrenzr.\n\nSwipontgwook proudgs hus yag su ba dagarmidad.
+        Plasa maku noga wipont trenzsa schengos ent kaap zux comy.\n\nWipont trenz
+        kipg naar mixent phona. Cak pwico siructiun
+        ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg\n\n
+        Plloaso mako nuto siwuf cakso dodtos anr koop a
+        cupy uf cak vux noaw yerw phuno. Whag schengos, uf efed, quiel
+        ba mada su otrenzr.\n\nSwipontgwook proudgs hus yag su ba dagarmidad.
+        Plasa maku noga wipont trenzsa schengos ent kaap zux comy.\n\nWipont trenz
+        kipg naar mixent phona. Cak pwico siructiun
+        ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg\n\n
+        Plloaso mako nuto siwuf cakso dodtos anr koop a
+        cupy uf cak vux noaw yerw phuno. Whag schengos, uf efed, quiel
+        ba mada su otrenzr.\n\nSwipontgwook proudgs hus yag su ba dagarmidad.
+        Plasa maku noga wipont trenzsa schengos ent kaap zux comy.\n\nWipont trenz
+        kipg naar mixent phona. Cak pwico siructiun
+        ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg\n\n
+        Plloaso mako nuto siwuf cakso dodtos anr koop a
+        cupy uf cak vux noaw yerw phuno. Whag schengos, uf efed, quiel
+        ba mada su otrenzr.\n\nSwipontgwook proudgs hus yag su ba dagarmidad.
+        Plasa maku noga wipont trenzsa schengos ent kaap zux comy.\n\nWipont trenz
+        kipg naar mixent phona. Cak pwico siructiun
+        ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg\n\n
+    </string>
     <string name="alert_dialog_ok">OK</string>
     <string name="alert_dialog_hide">Hide</string>
     <string name="alert_dialog_something">Something</string>
@@ -363,12 +522,14 @@
     <!--  app/menu examples strings     -->
     <!-- ============================== -->
 
-    <string name="preferences_from_xml">App/Preferences/1. Preferences from XML</string>
-    <string name="launching_preferences">App/Preferences/2. Launching preferences</string>
-    <string name="preference_dependencies">App/Preferences/3. Preference dependencies</string>
-    <string name="default_values">App/Preferences/4. Default values</string>
-    <string name="preferences_from_code">App/Preferences/5. Preferences from code</string>
-    <string name="advanced_preferences">App/Preferences/6. Advanced preferences</string>
+    <string name="preferences_from_xml">Preference/1. Preferences from XML</string>
+    <string name="launching_preferences">Preference/2. Launching preferences</string>
+    <string name="preference_dependencies">Preference/3. Preference dependencies</string>
+    <string name="default_values">Preference/4. Default values</string>
+    <string name="preferences_from_code">Preference/5. Preferences from code</string>
+    <string name="advanced_preferences">Preference/6. Advanced preferences</string>
+    <string name="fragment_preferences">Preference/7. Fragment</string>
+    <string name="preference_with_headers">Preference/8. Headers</string>
 
     <string name="launch_preference_activity">Launch PreferenceActivity</string>
     <string name="counter_value_is">The counter value is</string>
@@ -399,6 +560,9 @@
     <string name="title_screen_preference">Screen preference</string>
     <string name="summary_screen_preference">Shows another screen of preferences</string>
 
+    <string name="title_fragment_preference">Fragment preference</string>
+    <string name="summary_fragment_preference">Shows another fragment of preferences</string>
+
     <string name="title_next_screen_toggle_preference">Toggle preference</string>
     <string name="summary_next_screen_toggle_preference">Preference that is on the next screen but same hierarchy</string>
 
@@ -473,6 +637,16 @@
     <string name="disable_admin">Disable Admin</string>
     <string name="password_quality">Password Quality</string>
     <string name="password_length_hint">Minimum Length</string>
+    <string name="password_minimum_letters_hint">Minimum Letters</string>
+    <string name="password_minimum_uppercase_hint">Minimum Uppercase</string>
+    <string name="password_minimum_lowercase_hint">Minimum Lowercase</string>
+    <string name="password_minimum_symbols_hint">Minimum Symbols</string>
+    <string name="password_minimum_numeric_hint">Minimum Numeric</string>
+    <string name="password_minimum_nonletter_hint">Minimum Non-Letter</string>
+    <string name="password_history_length_hint">Password History Length</string>
+    <string name="password_expiration_hint">Password Expiration Timeout (minutes) </string>
+    <string name="update_expiration_label">Update</string>
+    <string name="update_expiration_status_label">Update Status</string>
     <string name="set_password">Set Password</string>
     <string name="password_hint">Password</string>
     <string name="reset_password">Reset Password</string>
@@ -483,6 +657,11 @@
     <string name="timeout_hint">Max screen timeout</string>
     <string name="set_timeout_label">Set Timeout</string>
 
+    <string name="encryption_enable_label">Enable Encryption</string>
+    <string name="encryption_disable_label">Disable Encryption</string>
+    <string name="encryption_activate_label">Activate Encryption</string>
+    <string name="update_encryption_status_label">Update Status</string>
+
     <!-- ============================== -->
     <!--  app/voice recognition examples strings  -->
     <!-- ============================== -->
@@ -491,6 +670,39 @@
     <string name="speak_button">Speak!</string>
     <string name="voice_recognition_results">Results:</string>
 
+    <!-- ================================= -->
+    <!--  app/action bar examples strings  -->
+    <!-- ================================= -->
+
+    <string name="action_bar_mechanics">App/Action Bar/Action Bar Mechanics</string>
+    <string name="action_bar_usage">App/Action Bar/Action Bar Usage</string>
+    <string name="action_bar_tabs">App/Action Bar/Action Bar Tabs</string>
+
+    <string name="action_bar_search">Search</string>
+    <string name="action_bar_add">Add</string>
+    <string name="action_bar_edit">Edit</string>
+    <string name="action_bar_share">Share</string>
+    <string name="action_bar_sort">Sort</string>
+    <string name="action_bar_sort_alpha">Alphabetically</string>
+    <string name="action_bar_sort_size">By size</string>
+
+    <string name="action_bar_display_options">App/Action Bar/Display Options</string>
+    <string name="toggle_home_as_up">DISPLAY_HOME_AS_UP</string>
+    <string name="toggle_show_home">DISPLAY_SHOW_HOME</string>
+    <string name="toggle_use_logo">DISPLAY_USE_LOGO</string>
+    <string name="toggle_show_title">DISPLAY_SHOW_TITLE</string>
+    <string name="toggle_show_custom">DISPLAY_SHOW_CUSTOM</string>
+    <string name="toggle_navigation">Navigation</string>
+    <string name="cycle_custom_gravity">Cycle Custom View Gravity</string>
+
+    <string name="display_options_custom_button">Custom View!</string>
+    <string name="display_options_menu_item">Menu Item</string>
+
+    <string name="btn_add_tab">Add new tab</string>
+    <string name="btn_remove_tab">Remove last tab</string>
+    <string name="btn_toggle_tabs">Toggle tab mode</string>
+    <string name="btn_remove_all_tabs">Remove all tabs</string>
+
     <!-- ============================ -->
     <!--  graphics examples strings  -->
     <!-- ============================ -->
@@ -538,6 +750,12 @@
 
     <string name="ratingbar_rating">Rating:</string>
 
+    <string name="popup_menu_search">Search</string>
+    <string name="popup_menu_add">Add</string>
+    <string name="popup_menu_edit">Edit</string>
+    <string name="popup_menu_share">Share</string>
+    <string name="popup_menu_button">Make a Popup!</string>
+
     <string name="secure_view_description">
         This activity demonstrates a view that detects when it is potentially obscured
         by other windows.
@@ -581,6 +799,38 @@
     <string name="secure_view_overlay_button2">Clicky?</string>
     <string name="secure_view_overlay_button3">Think of the penguins!</string>
 
+    <string name="split_touch_view_description">
+        This activity demonstrates splitting touch events across multiple views
+        within a view group.  Here we have two ListViews within a LinearLayout
+        that has the attribute android:splitMotionEvents set to "true".
+        Try scrolling both lists simultaneously using multiple fingers.
+    </string>
+    <string name="split_touch_view_cheese_toast">Do you have any %1$s?\n%2$s</string>
+
+    <string name="searchview_hint">Find something</string>
+    <string name="cheese_hunt_hint">Cheese hunt</string>
+    <string name="open_search">Expand</string>
+    <string name="close_search">Iconify</string>
+
+    <string name="drag_explanation">
+        Longpress on a dot to start a drag, then drop over another dot. The destination
+        dot will append the drag\'s textual conversion to the EditText.
+    </string>
+
+    <string name="game_controller_input_description">
+        This activity demonstrates how to process input events received from
+        game controllers.  Please connect your game controller now and try
+        moving the joysticks or pressing buttons.  If it helps, try to imagine
+        that you are a lone space cowboy in hot pursuit of the aliens who kidnapped
+        your favorite llama on their way back to Andromeda...
+    </string>
+    <string name="game_controller_input_heading_device">Input Device</string>
+    <string name="game_controller_input_heading_axes">Axes</string>
+    <string name="game_controller_input_heading_keys">Keys and Buttons</string>
+    <string name="game_controller_input_label_device_name">Name</string>
+    <string name="game_controller_input_key_pressed">Pressed</string>
+    <string name="game_controller_input_key_released">Released</string>
+
     <!-- ============================== -->
     <!--  GoogleLogin examples strings  -->
     <!-- ============================== -->
@@ -659,6 +909,11 @@
     <string name="focus_3_right">right</string>
     <string name="focus_3_top">top</string>
     <string name="focus_3_bottom">bottom</string>
+    <string name="focus_5_button1">1</string>
+    <string name="focus_5_button2">2</string>
+    <string name="focus_5_button3">3</string>
+    <string name="focus_5_button4">4</string>
+    <string name="focus_5_button5">5</string>
     <string name="gallery_2_text">Testing</string>
     <string name="googlelogin_login">Login</string>
     <string name="googlelogin_bad_login">Bad Login</string>
@@ -957,4 +1212,6 @@
     <string name="sms_speak_string_format">Message from "%1$s": %2$s</string>
     <string name="reply">Reply</string>
     <string name="dismiss">Dismiss</string>
+
+    <string name="share">Share</string>
 </resources>
diff --git a/samples/ApiDemos/res/values/styles.xml b/samples/ApiDemos/res/values/styles.xml
index 8cc8312..d38ab34 100644
--- a/samples/ApiDemos/res/values/styles.xml
+++ b/samples/ApiDemos/res/values/styles.xml
@@ -15,6 +15,21 @@
 -->
 
 <resources>
+    <!-- A custom theme that is a variation on the light them with a different
+         background color. -->
+    <color name="custom_theme_color">#b0b0ff</color>
+    <style name="CustomTheme" parent="android:Theme.Light">
+        <item name="android:windowBackground">@color/custom_theme_color</item>
+        <item name="android:colorBackground">@color/custom_theme_color</item>
+    </style>
+
+    <!-- This is a theme that will adjust itself depending on the API version.
+         The default definition is the safe one, using a theme that has always
+         been defined.  Look at values-11/styles.xml for a variation that is
+         selected when the holographic theme is available. -->
+    <style name="ThemeHolo" parent="android:Theme">
+    </style>
+
     <!-- Base application theme is the default theme. -->
     <style name="Theme" parent="android:Theme">
     </style>
@@ -66,6 +81,14 @@
         <item name="android:colorForeground">#fff</item>
     </style>
     
+    <!-- Older platforms don't have Theme.Holo.DialogWhenLarge; we will define
+         our own wrapper theme that uses it only when running on the appropriate
+         platform version.  On older platforms, we always use the generic
+         fullscreen theme, because they don't support some feature that help
+         in correctly laying out an activity as a dialog. -->
+    <style name="ThemeDialogWhenLarge" parent="android:style/Theme">
+    </style>
+
     <style name="TextAppearance.Theme.PlainText" parent="android:TextAppearance.Theme">
         <item name="android:textStyle">normal</item>
     </style>
diff --git a/samples/ApiDemos/res/xml/advanced_preferences.xml b/samples/ApiDemos/res/xml/advanced_preferences.xml
index c362297..dd6de31 100644
--- a/samples/ApiDemos/res/xml/advanced_preferences.xml
+++ b/samples/ApiDemos/res/xml/advanced_preferences.xml
@@ -23,7 +23,7 @@
          portion of the preference, if the whole preference wanted to be
          replaced we would use the layout attribute instead of the widgetLayout
          attribute. -->
-    <com.example.android.apis.app.MyPreference
+    <com.example.android.apis.preference.MyPreference
             android:key="my_preference"
             android:title="@string/title_my_preference"
             android:summary="@string/summary_my_preference"
diff --git a/samples/ApiDemos/res/xml/device_admin_sample.xml b/samples/ApiDemos/res/xml/device_admin_sample.xml
index 7158003..10edb7e 100644
--- a/samples/ApiDemos/res/xml/device_admin_sample.xml
+++ b/samples/ApiDemos/res/xml/device_admin_sample.xml
@@ -4,9 +4,9 @@
      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.
@@ -22,6 +22,8 @@
         <reset-password />
         <force-lock />
         <wipe-data />
+        <expire-password />
+        <encrypted-storage />
     </uses-policies>
 </device-admin>
 <!-- END_INCLUDE(meta_data) -->
diff --git a/samples/ApiDemos/res/xml/fragmented_preferences.xml b/samples/ApiDemos/res/xml/fragmented_preferences.xml
new file mode 100644
index 0000000..5033ab8
--- /dev/null
+++ b/samples/ApiDemos/res/xml/fragmented_preferences.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- This is a primitive example showing the different types of preferences available. -->
+<!-- BEGIN_INCLUDE(preferences) -->
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <PreferenceCategory
+            android:title="@string/inline_preferences">
+
+        <CheckBoxPreference
+                android:key="checkbox_preference"
+                android:title="@string/title_toggle_preference"
+                android:summary="@string/summary_toggle_preference" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/dialog_based_preferences">
+
+        <EditTextPreference
+                android:key="edittext_preference"
+                android:title="@string/title_edittext_preference"
+                android:summary="@string/summary_edittext_preference"
+                android:dialogTitle="@string/dialog_title_edittext_preference" />
+
+        <ListPreference
+                android:key="list_preference"
+                android:title="@string/title_list_preference"
+                android:summary="@string/summary_list_preference"
+                android:entries="@array/entries_list_preference"
+                android:entryValues="@array/entryvalues_list_preference"
+                android:dialogTitle="@string/dialog_title_list_preference" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/launch_preferences">
+
+        <!-- This PreferenceScreen tag sends the user to a new fragment of
+             preferences.  If running in a large screen, they can be embedded
+             inside of the overall preferences UI. -->
+        <PreferenceScreen
+                android:fragment="com.example.android.apis.preference.PreferenceWithHeaders$Prefs1FragmentInner"
+                android:title="@string/title_fragment_preference"
+                android:summary="@string/summary_fragment_preference">
+            <!-- Arbitrary key/value pairs can be included for fragment arguments -->
+            <extra android:name="someKey" android:value="somePrefValue" />
+        </PreferenceScreen>
+
+        <!-- This PreferenceScreen tag sends the user to a completely different
+             activity, switching out of the current preferences UI. -->
+        <PreferenceScreen
+                android:title="@string/title_intent_preference"
+                android:summary="@string/summary_intent_preference">
+
+            <intent android:action="android.intent.action.VIEW"
+                    android:data="http://www.android.com" />
+
+        </PreferenceScreen>
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/preference_attributes">
+
+        <CheckBoxPreference
+                android:key="parent_checkbox_preference"
+                android:title="@string/title_parent_preference"
+                android:summary="@string/summary_parent_preference" />
+
+        <!-- The visual style of a child is defined by this styled theme attribute. -->
+        <CheckBoxPreference
+                android:key="child_checkbox_preference"
+                android:dependency="parent_checkbox_preference"
+                android:layout="?android:attr/preferenceLayoutChild"
+                android:title="@string/title_child_preference"
+                android:summary="@string/summary_child_preference" />
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
+<!-- END_INCLUDE(preferences) -->
diff --git a/samples/ApiDemos/res/xml/fragmented_preferences_inner.xml b/samples/ApiDemos/res/xml/fragmented_preferences_inner.xml
new file mode 100644
index 0000000..f462c57
--- /dev/null
+++ b/samples/ApiDemos/res/xml/fragmented_preferences_inner.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- This is a primitive example showing the different types of preferences available. -->
+<!-- BEGIN_INCLUDE(preferences) -->
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android">
+    <CheckBoxPreference
+            android:key="next_screen_checkbox_preference"
+            android:title="@string/title_next_screen_toggle_preference"
+            android:summary="@string/summary_next_screen_toggle_preference" />
+</PreferenceScreen>
+<!-- END_INCLUDE(preferences) -->
diff --git a/samples/ApiDemos/res/xml/preference_headers.xml b/samples/ApiDemos/res/xml/preference_headers.xml
new file mode 100644
index 0000000..7dcc531
--- /dev/null
+++ b/samples/ApiDemos/res/xml/preference_headers.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- This is a primitive example showing the different types of preferences available. -->
+<!-- BEGIN_INCLUDE(headers) -->
+<preference-headers
+        xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <header android:fragment="com.example.android.apis.preference.PreferenceWithHeaders$Prefs1Fragment"
+            android:icon="@drawable/ic_settings_applications"
+            android:title="Prefs 1"
+            android:summary="An example of some preferences." />
+            
+    <header android:fragment="com.example.android.apis.preference.PreferenceWithHeaders$Prefs2Fragment"
+            android:icon="@drawable/ic_settings_display"
+            android:title="Prefs 2"
+            android:summary="Some other preferences you can see.">
+        <!-- Arbitrary key/value pairs can be included with a header as
+             arguments to its fragment. -->
+        <extra android:name="someKey" android:value="someHeaderValue" />
+    </header>
+
+    <header android:icon="@drawable/ic_settings_display"
+            android:title="Intent"
+            android:summary="Launches an Intent.">
+        <intent android:action="android.intent.action.VIEW"
+                android:data="http://www.android.com" />
+    </header>
+    
+</preference-headers>
+<!-- END_INCLUDE(headers) -->
diff --git a/samples/ApiDemos/res/xml/preferences.xml b/samples/ApiDemos/res/xml/preferences.xml
index 59b23f1..4d982ac 100644
--- a/samples/ApiDemos/res/xml/preferences.xml
+++ b/samples/ApiDemos/res/xml/preferences.xml
@@ -15,6 +15,7 @@
 -->
 
 <!-- This is a primitive example showing the different types of preferences available. -->
+<!-- BEGIN_INCLUDE(preferences) -->
 <PreferenceScreen
         xmlns:android="http://schemas.android.com/apk/res/android">
 
@@ -97,3 +98,4 @@
     </PreferenceCategory>
     
 </PreferenceScreen>
+<!-- END_INCLUDE(preferences) -->
diff --git a/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
index 39f24b6..ffce027 100644
--- a/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
+++ b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
@@ -65,11 +65,13 @@
             return myData;
 
         String[] prefixPath;
+        String prefixWithSlash = prefix;
         
         if (prefix.equals("")) {
             prefixPath = null;
         } else {
             prefixPath = prefix.split("/");
+            prefixWithSlash = prefix + "/";
         }
         
         int len = list.size();
@@ -83,7 +85,7 @@
                     ? labelSeq.toString()
                     : info.activityInfo.name;
             
-            if (prefix.length() == 0 || label.startsWith(prefix)) {
+            if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
                 
                 String[] labelPath = label.split("/");
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/Shakespeare.java b/samples/ApiDemos/src/com/example/android/apis/Shakespeare.java
new file mode 100644
index 0000000..481df4b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/Shakespeare.java
@@ -0,0 +1,223 @@
+package com.example.android.apis;
+
+public final class Shakespeare {
+    /**
+     * Our data, part 1.
+     */
+    public static final String[] TITLES = 
+    {
+            "Henry IV (1)",   
+            "Henry V",
+            "Henry VIII",       
+            "Richard II",
+            "Richard III",
+            "Merchant of Venice",  
+            "Othello",
+            "King Lear"
+    };
+    
+    /**
+     * Our data, part 2.
+     */
+    public static final String[] DIALOGUE = 
+    {
+            "So shaken as we are, so wan with care," +
+            "Find we a time for frighted peace to pant," +
+            "And breathe short-winded accents of new broils" +
+            "To be commenced in strands afar remote." +
+            "No more the thirsty entrance of this soil" +
+            "Shall daub her lips with her own children's blood;" +
+            "Nor more shall trenching war channel her fields," +
+            "Nor bruise her flowerets with the armed hoofs" +
+            "Of hostile paces: those opposed eyes," +
+            "Which, like the meteors of a troubled heaven," +
+            "All of one nature, of one substance bred," +
+            "Did lately meet in the intestine shock" +
+            "And furious close of civil butchery" +
+            "Shall now, in mutual well-beseeming ranks," +
+            "March all one way and be no more opposed" +
+            "Against acquaintance, kindred and allies:" +
+            "The edge of war, like an ill-sheathed knife," +
+            "No more shall cut his master. Therefore, friends," +
+            "As far as to the sepulchre of Christ," +
+            "Whose soldier now, under whose blessed cross" +
+            "We are impressed and engaged to fight," +
+            "Forthwith a power of English shall we levy;" +
+            "Whose arms were moulded in their mothers' womb" +
+            "To chase these pagans in those holy fields" +
+            "Over whose acres walk'd those blessed feet" +
+            "Which fourteen hundred years ago were nail'd" +
+            "For our advantage on the bitter cross." +
+            "But this our purpose now is twelve month old," +
+            "And bootless 'tis to tell you we will go:" +
+            "Therefore we meet not now. Then let me hear" +
+            "Of you, my gentle cousin Westmoreland," +
+            "What yesternight our council did decree" +
+            "In forwarding this dear expedience.",
+            
+            "Hear him but reason in divinity," + 
+            "And all-admiring with an inward wish" + 
+            "You would desire the king were made a prelate:" + 
+            "Hear him debate of commonwealth affairs," + 
+            "You would say it hath been all in all his study:" + 
+            "List his discourse of war, and you shall hear" + 
+            "A fearful battle render'd you in music:" + 
+            "Turn him to any cause of policy," + 
+            "The Gordian knot of it he will unloose," + 
+            "Familiar as his garter: that, when he speaks," + 
+            "The air, a charter'd libertine, is still," + 
+            "And the mute wonder lurketh in men's ears," + 
+            "To steal his sweet and honey'd sentences;" + 
+            "So that the art and practic part of life" + 
+            "Must be the mistress to this theoric:" + 
+            "Which is a wonder how his grace should glean it," + 
+            "Since his addiction was to courses vain," + 
+            "His companies unletter'd, rude and shallow," + 
+            "His hours fill'd up with riots, banquets, sports," + 
+            "And never noted in him any study," + 
+            "Any retirement, any sequestration" + 
+            "From open haunts and popularity.",
+
+            "I come no more to make you laugh: things now," +
+            "That bear a weighty and a serious brow," +
+            "Sad, high, and working, full of state and woe," +
+            "Such noble scenes as draw the eye to flow," +
+            "We now present. Those that can pity, here" +
+            "May, if they think it well, let fall a tear;" +
+            "The subject will deserve it. Such as give" +
+            "Their money out of hope they may believe," +
+            "May here find truth too. Those that come to see" +
+            "Only a show or two, and so agree" +
+            "The play may pass, if they be still and willing," +
+            "I'll undertake may see away their shilling" +
+            "Richly in two short hours. Only they" +
+            "That come to hear a merry bawdy play," +
+            "A noise of targets, or to see a fellow" +
+            "In a long motley coat guarded with yellow," +
+            "Will be deceived; for, gentle hearers, know," +
+            "To rank our chosen truth with such a show" +
+            "As fool and fight is, beside forfeiting" +
+            "Our own brains, and the opinion that we bring," +
+            "To make that only true we now intend," +
+            "Will leave us never an understanding friend." +
+            "Therefore, for goodness' sake, and as you are known" +
+            "The first and happiest hearers of the town," +
+            "Be sad, as we would make ye: think ye see" +
+            "The very persons of our noble story" +
+            "As they were living; think you see them great," +
+            "And follow'd with the general throng and sweat" +
+            "Of thousand friends; then in a moment, see" +
+            "How soon this mightiness meets misery:" +
+            "And, if you can be merry then, I'll say" +
+            "A man may weep upon his wedding-day.",
+            
+            "First, heaven be the record to my speech!" + 
+            "In the devotion of a subject's love," + 
+            "Tendering the precious safety of my prince," + 
+            "And free from other misbegotten hate," + 
+            "Come I appellant to this princely presence." + 
+            "Now, Thomas Mowbray, do I turn to thee," + 
+            "And mark my greeting well; for what I speak" + 
+            "My body shall make good upon this earth," + 
+            "Or my divine soul answer it in heaven." + 
+            "Thou art a traitor and a miscreant," + 
+            "Too good to be so and too bad to live," + 
+            "Since the more fair and crystal is the sky," + 
+            "The uglier seem the clouds that in it fly." + 
+            "Once more, the more to aggravate the note," + 
+            "With a foul traitor's name stuff I thy throat;" + 
+            "And wish, so please my sovereign, ere I move," + 
+            "What my tongue speaks my right drawn sword may prove.",
+            
+            "Now is the winter of our discontent" + 
+            "Made glorious summer by this sun of York;" + 
+            "And all the clouds that lour'd upon our house" + 
+            "In the deep bosom of the ocean buried." + 
+            "Now are our brows bound with victorious wreaths;" + 
+            "Our bruised arms hung up for monuments;" + 
+            "Our stern alarums changed to merry meetings," + 
+            "Our dreadful marches to delightful measures." + 
+            "Grim-visaged war hath smooth'd his wrinkled front;" + 
+            "And now, instead of mounting barded steeds" + 
+            "To fright the souls of fearful adversaries," + 
+            "He capers nimbly in a lady's chamber" + 
+            "To the lascivious pleasing of a lute." + 
+            "But I, that am not shaped for sportive tricks," + 
+            "Nor made to court an amorous looking-glass;" + 
+            "I, that am rudely stamp'd, and want love's majesty" + 
+            "To strut before a wanton ambling nymph;" + 
+            "I, that am curtail'd of this fair proportion," + 
+            "Cheated of feature by dissembling nature," + 
+            "Deformed, unfinish'd, sent before my time" + 
+            "Into this breathing world, scarce half made up," + 
+            "And that so lamely and unfashionable" + 
+            "That dogs bark at me as I halt by them;" + 
+            "Why, I, in this weak piping time of peace," + 
+            "Have no delight to pass away the time," + 
+            "Unless to spy my shadow in the sun" + 
+            "And descant on mine own deformity:" + 
+            "And therefore, since I cannot prove a lover," + 
+            "To entertain these fair well-spoken days," + 
+            "I am determined to prove a villain" + 
+            "And hate the idle pleasures of these days." + 
+            "Plots have I laid, inductions dangerous," + 
+            "By drunken prophecies, libels and dreams," + 
+            "To set my brother Clarence and the king" + 
+            "In deadly hate the one against the other:" + 
+            "And if King Edward be as true and just" + 
+            "As I am subtle, false and treacherous," + 
+            "This day should Clarence closely be mew'd up," + 
+            "About a prophecy, which says that 'G'" + 
+            "Of Edward's heirs the murderer shall be." + 
+            "Dive, thoughts, down to my soul: here" + 
+            "Clarence comes.",
+            
+            "To bait fish withal: if it will feed nothing else," + 
+            "it will feed my revenge. He hath disgraced me, and" + 
+            "hindered me half a million; laughed at my losses," + 
+            "mocked at my gains, scorned my nation, thwarted my" + 
+            "bargains, cooled my friends, heated mine" + 
+            "enemies; and what's his reason? I am a Jew. Hath" + 
+            "not a Jew eyes? hath not a Jew hands, organs," + 
+            "dimensions, senses, affections, passions? fed with" + 
+            "the same food, hurt with the same weapons, subject" + 
+            "to the same diseases, healed by the same means," + 
+            "warmed and cooled by the same winter and summer, as" + 
+            "a Christian is? If you prick us, do we not bleed?" + 
+            "if you tickle us, do we not laugh? if you poison" + 
+            "us, do we not die? and if you wrong us, shall we not" + 
+            "revenge? If we are like you in the rest, we will" + 
+            "resemble you in that. If a Jew wrong a Christian," + 
+            "what is his humility? Revenge. If a Christian" + 
+            "wrong a Jew, what should his sufferance be by" + 
+            "Christian example? Why, revenge. The villany you" + 
+            "teach me, I will execute, and it shall go hard but I" + 
+            "will better the instruction.",
+            
+            "Virtue! a fig! 'tis in ourselves that we are thus" + 
+            "or thus. Our bodies are our gardens, to the which" + 
+            "our wills are gardeners: so that if we will plant" + 
+            "nettles, or sow lettuce, set hyssop and weed up" + 
+            "thyme, supply it with one gender of herbs, or" + 
+            "distract it with many, either to have it sterile" + 
+            "with idleness, or manured with industry, why, the" + 
+            "power and corrigible authority of this lies in our" + 
+            "wills. If the balance of our lives had not one" + 
+            "scale of reason to poise another of sensuality, the" + 
+            "blood and baseness of our natures would conduct us" + 
+            "to most preposterous conclusions: but we have" + 
+            "reason to cool our raging motions, our carnal" + 
+            "stings, our unbitted lusts, whereof I take this that" + 
+            "you call love to be a sect or scion.",
+
+            "Blow, winds, and crack your cheeks! rage! blow!" + 
+            "You cataracts and hurricanoes, spout" + 
+            "Till you have drench'd our steeples, drown'd the cocks!" + 
+            "You sulphurous and thought-executing fires," + 
+            "Vaunt-couriers to oak-cleaving thunderbolts," + 
+            "Singe my white head! And thou, all-shaking thunder," + 
+            "Smite flat the thick rotundity o' the world!" + 
+            "Crack nature's moulds, an germens spill at once," + 
+            "That make ingrateful man!"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/AnimationCloning.java b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationCloning.java
new file mode 100644
index 0000000..61896fa
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationCloning.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.widget.Button;
+import com.example.android.apis.R;
+
+import android.animation.*;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.LinearLayout;
+
+import java.util.ArrayList;
+
+
+public class AnimationCloning extends Activity {
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_cloning);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final MyAnimationView animView = new MyAnimationView(this);
+        container.addView(animView);
+
+        Button starter = (Button) findViewById(R.id.startButton);
+        starter.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+    }
+
+    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        AnimatorSet animation = null;
+        private float mDensity;
+
+        public MyAnimationView(Context context) {
+            super(context);
+
+            mDensity = getContext().getResources().getDisplayMetrics().density;
+
+            ShapeHolder ball0 = addBall(50f, 25f);
+            ShapeHolder ball1 = addBall(150f, 25f);
+            ShapeHolder ball2 = addBall(250f, 25f);
+            ShapeHolder ball3 = addBall(350f, 25f);
+        }
+
+        private void createAnimation() {
+            if (animation == null) {
+                ObjectAnimator anim1 = ObjectAnimator.ofFloat(balls.get(0), "y",
+                        0f, getHeight() - balls.get(0).getHeight()).setDuration(500);
+                ObjectAnimator anim2 = anim1.clone();
+                anim2.setTarget(balls.get(1));
+                anim1.addUpdateListener(this);
+
+                ShapeHolder ball2 = balls.get(2);
+                ObjectAnimator animDown = ObjectAnimator.ofFloat(ball2, "y",
+                        0f, getHeight() - ball2.getHeight()).setDuration(500);
+                animDown.setInterpolator(new AccelerateInterpolator());
+                ObjectAnimator animUp = ObjectAnimator.ofFloat(ball2, "y",
+                        getHeight() - ball2.getHeight(), 0f).setDuration(500);
+                animUp.setInterpolator(new DecelerateInterpolator());
+                AnimatorSet s1 = new AnimatorSet();
+                s1.playSequentially(animDown, animUp);
+                animDown.addUpdateListener(this);
+                animUp.addUpdateListener(this);
+                AnimatorSet s2 = (AnimatorSet) s1.clone();
+                s2.setTarget(balls.get(3));
+
+                animation = new AnimatorSet();
+                animation.playTogether(anim1, anim2, s1);
+                animation.playSequentially(s1, s2);
+            }
+        }
+
+        private ShapeHolder addBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(50f * mDensity, 50f * mDensity);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x - 25f);
+            shapeHolder.setY(y - 25f);
+            int red = (int)(100 + Math.random() * 155);
+            int green = (int)(100 + Math.random() * 155);
+            int blue = (int)(100 + Math.random() * 155);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            shapeHolder.setPaint(paint);
+            balls.add(shapeHolder);
+            return shapeHolder;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            for (int i = 0; i < balls.size(); ++i) {
+                ShapeHolder shapeHolder = balls.get(i);
+                canvas.save();
+                canvas.translate(shapeHolder.getX(), shapeHolder.getY());
+                shapeHolder.getShape().draw(canvas);
+                canvas.restore();
+            }
+        }
+
+        public void startAnimation() {
+            createAnimation();
+            animation.start();
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+            invalidate();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java
new file mode 100644
index 0000000..910ee28
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.graphics.Color;
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+/**
+ * This application demonstrates loading Animator objects from XML resources.
+ */
+public class AnimationLoading extends Activity {
+
+    private static final int DURATION = 1500;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_loading);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final MyAnimationView animView = new MyAnimationView(this);
+        container.addView(animView);
+
+        Button starter = (Button) findViewById(R.id.startButton);
+        starter.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+    }
+
+    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {
+
+        private static final float BALL_SIZE = 100f;
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        Animator animation = null;
+
+        public MyAnimationView(Context context) {
+            super(context);
+            addBall(50, 50);
+            addBall(200, 50);
+            addBall(350, 50);
+            addBall(500, 50, Color.GREEN);
+        }
+
+        private void createAnimation() {
+            Context appContext = AnimationLoading.this;
+
+            if (animation == null) {
+                ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.
+                        loadAnimator(appContext, R.anim.object_animator);
+                anim.addUpdateListener(this);
+                anim.setTarget(balls.get(0));
+
+                ValueAnimator fader = (ValueAnimator) AnimatorInflater.
+                        loadAnimator(appContext, R.anim.animator);
+                fader.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        balls.get(1).setAlpha((Float) animation.getAnimatedValue());
+                    }
+                });
+
+                AnimatorSet seq =
+                        (AnimatorSet) AnimatorInflater.loadAnimator(appContext,
+                        R.anim.animator_set);
+                seq.setTarget(balls.get(2));
+
+                ObjectAnimator colorizer = (ObjectAnimator) AnimatorInflater.
+                        loadAnimator(appContext, R.anim.color_animator);
+                colorizer.setTarget(balls.get(3));
+
+                animation = new AnimatorSet();
+                ((AnimatorSet) animation).playTogether(anim, fader, seq, colorizer);
+            }
+        }
+
+        public void startAnimation() {
+            createAnimation();
+            animation.start();
+        }
+
+        private ShapeHolder createBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(BALL_SIZE, BALL_SIZE);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x);
+            shapeHolder.setY(y);
+            return shapeHolder;
+        }
+
+        private void addBall(float x, float y, int color) {
+            ShapeHolder shapeHolder = createBall(x, y);
+            shapeHolder.setColor(color);
+            balls.add(shapeHolder);
+        }
+
+        private void addBall(float x, float y) {
+            ShapeHolder shapeHolder = createBall(x, y);
+            int red = (int)(100 + Math.random() * 155);
+            int green = (int)(100 + Math.random() * 155);
+            int blue = (int)(100 + Math.random() * 155);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = shapeHolder.getShape().getPaint();
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            balls.add(shapeHolder);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            for (ShapeHolder ball : balls) {
+                canvas.translate(ball.getX(), ball.getY());
+                ball.getShape().draw(canvas);
+                canvas.translate(-ball.getX(), -ball.getY());
+            }
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+
+            invalidate();
+            ShapeHolder ball = balls.get(0);
+            ball.setY((Float)animation.getAnimatedValue());
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/AnimationSeeking.java b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationSeeking.java
new file mode 100644
index 0000000..066912b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationSeeking.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.Animator;
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+import android.animation.ValueAnimator;
+import android.animation.ObjectAnimator;
+import android.animation.AnimatorSet;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.BounceInterpolator;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+
+/**
+ * This application demonstrates the seeking capability of ValueAnimator. The SeekBar in the
+ * UI allows you to set the position of the animation. Pressing the Run button will play from
+ * the current position of the animation.
+ */
+public class AnimationSeeking extends Activity {
+
+    private static final int DURATION = 1500;
+    private SeekBar mSeekBar;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_seeking);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final MyAnimationView animView = new MyAnimationView(this);
+        container.addView(animView);
+
+        Button starter = (Button) findViewById(R.id.startButton);
+        starter.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+
+        mSeekBar = (SeekBar) findViewById(R.id.seekBar);
+        mSeekBar.setMax(DURATION);
+        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                // prevent seeking on app creation
+                if (animView.getHeight() != 0) {
+                    animView.seek(progress);
+                }
+            }
+        });
+    }
+
+    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
+
+        private static final int RED = 0xffFF8080;
+        private static final int BLUE = 0xff8080FF;
+        private static final int CYAN = 0xff80ffff;
+        private static final int GREEN = 0xff80ff80;
+        private static final float BALL_SIZE = 100f;
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        AnimatorSet animation = null;
+        ValueAnimator bounceAnim = null;
+        ShapeHolder ball = null;
+
+        public MyAnimationView(Context context) {
+            super(context);
+            ball = addBall(200, 0);
+        }
+
+        private void createAnimation() {
+            if (bounceAnim == null) {
+                bounceAnim = ObjectAnimator.ofFloat(ball, "y",
+                        ball.getY(), getHeight() - BALL_SIZE).setDuration(1500);
+                bounceAnim.setInterpolator(new BounceInterpolator());
+                bounceAnim.addUpdateListener(this);
+            }
+        }
+
+        public void startAnimation() {
+            createAnimation();
+            bounceAnim.start();
+        }
+
+        public void seek(long seekTime) {
+            createAnimation();
+            bounceAnim.setCurrentPlayTime(seekTime);
+        }
+
+        private ShapeHolder addBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(BALL_SIZE, BALL_SIZE);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x);
+            shapeHolder.setY(y);
+            int red = (int)(100 + Math.random() * 155);
+            int green = (int)(100 + Math.random() * 155);
+            int blue = (int)(100 + Math.random() * 155);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = drawable.getPaint();
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            shapeHolder.setPaint(paint);
+            balls.add(shapeHolder);
+            return shapeHolder;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            canvas.translate(ball.getX(), ball.getY());
+            ball.getShape().draw(canvas);
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+            invalidate();
+            long playtime = bounceAnim.getCurrentPlayTime();
+            //mSeekBar.setProgress((int)playtime);
+        }
+
+        public void onAnimationCancel(Animator animation) {
+        }
+
+        public void onAnimationEnd(Animator animation) {
+            balls.remove(((ObjectAnimator)animation).getTarget());
+
+        }
+
+        public void onAnimationRepeat(Animator animation) {
+        }
+
+        public void onAnimationStart(Animator animation) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/AnimatorEvents.java b/samples/ApiDemos/src/com/example/android/apis/animation/AnimatorEvents.java
new file mode 100644
index 0000000..81ece18
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimatorEvents.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.widget.CheckBox;
+import android.widget.TextView;
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+import android.animation.ValueAnimator;
+import android.animation.AnimatorSet;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+/**
+ * This demo shows how the AnimatorListener events work.
+ */
+public class AnimatorEvents extends Activity {
+
+    TextView startText, repeatText, cancelText, endText;
+    TextView startTextAnimator, repeatTextAnimator, cancelTextAnimator, endTextAnimator;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animator_events);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final MyAnimationView animView = new MyAnimationView(this);
+        container.addView(animView);
+        startText = (TextView) findViewById(R.id.startText);
+        startText.setAlpha(.5f);
+        repeatText = (TextView) findViewById(R.id.repeatText);
+        repeatText.setAlpha(.5f);
+        cancelText = (TextView) findViewById(R.id.cancelText);
+        cancelText.setAlpha(.5f);
+        endText = (TextView) findViewById(R.id.endText);
+        endText.setAlpha(.5f);
+        startTextAnimator = (TextView) findViewById(R.id.startTextAnimator);
+        startTextAnimator.setAlpha(.5f);
+        repeatTextAnimator = (TextView) findViewById(R.id.repeatTextAnimator);
+        repeatTextAnimator.setAlpha(.5f);
+        cancelTextAnimator = (TextView) findViewById(R.id.cancelTextAnimator);
+        cancelTextAnimator.setAlpha(.5f);
+        endTextAnimator = (TextView) findViewById(R.id.endTextAnimator);
+        endTextAnimator.setAlpha(.5f);
+        final CheckBox endCB = (CheckBox) findViewById(R.id.endCB);
+
+
+        Button starter = (Button) findViewById(R.id.startButton);
+        starter.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                animView.startAnimation(endCB.isChecked());
+            }
+        });
+
+        Button canceler = (Button) findViewById(R.id.cancelButton);
+        canceler.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                animView.cancelAnimation();
+            }
+        });
+
+        Button ender = (Button) findViewById(R.id.endButton);
+        ender.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                animView.endAnimation();
+            }
+        });
+
+    }
+
+    public class MyAnimationView extends View implements Animator.AnimatorListener,
+    ValueAnimator.AnimatorUpdateListener {
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        Animator animation;
+        ShapeHolder ball = null;
+        boolean endImmediately = false;
+
+        public MyAnimationView(Context context) {
+            super(context);
+            ball = createBall(25, 25);
+        }
+
+        private void createAnimation() {
+            if (animation == null) {
+                ObjectAnimator yAnim = ObjectAnimator.ofFloat(ball, "y",
+                        ball.getY(), getHeight() - 50f).setDuration(1500);
+                yAnim.setRepeatCount(0);
+                yAnim.setRepeatMode(ValueAnimator.REVERSE);
+                yAnim.setInterpolator(new AccelerateInterpolator(2f));
+                yAnim.addUpdateListener(this);
+                yAnim.addListener(this);
+
+                ObjectAnimator xAnim = ObjectAnimator.ofFloat(ball, "x",
+                        ball.getX(), ball.getX() + 300).setDuration(1000);
+                xAnim.setStartDelay(0);
+                xAnim.setRepeatCount(0);
+                xAnim.setRepeatMode(ValueAnimator.REVERSE);
+                xAnim.setInterpolator(new AccelerateInterpolator(2f));
+
+                ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(ball, "alpha", 1f, .5f).
+                        setDuration(1000);
+                AnimatorSet alphaSeq = new AnimatorSet();
+                alphaSeq.play(alphaAnim);
+
+                animation = new AnimatorSet();
+                ((AnimatorSet) animation).playTogether(yAnim, xAnim);
+                animation.addListener(this);
+            }
+        }
+
+        public void startAnimation(boolean endImmediately) {
+            this.endImmediately = endImmediately;
+            startText.setAlpha(.5f);
+            repeatText.setAlpha(.5f);
+            cancelText.setAlpha(.5f);
+            endText.setAlpha(.5f);
+            startTextAnimator.setAlpha(.5f);
+            repeatTextAnimator.setAlpha(.5f);
+            cancelTextAnimator.setAlpha(.5f);
+            endTextAnimator.setAlpha(.5f);
+            createAnimation();
+            animation.start();
+        }
+
+        public void cancelAnimation() {
+            createAnimation();
+            animation.cancel();
+        }
+
+        public void endAnimation() {
+            createAnimation();
+            animation.end();
+        }
+
+        private ShapeHolder createBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(50f, 50f);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x - 25f);
+            shapeHolder.setY(y - 25f);
+            int red = (int)(Math.random() * 255);
+            int green = (int)(Math.random() * 255);
+            int blue = (int)(Math.random() * 255);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            shapeHolder.setPaint(paint);
+            return shapeHolder;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            canvas.save();
+            canvas.translate(ball.getX(), ball.getY());
+            ball.getShape().draw(canvas);
+            canvas.restore();
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+            invalidate();
+        }
+
+        public void onAnimationStart(Animator animation) {
+            if (animation instanceof AnimatorSet) {
+                startText.setAlpha(1f);
+            } else {
+                startTextAnimator.setAlpha(1f);
+            }
+            if (endImmediately) {
+                animation.end();
+            }
+        }
+
+        public void onAnimationEnd(Animator animation) {
+            if (animation instanceof AnimatorSet) {
+                endText.setAlpha(1f);
+            } else {
+                endTextAnimator.setAlpha(1f);
+            }
+        }
+
+        public void onAnimationCancel(Animator animation) {
+            if (animation instanceof AnimatorSet) {
+                cancelText.setAlpha(1f);
+            } else {
+                cancelTextAnimator.setAlpha(1f);
+            }
+        }
+
+        public void onAnimationRepeat(Animator animation) {
+            if (animation instanceof AnimatorSet) {
+                repeatText.setAlpha(1f);
+            } else {
+                repeatTextAnimator.setAlpha(1f);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.java b/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.java
new file mode 100644
index 0000000..de28da3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.graphics.drawable.ColorDrawable;
+import com.example.android.apis.R;
+
+import android.animation.*;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.LinearLayout;
+
+import java.util.ArrayList;
+
+
+public class BouncingBalls extends Activity {
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.bouncing_balls);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        container.addView(new MyAnimationView(this));
+    }
+
+    public class MyAnimationView extends View {
+
+        private static final int RED = 0xffFF8080;
+        private static final int BLUE = 0xff8080FF;
+        private static final int CYAN = 0xff80ffff;
+        private static final int GREEN = 0xff80ff80;
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        AnimatorSet animation = null;
+
+        public MyAnimationView(Context context) {
+            super(context);
+
+            // Animate background color
+            // Note that setting the background color will automatically invalidate the
+            // view, so that the animated color, and the bouncing balls, get redisplayed on
+            // every frame of the animation.
+            ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
+            colorAnim.setDuration(3000);
+            colorAnim.setEvaluator(new ArgbEvaluator());
+            colorAnim.setRepeatCount(ValueAnimator.INFINITE);
+            colorAnim.setRepeatMode(ValueAnimator.REVERSE);
+            colorAnim.start();
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            if (event.getAction() != MotionEvent.ACTION_DOWN &&
+                    event.getAction() != MotionEvent.ACTION_MOVE) {
+                return false;
+            }
+            ShapeHolder newBall = addBall(event.getX(), event.getY());
+
+            // Bouncing animation with squash and stretch
+            float startY = newBall.getY();
+            float endY = getHeight() - 50f;
+            float h = (float)getHeight();
+            float eventY = event.getY();
+            int duration = (int)(500 * ((h - eventY)/h));
+            ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);
+            bounceAnim.setDuration(duration);
+            bounceAnim.setInterpolator(new AccelerateInterpolator());
+            ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", newBall.getX(),
+                    newBall.getX() - 25f);
+            squashAnim1.setDuration(duration/4);
+            squashAnim1.setRepeatCount(1);
+            squashAnim1.setRepeatMode(ValueAnimator.REVERSE);
+            squashAnim1.setInterpolator(new DecelerateInterpolator());
+            ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", newBall.getWidth(),
+                    newBall.getWidth() + 50);
+            squashAnim2.setDuration(duration/4);
+            squashAnim2.setRepeatCount(1);
+            squashAnim2.setRepeatMode(ValueAnimator.REVERSE);
+            squashAnim2.setInterpolator(new DecelerateInterpolator());
+            ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", endY,
+                    endY + 25f);
+            stretchAnim1.setDuration(duration/4);
+            stretchAnim1.setRepeatCount(1);
+            stretchAnim1.setInterpolator(new DecelerateInterpolator());
+            stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);
+            ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height",
+                    newBall.getHeight(), newBall.getHeight() - 25);
+            stretchAnim2.setDuration(duration/4);
+            stretchAnim2.setRepeatCount(1);
+            stretchAnim2.setInterpolator(new DecelerateInterpolator());
+            stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);
+            ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY,
+                    startY);
+            bounceBackAnim.setDuration(duration);
+            bounceBackAnim.setInterpolator(new DecelerateInterpolator());
+            // Sequence the down/squash&stretch/up animations
+            AnimatorSet bouncer = new AnimatorSet();
+            bouncer.play(bounceAnim).before(squashAnim1);
+            bouncer.play(squashAnim1).with(squashAnim2);
+            bouncer.play(squashAnim1).with(stretchAnim1);
+            bouncer.play(squashAnim1).with(stretchAnim2);
+            bouncer.play(bounceBackAnim).after(stretchAnim2);
+
+            // Fading animation - remove the ball when the animation is done
+            ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+            fadeAnim.setDuration(250);
+            fadeAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    balls.remove(((ObjectAnimator)animation).getTarget());
+
+                }
+            });
+
+            // Sequence the two animations to play one after the other
+            AnimatorSet animatorSet = new AnimatorSet();
+            animatorSet.play(bouncer).before(fadeAnim);
+
+            // Start the animation
+            animatorSet.start();
+
+            return true;
+        }
+
+        private ShapeHolder addBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(50f, 50f);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x - 25f);
+            shapeHolder.setY(y - 25f);
+            int red = (int)(Math.random() * 255);
+            int green = (int)(Math.random() * 255);
+            int blue = (int)(Math.random() * 255);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            shapeHolder.setPaint(paint);
+            balls.add(shapeHolder);
+            return shapeHolder;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            for (int i = 0; i < balls.size(); ++i) {
+                ShapeHolder shapeHolder = balls.get(i);
+                canvas.save();
+                canvas.translate(shapeHolder.getX(), shapeHolder.getY());
+                shapeHolder.getShape().draw(canvas);
+                canvas.restore();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/CustomEvaluator.java b/samples/ApiDemos/src/com/example/android/apis/animation/CustomEvaluator.java
new file mode 100644
index 0000000..623450a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/CustomEvaluator.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.ObjectAnimator;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class CustomEvaluator extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animator_custom_evaluator);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final MyAnimationView animView = new MyAnimationView(this);
+        container.addView(animView);
+
+        Button starter = (Button) findViewById(R.id.startButton);
+        starter.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+    }
+
+    public class XYHolder {
+        private float mX;
+        private float mY;
+
+        public XYHolder(float x, float y) {
+            mX = x;
+            mY = y;
+        }
+
+        public float getX() {
+            return mX;
+        }
+
+        public void setX(float x) {
+            mX = x;
+        }
+
+        public float getY() {
+            return mY;
+        }
+
+        public void setY(float y) {
+            mY = y;
+        }
+    }
+
+    public class XYEvaluator implements TypeEvaluator {
+        public Object evaluate(float fraction, Object startValue, Object endValue) {
+            XYHolder startXY = (XYHolder) startValue;
+            XYHolder endXY = (XYHolder) endValue;
+            return new XYHolder(startXY.getX() + fraction * (endXY.getX() - startXY.getX()),
+                    startXY.getY() + fraction * (endXY.getY() - startXY.getY()));
+        }
+    }
+
+    public class BallXYHolder {
+
+        private ShapeHolder mBall;
+
+        public BallXYHolder(ShapeHolder ball) {
+            mBall = ball;
+        }
+
+        public void setXY(XYHolder xyHolder) {
+            mBall.setX(xyHolder.getX());
+            mBall.setY(xyHolder.getY());
+        }
+
+        public XYHolder getXY() {
+            return new XYHolder(mBall.getX(), mBall.getY());
+        }
+    }
+
+    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        ValueAnimator bounceAnim = null;
+        ShapeHolder ball = null;
+        BallXYHolder ballHolder = null;
+
+        public MyAnimationView(Context context) {
+            super(context);
+            ball = createBall(25, 25);
+            ballHolder = new BallXYHolder(ball);
+        }
+
+        private void createAnimation() {
+            if (bounceAnim == null) {
+                XYHolder startXY = new XYHolder(0f, 0f);
+                XYHolder endXY = new XYHolder(300f, 500f);
+                bounceAnim = ObjectAnimator.ofObject(ballHolder, "xY",
+                        new XYEvaluator(), endXY);
+                bounceAnim.setDuration(1500);
+                bounceAnim.addUpdateListener(this);
+            }
+        }
+
+        public void startAnimation() {
+            createAnimation();
+            bounceAnim.start();
+        }
+
+        private ShapeHolder createBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(50f, 50f);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x - 25f);
+            shapeHolder.setY(y - 25f);
+            int red = (int)(Math.random() * 255);
+            int green = (int)(Math.random() * 255);
+            int blue = (int)(Math.random() * 255);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            shapeHolder.setPaint(paint);
+            return shapeHolder;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            canvas.save();
+            canvas.translate(ball.getX(), ball.getY());
+            ball.getShape().draw(canvas);
+            canvas.restore();
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+            invalidate();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/FixedGridLayout.java b/samples/ApiDemos/src/com/example/android/apis/animation/FixedGridLayout.java
new file mode 100644
index 0000000..5d92e85
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/FixedGridLayout.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package com.example.android.apis.animation;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A layout that arranges its children in a grid.  The size of the
+ * cells is set by the {@link #setCellSize} method and the
+ * android:cell_width and android:cell_height attributes in XML.
+ * The number of rows and columns is determined at runtime.  Each
+ * cell contains exactly one view, and they flow in the natural
+ * child order (the order in which they were added, or the index
+ * in {@link #addViewAt}.  Views can not span multiple cells.
+ *
+ * <p>This class was copied from the FixedGridLayout Api demo; see that demo for
+ * more information on using the layout.</p>
+ */
+public class FixedGridLayout extends ViewGroup {
+    int mCellWidth;
+    int mCellHeight;
+
+    public FixedGridLayout(Context context) {
+        super(context);
+    }
+
+    public void setCellWidth(int px) {
+        mCellWidth = px;
+        requestLayout();
+    }
+
+    public void setCellHeight(int px) {
+        mCellHeight = px;
+        requestLayout();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int cellWidthSpec = MeasureSpec.makeMeasureSpec(mCellWidth,
+                MeasureSpec.AT_MOST);
+        int cellHeightSpec = MeasureSpec.makeMeasureSpec(mCellHeight,
+                MeasureSpec.AT_MOST);
+
+        int count = getChildCount();
+        for (int index=0; index<count; index++) {
+            final View child = getChildAt(index);
+            child.measure(cellWidthSpec, cellHeightSpec);
+        }
+        // Use the size our parents gave us, but default to a minimum size to avoid
+        // clipping transitioning children
+        int minCount =  count > 3 ? count : 3;
+        setMeasuredDimension(resolveSize(mCellWidth * minCount, widthMeasureSpec),
+                resolveSize(mCellHeight * minCount, heightMeasureSpec));
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        int cellWidth = mCellWidth;
+        int cellHeight = mCellHeight;
+        int columns = (r - l) / cellWidth;
+        if (columns < 0) {
+            columns = 1;
+        }
+        int x = 0;
+        int y = 0;
+        int i = 0;
+        int count = getChildCount();
+        for (int index=0; index<count; index++) {
+            final View child = getChildAt(index);
+
+            int w = child.getMeasuredWidth();
+            int h = child.getMeasuredHeight();
+
+            int left = x + ((cellWidth-w)/2);
+            int top = y + ((cellHeight-h)/2);
+
+            child.layout(left, top, left+w, top+h);
+            if (i >= (columns-1)) {
+                // advance to next row
+                i = 0;
+                x = 0;
+                y += cellHeight;
+            } else {
+                i++;
+                x += cellWidth;
+            }
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java
new file mode 100644
index 0000000..65ad782
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.widget.LinearLayout;
+import com.example.android.apis.R;
+
+import android.animation.AnimatorListenerAdapter;
+import android.animation.Keyframe;
+import android.animation.LayoutTransition;
+import android.animation.PropertyValuesHolder;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+
+/**
+ * This application demonstrates how to use LayoutTransition to automate transition animations
+ * as items are removed from or added to a container.
+ */
+public class LayoutAnimations extends Activity {
+
+    private int numButtons = 1;
+    ViewGroup container = null;
+    Animator defaultAppearingAnim, defaultDisappearingAnim;
+    Animator defaultChangingAppearingAnim, defaultChangingDisappearingAnim;
+    Animator customAppearingAnim, customDisappearingAnim;
+    Animator customChangingAppearingAnim, customChangingDisappearingAnim;
+    Animator currentAppearingAnim, currentDisappearingAnim;
+    Animator currentChangingAppearingAnim, currentChangingDisappearingAnim;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.layout_animations);
+
+        container = new FixedGridLayout(this);
+        container.setClipChildren(false);
+        ((FixedGridLayout)container).setCellHeight(50);
+        ((FixedGridLayout)container).setCellWidth(200);
+        final LayoutTransition transitioner = new LayoutTransition();
+        container.setLayoutTransition(transitioner);
+        defaultAppearingAnim = transitioner.getAnimator(LayoutTransition.APPEARING);
+        defaultDisappearingAnim =
+                transitioner.getAnimator(LayoutTransition.DISAPPEARING);
+        defaultChangingAppearingAnim =
+                transitioner.getAnimator(LayoutTransition.CHANGE_APPEARING);
+        defaultChangingDisappearingAnim =
+                transitioner.getAnimator(LayoutTransition.CHANGE_DISAPPEARING);
+        createCustomAnimations(transitioner);
+        currentAppearingAnim = defaultAppearingAnim;
+        currentDisappearingAnim = defaultDisappearingAnim;
+        currentChangingAppearingAnim = defaultChangingAppearingAnim;
+        currentChangingDisappearingAnim = defaultChangingDisappearingAnim;
+
+        ViewGroup parent = (ViewGroup) findViewById(R.id.parent);
+        parent.addView(container);
+        parent.setClipChildren(false);
+        Button addButton = (Button) findViewById(R.id.addNewButton);
+        addButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                Button newButton = new Button(LayoutAnimations.this);
+                newButton.setText("Click to Delete " + (numButtons++));
+                newButton.setOnClickListener(new View.OnClickListener() {
+                    public void onClick(View v) {
+                        container.removeView(v);
+                    }
+                });
+                container.addView(newButton, Math.min(1, container.getChildCount()));
+            }
+        });
+
+        CheckBox customAnimCB = (CheckBox) findViewById(R.id.customAnimCB);
+        customAnimCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                setupTransition(transitioner);
+            }
+        });
+
+        // Check for disabled animations
+        CheckBox appearingCB = (CheckBox) findViewById(R.id.appearingCB);
+        appearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                setupTransition(transitioner);
+            }
+        });
+        CheckBox disappearingCB = (CheckBox) findViewById(R.id.disappearingCB);
+        disappearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                setupTransition(transitioner);
+            }
+        });
+        CheckBox changingAppearingCB = (CheckBox) findViewById(R.id.changingAppearingCB);
+        changingAppearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                setupTransition(transitioner);
+            }
+        });
+        CheckBox changingDisappearingCB = (CheckBox) findViewById(R.id.changingDisappearingCB);
+        changingDisappearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                setupTransition(transitioner);
+            }
+        });
+    }
+
+    private void setupTransition(LayoutTransition transition) {
+        CheckBox customAnimCB = (CheckBox) findViewById(R.id.customAnimCB);
+        CheckBox appearingCB = (CheckBox) findViewById(R.id.appearingCB);
+        CheckBox disappearingCB = (CheckBox) findViewById(R.id.disappearingCB);
+        CheckBox changingAppearingCB = (CheckBox) findViewById(R.id.changingAppearingCB);
+        CheckBox changingDisappearingCB = (CheckBox) findViewById(R.id.changingDisappearingCB);
+        transition.setAnimator(LayoutTransition.APPEARING, appearingCB.isChecked() ?
+                (customAnimCB.isChecked() ? customAppearingAnim : defaultAppearingAnim) : null);
+        transition.setAnimator(LayoutTransition.DISAPPEARING, disappearingCB.isChecked() ?
+                (customAnimCB.isChecked() ? customDisappearingAnim : defaultDisappearingAnim) : null);
+        transition.setAnimator(LayoutTransition.CHANGE_APPEARING, changingAppearingCB.isChecked() ?
+                (customAnimCB.isChecked() ? customChangingAppearingAnim :
+                        defaultChangingAppearingAnim) : null);
+        transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,
+                changingDisappearingCB.isChecked() ?
+                (customAnimCB.isChecked() ? customChangingDisappearingAnim :
+                        defaultChangingDisappearingAnim) : null);
+    }
+
+    private void createCustomAnimations(LayoutTransition transition) {
+        // Changing while Adding
+        PropertyValuesHolder pvhLeft =
+                PropertyValuesHolder.ofInt("left", 0, 1);
+        PropertyValuesHolder pvhTop =
+                PropertyValuesHolder.ofInt("top", 0, 1);
+        PropertyValuesHolder pvhRight =
+                PropertyValuesHolder.ofInt("right", 0, 1);
+        PropertyValuesHolder pvhBottom =
+                PropertyValuesHolder.ofInt("bottom", 0, 1);
+        PropertyValuesHolder pvhScaleX =
+                PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);
+        PropertyValuesHolder pvhScaleY =
+                PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
+        customChangingAppearingAnim = ObjectAnimator.ofPropertyValuesHolder(
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX, pvhScaleY).
+                setDuration(transition.getDuration(LayoutTransition.CHANGE_APPEARING));
+        customChangingAppearingAnim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setScaleX(1f);
+                view.setScaleY(1f);
+            }
+        });
+
+        // Changing while Removing
+        Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+        Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
+        Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+        PropertyValuesHolder pvhRotation =
+                PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
+        customChangingDisappearingAnim = ObjectAnimator.ofPropertyValuesHolder(
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation).
+                setDuration(transition.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
+        customChangingDisappearingAnim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotation(0f);
+            }
+        });
+
+        // Adding
+        customAppearingAnim = ObjectAnimator.ofFloat(null, "rotationY", 90f, 0f).
+                setDuration(transition.getDuration(LayoutTransition.APPEARING));
+        customAppearingAnim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotationY(0f);
+            }
+        });
+
+        // Removing
+        customDisappearingAnim = ObjectAnimator.ofFloat(null, "rotationX", 0f, 90f).
+                setDuration(transition.getDuration(LayoutTransition.DISAPPEARING));
+        customDisappearingAnim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotationX(0f);
+            }
+        });
+
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.java b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.java
new file mode 100644
index 0000000..67b9b51
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+
+/**
+ * This application demonstrates how to use the animateLayoutChanges tag in XML to automate
+ * transition animations as items are removed from or added to a container.
+ */
+public class LayoutAnimationsByDefault extends Activity {
+
+    private int numButtons = 1;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.layout_animations_by_default);
+
+        final ViewGroup horizontalContainer = (ViewGroup) findViewById(R.id.horizontalContainer);
+        final ViewGroup verticalContainer = (ViewGroup) findViewById(R.id.verticalContainer);
+
+        Button addButton = (Button) findViewById(R.id.addNewButton);
+        addButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                Button newButton = new Button(LayoutAnimationsByDefault.this);
+                newButton.setText("Click To Remove " + (numButtons++));
+                newButton.setOnClickListener(new View.OnClickListener() {
+                    public void onClick(View v) {
+                        horizontalContainer.removeView(v);
+                    }
+                });
+                horizontalContainer.addView(newButton, Math.min(1, horizontalContainer.getChildCount()));
+
+                newButton = new Button(LayoutAnimationsByDefault.this);
+                newButton.setText("Click To Remove " + (numButtons++));
+                newButton.setOnClickListener(new View.OnClickListener() {
+                    public void onClick(View v) {
+                        verticalContainer.removeView(v);
+                    }
+                });
+                verticalContainer.addView(newButton, Math.min(1, verticalContainer.getChildCount()));
+            }
+        });
+    }
+
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java
new file mode 100644
index 0000000..3ee7b0c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.widget.LinearLayout;
+import com.example.android.apis.R;
+
+import android.animation.AnimatorListenerAdapter;
+import android.animation.Keyframe;
+import android.animation.LayoutTransition;
+import android.animation.PropertyValuesHolder;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+
+/**
+ * This application demonstrates how to use LayoutTransition to automate transition animations
+ * as items are hidden or shown in a container.
+ */
+public class LayoutAnimationsHideShow extends Activity {
+
+    private int numButtons = 1;
+    ViewGroup container = null;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.layout_animations_hideshow);
+
+        final CheckBox hideGoneCB = (CheckBox) findViewById(R.id.hideGoneCB);
+
+        container = new LinearLayout(this);
+        container.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // Add a slew of buttons to the container. We won't add any more buttons at runtime, but
+        // will just show/hide the buttons we've already created
+        for (int i = 0; i < 6; ++i) {
+            Button newButton = new Button(this);
+            newButton.setText("Click to Hide " + i);
+            container.addView(newButton);
+            newButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    v.setVisibility(hideGoneCB.isChecked() ? View.GONE : View.INVISIBLE);
+                }
+            });
+        }
+        final LayoutTransition transitioner = new LayoutTransition();
+        container.setLayoutTransition(transitioner);
+
+        ViewGroup parent = (ViewGroup) findViewById(R.id.parent);
+        parent.addView(container);
+
+        Button addButton = (Button) findViewById(R.id.addNewButton);
+        addButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                for (int i = 0; i < container.getChildCount(); ++i) {
+                    View view = (View) container.getChildAt(i);
+                    view.setVisibility(View.VISIBLE);
+                }
+            }
+        });
+
+        CheckBox customAnimCB = (CheckBox) findViewById(R.id.customAnimCB);
+        customAnimCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                long duration;
+                if (isChecked) {
+                    transitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);
+                    transitioner.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 30);
+                    setupAnimations(transitioner);
+                    duration = 500;
+                } else {
+                    transitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 0);
+                    transitioner.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 0);
+                    transitioner.setAnimator(LayoutTransition.APPEARING, null);
+                    transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
+                    transitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, null);
+                    transitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
+                    duration = 300;
+                }
+                transitioner.setDuration(duration);
+            }
+        });
+    }
+
+    private void setupAnimations(LayoutTransition transition) {
+        // Changing while Adding
+        PropertyValuesHolder pvhLeft =
+                PropertyValuesHolder.ofInt("left", 0, 1);
+        PropertyValuesHolder pvhTop =
+                PropertyValuesHolder.ofInt("top", 0, 1);
+        PropertyValuesHolder pvhRight =
+                PropertyValuesHolder.ofInt("right", 0, 1);
+        PropertyValuesHolder pvhBottom =
+                PropertyValuesHolder.ofInt("bottom", 0, 1);
+        PropertyValuesHolder pvhScaleX =
+                PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);
+        PropertyValuesHolder pvhScaleY =
+                PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
+        final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX, pvhScaleY).
+                setDuration(transition.getDuration(LayoutTransition.CHANGE_APPEARING));
+        transition.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);
+        changeIn.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setScaleX(1f);
+                view.setScaleY(1f);
+            }
+        });
+
+        // Changing while Removing
+        Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+        Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
+        Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+        PropertyValuesHolder pvhRotation =
+                PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
+        final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder(
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation).
+                setDuration(transition.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
+        transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut);
+        changeOut.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotation(0f);
+            }
+        });
+
+        // Adding
+        ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 90f, 0f).
+                setDuration(transition.getDuration(LayoutTransition.APPEARING));
+        transition.setAnimator(LayoutTransition.APPEARING, animIn);
+        animIn.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotationY(0f);
+            }
+        });
+
+        // Removing
+        ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotationX", 0f, 90f).
+                setDuration(transition.getDuration(LayoutTransition.DISAPPEARING));
+        transition.setAnimator(LayoutTransition.DISAPPEARING, animOut);
+        animIn.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotationX(0f);
+            }
+        });
+
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ListFlipper.java b/samples/ApiDemos/src/com/example/android/apis/animation/ListFlipper.java
new file mode 100644
index 0000000..7cc03db
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ListFlipper.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.AnimatorListenerAdapter;
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.SeekBar;
+
+/**
+ * This application demonstrates the seeking capability of ValueAnimator. The SeekBar in the
+ * UI allows you to set the position of the animation. Pressing the Run button will play from
+ * the current position of the animation.
+ */
+public class ListFlipper extends Activity {
+
+    private static final int DURATION = 1500;
+    private SeekBar mSeekBar;
+
+    private static final String[] LIST_STRINGS_EN = new String[] {
+            "One",
+            "Two",
+            "Three",
+            "Four",
+            "Five",
+            "Six"
+    };
+    private static final String[] LIST_STRINGS_FR = new String[] {
+            "Un",
+            "Deux",
+            "Trois",
+            "Quatre",
+            "Le Five",
+            "Six"
+    };
+
+    ListView mEnglishList;
+    ListView mFrenchList;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.rotating_list);
+        //FrameLayout container = (LinearLayout) findViewById(R.id.container);
+        mEnglishList = (ListView) findViewById(R.id.list_en);
+        mFrenchList = (ListView) findViewById(R.id.list_fr);
+
+        // Prepare the ListView
+        final ArrayAdapter<String> adapterEn = new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, LIST_STRINGS_EN);
+        // Prepare the ListView
+        final ArrayAdapter<String> adapterFr = new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, LIST_STRINGS_FR);
+
+        mEnglishList.setAdapter(adapterEn);
+        mFrenchList.setAdapter(adapterFr);
+        mFrenchList.setRotationY(-90f);
+
+        Button starter = (Button) findViewById(R.id.button);
+        starter.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                flipit();
+            }
+        });
+    }
+
+    private Interpolator accelerator = new AccelerateInterpolator();
+    private Interpolator decelerator = new DecelerateInterpolator();
+    private void flipit() {
+        final ListView visibleList;
+        final ListView invisibleList;
+        if (mEnglishList.getVisibility() == View.GONE) {
+            visibleList = mFrenchList;
+            invisibleList = mEnglishList;
+        } else {
+            invisibleList = mFrenchList;
+            visibleList = mEnglishList;
+        }
+        ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibleList, "rotationY", 0f, 90f);
+        visToInvis.setDuration(500);
+        visToInvis.setInterpolator(accelerator);
+        final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibleList, "rotationY",
+                -90f, 0f);
+        invisToVis.setDuration(500);
+        invisToVis.setInterpolator(decelerator);
+        visToInvis.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator anim) {
+                visibleList.setVisibility(View.GONE);
+                invisToVis.start();
+                invisibleList.setVisibility(View.VISIBLE);
+            }
+        });
+        visToInvis.start();
+    }
+
+
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.java b/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.java
new file mode 100644
index 0000000..71af03f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.*;
+import android.view.animation.AccelerateInterpolator;
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.BounceInterpolator;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+/**
+ * This application demonstrates the seeking capability of ValueAnimator. The SeekBar in the
+ * UI allows you to set the position of the animation. Pressing the Run button will play from
+ * the current position of the animation.
+ */
+public class MultiPropertyAnimation extends Activity {
+
+    private static final int DURATION = 1500;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_multi_property);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final MyAnimationView animView = new MyAnimationView(this);
+        container.addView(animView);
+
+        Button starter = (Button) findViewById(R.id.startButton);
+        starter.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+
+    }
+
+    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {
+
+        private static final float BALL_SIZE = 100f;
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        AnimatorSet animation = null;
+        Animator bounceAnim = null;
+        ShapeHolder ball = null;
+
+        public MyAnimationView(Context context) {
+            super(context);
+            addBall(50, 0);
+            addBall(150, 0);
+            addBall(250, 0);
+            addBall(350, 0);
+        }
+
+        private void createAnimation() {
+            if (bounceAnim == null) {
+                ShapeHolder ball;
+                ball = balls.get(0);
+                ObjectAnimator yBouncer = ObjectAnimator.ofFloat(ball, "y",
+                        ball.getY(), getHeight() - BALL_SIZE).setDuration(DURATION);
+                yBouncer.setInterpolator(new BounceInterpolator());
+                yBouncer.addUpdateListener(this);
+
+                ball = balls.get(1);
+                PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(),
+                        getHeight() - BALL_SIZE);
+                PropertyValuesHolder pvhAlpha = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f);
+                ObjectAnimator yAlphaBouncer = ObjectAnimator.ofPropertyValuesHolder(ball,
+                        pvhY, pvhAlpha).setDuration(DURATION/2);
+                yAlphaBouncer.setInterpolator(new AccelerateInterpolator());
+                yAlphaBouncer.setRepeatCount(1);
+                yAlphaBouncer.setRepeatMode(ValueAnimator.REVERSE);
+
+
+                ball = balls.get(2);
+                PropertyValuesHolder pvhW = PropertyValuesHolder.ofFloat("width", ball.getWidth(),
+                        ball.getWidth() * 2);
+                PropertyValuesHolder pvhH = PropertyValuesHolder.ofFloat("height", ball.getHeight(),
+                        ball.getHeight() * 2);
+                PropertyValuesHolder pvTX = PropertyValuesHolder.ofFloat("x", ball.getX(),
+                        ball.getX() - BALL_SIZE/2f);
+                PropertyValuesHolder pvTY = PropertyValuesHolder.ofFloat("y", ball.getY(),
+                        ball.getY() - BALL_SIZE/2f);
+                ObjectAnimator whxyBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhW, pvhH,
+                        pvTX, pvTY).setDuration(DURATION/2);
+                whxyBouncer.setRepeatCount(1);
+                whxyBouncer.setRepeatMode(ValueAnimator.REVERSE);
+
+                ball = balls.get(3);
+                pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(), getHeight() - BALL_SIZE);
+                float ballX = ball.getX();
+                Keyframe kf0 = Keyframe.ofFloat(0f, ballX);
+                Keyframe kf1 = Keyframe.ofFloat(.5f, ballX + 100f);
+                Keyframe kf2 = Keyframe.ofFloat(1f, ballX + 50f);
+                PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe("x", kf0, kf1, kf2);
+                ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhY,
+                        pvhX).setDuration(DURATION/2);
+                yxBouncer.setRepeatCount(1);
+                yxBouncer.setRepeatMode(ValueAnimator.REVERSE);
+
+
+                bounceAnim = new AnimatorSet();
+                ((AnimatorSet)bounceAnim).playTogether(yBouncer, yAlphaBouncer, whxyBouncer,
+                        yxBouncer);
+            }
+        }
+
+        public void startAnimation() {
+            createAnimation();
+            bounceAnim.start();
+        }
+
+        private ShapeHolder addBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(BALL_SIZE, BALL_SIZE);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x);
+            shapeHolder.setY(y);
+            int red = (int)(100 + Math.random() * 155);
+            int green = (int)(100 + Math.random() * 155);
+            int blue = (int)(100 + Math.random() * 155);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = drawable.getPaint();
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            shapeHolder.setPaint(paint);
+            balls.add(shapeHolder);
+            return shapeHolder;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            for (ShapeHolder ball : balls) {
+                canvas.translate(ball.getX(), ball.getY());
+                ball.getShape().draw(canvas);
+                canvas.translate(-ball.getX(), -ball.getY());
+            }
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+            invalidate();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ReversingAnimation.java b/samples/ApiDemos/src/com/example/android/apis/animation/ReversingAnimation.java
new file mode 100644
index 0000000..89af6de
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ReversingAnimation.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ReversingAnimation extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_reversing);
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final MyAnimationView animView = new MyAnimationView(this);
+        container.addView(animView);
+
+        Button starter = (Button) findViewById(R.id.startButton);
+        starter.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+
+        Button reverser = (Button) findViewById(R.id.reverseButton);
+        reverser.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                animView.reverseAnimation();
+            }
+        });
+
+    }
+
+    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        ValueAnimator bounceAnim = null;
+        ShapeHolder ball = null;
+
+        public MyAnimationView(Context context) {
+            super(context);
+            ball = createBall(25, 25);
+        }
+
+        private void createAnimation() {
+            if (bounceAnim == null) {
+                bounceAnim = ObjectAnimator.ofFloat(ball, "y", ball.getY(), getHeight() - 50f).
+                        setDuration(1500);
+                bounceAnim.setInterpolator(new AccelerateInterpolator(2f));
+                bounceAnim.addUpdateListener(this);
+            }
+        }
+
+        public void startAnimation() {
+            createAnimation();
+            bounceAnim.start();
+        }
+
+        public void reverseAnimation() {
+            createAnimation();
+            bounceAnim.reverse();
+        }
+
+        public void seek(long seekTime) {
+            createAnimation();
+            bounceAnim.setCurrentPlayTime(seekTime);
+        }
+
+        private ShapeHolder createBall(float x, float y) {
+            OvalShape circle = new OvalShape();
+            circle.resize(50f, 50f);
+            ShapeDrawable drawable = new ShapeDrawable(circle);
+            ShapeHolder shapeHolder = new ShapeHolder(drawable);
+            shapeHolder.setX(x - 25f);
+            shapeHolder.setY(y - 25f);
+            int red = (int)(Math.random() * 255);
+            int green = (int)(Math.random() * 255);
+            int blue = (int)(Math.random() * 255);
+            int color = 0xff000000 | red << 16 | green << 8 | blue;
+            Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
+            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+                    50f, color, darkColor, Shader.TileMode.CLAMP);
+            paint.setShader(gradient);
+            shapeHolder.setPaint(paint);
+            return shapeHolder;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            canvas.save();
+            canvas.translate(ball.getX(), ball.getY());
+            ball.getShape().draw(canvas);
+            canvas.restore();
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+            invalidate();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ShapeHolder.java b/samples/ApiDemos/src/com/example/android/apis/animation/ShapeHolder.java
new file mode 100644
index 0000000..2d40672
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ShapeHolder.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.Shape;
+import android.view.View;
+
+/**
+ * A data structure that holds a Shape and various properties that can be used to define
+ * how the shape is drawn.
+ */
+public class ShapeHolder {
+    private float x = 0, y = 0;
+    private ShapeDrawable shape;
+    private int color;
+    private RadialGradient gradient;
+    private float alpha = 1f;
+    private Paint paint;
+
+    public void setPaint(Paint value) {
+        paint = value;
+    }
+    public Paint getPaint() {
+        return paint;
+    }
+
+    public void setX(float value) {
+        x = value;
+    }
+    public float getX() {
+        return x;
+    }
+    public void setY(float value) {
+        y = value;
+    }
+    public float getY() {
+        return y;
+    }
+    public void setShape(ShapeDrawable value) {
+        shape = value;
+    }
+    public ShapeDrawable getShape() {
+        return shape;
+    }
+    public int getColor() {
+        return color;
+    }
+    public void setColor(int value) {
+        shape.getPaint().setColor(value);
+        color = value;
+    }
+    public void setGradient(RadialGradient value) {
+        gradient = value;
+    }
+    public RadialGradient getGradient() {
+        return gradient;
+    }
+
+    public void setAlpha(float alpha) {
+        this.alpha = alpha;
+        shape.setAlpha((int)((alpha * 255f) + .5f));
+    }
+
+    public float getWidth() {
+        return shape.getShape().getWidth();
+    }
+    public void setWidth(float width) {
+        Shape s = shape.getShape();
+        s.resize(width, s.getHeight());
+    }
+
+    public float getHeight() {
+        return shape.getShape().getHeight();
+    }
+    public void setHeight(float height) {
+        Shape s = shape.getShape();
+        s.resize(s.getWidth(), height);
+    }
+
+    public ShapeHolder(ShapeDrawable s) {
+        shape = s;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ActionBarDisplayOptions.java b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarDisplayOptions.java
new file mode 100644
index 0000000..5585c91
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarDisplayOptions.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.Activity;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+
+/**
+ * This demo shows how various action bar display option flags can be combined and their effects.
+ */
+public class ActionBarDisplayOptions extends Activity
+        implements View.OnClickListener, ActionBar.TabListener {
+    private View mCustomView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.action_bar_display_options);
+
+        findViewById(R.id.toggle_home_as_up).setOnClickListener(this);
+        findViewById(R.id.toggle_show_home).setOnClickListener(this);
+        findViewById(R.id.toggle_use_logo).setOnClickListener(this);
+        findViewById(R.id.toggle_show_title).setOnClickListener(this);
+        findViewById(R.id.toggle_show_custom).setOnClickListener(this);
+        findViewById(R.id.toggle_navigation).setOnClickListener(this);
+        findViewById(R.id.cycle_custom_gravity).setOnClickListener(this);
+
+        mCustomView = getLayoutInflater().inflate(R.layout.action_bar_display_options_custom, null);
+        // Configure several action bar elements that will be toggled by display options.
+        final ActionBar bar = getActionBar();
+        bar.setCustomView(mCustomView,
+                new ActionBar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+
+        bar.addTab(bar.newTab().setText("Tab 1").setTabListener(this));
+        bar.addTab(bar.newTab().setText("Tab 2").setTabListener(this));
+        bar.addTab(bar.newTab().setText("Tab 3").setTabListener(this));
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.display_options_actions, menu);
+        return true;
+    }
+
+    public void onClick(View v) {
+        final ActionBar bar = getActionBar();
+        int flags = 0;
+        switch (v.getId()) {
+            case R.id.toggle_home_as_up:
+                flags = ActionBar.DISPLAY_HOME_AS_UP;
+                break;
+            case R.id.toggle_show_home:
+                flags = ActionBar.DISPLAY_SHOW_HOME;
+                break;
+            case R.id.toggle_use_logo:
+                flags = ActionBar.DISPLAY_USE_LOGO;
+                break;
+            case R.id.toggle_show_title:
+                flags = ActionBar.DISPLAY_SHOW_TITLE;
+                break;
+            case R.id.toggle_show_custom:
+                flags = ActionBar.DISPLAY_SHOW_CUSTOM;
+                break;
+
+            case R.id.toggle_navigation:
+                bar.setNavigationMode(
+                        bar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD
+                                ? ActionBar.NAVIGATION_MODE_TABS
+                                : ActionBar.NAVIGATION_MODE_STANDARD);
+                return;
+            case R.id.cycle_custom_gravity:
+                ActionBar.LayoutParams lp = (ActionBar.LayoutParams) mCustomView.getLayoutParams();
+                int newGravity = 0;
+                switch (lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                    case Gravity.LEFT:
+                        newGravity = Gravity.CENTER_HORIZONTAL;
+                        break;
+                    case Gravity.CENTER_HORIZONTAL:
+                        newGravity = Gravity.RIGHT;
+                        break;
+                    case Gravity.RIGHT:
+                        newGravity = Gravity.LEFT;
+                        break;
+                }
+                lp.gravity = lp.gravity & ~Gravity.HORIZONTAL_GRAVITY_MASK | newGravity;
+                bar.setCustomView(mCustomView, lp);
+                return;
+        }
+
+        int change = bar.getDisplayOptions() ^ flags;
+        bar.setDisplayOptions(change, flags);
+    }
+
+    public void onTabSelected(Tab tab, FragmentTransaction ft) {
+    }
+
+    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+    }
+
+    public void onTabReselected(Tab tab, FragmentTransaction ft) {
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ActionBarMechanics.java b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarMechanics.java
new file mode 100644
index 0000000..e479780
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarMechanics.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.Window;
+import android.widget.Toast;
+
+/**
+ * This demonstrates the basics of the Action Bar and how it interoperates with the
+ * standard options menu. This demo is for informative purposes only; see ActionBarUsage for
+ * an example of using the Action Bar in a more idiomatic manner.
+ */
+public class ActionBarMechanics extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // The Action Bar is a window feature. The feature must be requested
+        // before setting a content view. Normally this is set automatically
+        // by your Activity's theme in your manifest. The provided system
+        // theme Theme.WithActionBar enables this for you. Use it as you would
+        // use Theme.NoTitleBar. You can add an Action Bar to your own themes
+        // by adding the element <item name="android:windowActionBar">true</item>
+        // to your style definition.
+        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Menu items default to never show in the action bar. On most devices this means
+        // they will show in the standard options menu panel when the menu button is pressed.
+        // On xlarge-screen devices a "More" button will appear in the far right of the
+        // Action Bar that will display remaining items in a cascading menu.
+        menu.add("Normal item");
+
+        MenuItem actionItem = menu.add("Action Button");
+
+        // Items that show as actions should favor the "if room" setting, which will
+        // prevent too many buttons from crowding the bar. Extra items will show in the
+        // overflow area.
+        actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+        // Items that show as actions are strongly encouraged to use an icon.
+        // These icons are shown without a text description, and therefore should
+        // be sufficiently descriptive on their own.
+        actionItem.setIcon(android.R.drawable.ic_menu_share);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        Toast.makeText(this, "Selected Item: " + item.getTitle(), Toast.LENGTH_SHORT).show();
+        return true;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ActionBarTabs.java b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarTabs.java
new file mode 100644
index 0000000..8a7bf51
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarTabs.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * This demonstrates the use of action bar tabs and how they interact
+ * with other action bar features.
+ */
+public class ActionBarTabs extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.action_bar_tabs);
+    }
+
+    public void onAddTab(View v) {
+        final ActionBar bar = getActionBar();
+        final int tabCount = bar.getTabCount();
+        final String text = "Tab " + tabCount;
+        bar.addTab(bar.newTab()
+                .setText(text)
+                .setTabListener(new TabListener(new TabContentFragment(text))));
+    }
+
+    public void onRemoveTab(View v) {
+        final ActionBar bar = getActionBar();
+        bar.removeTabAt(bar.getTabCount() - 1);
+    }
+
+    public void onToggleTabs(View v) {
+        final ActionBar bar = getActionBar();
+
+        if (bar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
+            bar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+            bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
+        } else {
+            bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+            bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
+        }
+    }
+
+    public void onRemoveAllTabs(View v) {
+        getActionBar().removeAllTabs();
+    }
+
+    /**
+     * A TabListener receives event callbacks from the action bar as tabs
+     * are deselected, selected, and reselected. A FragmentTransaction
+     * is provided to each of these callbacks; if any operations are added
+     * to it, it will be committed at the end of the full tab switch operation.
+     * This lets tab switches be atomic without the app needing to track
+     * the interactions between different tabs.
+     */
+    private class TabListener implements ActionBar.TabListener {
+        private TabContentFragment mFragment;
+
+        public TabListener(TabContentFragment fragment) {
+            mFragment = fragment;
+        }
+
+        public void onTabSelected(Tab tab, FragmentTransaction ft) {
+            ft.add(R.id.fragment_content, mFragment, mFragment.getText());
+        }
+
+        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+            ft.remove(mFragment);
+        }
+
+        public void onTabReselected(Tab tab, FragmentTransaction ft) {
+            Toast.makeText(ActionBarTabs.this, "Reselected!", Toast.LENGTH_SHORT).show();
+        }
+
+    }
+
+    private class TabContentFragment extends Fragment {
+        private String mText;
+
+        public TabContentFragment(String text) {
+            mText = text;
+        }
+
+        public String getText() {
+            return mText;
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View fragView = inflater.inflate(R.layout.action_bar_tab_content, container, false);
+
+            TextView text = (TextView) fragView.findViewById(R.id.text);
+            text.setText(mText);
+
+            return fragView;
+        }
+
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ActionBarUsage.java b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarUsage.java
new file mode 100644
index 0000000..d76cd0b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarUsage.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.SearchView;
+import android.widget.SearchView.OnQueryTextListener;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.example.android.apis.R;
+
+/**
+ * This demonstrates idiomatic usage of the Action Bar. The default Honeycomb theme
+ * includes the action bar by default and a menu resource is used to populate the
+ * menu data itself. If you'd like to see how these things work under the hood, see
+ * ActionBarMechanics.
+ */
+public class ActionBarUsage extends Activity implements OnQueryTextListener {
+    TextView mSearchText;
+    int mSortMode = -1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSearchText = new TextView(this);
+        setContentView(mSearchText);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.actions, menu);
+        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
+        searchView.setOnQueryTextListener(this);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        if (mSortMode != -1) {
+            Drawable icon = menu.findItem(mSortMode).getIcon();
+            menu.findItem(R.id.action_sort).setIcon(icon);
+        }
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        Toast.makeText(this, "Selected Item: " + item.getTitle(), Toast.LENGTH_SHORT).show();
+        return true;
+    }
+
+    // This method is specified as an onClick handler in the menu xml and will
+    // take precedence over the Activity's onOptionsItemSelected method.
+    // See res/menu/actions.xml for more info.
+    public void onSort(MenuItem item) {
+        mSortMode = item.getItemId();
+        // Request a call to onPrepareOptionsMenu so we can change the sort icon
+        invalidateOptionsMenu();
+    }
+
+    // The following callbacks are called for the SearchView.OnQueryChangeListener
+    // For more about using SearchView, see src/.../view/SearchView1.java and SearchView2.java
+    public boolean onQueryTextChange(String newText) {
+        newText = newText.isEmpty() ? "" : "Query so far: " + newText;
+        mSearchText.setText(newText);
+        return true;
+    }
+
+    public boolean onQueryTextSubmit(String query) {
+        Toast.makeText(this, "Searching for: " + query + "...", Toast.LENGTH_SHORT).show();
+        return true;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ActivityRecreate.java b/samples/ApiDemos/src/com/example/android/apis/app/ActivityRecreate.java
new file mode 100644
index 0000000..4c112b3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ActivityRecreate.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+import com.example.android.apis.app.LocalServiceActivities.Controller;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class ActivityRecreate extends Activity {
+    int mCurTheme;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (savedInstanceState != null) {
+            mCurTheme = savedInstanceState.getInt("theme");
+
+            // Switch to a new theme different from last theme.
+            switch (mCurTheme) {
+                case android.R.style.Theme_Holo_Light:
+                    mCurTheme = android.R.style.Theme_Holo_Dialog;
+                    break;
+                case android.R.style.Theme_Holo_Dialog:
+                    mCurTheme = android.R.style.Theme_Holo;
+                    break;
+                default:
+                    mCurTheme = android.R.style.Theme_Holo_Light;
+                    break;
+            }
+            setTheme(mCurTheme);
+        }
+
+        setContentView(R.layout.activity_recreate);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.recreate);
+        button.setOnClickListener(mRecreateListener);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle savedInstanceState) {
+        super.onSaveInstanceState(savedInstanceState);
+        savedInstanceState.putInt("theme", mCurTheme);
+    }
+
+    private OnClickListener mRecreateListener = new OnClickListener() {
+        public void onClick(View v) {
+            recreate();
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java b/samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java
deleted file mode 100644
index 2dbbc45..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.app;
-
-import com.example.android.apis.R;
-
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceActivity;
-import android.preference.CheckBoxPreference;
-import android.widget.Toast;
-
-/**
- * Example that shows finding a preference from the hierarchy and a custom preference type.
- */
-public class AdvancedPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {
-    public static final String KEY_MY_PREFERENCE = "my_preference";
-    public static final String KEY_ADVANCED_CHECKBOX_PREFERENCE = "advanced_checkbox_preference";
-
-    private CheckBoxPreference mCheckBoxPreference;
-    private Handler mHandler = new Handler();
-    
-    /**
-     * This is a simple example of controlling a preference from code.
-     */
-    private Runnable mForceCheckBoxRunnable = new Runnable() {
-        public void run() {
-            if (mCheckBoxPreference != null) {
-                mCheckBoxPreference.setChecked(!mCheckBoxPreference.isChecked());
-            }
-            
-            // Force toggle again in a second
-            mHandler.postDelayed(this, 1000);
-        }
-    };
-    
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Load the XML preferences file
-        addPreferencesFromResource(R.xml.advanced_preferences);
-        
-        // Get a reference to the checkbox preference
-        mCheckBoxPreference = (CheckBoxPreference)getPreferenceScreen().findPreference(
-                KEY_ADVANCED_CHECKBOX_PREFERENCE);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        // Start the force toggle
-        mForceCheckBoxRunnable.run();
-        
-        // Set up a listener whenever a key changes
-        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-
-        // Unregister the listener whenever a key changes
-        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
-        
-        mHandler.removeCallbacks(mForceCheckBoxRunnable);
-    }
-
-    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-        // Let's do something when my counter preference value changes
-        if (key.equals(KEY_MY_PREFERENCE)) {
-            Toast.makeText(this, "Thanks! You increased my count to "
-                    + sharedPreferences.getInt(key, 0), Toast.LENGTH_SHORT).show();
-        }
-    }
-    
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java b/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
index 6714175..a22753a 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
@@ -64,6 +64,9 @@
     private static final int DIALOG_MULTIPLE_CHOICE = 6;
     private static final int DIALOG_TEXT_ENTRY = 7;
     private static final int DIALOG_MULTIPLE_CHOICE_CURSOR = 8;
+    private static final int DIALOG_YES_NO_ULTRA_LONG_MESSAGE = 9;
+    private static final int DIALOG_YES_NO_OLD_SCHOOL_MESSAGE = 10;
+    private static final int DIALOG_YES_NO_HOLO_LIGHT_MESSAGE = 11;
 
     private static final int MAX_PROGRESS = 100;
     
@@ -76,7 +79,7 @@
         switch (id) {
         case DIALOG_YES_NO_MESSAGE:
             return new AlertDialog.Builder(AlertDialogSamples.this)
-                .setIcon(R.drawable.alert_dialog_icon)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setTitle(R.string.alert_dialog_two_buttons_title)
                 .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int whichButton) {
@@ -91,9 +94,35 @@
                     }
                 })
                 .create();
+        case DIALOG_YES_NO_OLD_SCHOOL_MESSAGE:
+            return new AlertDialog.Builder(AlertDialogSamples.this, AlertDialog.THEME_TRADITIONAL)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setTitle(R.string.alert_dialog_two_buttons_title)
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                    }
+                })
+                .create();
+        case DIALOG_YES_NO_HOLO_LIGHT_MESSAGE:
+            return new AlertDialog.Builder(AlertDialogSamples.this, AlertDialog.THEME_HOLO_LIGHT)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setTitle(R.string.alert_dialog_two_buttons_title)
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                    }
+                })
+                .create();
         case DIALOG_YES_NO_LONG_MESSAGE:
             return new AlertDialog.Builder(AlertDialogSamples.this)
-                .setIcon(R.drawable.alert_dialog_icon)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setTitle(R.string.alert_dialog_two_buttons_msg)
                 .setMessage(R.string.alert_dialog_two_buttons2_msg)
                 .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
@@ -115,6 +144,30 @@
                     }
                 })
                 .create();
+        case DIALOG_YES_NO_ULTRA_LONG_MESSAGE:
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setTitle(R.string.alert_dialog_two_buttons_msg)
+                .setMessage(R.string.alert_dialog_two_buttons2ultra_msg)
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked OK so do some stuff */
+                    }
+                })
+                .setNeutralButton(R.string.alert_dialog_something, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked Something so do some stuff */
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked Cancel so do some stuff */
+                    }
+                })
+                .create();
         case DIALOG_LIST:
             return new AlertDialog.Builder(AlertDialogSamples.this)
                 .setTitle(R.string.select_dialog)
@@ -131,7 +184,7 @@
                 .create();
         case DIALOG_PROGRESS:
             mProgressDialog = new ProgressDialog(AlertDialogSamples.this);
-            mProgressDialog.setIcon(R.drawable.alert_dialog_icon);
+            mProgressDialog.setIconAttribute(android.R.attr.alertDialogIcon);
             mProgressDialog.setTitle(R.string.select_dialog);
             mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
             mProgressDialog.setMax(MAX_PROGRESS);
@@ -152,7 +205,7 @@
             return mProgressDialog;
         case DIALOG_SINGLE_CHOICE:
             return new AlertDialog.Builder(AlertDialogSamples.this)
-                .setIcon(R.drawable.alert_dialog_icon)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setTitle(R.string.alert_dialog_single_choice)
                 .setSingleChoiceItems(R.array.select_dialog_items2, 0, new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int whichButton) {
@@ -229,7 +282,7 @@
             LayoutInflater factory = LayoutInflater.from(this);
             final View textEntryView = factory.inflate(R.layout.alert_dialog_text_entry, null);
             return new AlertDialog.Builder(AlertDialogSamples.this)
-                .setIcon(R.drawable.alert_dialog_icon)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setTitle(R.string.alert_dialog_text_entry)
                 .setView(textEntryView)
                 .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
@@ -277,6 +330,15 @@
         });
         
         
+        /* Display an ultra long text message with yes/no buttons and handle each message as well as the cancel action */
+        Button twoButtons2UltraTitle = (Button) findViewById(R.id.two_buttons2ultra);
+        twoButtons2UltraTitle.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_YES_NO_ULTRA_LONG_MESSAGE);
+            }
+        });
+
+
         /* Display a list of items */
         Button selectButton = (Button) findViewById(R.id.select_button);
         selectButton.setOnClickListener(new OnClickListener() {
@@ -328,6 +390,22 @@
             }
         });
         
+        /* Two points, in the traditional theme */
+        Button twoButtonsOldSchoolTitle = (Button) findViewById(R.id.two_buttons_old_school);
+        twoButtonsOldSchoolTitle.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_YES_NO_OLD_SCHOOL_MESSAGE);
+            }
+        });
+        
+        /* Two points, in the light holographic theme */
+        Button twoButtonsHoloLightTitle = (Button) findViewById(R.id.two_buttons_holo_light);
+        twoButtonsHoloLightTitle.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_YES_NO_HOLO_LIGHT_MESSAGE);
+            }
+        });
+        
         mProgressHandler = new Handler() {
             @Override
             public void handleMessage(Message msg) {
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
index 5ba41c4..bd2bd89 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
@@ -30,10 +30,7 @@
 
 
 /**
- * <p>Example of explicitly starting and stopping the {@link LocalService}.
- * This demonstrates the implementation of a service that runs in the same
- * process as the rest of the application, which is explicitly started and stopped
- * as desired.</p>
+ * <p>Example of using a custom animation when transitioning between activities.</p>
  */
 public class Animation extends Activity {
     @Override
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AppUpdateReceiver.java b/samples/ApiDemos/src/com/example/android/apis/app/AppUpdateReceiver.java
new file mode 100644
index 0000000..ac0dcf0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AppUpdateReceiver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.Toast;
+
+/**
+ * Executed when a new version of the application is is installed.
+ */
+public class AppUpdateReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Toast.makeText(context, R.string.app_update_received, Toast.LENGTH_SHORT).show();
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java b/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
deleted file mode 100644
index 494a2ea..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.app;
-
-import com.example.android.apis.ApiDemosApplication;
-import com.example.android.apis.R;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
-
-/**
- * This activity is an example of a simple settings screen that has default
- * values.
- * <p>
- * In order for the default values to be populated into the
- * {@link SharedPreferences} (from the preferences XML file), the client must
- * call
- * {@link PreferenceManager#setDefaultValues(android.content.Context, int, boolean)}.
- * <p>
- * This should be called early, typically when the application is first created.
- * This ensures any of the application's activities, services, etc. will have
- * the default values present, even if the user has not wandered into the
- * application's settings. For ApiDemos, this is {@link ApiDemosApplication},
- * and you can find the call to
- * {@link PreferenceManager#setDefaultValues(android.content.Context, int, boolean)}
- * in its {@link ApiDemosApplication#onCreate() onCreate}.
- */
-public class DefaultValues extends PreferenceActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        addPreferencesFromResource(R.xml.default_values);
-    }
-
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
index b3fc2f9..04944ef 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
@@ -35,12 +35,16 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.Spinner;
+import android.widget.TextView;
 import android.widget.Toast;
-import android.widget.AdapterView.OnItemSelectedListener;
+
+import java.text.DateFormat;
+import java.util.Date;
 
 /**
  * Example of a do-nothing admin class.  When enabled, it lets you control
@@ -48,21 +52,34 @@
  */
 public class DeviceAdminSample extends DeviceAdminReceiver {
 
+    private static final String TAG = "DeviceAdminSample";
+    private static final long MS_PER_DAY = 86400 * 1000;
+    private static final long MS_PER_HOUR = 3600 * 1000;
+    private static final long MS_PER_MINUTE = 60 * 1000;
+
     static SharedPreferences getSamplePreferences(Context context) {
         return context.getSharedPreferences(DeviceAdminReceiver.class.getName(), 0);
     }
 
     static String PREF_PASSWORD_QUALITY = "password_quality";
     static String PREF_PASSWORD_LENGTH = "password_length";
+    static String PREF_PASSWORD_MINIMUM_LETTERS = "password_minimum_letters";
+    static String PREF_PASSWORD_MINIMUM_UPPERCASE = "password_minimum_uppercase";
+    static String PREF_PASSWORD_MINIMUM_LOWERCASE = "password_minimum_lowercase";
+    static String PREF_PASSWORD_MINIMUM_NUMERIC = "password_minimum_numeric";
+    static String PREF_PASSWORD_MINIMUM_SYMBOLS = "password_minimum_symbols";
+    static String PREF_PASSWORD_MINIMUM_NONLETTER = "password_minimum_nonletter";
+    static String PREF_PASSWORD_HISTORY_LENGTH = "password_history_length";
+    static String PREF_PASSWORD_EXPIRATION_TIMEOUT = "password_expiration_timeout";
     static String PREF_MAX_FAILED_PW = "max_failed_pw";
 
     void showToast(Context context, CharSequence msg) {
-        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+        Toast.makeText(context, "Sample Device Admin: " + msg, Toast.LENGTH_SHORT).show();
     }
 
     @Override
     public void onEnabled(Context context, Intent intent) {
-        showToast(context, "Sample Device Admin: enabled");
+        showToast(context, "enabled");
     }
 
     @Override
@@ -72,22 +89,43 @@
 
     @Override
     public void onDisabled(Context context, Intent intent) {
-        showToast(context, "Sample Device Admin: disabled");
+        showToast(context, "disabled");
     }
 
     @Override
     public void onPasswordChanged(Context context, Intent intent) {
-        showToast(context, "Sample Device Admin: pw changed");
+        showToast(context, "pw changed");
     }
 
     @Override
     public void onPasswordFailed(Context context, Intent intent) {
-        showToast(context, "Sample Device Admin: pw failed");
+        showToast(context, "pw failed");
     }
 
     @Override
     public void onPasswordSucceeded(Context context, Intent intent) {
-        showToast(context, "Sample Device Admin: pw succeeded");
+        showToast(context, "pw succeeded");
+    }
+
+    static String countdownString(long time) {
+        long days = time / MS_PER_DAY;
+        long hours = (time / MS_PER_HOUR) % 24;
+        long minutes = (time / MS_PER_MINUTE) % 60;
+        return days + "d" + hours + "h" + minutes + "m";
+    }
+
+    @Override
+    public void onPasswordExpiring(Context context, Intent intent) {
+        DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        long expr = dpm.getPasswordExpiration(new ComponentName(context, DeviceAdminSample.class));
+        long delta = expr - System.currentTimeMillis();
+        boolean expired = delta < 0L;
+        String msg = expired ? "Password expired " : "Password will expire "
+                + countdownString(Math.abs(delta))
+                + (expired ? " ago" : " from now");
+        showToast(context, msg);
+        Log.v(TAG, msg);
     }
 
     /**
@@ -99,7 +137,11 @@
      * all together; typically this code would appear in some separate class.
      */
     public static class Controller extends Activity {
-        static final int RESULT_ENABLE = 1;
+
+        static final int REQUEST_CODE_ENABLE_ADMIN = 1;
+        static final int REQUEST_CODE_START_ENCRYPTION = 2;
+
+        private static final long MS_PER_MINUTE = 60*1000;
 
         DevicePolicyManager mDPM;
         ActivityManager mAM;
@@ -115,10 +157,19 @@
             DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
             DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
             DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
-            DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+            DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
+            DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
         };
+
         Spinner mPasswordQuality;
         EditText mPasswordLength;
+        EditText mPasswordMinimumLetters;
+        EditText mPasswordMinimumUppercase;
+        EditText mPasswordMinimumLowercase;
+        EditText mPasswordMinimumNumeric;
+        EditText mPasswordMinimumSymbols;
+        EditText mPasswordMinimumNonLetter;
+        EditText mPasswordHistoryLength;
         Button mSetPasswordButton;
 
         EditText mPassword;
@@ -134,6 +185,17 @@
 
         private EditText mTimeout;
 
+        private EditText mPasswordExpirationTimeout;
+        private Button mPasswordExpirationButton;
+        private TextView mPasswordExpirationStatus;
+        private Button mPasswordExpirationStatusButton;
+
+        private Button mEnableEncryptionButton;
+        private Button mDisableEncryptionButton;
+        private Button mActivateEncryptionButton;
+        private Button mEncryptionStatusButton;
+        private TextView mEncryptionStatus;
+
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
@@ -179,6 +241,120 @@
                     }
                 }
             });
+            mPasswordMinimumLetters = (EditText)findViewById(R.id.password_minimum_letters);
+            mPasswordMinimumLetters.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s) {
+                }
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setPasswordMinimumLetters(Integer.parseInt(s.toString()));
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            });
+            mPasswordMinimumUppercase = (EditText)findViewById(R.id.password_minimum_uppercase);
+            mPasswordMinimumUppercase.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s) {
+                }
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setPasswordMinimumUppercase(Integer.parseInt(s.toString()));
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            });
+            mPasswordMinimumLowercase = (EditText)findViewById(R.id.password_minimum_lowercase);
+            mPasswordMinimumLowercase.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s) {
+                }
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setPasswordMinimumLowercase(Integer.parseInt(s.toString()));
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            });
+            mPasswordMinimumNumeric = (EditText)findViewById(R.id.password_minimum_numeric);
+            mPasswordMinimumNumeric.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s) {
+                }
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setPasswordMinimumNumeric(Integer.parseInt(s.toString()));
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            });
+            mPasswordMinimumSymbols = (EditText)findViewById(R.id.password_minimum_symbols);
+            mPasswordMinimumSymbols.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s) {
+                }
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setPasswordMinimumSymbols(Integer.parseInt(s.toString()));
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            });
+            mPasswordMinimumNonLetter = (EditText)findViewById(R.id.password_minimum_nonletter);
+            mPasswordMinimumNonLetter.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s) {
+                }
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setPasswordMinimumNonLetter(Integer.parseInt(s.toString()));
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            });
+            mPasswordHistoryLength = (EditText)findViewById(R.id.password_history_length);
+            mPasswordHistoryLength.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s) {
+                }
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setPasswordHistoryLength(Integer.parseInt(s.toString()));
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            });
+
+            mPasswordExpirationTimeout = (EditText)findViewById(R.id.password_expiration);
+            mPasswordExpirationButton = (Button) findViewById(R.id.update_expiration_button);
+            mPasswordExpirationButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    try {
+                        setPasswordExpiration(
+                                Long.parseLong(mPasswordExpirationTimeout.getText().toString()));
+                    } catch (NumberFormatException nfe) {
+                    }
+                    updatePasswordExpirationStatus();
+                }
+            });
+
+            mPasswordExpirationStatus = (TextView) findViewById(R.id.password_expiration_status);
+            mPasswordExpirationStatusButton =
+                    (Button) findViewById(R.id.update_expiration_status_button);
+            mPasswordExpirationStatusButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    updatePasswordExpirationStatus();
+                }
+            });
+
             mSetPasswordButton = (Button)findViewById(R.id.set_password);
             mSetPasswordButton.setOnClickListener(mSetPasswordListener);
 
@@ -215,6 +391,16 @@
             mTimeout = (EditText) findViewById(R.id.timeout);
             mTimeoutButton = (Button) findViewById(R.id.set_timeout);
             mTimeoutButton.setOnClickListener(mSetTimeoutListener);
+
+            mEnableEncryptionButton = (Button) findViewById(R.id.encryption_enable_button);
+            mEnableEncryptionButton.setOnClickListener(mEncryptionButtonListener);
+            mDisableEncryptionButton = (Button) findViewById(R.id.encryption_disable_button);
+            mDisableEncryptionButton.setOnClickListener(mEncryptionButtonListener);
+            mActivateEncryptionButton = (Button) findViewById(R.id.encryption_activate_button);
+            mActivateEncryptionButton.setOnClickListener(mEncryptionButtonListener);
+            mEncryptionStatusButton = (Button) findViewById(R.id.encryption_update_status_button);
+            mEncryptionStatusButton.setOnClickListener(mEncryptionButtonListener);
+            mEncryptionStatus = (TextView) findViewById(R.id.encryption_status);
         }
 
         void updateButtonStates() {
@@ -224,23 +410,45 @@
                 mDisableButton.setEnabled(true);
                 mPasswordQuality.setEnabled(true);
                 mPasswordLength.setEnabled(true);
+                mPasswordMinimumLetters.setEnabled(true);
+                mPasswordMinimumUppercase.setEnabled(true);
+                mPasswordMinimumLowercase.setEnabled(true);
+                mPasswordMinimumSymbols.setEnabled(true);
+                mPasswordMinimumNumeric.setEnabled(true);
+                mPasswordMinimumNonLetter.setEnabled(true);
+                mPasswordHistoryLength.setEnabled(true);
                 mSetPasswordButton.setEnabled(true);
                 mPassword.setEnabled(true);
                 mResetPasswordButton.setEnabled(true);
                 mForceLockButton.setEnabled(true);
                 mWipeDataButton.setEnabled(true);
                 mWipeAllDataButton.setEnabled(true);
+                mEnableEncryptionButton.setEnabled(true);
+                mDisableEncryptionButton.setEnabled(true);
+                mActivateEncryptionButton.setEnabled(true);
+                mEncryptionStatusButton.setEnabled(true);
             } else {
                 mEnableButton.setEnabled(true);
                 mDisableButton.setEnabled(false);
                 mPasswordQuality.setEnabled(false);
                 mPasswordLength.setEnabled(false);
+                mPasswordMinimumLetters.setEnabled(false);
+                mPasswordMinimumUppercase.setEnabled(false);
+                mPasswordMinimumLowercase.setEnabled(false);
+                mPasswordMinimumSymbols.setEnabled(false);
+                mPasswordMinimumNumeric.setEnabled(false);
+                mPasswordMinimumNonLetter.setEnabled(false);
+                mPasswordHistoryLength.setEnabled(false);
                 mSetPasswordButton.setEnabled(false);
                 mPassword.setEnabled(false);
                 mResetPasswordButton.setEnabled(false);
                 mForceLockButton.setEnabled(false);
                 mWipeDataButton.setEnabled(false);
                 mWipeAllDataButton.setEnabled(false);
+                mEnableEncryptionButton.setEnabled(false);
+                mDisableEncryptionButton.setEnabled(false);
+                mActivateEncryptionButton.setEnabled(false);
+                mEncryptionStatusButton.setEnabled(false);
             }
         }
 
@@ -249,6 +457,14 @@
             final int pwQuality = prefs.getInt(PREF_PASSWORD_QUALITY,
                     DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
             final int pwLength = prefs.getInt(PREF_PASSWORD_LENGTH, 0);
+            final int pwMinLetters = prefs.getInt(PREF_PASSWORD_MINIMUM_LETTERS, 0);
+            final int pwMinUppercase = prefs.getInt(PREF_PASSWORD_MINIMUM_UPPERCASE, 0);
+            final int pwMinLowercase = prefs.getInt(PREF_PASSWORD_MINIMUM_LOWERCASE, 0);
+            final int pwMinNumeric = prefs.getInt(PREF_PASSWORD_MINIMUM_NUMERIC, 0);
+            final int pwMinSymbols = prefs.getInt(PREF_PASSWORD_MINIMUM_SYMBOLS, 0);
+            final int pwMinNonLetter = prefs.getInt(PREF_PASSWORD_MINIMUM_NONLETTER, 0);
+            final int pwHistoryLength = prefs.getInt(PREF_PASSWORD_HISTORY_LENGTH, 0);
+            final long pwExpirationTimeout = prefs.getLong(PREF_PASSWORD_EXPIRATION_TIMEOUT, 0L);
             final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
 
             for (int i=0; i<mPasswordQualityValues.length; i++) {
@@ -257,21 +473,80 @@
                 }
             }
             mPasswordLength.setText(Integer.toString(pwLength));
+            mPasswordMinimumLetters.setText(Integer.toString(pwMinLetters));
+            mPasswordMinimumUppercase.setText(Integer.toString(pwMinUppercase));
+            mPasswordMinimumLowercase.setText(Integer.toString(pwMinLowercase));
+            mPasswordMinimumSymbols.setText(Integer.toString(pwMinSymbols));
+            mPasswordMinimumNumeric.setText(Integer.toString(pwMinNumeric));
+            mPasswordMinimumNonLetter.setText(Integer.toString(pwMinNonLetter));
+            mPasswordHistoryLength.setText(Integer.toString(pwHistoryLength));
+            mPasswordExpirationTimeout.setText(Long.toString(pwExpirationTimeout/MS_PER_MINUTE));
             mMaxFailedPw.setText(Integer.toString(maxFailedPw));
         }
 
+        void updatePasswordExpirationStatus() {
+            boolean active = mDPM.isAdminActive(mDeviceAdminSample);
+            String statusText;
+            if (active) {
+                long now = System.currentTimeMillis();
+                // We'll query the DevicePolicyManager twice - first for the expiration values
+                // set by the sample app, and later, for the system values (which may be different
+                // if there is another administrator active.)
+                long expirationDate = mDPM.getPasswordExpiration(mDeviceAdminSample);
+                long mSecUntilExpiration = expirationDate - now;
+                if (mSecUntilExpiration >= 0) {
+                    statusText = "Expiration in " + countdownString(mSecUntilExpiration);
+                } else {
+                    statusText = "Expired " + countdownString(-mSecUntilExpiration) + " ago";
+                }
+
+                // expirationTimeout is the cycle time between required password refresh
+                long expirationTimeout = mDPM.getPasswordExpirationTimeout(mDeviceAdminSample);
+                statusText += " / timeout period " + countdownString(expirationTimeout);
+
+                // Now report the aggregate (global) expiration time
+                statusText += " / Aggregate ";
+                expirationDate = mDPM.getPasswordExpiration(null);
+                mSecUntilExpiration = expirationDate - now;
+                if (mSecUntilExpiration >= 0) {
+                    statusText += "expiration in " + countdownString(mSecUntilExpiration);
+                } else {
+                    statusText += "expired " + countdownString(-mSecUntilExpiration) + " ago";
+                }
+            } else {
+                statusText = "<inactive>";
+            }
+            mPasswordExpirationStatus.setText(statusText);
+        }
+
         void updatePolicies() {
             SharedPreferences prefs = getSamplePreferences(this);
             final int pwQuality = prefs.getInt(PREF_PASSWORD_QUALITY,
                     DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
             final int pwLength = prefs.getInt(PREF_PASSWORD_LENGTH, 0);
+            final int pwMinLetters = prefs.getInt(PREF_PASSWORD_MINIMUM_LETTERS, 0);
+            final int pwMinUppercase = prefs.getInt(PREF_PASSWORD_MINIMUM_UPPERCASE, 0);
+            final int pwMinLowercase = prefs.getInt(PREF_PASSWORD_MINIMUM_LOWERCASE, 0);
+            final int pwMinNumeric = prefs.getInt(PREF_PASSWORD_MINIMUM_NUMERIC, 0);
+            final int pwMinSymbols = prefs.getInt(PREF_PASSWORD_MINIMUM_SYMBOLS, 0);
+            final int pwMinNonLetter = prefs.getInt(PREF_PASSWORD_MINIMUM_NONLETTER, 0);
+            final int pwHistoryLength = prefs.getInt(PREF_PASSWORD_HISTORY_LENGTH, 0);
+            final long pwExpiration = prefs.getLong(PREF_PASSWORD_EXPIRATION_TIMEOUT, 0L);
             final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
 
             boolean active = mDPM.isAdminActive(mDeviceAdminSample);
             if (active) {
                 mDPM.setPasswordQuality(mDeviceAdminSample, pwQuality);
                 mDPM.setPasswordMinimumLength(mDeviceAdminSample, pwLength);
+                mDPM.setPasswordMinimumLetters(mDeviceAdminSample, pwMinLetters);
+                mDPM.setPasswordMinimumUpperCase(mDeviceAdminSample, pwMinUppercase);
+                mDPM.setPasswordMinimumLowerCase(mDeviceAdminSample, pwMinLowercase);
+                mDPM.setPasswordMinimumNumeric(mDeviceAdminSample, pwMinNumeric);
+                mDPM.setPasswordMinimumSymbols(mDeviceAdminSample, pwMinSymbols);
+                mDPM.setPasswordMinimumNonLetter(mDeviceAdminSample, pwMinNonLetter);
+                mDPM.setPasswordHistoryLength(mDeviceAdminSample, pwHistoryLength);
                 mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, maxFailedPw);
+                mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration);
             }
         }
 
@@ -287,6 +562,64 @@
             updatePolicies();
         }
 
+        void setPasswordMinimumLetters(int length) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            prefs.edit().putInt(PREF_PASSWORD_MINIMUM_LETTERS, length).commit();
+            updatePolicies();
+        }
+
+        void setPasswordMinimumUppercase(int length) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            prefs.edit().putInt(PREF_PASSWORD_MINIMUM_UPPERCASE, length).commit();
+            updatePolicies();
+        }
+
+        void setPasswordMinimumLowercase(int length) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            prefs.edit().putInt(PREF_PASSWORD_MINIMUM_LOWERCASE, length).commit();
+            updatePolicies();
+        }
+
+        void setPasswordMinimumNumeric(int length) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            prefs.edit().putInt(PREF_PASSWORD_MINIMUM_NUMERIC, length).commit();
+            updatePolicies();
+        }
+
+        void setPasswordMinimumSymbols(int length) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            prefs.edit().putInt(PREF_PASSWORD_MINIMUM_SYMBOLS, length).commit();
+            updatePolicies();
+        }
+
+        void setPasswordMinimumNonLetter(int length) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            prefs.edit().putInt(PREF_PASSWORD_MINIMUM_NONLETTER, length).commit();
+            updatePolicies();
+        }
+
+        void setPasswordHistoryLength(int length) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            prefs.edit().putInt(PREF_PASSWORD_HISTORY_LENGTH, length).commit();
+            updatePolicies();
+        }
+
+        void setPasswordExpiration(long expiration) {
+            SharedPreferences prefs = getSamplePreferences(this);
+            long exp = expiration * MS_PER_MINUTE; // convert from UI units to ms
+            prefs.edit().putLong(PREF_PASSWORD_EXPIRATION_TIMEOUT, exp).commit();
+            updatePolicies();
+            // Show confirmation dialog
+            long confirm = mDPM.getPasswordExpiration(mDeviceAdminSample);
+            String date = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT)
+                    .format(new Date(confirm));
+            new AlertDialog.Builder(this)
+                    .setMessage("Password will expire on " + date)
+                    .setPositiveButton("OK", null)
+                    .create()
+                    .show();
+        }
+
         void setMaxFailedPw(int length) {
             SharedPreferences prefs = getSamplePreferences(this);
             prefs.edit().putInt(PREF_MAX_FAILED_PW, length).commit();
@@ -297,18 +630,22 @@
         protected void onResume() {
             super.onResume();
             updateButtonStates();
+            updatePasswordExpirationStatus();
         }
 
         @Override
         protected void onActivityResult(int requestCode, int resultCode, Intent data) {
             switch (requestCode) {
-                case RESULT_ENABLE:
+                case REQUEST_CODE_ENABLE_ADMIN:
                     if (resultCode == Activity.RESULT_OK) {
-                        Log.i("DeviceAdminSample", "Admin enabled!");
+                        Log.i(TAG, "Admin enabled!");
                     } else {
-                        Log.i("DeviceAdminSample", "Admin enable FAILED!");
+                        Log.i(TAG, "Admin enable FAILED!");
                     }
                     return;
+                case REQUEST_CODE_START_ENCRYPTION:
+                    updateEncryptionStatus();
+                    return;
             }
 
             super.onActivityResult(requestCode, resultCode, data);
@@ -322,7 +659,7 @@
                         mDeviceAdminSample);
                 intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                         "Additional text explaining why this needs to be added.");
-                startActivityForResult(intent, RESULT_ENABLE);
+                startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
             }
         };
 
@@ -343,7 +680,7 @@
 
         private OnClickListener mResetPasswordListener = new OnClickListener() {
             public void onClick(View v) {
-                if (mAM.isUserAMonkey()) {
+                if (ActivityManager.isUserAMonkey()) {
                     // Don't trust monkeys to do the right thing!
                     AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
                     builder.setMessage("You can't reset my password because you are a monkey!");
@@ -361,7 +698,7 @@
 
         private OnClickListener mForceLockListener = new OnClickListener() {
             public void onClick(View v) {
-                if (mAM.isUserAMonkey()) {
+                if (ActivityManager.isUserAMonkey()) {
                     // Don't trust monkeys to do the right thing!
                     AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
                     builder.setMessage("You can't lock my screen because you are a monkey!");
@@ -378,7 +715,7 @@
 
         private OnClickListener mWipeDataListener = new OnClickListener() {
             public void onClick(final View v) {
-                if (mAM.isUserAMonkey()) {
+                if (ActivityManager.isUserAMonkey()) {
                     // Don't trust monkeys to do the right thing!
                     AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
                     builder.setMessage("You can't wipe my data because you are a monkey!");
@@ -422,7 +759,7 @@
         private OnClickListener mSetTimeoutListener = new OnClickListener() {
 
             public void onClick(View v) {
-                if (mAM.isUserAMonkey()) {
+                if (ActivityManager.isUserAMonkey()) {
                     // Don't trust monkeys to do the right thing!
                     AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
                     builder.setMessage("You can't lock my screen because you are a monkey!");
@@ -437,5 +774,70 @@
                 }
             }
         };
+
+        private OnClickListener mEncryptionButtonListener = new OnClickListener() {
+            public void onClick(View v) {
+                int buttonId = v.getId();
+                if (buttonId == R.id.encryption_enable_button) {
+                    mDPM.setStorageEncryption(mDeviceAdminSample, true);
+                } else if (buttonId == R.id.encryption_disable_button) {
+                    mDPM.setStorageEncryption(mDeviceAdminSample, false);
+                } else if (buttonId == R.id.encryption_activate_button) {
+                    if (ActivityManager.isUserAMonkey()) {
+                        // Don't trust monkeys to do the right thing!
+                        AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
+                        builder.setMessage("You can't activate encryption, you're a monkey!");
+                        builder.setPositiveButton("I admit defeat", null);
+                        builder.show();
+                        return;
+                    }
+                    if (mDPM.getStorageEncryptionStatus() ==
+                            DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED) {
+                        AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
+                        builder.setMessage("Encryption is unsupported on this device.");
+                        builder.setPositiveButton("OK", null);
+                        builder.show();
+                        return;
+                    }
+                    // Launch the activity to activate encryption.  May or may not return!
+                    Intent intent = new Intent(DevicePolicyManager.ACTION_START_ENCRYPTION);
+                    startActivityForResult(intent, REQUEST_CODE_START_ENCRYPTION);
+                }
+
+                // In all cases, fall through to update status
+                updateEncryptionStatus();
+            }
+        };
+
+        private void updateEncryptionStatus() {
+            boolean sampleAdminStatusValue = mDPM.getStorageEncryption(mDeviceAdminSample);
+            String sampleAdminStatus = Boolean.toString(sampleAdminStatusValue);
+            boolean adminStatusValue = mDPM.getStorageEncryption(null);
+            String adminStatus = Boolean.toString(adminStatusValue);
+            int deviceStatusCode = mDPM.getStorageEncryptionStatus();
+            String deviceStatus = statusCodeToString(deviceStatusCode);
+            mEncryptionStatus.setText("sample:" + sampleAdminStatus + " admins:" + adminStatus
+                    + " device:" + deviceStatus);
+        }
+
+        private String statusCodeToString(int newStatusCode) {
+            String newStatus = "unknown";
+            switch (newStatusCode) {
+                case DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED:
+                    newStatus = "unsupported";
+                    break;
+                case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
+                    newStatus = "inactive";
+                    break;
+                case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING:
+                    newStatus = "activating";
+                    break;
+                case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
+                    newStatus = "active";
+                    break;
+            }
+            return newStatus;
+        }
     }
 }
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java
index 7441b75..d9deb47 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java
@@ -18,16 +18,21 @@
 
 // Need the following import to get access to the app resources, since this
 // class is in a sub-package.
+import com.example.android.apis.R;
+
 import android.app.Activity;
 import android.os.Bundle;
+import android.view.View;
 import android.view.Window;
-
-import com.example.android.apis.R;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
 
 /**
  * <h3>Dialog Activity</h3>
- * 
- * <p>This demonstrates the how to write an activity that looks like 
+ *
+ * <p>This demonstrates the how to write an activity that looks like
  * a pop-up dialog.</p>
  */
 public class DialogActivity extends Activity {
@@ -40,15 +45,42 @@
 	protected void onCreate(Bundle savedInstanceState) {
         // Be sure to call the super class.
         super.onCreate(savedInstanceState);
-        
+
         requestWindowFeature(Window.FEATURE_LEFT_ICON);
-        
+
+
         // See assets/res/any/layout/dialog_activity.xml for this
         // view layout definition, which is being set here as
         // the content of our screen.
         setContentView(R.layout.dialog_activity);
-        
-        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, 
+        getWindow().setTitle("This is just a test");
+
+        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
                 android.R.drawable.ic_dialog_alert);
+
+        Button button = (Button)findViewById(R.id.add);
+        button.setOnClickListener(mAddContentListener);
+        button = (Button)findViewById(R.id.remove);
+        button.setOnClickListener(mRemoveContentListener);
     }
+
+    private OnClickListener mAddContentListener = new OnClickListener() {
+        public void onClick(View v) {
+            LinearLayout layout = (LinearLayout)findViewById(R.id.inner_content);
+            ImageView iv = new ImageView(DialogActivity.this);
+            iv.setImageDrawable(getResources().getDrawable(R.drawable.icon48x48_1));
+            iv.setPadding(4, 4, 4, 4);
+            layout.addView(iv);
+        }
+    };
+
+    private OnClickListener mRemoveContentListener = new OnClickListener() {
+        public void onClick(View v) {
+            LinearLayout layout = (LinearLayout)findViewById(R.id.inner_content);
+            int num = layout.getChildCount();
+            if (num > 0) {
+                layout.removeViewAt(num-1);
+            }
+        }
+    };
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
index 7e061ed..9f84be1 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
@@ -49,17 +49,33 @@
     static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
     
  // BEGIN_INCLUDE(foreground_compatibility)
+    private static final Class<?>[] mSetForegroundSignature = new Class[] {
+        boolean.class};
     private static final Class<?>[] mStartForegroundSignature = new Class[] {
         int.class, Notification.class};
     private static final Class<?>[] mStopForegroundSignature = new Class[] {
         boolean.class};
     
     private NotificationManager mNM;
+    private Method mSetForeground;
     private Method mStartForeground;
     private Method mStopForeground;
+    private Object[] mSetForegroundArgs = new Object[1];
     private Object[] mStartForegroundArgs = new Object[2];
     private Object[] mStopForegroundArgs = new Object[1];
     
+    void invokeMethod(Method method, Object[] args) {
+        try {
+            mStartForeground.invoke(this, mStartForegroundArgs);
+        } catch (InvocationTargetException e) {
+            // Should not happen.
+            Log.w("ApiDemos", "Unable to invoke method", e);
+        } catch (IllegalAccessException e) {
+            // Should not happen.
+            Log.w("ApiDemos", "Unable to invoke method", e);
+        }
+    }
+    
     /**
      * This is a wrapper around the new startForeground method, using the older
      * APIs if it is not available.
@@ -69,20 +85,13 @@
         if (mStartForeground != null) {
             mStartForegroundArgs[0] = Integer.valueOf(id);
             mStartForegroundArgs[1] = notification;
-            try {
-                mStartForeground.invoke(this, mStartForegroundArgs);
-            } catch (InvocationTargetException e) {
-                // Should not happen.
-                Log.w("ApiDemos", "Unable to invoke startForeground", e);
-            } catch (IllegalAccessException e) {
-                // Should not happen.
-                Log.w("ApiDemos", "Unable to invoke startForeground", e);
-            }
+            invokeMethod(mStartForeground, mStartForegroundArgs);
             return;
         }
         
         // Fall back on the old API.
-        setForeground(true);
+        mSetForegroundArgs[0] = Boolean.TRUE;
+        invokeMethod(mSetForeground, mSetForegroundArgs);
         mNM.notify(id, notification);
     }
     
@@ -109,7 +118,8 @@
         // Fall back on the old API.  Note to cancel BEFORE changing the
         // foreground state, since we could be killed at that point.
         mNM.cancel(id);
-        setForeground(false);
+        mSetForegroundArgs[0] = Boolean.FALSE;
+        invokeMethod(mSetForeground, mSetForegroundArgs);
     }
     
     @Override
@@ -123,6 +133,14 @@
         } catch (NoSuchMethodException e) {
             // Running on an older platform.
             mStartForeground = mStopForeground = null;
+            return;
+        }
+        try {
+            mSetForeground = getClass().getMethod("setForeground",
+                    mSetForegroundSignature);
+        } catch (NoSuchMethodException e) {
+            throw new IllegalStateException(
+                    "OS doesn't have Service.startForeground OR Service.setForeground!");
         }
     }
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.java
new file mode 100644
index 0000000..56ddc6b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstrates how to show an AlertDialog that is managed by a Fragment.
+ */
+public class FragmentAlertDialog extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_dialog);
+
+        View tv = findViewById(R.id.text);
+        ((TextView)tv).setText("Example of displaying an alert dialog with a DialogFragment");
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.show);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog();
+            }
+        });
+    }
+
+//BEGIN_INCLUDE(activity)
+    void showDialog() {
+        DialogFragment newFragment = MyAlertDialogFragment.newInstance(
+                R.string.alert_dialog_two_buttons_title);
+        newFragment.show(getFragmentManager(), "dialog");
+    }
+
+    public void doPositiveClick() {
+        // Do stuff here.
+        Log.i("FragmentAlertDialog", "Positive click!");
+    }
+    
+    public void doNegativeClick() {
+        // Do stuff here.
+        Log.i("FragmentAlertDialog", "Negative click!");
+    }
+//END_INCLUDE(activity)
+    
+//BEGIN_INCLUDE(dialog)
+    public static class MyAlertDialogFragment extends DialogFragment {
+
+        public static MyAlertDialogFragment newInstance(int title) {
+            MyAlertDialogFragment frag = new MyAlertDialogFragment();
+            Bundle args = new Bundle();
+            args.putInt("title", title);
+            frag.setArguments(args);
+            return frag;
+        }
+        
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            int title = getArguments().getInt("title");
+            
+            return new AlertDialog.Builder(getActivity())
+                    .setIcon(R.drawable.alert_dialog_icon)
+                    .setTitle(title)
+                    .setPositiveButton(R.string.alert_dialog_ok,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                ((FragmentAlertDialog)getActivity()).doPositiveClick();
+                            }
+                        }
+                    )
+                    .setNegativeButton(R.string.alert_dialog_cancel,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                ((FragmentAlertDialog)getActivity()).doNegativeClick();
+                            }
+                        }
+                    )
+                    .create();
+        }
+    }
+//END_INCLUDE(dialog)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
new file mode 100644
index 0000000..bf17728
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Demonstrates a fragment that can be configured through both Bundle arguments
+ * and layout attributes.
+ */
+public class FragmentArguments extends Activity {
+//BEGIN_INCLUDE(create)
+    @Override protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_arguments);
+
+        if (savedInstanceState == null) {
+            // First-time init; create fragment to embed in activity.
+            FragmentTransaction ft = getFragmentManager().beginTransaction();
+            Fragment newFragment = MyFragment.newInstance("From Arguments");
+            ft.add(R.id.created, newFragment);
+            ft.commit();
+        }
+    }
+//END_INCLUDE(create)
+
+//BEGIN_INCLUDE(fragment)
+    public static class MyFragment extends Fragment {
+        CharSequence mLabel;
+
+        /**
+         * Create a new instance of MyFragment that will be initialized
+         * with the given arguments.
+         */
+        static MyFragment newInstance(CharSequence label) {
+            MyFragment f = new MyFragment();
+            Bundle b = new Bundle();
+            b.putCharSequence("label", label);
+            f.setArguments(b);
+            return f;
+        }
+
+        /**
+         * Parse attributes during inflation from a view hierarchy into the
+         * arguments we handle.
+         */
+        @Override public void onInflate(Activity activity, AttributeSet attrs,
+                Bundle savedInstanceState) {
+            super.onInflate(activity, attrs, savedInstanceState);
+
+            TypedArray a = activity.obtainStyledAttributes(attrs,
+                    R.styleable.FragmentArguments);
+            mLabel = a.getText(R.styleable.FragmentArguments_android_label);
+            a.recycle();
+        }
+
+        /**
+         * During creation, if arguments have been supplied to the fragment
+         * then parse those out.
+         */
+        @Override public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            Bundle args = getArguments();
+            if (args != null) {
+                mLabel = args.getCharSequence("label", mLabel);
+            }
+        }
+
+        /**
+         * Create the view for this fragment, using the arguments given to it.
+         */
+        @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText(mLabel != null ? mLabel : "(no label)");
+            tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+            return v;
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentContextMenu.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentContextMenu.java
new file mode 100644
index 0000000..6bc73e0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentContextMenu.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+
+/**
+ * Demonstration of displaying a context menu from a fragment.
+ */
+public class FragmentContextMenu extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create the list fragment and add it as our sole content.
+        ContextMenuFragment content = new ContextMenuFragment();
+        getFragmentManager().beginTransaction().add(android.R.id.content, content).commit();
+    }
+
+    public static class ContextMenuFragment extends Fragment {
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View root = inflater.inflate(R.layout.fragment_context_menu, container, false);
+            registerForContextMenu(root.findViewById(R.id.long_press));
+            return root;
+        }
+
+        @Override
+        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+            super.onCreateContextMenu(menu, v, menuInfo);
+            menu.add(Menu.NONE, R.id.a_item, Menu.NONE, "Menu A");
+            menu.add(Menu.NONE, R.id.b_item, Menu.NONE, "Menu B");
+        }
+
+        @Override
+        public boolean onContextItemSelected(MenuItem item) {
+            switch (item.getItemId()) {
+                case R.id.a_item:
+                    Log.i("ContextMenu", "Item 1a was chosen");
+                    return true;
+                case R.id.b_item:
+                    Log.i("ContextMenu", "Item 1b was chosen");
+                    return true;
+            }
+            return super.onContextItemSelected(item);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialog.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialog.java
new file mode 100644
index 0000000..d611601
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialog.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentDialog extends Activity {
+    int mStackLevel = 0;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_dialog);
+
+        View tv = findViewById(R.id.text);
+        ((TextView)tv).setText("Example of displaying dialogs with a DialogFragment.  "
+                + "Press the show button below to see the first dialog; pressing "
+                + "successive show buttons will display other dialog styles as a "
+                + "stack, with dismissing or back going to the previous dialog.");
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.show);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog();
+            }
+        });
+
+        if (savedInstanceState != null) {
+            mStackLevel = savedInstanceState.getInt("level");
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("level", mStackLevel);
+    }
+
+//BEGIN_INCLUDE(add_dialog)
+    void showDialog() {
+        mStackLevel++;
+
+        // DialogFragment.show() will take care of adding the fragment
+        // in a transaction.  We also want to remove any currently showing
+        // dialog, so make our own transaction and take care of that here.
+        FragmentTransaction ft = getFragmentManager().beginTransaction();
+        Fragment prev = getFragmentManager().findFragmentByTag("dialog");
+        if (prev != null) {
+            ft.remove(prev);
+        }
+        ft.addToBackStack(null);
+
+        // Create and show the dialog.
+        DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
+        newFragment.show(ft, "dialog");
+    }
+//END_INCLUDE(add_dialog)
+
+    static String getNameForNum(int num) {
+        switch ((num-1)%6) {
+            case 1: return "STYLE_NO_TITLE";
+            case 2: return "STYLE_NO_FRAME";
+            case 3: return "STYLE_NO_INPUT (this window can't receive input, so "
+                    + "you will need to press the bottom show button)";
+            case 4: return "STYLE_NORMAL with dark fullscreen theme";
+            case 5: return "STYLE_NORMAL with light theme";
+            case 6: return "STYLE_NO_TITLE with light theme";
+            case 7: return "STYLE_NO_FRAME with light theme";
+            case 8: return "STYLE_NORMAL with light fullscreen theme";
+        }
+        return "STYLE_NORMAL";
+    }
+
+//BEGIN_INCLUDE(dialog)
+    public static class MyDialogFragment extends DialogFragment {
+        int mNum;
+
+        /**
+         * Create a new instance of MyDialogFragment, providing "num"
+         * as an argument.
+         */
+        static MyDialogFragment newInstance(int num) {
+            MyDialogFragment f = new MyDialogFragment();
+
+            // Supply num input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("num", num);
+            f.setArguments(args);
+
+            return f;
+        }
+        
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNum = getArguments().getInt("num");
+
+            // Pick a style based on the num.
+            int style = DialogFragment.STYLE_NORMAL, theme = 0;
+            switch ((mNum-1)%6) {
+                case 1: style = DialogFragment.STYLE_NO_TITLE; break;
+                case 2: style = DialogFragment.STYLE_NO_FRAME; break;
+                case 3: style = DialogFragment.STYLE_NO_INPUT; break;
+                case 4: style = DialogFragment.STYLE_NORMAL; break;
+                case 5: style = DialogFragment.STYLE_NORMAL; break;
+                case 6: style = DialogFragment.STYLE_NO_TITLE; break;
+                case 7: style = DialogFragment.STYLE_NO_FRAME; break;
+                case 8: style = DialogFragment.STYLE_NORMAL; break;
+            }
+            switch ((mNum-1)%6) {
+                case 4: theme = android.R.style.Theme_Holo; break;
+                case 5: theme = android.R.style.Theme_Holo_Light_Dialog; break;
+                case 6: theme = android.R.style.Theme_Holo_Light; break;
+                case 7: theme = android.R.style.Theme_Holo_Light_Panel; break;
+                case 8: theme = android.R.style.Theme_Holo_Light; break;
+            }
+            setStyle(style, theme);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.fragment_dialog, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("Dialog #" + mNum + ": using style "
+                    + getNameForNum(mNum));
+
+            // Watch for button clicks.
+            Button button = (Button)v.findViewById(R.id.show);
+            button.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    // When button is clicked, call up to owning activity.
+                    ((FragmentDialog)getActivity()).showDialog();
+                }
+            });
+
+            return v;
+        }
+    }
+//END_INCLUDE(dialog)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialogOrActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialogOrActivity.java
new file mode 100644
index 0000000..2d2be22
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialogOrActivity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentDialogOrActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_dialog_or_activity);
+
+        if (savedInstanceState == null) {
+            // First-time init; create fragment to embed in activity.
+//BEGIN_INCLUDE(embed)
+            FragmentTransaction ft = getFragmentManager().beginTransaction();
+            DialogFragment newFragment = MyDialogFragment.newInstance();
+            ft.add(R.id.embedded, newFragment);
+            ft.commit();
+//END_INCLUDE(embed)
+        }
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.show_dialog);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog();
+            }
+        });
+    }
+
+//BEGIN_INCLUDE(show_dialog)
+    void showDialog() {
+        // Create the fragment and show it as a dialog.
+        DialogFragment newFragment = MyDialogFragment.newInstance();
+        newFragment.show(getFragmentManager(), "dialog");
+    }
+//END_INCLUDE(show_dialog)
+
+//BEGIN_INCLUDE(dialog)
+    public static class MyDialogFragment extends DialogFragment {
+        static MyDialogFragment newInstance() {
+            return new MyDialogFragment();
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("This is an instance of MyDialogFragment");
+            return v;
+        }
+    }
+//END_INCLUDE(dialog)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentHideShow.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentHideShow.java
new file mode 100644
index 0000000..e5e2599
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentHideShow.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstration of hiding and showing fragments.
+ */
+public class FragmentHideShow extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_hide_show);
+
+        // The content view embeds two fragments; now retrieve them and attach
+        // their "hide" button.
+        FragmentManager fm = getFragmentManager();
+        addShowHideListener(R.id.frag1hide, fm.findFragmentById(R.id.fragment1));
+        addShowHideListener(R.id.frag2hide, fm.findFragmentById(R.id.fragment2));
+    }
+
+    void addShowHideListener(int buttonId, final Fragment fragment) {
+        final Button button = (Button)findViewById(buttonId);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                FragmentTransaction ft = getFragmentManager().beginTransaction();
+                ft.setCustomAnimations(android.R.animator.fade_in,
+                        android.R.animator.fade_out);
+                if (fragment.isHidden()) {
+                    ft.show(fragment);
+                    button.setText("Hide");
+                } else {
+                    ft.hide(fragment);
+                    button.setText("Show");
+                }
+                ft.commit();
+            }
+        });
+    }
+
+    public static class FirstFragment extends Fragment {
+        TextView mTextView;
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.labeled_text_edit, container, false);
+            View tv = v.findViewById(R.id.msg);
+            ((TextView)tv).setText("The fragment saves and restores this text.");
+
+            // Retrieve the text editor, and restore the last saved state if needed.
+            mTextView = (TextView)v.findViewById(R.id.saved);
+            if (savedInstanceState != null) {
+                mTextView.setText(savedInstanceState.getCharSequence("text"));
+            }
+            return v;
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+
+            // Remember the current text, to restore if we later restart.
+            outState.putCharSequence("text", mTextView.getText());
+        }
+    }
+
+    public static class SecondFragment extends Fragment {
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.labeled_text_edit, container, false);
+            View tv = v.findViewById(R.id.msg);
+            ((TextView)tv).setText("The TextView saves and restores this text.");
+
+            // Retrieve the text editor and tell it to save and restore its state.
+            // Note that you will often set this in the layout XML, but since
+            // we are sharing our layout with the other fragment we will customize
+            // it here.
+            ((TextView)v.findViewById(R.id.saved)).setSaveEnabled(true);
+            return v;
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
new file mode 100644
index 0000000..730f4d4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+import com.example.android.apis.Shakespeare;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.app.ListFragment;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+/**
+ * Demonstration of using fragments to implement different activity layouts.
+ * This sample provides a different layout (and activity flow) when run in
+ * landscape.
+ */
+public class FragmentLayout extends Activity {
+
+//BEGIN_INCLUDE(main)
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setContentView(R.layout.fragment_layout);
+    }
+//END_INCLUDE(main)
+
+    /**
+     * This is a secondary activity, to show what the user has selected
+     * when the screen is not large enough to show it all in one activity.
+     */
+//BEGIN_INCLUDE(details_activity)
+    public static class DetailsActivity extends Activity {
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            if (getResources().getConfiguration().orientation
+                    == Configuration.ORIENTATION_LANDSCAPE) {
+                // If the screen is now in landscape mode, we can show the
+                // dialog in-line with the list so we don't need this activity.
+                finish();
+                return;
+            }
+
+            if (savedInstanceState == null) {
+                // During initial setup, plug in the details fragment.
+                DetailsFragment details = new DetailsFragment();
+                details.setArguments(getIntent().getExtras());
+                getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
+            }
+        }
+    }
+//END_INCLUDE(details_activity)
+
+    /**
+     * This is the "top-level" fragment, showing a list of items that the
+     * user can pick.  Upon picking an item, it takes care of displaying the
+     * data to the user as appropriate based on the currrent UI layout.
+     */
+//BEGIN_INCLUDE(titles)
+    public static class TitlesFragment extends ListFragment {
+        boolean mDualPane;
+        int mCurCheckPosition = 0;
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            // Populate list with our static array of titles.
+            setListAdapter(new ArrayAdapter<String>(getActivity(),
+                    android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES));
+
+            // Check to see if we have a frame in which to embed the details
+            // fragment directly in the containing UI.
+            View detailsFrame = getActivity().findViewById(R.id.details);
+            mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;
+
+            if (savedInstanceState != null) {
+                // Restore last state for checked position.
+                mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
+            }
+
+            if (mDualPane) {
+                // In dual-pane mode, the list view highlights the selected item.
+                getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+                // Make sure our UI is in the correct state.
+                showDetails(mCurCheckPosition);
+            }
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            outState.putInt("curChoice", mCurCheckPosition);
+        }
+
+        @Override
+        public void onListItemClick(ListView l, View v, int position, long id) {
+            showDetails(position);
+        }
+
+        /**
+         * Helper function to show the details of a selected item, either by
+         * displaying a fragment in-place in the current UI, or starting a
+         * whole new activity in which it is displayed.
+         */
+        void showDetails(int index) {
+            mCurCheckPosition = index;
+
+            if (mDualPane) {
+                // We can display everything in-place with fragments, so update
+                // the list to highlight the selected item and show the data.
+                getListView().setItemChecked(index, true);
+
+                // Check what fragment is currently shown, replace if needed.
+                DetailsFragment details = (DetailsFragment)
+                        getFragmentManager().findFragmentById(R.id.details);
+                if (details == null || details.getShownIndex() != index) {
+                    // Make new fragment to show this selection.
+                    details = DetailsFragment.newInstance(index);
+
+                    // Execute a transaction, replacing any existing fragment
+                    // with this one inside the frame.
+                    FragmentTransaction ft = getFragmentManager().beginTransaction();
+                    ft.replace(R.id.details, details);
+                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+                    ft.commit();
+                }
+
+            } else {
+                // Otherwise we need to launch a new activity to display
+                // the dialog fragment with selected text.
+                Intent intent = new Intent();
+                intent.setClass(getActivity(), DetailsActivity.class);
+                intent.putExtra("index", index);
+                startActivity(intent);
+            }
+        }
+    }
+//END_INCLUDE(titles)
+
+    /**
+     * This is the secondary fragment, displaying the details of a particular
+     * item.
+     */
+//BEGIN_INCLUDE(details)
+    public static class DetailsFragment extends Fragment {
+        /**
+         * Create a new instance of DetailsFragment, initialized to
+         * show the text at 'index'.
+         */
+        public static DetailsFragment newInstance(int index) {
+            DetailsFragment f = new DetailsFragment();
+
+            // Supply index input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("index", index);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        public int getShownIndex() {
+            return getArguments().getInt("index", 0);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            if (container == null) {
+                // We have different layouts, and in one of them this
+                // fragment's containing frame doesn't exist.  The fragment
+                // may still be created from its saved state, but there is
+                // no reason to try to create its view hierarchy because it
+                // won't be displayed.  Note this is not needed -- we could
+                // just run the code below, where we would create and return
+                // the view hierarchy; it would just never be used.
+                return null;
+            }
+
+            ScrollView scroller = new ScrollView(getActivity());
+            TextView text = new TextView(getActivity());
+            int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    4, getActivity().getResources().getDisplayMetrics());
+            text.setPadding(padding, padding, padding, padding);
+            scroller.addView(text);
+            text.setText(Shakespeare.DIALOGUE[getShownIndex()]);
+            return scroller;
+        }
+    }
+//END_INCLUDE(details)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentListArray.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentListArray.java
new file mode 100644
index 0000000..cdf6ddc
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentListArray.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.Shakespeare;
+
+import android.app.Activity;
+import android.app.ListFragment;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * Demonstration of using ListFragment to show a list of items
+ * from a canned array.
+ */
+public class FragmentListArray extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create the list fragment and add it as our sole content.
+        if (getFragmentManager().findFragmentById(android.R.id.content) == null) {
+            ArrayListFragment list = new ArrayListFragment();
+            getFragmentManager().beginTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+    public static class ArrayListFragment extends ListFragment {
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+            setListAdapter(new ArrayAdapter<String>(getActivity(),
+                    android.R.layout.simple_list_item_1, Shakespeare.TITLES));
+        }
+
+        @Override
+        public void onListItemClick(ListView l, View v, int position, long id) {
+            Log.i("FragmentList", "Item clicked: " + id);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentMenu.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentMenu.java
new file mode 100644
index 0000000..8f588d1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentMenu.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.CheckBox;
+
+/**
+ * Demonstrates how fragments can participate in the options menu.
+ */
+public class FragmentMenu extends Activity {
+    Fragment mFragment1;
+    Fragment mFragment2;
+    CheckBox mCheckBox1;
+    CheckBox mCheckBox2;
+
+    // Update fragment visibility when check boxes are changed.
+    final OnClickListener mClickListener = new OnClickListener() {
+        public void onClick(View v) {
+            updateFragmentVisibility();
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_menu);
+        
+        // Make sure the two menu fragments are created.
+        FragmentManager fm = getFragmentManager();
+        FragmentTransaction ft = fm.beginTransaction();
+        mFragment1 = fm.findFragmentByTag("f1");
+        if (mFragment1 == null) {
+            mFragment1 = new MenuFragment();
+            ft.add(mFragment1, "f1");
+        }
+        mFragment2 = fm.findFragmentByTag("f2");
+        if (mFragment2 == null) {
+            mFragment2 = new Menu2Fragment();
+            ft.add(mFragment2, "f2");
+        }
+        ft.commit();
+        
+        // Watch check box clicks.
+        mCheckBox1 = (CheckBox)findViewById(R.id.menu1);
+        mCheckBox1.setOnClickListener(mClickListener);
+        mCheckBox2 = (CheckBox)findViewById(R.id.menu2);
+        mCheckBox2.setOnClickListener(mClickListener);
+        
+        // Make sure fragments start out with correct visibility.
+        updateFragmentVisibility();
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        // Make sure fragments are updated after check box view state is restored.
+        updateFragmentVisibility();
+    }
+
+    // Update fragment visibility based on current check box state.
+    void updateFragmentVisibility() {
+        FragmentTransaction ft = getFragmentManager().beginTransaction();
+        if (mCheckBox1.isChecked()) ft.show(mFragment1);
+        else ft.hide(mFragment1);
+        if (mCheckBox2.isChecked()) ft.show(mFragment2);
+        else ft.hide(mFragment2);
+        ft.commit();
+    }
+
+    /**
+     * A fragment that displays a menu.  This fragment happens to not
+     * have a UI (it does not implement onCreateView), but it could also
+     * have one if it wanted.
+     */
+    public static class MenuFragment extends Fragment {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setHasOptionsMenu(true);
+        }
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            menu.add("Menu 1a").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            menu.add("Menu 1b").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        }
+    }
+
+    /**
+     * Second fragment with a menu.
+     */
+    public static class Menu2Fragment extends Fragment {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setHasOptionsMenu(true);
+        }
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            menu.add("Menu 2").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentReceiveResult.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentReceiveResult.java
new file mode 100644
index 0000000..f207cf9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentReceiveResult.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+public class FragmentReceiveResult extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        FrameLayout frame = new FrameLayout(this);
+        frame.setId(R.id.simple_fragment);
+        setContentView(frame, lp);
+        
+        if (savedInstanceState == null) {
+            // Do first time initialization -- add fragment. 
+            Fragment newFragment = new ReceiveResultFragment();
+            FragmentTransaction ft = getFragmentManager().beginTransaction();
+            ft.add(R.id.simple_fragment, newFragment).commit();
+        }
+    }
+
+    public static class ReceiveResultFragment extends Fragment {
+        // Definition of the one requestCode we use for receiving resuls.
+        static final private int GET_CODE = 0;
+
+        private TextView mResults;
+
+        private OnClickListener mGetListener = new OnClickListener() {
+            public void onClick(View v) {
+                // Start the activity whose result we want to retrieve.  The
+                // result will come back with request code GET_CODE.
+                Intent intent = new Intent(getActivity(), SendResult.class);
+                startActivityForResult(intent, GET_CODE);
+            }
+        };
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.receive_result, container, false);
+            
+            // Retrieve the TextView widget that will display results.
+            mResults = (TextView)v.findViewById(R.id.results);
+
+            // This allows us to later extend the text buffer.
+            mResults.setText(mResults.getText(), TextView.BufferType.EDITABLE);
+
+            // Watch for button clicks.
+            Button getButton = (Button)v.findViewById(R.id.get);
+            getButton.setOnClickListener(mGetListener);
+            
+            return v;
+        }
+
+        /**
+         * This method is called when the sending activity has finished, with the
+         * result it supplied.
+         */
+        @Override
+        public void onActivityResult(int requestCode, int resultCode, Intent data) {
+            // You can use the requestCode to select between multiple child
+            // activities you may have started.  Here there is only one thing
+            // we launch.
+            if (requestCode == GET_CODE) {
+
+                // We will be adding to our text.
+                Editable text = (Editable)mResults.getText();
+
+                // This is a standard resultCode that is sent back if the
+                // activity doesn't supply an explicit result.  It will also
+                // be returned if the activity failed to launch.
+                if (resultCode == RESULT_CANCELED) {
+                    text.append("(cancelled)");
+
+                // Our protocol with the sending activity is that it will send
+                // text in 'data' as its result.
+                } else {
+                    text.append("(okay ");
+                    text.append(Integer.toString(resultCode));
+                    text.append(") ");
+                    if (data != null) {
+                        text.append(data.getAction());
+                    }
+                }
+
+                text.append("\n");
+            }
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java
new file mode 100644
index 0000000..e2ddae2
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ProgressBar;
+
+/**
+ * This example shows how you can use a Fragment to easily propagate state
+ * (such as threads) across activity instances when an activity needs to be
+ * restarted due to, for example, a configuration change.  This is a lot
+ * easier than using the raw Activity.onRetainNonConfiguratinInstance() API.
+ */
+public class FragmentRetainInstance extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // First time init, create the UI.
+        if (savedInstanceState == null) {
+            getFragmentManager().beginTransaction().add(android.R.id.content,
+                    new UiFragment()).commit();
+        }
+    }
+
+    /**
+     * This is a fragment showing UI that will be updated from work done
+     * in the retained fragment.
+     */
+    public static class UiFragment extends Fragment {
+        RetainedFragment mWorkFragment;
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.fragment_retain_instance, container, false);
+
+            // Watch for button clicks.
+            Button button = (Button)v.findViewById(R.id.restart);
+            button.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    mWorkFragment.restart();
+                }
+            });
+
+            return v;
+        }
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            FragmentManager fm = getFragmentManager();
+
+            // Check to see if we have retained the worker fragment.
+            mWorkFragment = (RetainedFragment)fm.findFragmentByTag("work");
+
+            // If not retained (or first time running), we need to create it.
+            if (mWorkFragment == null) {
+                mWorkFragment = new RetainedFragment();
+                // Tell it who it is working with.
+                mWorkFragment.setTargetFragment(this, 0);
+                fm.beginTransaction().add(mWorkFragment, "work").commit();
+            }
+        }
+
+    }
+
+    /**
+     * This is the Fragment implementation that will be retained across
+     * activity instances.  It represents some ongoing work, here a thread
+     * we have that sits around incrementing a progress indicator.
+     */
+    public static class RetainedFragment extends Fragment {
+        ProgressBar mProgressBar;
+        int mPosition;
+        boolean mReady = false;
+        boolean mQuiting = false;
+
+        /**
+         * This is the thread that will do our work.  It sits in a loop running
+         * the progress up until it has reached the top, then stops and waits.
+         */
+        final Thread mThread = new Thread() {
+            @Override
+            public void run() {
+                // We'll figure the real value out later.
+                int max = 10000;
+
+                // This thread runs almost forever.
+                while (true) {
+
+                    // Update our shared state with the UI.
+                    synchronized (this) {
+                        // Our thread is stopped if the UI is not ready
+                        // or it has completed its work.
+                        while (!mReady || mPosition >= max) {
+                            if (mQuiting) {
+                                return;
+                            }
+                            try {
+                                wait();
+                            } catch (InterruptedException e) {
+                            }
+                        }
+
+                        // Now update the progress.  Note it is important that
+                        // we touch the progress bar with the lock held, so it
+                        // doesn't disappear on us.
+                        mPosition++;
+                        max = mProgressBar.getMax();
+                        mProgressBar.setProgress(mPosition);
+                    }
+
+                    // Normally we would be doing some work, but put a kludge
+                    // here to pretend like we are.
+                    synchronized (this) {
+                        try {
+                            wait(50);
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                }
+            }
+        };
+
+        /**
+         * Fragment initialization.  We way we want to be retained and
+         * start our thread.
+         */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            
+            // Tell the framework to try to keep this fragment around
+            // during a configuration change.
+            setRetainInstance(true);
+            
+            // Start up the worker thread.
+            mThread.start();
+        }
+
+        /**
+         * This is called when the Fragment's Activity is ready to go, after
+         * its content view has been installed; it is called both after
+         * the initial fragment creation and after the fragment is re-attached
+         * to a new activity.
+         */
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+            
+            // Retrieve the progress bar from the target's view hierarchy.
+            mProgressBar = (ProgressBar)getTargetFragment().getView().findViewById(
+                    R.id.progress_horizontal);
+            
+            // We are ready for our thread to go.
+            synchronized (mThread) {
+                mReady = true;
+                mThread.notify();
+            }
+        }
+
+        /**
+         * This is called when the fragment is going away.  It is NOT called
+         * when the fragment is being propagated between activity instances.
+         */
+        @Override
+        public void onDestroy() {
+            // Make the thread go away.
+            synchronized (mThread) {
+                mReady = false;
+                mQuiting = true;
+                mThread.notify();
+            }
+            
+            super.onDestroy();
+        }
+
+        /**
+         * This is called right before the fragment is detached from its
+         * current activity instance.
+         */
+        @Override
+        public void onDetach() {
+            // This fragment is being detached from its activity.  We need
+            // to make sure its thread is not going to touch any activity
+            // state after returning from this function.
+            synchronized (mThread) {
+                mProgressBar = null;
+                mReady = false;
+                mThread.notify();
+            }
+            
+            super.onDetach();
+        }
+
+        /**
+         * API for our UI to restart the progress thread.
+         */
+        public void restart() {
+            synchronized (mThread) {
+                mPosition = 0;
+                mThread.notify();
+            }
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java
new file mode 100644
index 0000000..891eda4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentStack extends Activity {
+    int mStackLevel = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_stack);
+        
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.new_fragment);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                addFragmentToStack();
+            }
+        });
+
+        if (savedInstanceState == null) {
+            // Do first time initialization -- add initial fragment.
+            Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+            FragmentTransaction ft = getFragmentManager().beginTransaction();
+            ft.add(R.id.simple_fragment, newFragment).commit();
+        } else {
+            mStackLevel = savedInstanceState.getInt("level");
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("level", mStackLevel);
+    }
+
+//BEGIN_INCLUDE(add_stack)
+    void addFragmentToStack() {
+        mStackLevel++;
+
+        // Instantiate a new fragment.
+        Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+
+        // Add the fragment to the activity, pushing this transaction
+        // on to the back stack.
+        FragmentTransaction ft = getFragmentManager().beginTransaction();
+        ft.replace(R.id.simple_fragment, newFragment);
+        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+        ft.addToBackStack(null);
+        ft.commit();
+    }
+//END_INCLUDE(add_stack)
+
+//BEGIN_INCLUDE(fragment)
+    public static class CountingFragment extends Fragment {
+        int mNum;
+
+        /**
+         * Create a new instance of CountingFragment, providing "num"
+         * as an argument.
+         */
+        static CountingFragment newInstance(int num) {
+            CountingFragment f = new CountingFragment();
+
+            // Supply num input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("num", num);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        /**
+         * When creating, retrieve this instance's number from its arguments.
+         */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNum = getArguments() != null ? getArguments().getInt("num") : 1;
+        }
+
+        /**
+         * The Fragment's UI is just a simple text view showing its
+         * instance number.
+         */
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("Fragment #" + mNum);
+            tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+            return v;
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
index d44c008..41d2ea3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
@@ -24,12 +24,13 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;
-import android.widget.Toast;
 
 public class IncomingMessage extends Activity {
     @Override
@@ -41,31 +42,11 @@
         Button button = (Button) findViewById(R.id.notify);
         button.setOnClickListener(new Button.OnClickListener() {
                 public void onClick(View v) {
-                    showToast();
                     showNotification();
                 }
             });
     }
 
-    /**
-     * The toast pops up a quick message to the user showing what could be
-     * the text of an incoming message.  It uses a custom view to do so.
-     */
-    protected void showToast() {
-        // create the view
-        View view = inflateView(R.layout.incoming_message_panel);
-
-        // set the text in the view
-        TextView tv = (TextView)view.findViewById(R.id.message);
-        tv.setText("khtx. meet u for dinner. cul8r");
-
-        // show the toast
-        Toast toast = new Toast(this);
-        toast.setView(view);
-        toast.setDuration(Toast.LENGTH_LONG);
-        toast.show();
-    }
-
     private View inflateView(int resource) {
         LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         return vi.inflate(resource, null);
@@ -84,8 +65,10 @@
         CharSequence message = "kthx. meet u for dinner. cul8r";
 
         // The PendingIntent to launch our activity if the user selects this notification
+//BEGIN_INCLUDE(pending_intent)
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, IncomingMessageView.class), 0);
+//END_INCLUDE(pending_intent)
 
         // The ticker text, this uses a formatted string so our message could be localized
         String tickerText = getString(R.string.imcoming_message_ticker_text, message);
@@ -97,9 +80,20 @@
         // Set the info for the views that show in the notification panel.
         notif.setLatestEventInfo(this, from, message, contentIntent);
 
-        // after a 100ms delay, vibrate for 250ms, pause for 100 ms and
+        /*
+        // On tablets, the ticker shows the sender, the first line of the message,
+        // the photo of the person and the app icon.  For our sample, we just show
+        // the same icon twice.  If there is no sender, just pass an array of 1 Bitmap.
+        notif.tickerTitle = from;
+        notif.tickerSubtitle = message;
+        notif.tickerIcons = new Bitmap[2];
+        notif.tickerIcons[0] = getIconBitmap();;
+        notif.tickerIcons[1] = getIconBitmap();;
+        */
+
+        // after a 0ms delay, vibrate for 250ms, pause for 100 ms and
         // then vibrate for 500ms.
-        notif.vibrate = new long[] { 100, 250, 100, 500};
+        notif.vibrate = new long[] { 0, 250, 100, 500};
 
         // Note that we use R.layout.incoming_message_panel as the ID for
         // the notification.  It could be any integer you want, but we use
@@ -108,4 +102,10 @@
         // application.
         nm.notify(R.string.imcoming_message_ticker_text, notif);
     }
+
+    private Bitmap getIconBitmap() {
+        BitmapFactory f = new BitmapFactory();
+        return f.decodeResource(getResources(), R.drawable.app_sample_code);
+    }
 }
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/IntentActivityFlags.java b/samples/ApiDemos/src/com/example/android/apis/app/IntentActivityFlags.java
new file mode 100644
index 0000000..caf9d0f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/IntentActivityFlags.java
@@ -0,0 +1,86 @@
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+/**
+ * Example of various Intent flags to modify the activity stack.
+ */
+public class IntentActivityFlags extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.intent_activity_flags);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.flag_activity_clear_task);
+        button.setOnClickListener(mFlagActivityClearTaskListener);
+        button = (Button)findViewById(R.id.flag_activity_clear_task_pi);
+        button.setOnClickListener(mFlagActivityClearTaskPIListener);
+    }
+
+    /**
+     * This creates an array of Intent objects representing the back stack
+     * for a user going into the Views/Lists API demos.
+     */
+//BEGIN_INCLUDE(intent_array)
+    private Intent[] buildIntentsToViewsLists() {
+        // We are going to rebuild our task with a new back stack.  This will
+        // be done by launching an array of Intents, representing the new
+        // back stack to be created, with the first entry holding the root
+        // and requesting to reset the back stack.
+        Intent[] intents = new Intent[3];
+
+        // First: root activity of ApiDemos.
+        // This is a convenient way to make the proper Intent to launch and
+        // reset an application's task.
+        intents[0] = Intent.makeRestartActivityTask(new ComponentName(this,
+                com.example.android.apis.ApiDemos.class));
+
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClass(IntentActivityFlags.this, com.example.android.apis.ApiDemos.class);
+        intent.putExtra("com.example.android.apis.Path", "Views");
+        intents[1] = intent;
+
+        intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClass(IntentActivityFlags.this, com.example.android.apis.ApiDemos.class);
+        intent.putExtra("com.example.android.apis.Path", "Views/Lists");
+
+        intents[2] = intent;
+        return intents;
+    }
+//END_INCLUDE(intent_array)
+
+    private OnClickListener mFlagActivityClearTaskListener = new OnClickListener() {
+        public void onClick(View v) {
+            startActivities(buildIntentsToViewsLists());
+        }
+    };
+
+    private OnClickListener mFlagActivityClearTaskPIListener = new OnClickListener() {
+        public void onClick(View v) {
+            Context context = IntentActivityFlags.this;
+//BEGIN_INCLUDE(pending_intent)
+            PendingIntent pi = PendingIntent.getActivities(context, 0,
+                    buildIntentsToViewsLists(), PendingIntent.FLAG_UPDATE_CURRENT);
+//END_INCLUDE(pending_intent)
+            try {
+                pi.send();
+            } catch (CanceledException e) {
+                Log.w("IntentActivityFlags", "Failed sending PendingIntent", e);
+            }
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java b/samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java
deleted file mode 100644
index 4aa1522..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.app;
-
-import com.example.android.apis.R;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.LinearLayout.LayoutParams;
-
-/**
- * Demonstrates launching a PreferenceActivity and grabbing a value it saved.
- */
-public class LaunchingPreferences extends Activity implements OnClickListener {
-
-    private static final int REQUEST_CODE_PREFERENCES = 1;
-    
-    private TextView mCounterText;
-    
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        /*
-         * If this were my app's main activity, I would load the default values
-         * so they're set even if the user does not go into the preferences
-         * screen. Another good place to call this method would be from a
-         * subclass of Application, so your default values would be loaded
-         * regardless of entry into your application (for example, a service or
-         * activity).
-         */  
-        PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
-        
-        // Simple layout
-        LinearLayout layout = new LinearLayout(this);
-        layout.setOrientation(LinearLayout.VERTICAL);
-        setContentView(layout);
-        
-        // Create a simple button that will launch the preferences
-        Button launchPreferences = new Button(this);
-        launchPreferences.setText(getString(R.string.launch_preference_activity));
-        launchPreferences.setOnClickListener(this);
-        layout.addView(launchPreferences, new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.WRAP_CONTENT));
-        
-        mCounterText = new TextView(this);
-        layout.addView(mCounterText, new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.WRAP_CONTENT));
-        
-        updateCounterText();
-    }
-
-    public void onClick(View v) {
-        
-        // When the button is clicked, launch an activity through this intent
-        Intent launchPreferencesIntent = new Intent().setClass(this, AdvancedPreferences.class);
-        
-        // Make it a subactivity so we know when it returns
-        startActivityForResult(launchPreferencesIntent, REQUEST_CODE_PREFERENCES);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-        
-        // The preferences returned if the request code is what we had given
-        // earlier in startSubActivity
-        if (requestCode == REQUEST_CODE_PREFERENCES) {
-            // Read a sample value they have set
-            updateCounterText();
-        }
-    }
-
-    private void updateCounterText() {
-        // Since we're in the same package, we can use this context to get
-        // the default shared preferences
-        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
-        final int counter = sharedPref.getInt(AdvancedPreferences.KEY_MY_PREFERENCE, 0);
-        mCounterText.setText(getString(R.string.counter_value_is) + " " + counter);
-    }
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.java b/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.java
new file mode 100644
index 0000000..a8ac0d4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.app.FragmentManager;
+import android.app.ListFragment;
+import android.app.LoaderManager;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SearchView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.SearchView.OnQueryTextListener;
+
+/**
+ * Demonstration of the use of a CursorLoader to load and display contacts
+ * data in a fragment.
+ */
+public class LoaderCursor extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        FragmentManager fm = getFragmentManager();
+
+        // Create the list fragment and add it as our sole content.
+        if (fm.findFragmentById(android.R.id.content) == null) {
+            CursorLoaderListFragment list = new CursorLoaderListFragment();
+            fm.beginTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+//BEGIN_INCLUDE(fragment_cursor)
+    public static class CursorLoaderListFragment extends ListFragment
+            implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {
+
+        // This is the Adapter being used to display the list's data.
+        SimpleCursorAdapter mAdapter;
+
+        // If non-null, this is the current filter the user has provided.
+        String mCurFilter;
+
+        @Override public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            // Give some text to display if there is no data.  In a real
+            // application this would come from a resource.
+            setEmptyText("No phone numbers");
+
+            // We have a menu item to show in action bar.
+            setHasOptionsMenu(true);
+
+            // Create an empty adapter we will use to display the loaded data.
+            mAdapter = new SimpleCursorAdapter(getActivity(),
+                    android.R.layout.simple_list_item_2, null,
+                    new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
+                    new int[] { android.R.id.text1, android.R.id.text2 }, 0);
+            setListAdapter(mAdapter);
+
+            // Start out with a progress indicator.
+            setListShown(false);
+
+            // Prepare the loader.  Either re-connect with an existing one,
+            // or start a new one.
+            getLoaderManager().initLoader(0, null, this);
+        }
+
+        @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            // Place an action bar item for searching.
+            MenuItem item = menu.add("Search");
+            item.setIcon(android.R.drawable.ic_menu_search);
+            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            SearchView sv = new SearchView(getActivity());
+            sv.setOnQueryTextListener(this);
+            item.setActionView(sv);
+        }
+
+        public boolean onQueryTextChange(String newText) {
+            // Called when the action bar search text has changed.  Update
+            // the search filter, and restart the loader to do a new query
+            // with this filter.
+            mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+            getLoaderManager().restartLoader(0, null, this);
+            return true;
+        }
+
+        @Override public boolean onQueryTextSubmit(String query) {
+            // Don't care about this.
+            return true;
+        }
+
+        @Override public void onListItemClick(ListView l, View v, int position, long id) {
+            // Insert desired behavior here.
+            Log.i("FragmentComplexList", "Item clicked: " + id);
+        }
+
+        // These are the Contacts rows that we will retrieve.
+        static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
+            Contacts._ID,
+            Contacts.DISPLAY_NAME,
+            Contacts.CONTACT_STATUS,
+            Contacts.CONTACT_PRESENCE,
+            Contacts.PHOTO_ID,
+            Contacts.LOOKUP_KEY,
+        };
+
+        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+            // This is called when a new Loader needs to be created.  This
+            // sample only has one Loader, so we don't care about the ID.
+            // First, pick the base URI to use depending on whether we are
+            // currently filtering.
+            Uri baseUri;
+            if (mCurFilter != null) {
+                baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+                        Uri.encode(mCurFilter));
+            } else {
+                baseUri = Contacts.CONTENT_URI;
+            }
+
+            // Now create and return a CursorLoader that will take care of
+            // creating a Cursor for the data being displayed.
+            String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+                    + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+                    + Contacts.DISPLAY_NAME + " != '' ))";
+            return new CursorLoader(getActivity(), baseUri,
+                    CONTACTS_SUMMARY_PROJECTION, select, null,
+                    Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
+        }
+
+        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+            // Swap the new cursor in.  (The framework will take care of closing the
+            // old cursor once we return.)
+            mAdapter.swapCursor(data);
+
+            // The list should now be shown.
+            setListShown(true);
+        }
+
+        public void onLoaderReset(Loader<Cursor> loader) {
+            // This is called when the last Cursor provided to onLoadFinished()
+            // above is about to be closed.  We need to make sure we are no
+            // longer using it.
+            mAdapter.swapCursor(null);
+        }
+    }
+//END_INCLUDE(fragment_cursor)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LoaderCustom.java b/samples/ApiDemos/src/com/example/android/apis/app/LoaderCustom.java
new file mode 100644
index 0000000..883ab14
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LoaderCustom.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import java.io.File;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.FragmentManager;
+import android.app.ListFragment;
+import android.app.LoaderManager;
+import android.content.AsyncTaskLoader;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.Loader;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.SearchView;
+import android.widget.TextView;
+import android.widget.SearchView.OnQueryTextListener;
+
+/**
+ * Demonstration of the implementation of a custom Loader.
+ */
+public class LoaderCustom extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        FragmentManager fm = getFragmentManager();
+
+        // Create the list fragment and add it as our sole content.
+        if (fm.findFragmentById(android.R.id.content) == null) {
+            AppListFragment list = new AppListFragment();
+            fm.beginTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+//BEGIN_INCLUDE(loader)
+    /**
+     * This class holds the per-item data in our Loader.
+     */
+    public static class AppEntry {
+        public AppEntry(AppListLoader loader, ApplicationInfo info) {
+            mLoader = loader;
+            mInfo = info;
+            mApkFile = new File(info.sourceDir);
+        }
+
+        public ApplicationInfo getApplicationInfo() {
+            return mInfo;
+        }
+
+        public String getLabel() {
+            return mLabel;
+        }
+
+        public Drawable getIcon() {
+            if (mIcon == null) {
+                if (mApkFile.exists()) {
+                    mIcon = mInfo.loadIcon(mLoader.mPm);
+                    return mIcon;
+                } else {
+                    mMounted = false;
+                }
+            } else if (!mMounted) {
+                // If the app wasn't mounted but is now mounted, reload
+                // its icon.
+                if (mApkFile.exists()) {
+                    mMounted = true;
+                    mIcon = mInfo.loadIcon(mLoader.mPm);
+                    return mIcon;
+                }
+            } else {
+                return mIcon;
+            }
+
+            return mLoader.getContext().getResources().getDrawable(
+                    android.R.drawable.sym_def_app_icon);
+        }
+
+        @Override public String toString() {
+            return mLabel;
+        }
+
+        void loadLabel(Context context) {
+            if (mLabel == null || !mMounted) {
+                if (!mApkFile.exists()) {
+                    mMounted = false;
+                    mLabel = mInfo.packageName;
+                } else {
+                    mMounted = true;
+                    CharSequence label = mInfo.loadLabel(context.getPackageManager());
+                    mLabel = label != null ? label.toString() : mInfo.packageName;
+                }
+            }
+        }
+
+        private final AppListLoader mLoader;
+        private final ApplicationInfo mInfo;
+        private final File mApkFile;
+        private String mLabel;
+        private Drawable mIcon;
+        private boolean mMounted;
+    }
+
+    /**
+     * Perform alphabetical comparison of application entry objects.
+     */
+    public static final Comparator<AppEntry> ALPHA_COMPARATOR = new Comparator<AppEntry>() {
+        private final Collator sCollator = Collator.getInstance();
+        @Override
+        public int compare(AppEntry object1, AppEntry object2) {
+            return sCollator.compare(object1.getLabel(), object2.getLabel());
+        }
+    };
+
+    /**
+     * Helper for determining if the configuration has changed in an interesting
+     * way so we need to rebuild the app list.
+     */
+    public static class InterestingConfigChanges {
+        final Configuration mLastConfiguration = new Configuration();
+        int mLastDensity;
+
+        boolean applyNewConfig(Resources res) {
+            int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
+            boolean densityChanged = mLastDensity != res.getDisplayMetrics().densityDpi;
+            if (densityChanged || (configChanges&(ActivityInfo.CONFIG_LOCALE
+                    |ActivityInfo.CONFIG_UI_MODE|ActivityInfo.CONFIG_SCREEN_LAYOUT)) != 0) {
+                mLastDensity = res.getDisplayMetrics().densityDpi;
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Helper class to look for interesting changes to the installed apps
+     * so that the loader can be updated.
+     */
+    public static class PackageIntentReceiver extends BroadcastReceiver {
+        final AppListLoader mLoader;
+
+        public PackageIntentReceiver(AppListLoader loader) {
+            mLoader = loader;
+            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+            filter.addDataScheme("package");
+            mLoader.getContext().registerReceiver(this, filter);
+            // Register for events related to sdcard installation.
+            IntentFilter sdFilter = new IntentFilter();
+            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+            mLoader.getContext().registerReceiver(this, sdFilter);
+        }
+
+        @Override public void onReceive(Context context, Intent intent) {
+            // Tell the loader about the change.
+            mLoader.onContentChanged();
+        }
+    }
+
+    /**
+     * A custom Loader that loads all of the installed applications.
+     */
+    public static class AppListLoader extends AsyncTaskLoader<List<AppEntry>> {
+        final InterestingConfigChanges mLastConfig = new InterestingConfigChanges();
+        final PackageManager mPm;
+
+        List<AppEntry> mApps;
+        PackageIntentReceiver mPackageObserver;
+
+        public AppListLoader(Context context) {
+            super(context);
+
+            // Retrieve the package manager for later use; note we don't
+            // use 'context' directly but instead the save global application
+            // context returned by getContext().
+            mPm = getContext().getPackageManager();
+        }
+
+        /**
+         * This is where the bulk of our work is done.  This function is
+         * called in a background thread and should generate a new set of
+         * data to be published by the loader.
+         */
+        @Override public List<AppEntry> loadInBackground() {
+            // Retrieve all known applications.
+            List<ApplicationInfo> apps = mPm.getInstalledApplications(
+                    PackageManager.GET_UNINSTALLED_PACKAGES |
+                    PackageManager.GET_DISABLED_COMPONENTS);
+            if (apps == null) {
+                apps = new ArrayList<ApplicationInfo>();
+            }
+
+            final Context context = getContext();
+
+            // Create corresponding array of entries and load their labels.
+            List<AppEntry> entries = new ArrayList<AppEntry>(apps.size());
+            for (int i=0; i<apps.size(); i++) {
+                AppEntry entry = new AppEntry(this, apps.get(i));
+                entry.loadLabel(context);
+                entries.add(entry);
+            }
+
+            // Sort the list.
+            Collections.sort(entries, ALPHA_COMPARATOR);
+
+            // Done!
+            return entries;
+        }
+
+        /**
+         * Called when there is new data to deliver to the client.  The
+         * super class will take care of delivering it; the implementation
+         * here just adds a little more logic.
+         */
+        @Override public void deliverResult(List<AppEntry> apps) {
+            if (isReset()) {
+                // An async query came in while the loader is stopped.  We
+                // don't need the result.
+                if (apps != null) {
+                    onReleaseResources(apps);
+                }
+            }
+            List<AppEntry> oldApps = apps;
+            mApps = apps;
+
+            if (isStarted()) {
+                // If the Loader is currently started, we can immediately
+                // deliver its results.
+                super.deliverResult(apps);
+            }
+
+            // At this point we can release the resources associated with
+            // 'oldApps' if needed; now that the new result is delivered we
+            // know that it is no longer in use.
+            if (oldApps != null) {
+                onReleaseResources(oldApps);
+            }
+        }
+
+        /**
+         * Handles a request to start the Loader.
+         */
+        @Override protected void onStartLoading() {
+            if (mApps != null) {
+                // If we currently have a result available, deliver it
+                // immediately.
+                deliverResult(mApps);
+            }
+
+            // Start watching for changes in the app data.
+            if (mPackageObserver == null) {
+                mPackageObserver = new PackageIntentReceiver(this);
+            }
+
+            // Has something interesting in the configuration changed since we
+            // last built the app list?
+            boolean configChange = mLastConfig.applyNewConfig(getContext().getResources());
+
+            if (takeContentChanged() || mApps == null || configChange) {
+                // If the data has changed since the last time it was loaded
+                // or is not currently available, start a load.
+                forceLoad();
+            }
+        }
+
+        /**
+         * Handles a request to stop the Loader.
+         */
+        @Override protected void onStopLoading() {
+            // Attempt to cancel the current load task if possible.
+            cancelLoad();
+        }
+
+        /**
+         * Handles a request to cancel a load.
+         */
+        @Override public void onCanceled(List<AppEntry> apps) {
+            super.onCanceled(apps);
+
+            // At this point we can release the resources associated with 'apps'
+            // if needed.
+            onReleaseResources(apps);
+        }
+
+        /**
+         * Handles a request to completely reset the Loader.
+         */
+        @Override protected void onReset() {
+            super.onReset();
+
+            // Ensure the loader is stopped
+            onStopLoading();
+
+            // At this point we can release the resources associated with 'apps'
+            // if needed.
+            if (mApps != null) {
+                onReleaseResources(mApps);
+                mApps = null;
+            }
+
+            // Stop monitoring for changes.
+            if (mPackageObserver != null) {
+                getContext().unregisterReceiver(mPackageObserver);
+                mPackageObserver = null;
+            }
+        }
+
+        /**
+         * Helper function to take care of releasing resources associated
+         * with an actively loaded data set.
+         */
+        protected void onReleaseResources(List<AppEntry> apps) {
+            // For a simple List<> there is nothing to do.  For something
+            // like a Cursor, we would close it here.
+        }
+    }
+//END_INCLUDE(loader)
+
+//BEGIN_INCLUDE(fragment)
+    public static class AppListAdapter extends ArrayAdapter<AppEntry> {
+        private final LayoutInflater mInflater;
+
+        public AppListAdapter(Context context) {
+            super(context, android.R.layout.simple_list_item_2);
+            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        }
+
+        public void setData(List<AppEntry> data) {
+            clear();
+            if (data != null) {
+                addAll(data);
+            }
+        }
+
+        /**
+         * Populate new items in the list.
+         */
+        @Override public View getView(int position, View convertView, ViewGroup parent) {
+            View view;
+
+            if (convertView == null) {
+                view = mInflater.inflate(R.layout.list_item_icon_text, parent, false);
+            } else {
+                view = convertView;
+            }
+
+            AppEntry item = getItem(position);
+            ((ImageView)view.findViewById(R.id.icon)).setImageDrawable(item.getIcon());
+            ((TextView)view.findViewById(R.id.text)).setText(item.getLabel());
+
+            return view;
+        }
+    }
+
+    public static class AppListFragment extends ListFragment
+            implements OnQueryTextListener, LoaderManager.LoaderCallbacks<List<AppEntry>> {
+
+        // This is the Adapter being used to display the list's data.
+        AppListAdapter mAdapter;
+
+        // If non-null, this is the current filter the user has provided.
+        String mCurFilter;
+
+        @Override public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            // Give some text to display if there is no data.  In a real
+            // application this would come from a resource.
+            setEmptyText("No applications");
+
+            // We have a menu item to show in action bar.
+            setHasOptionsMenu(true);
+
+            // Create an empty adapter we will use to display the loaded data.
+            mAdapter = new AppListAdapter(getActivity());
+            setListAdapter(mAdapter);
+
+            // Start out with a progress indicator.
+            setListShown(false);
+
+            // Prepare the loader.  Either re-connect with an existing one,
+            // or start a new one.
+            getLoaderManager().initLoader(0, null, this);
+        }
+
+        @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            // Place an action bar item for searching.
+            MenuItem item = menu.add("Search");
+            item.setIcon(android.R.drawable.ic_menu_search);
+            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            SearchView sv = new SearchView(getActivity());
+            sv.setOnQueryTextListener(this);
+            item.setActionView(sv);
+        }
+
+        @Override public boolean onQueryTextChange(String newText) {
+            // Called when the action bar search text has changed.  Since this
+            // is a simple array adapter, we can just have it do the filtering.
+            mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+            mAdapter.getFilter().filter(mCurFilter);
+            return true;
+        }
+
+        @Override public boolean onQueryTextSubmit(String query) {
+            // Don't care about this.
+            return true;
+        }
+
+        @Override public void onListItemClick(ListView l, View v, int position, long id) {
+            // Insert desired behavior here.
+            Log.i("LoaderCustom", "Item clicked: " + id);
+        }
+
+        @Override public Loader<List<AppEntry>> onCreateLoader(int id, Bundle args) {
+            // This is called when a new Loader needs to be created.  This
+            // sample only has one Loader with no arguments, so it is simple.
+            return new AppListLoader(getActivity());
+        }
+
+        @Override public void onLoadFinished(Loader<List<AppEntry>> loader, List<AppEntry> data) {
+            // Set the new data in the adapter.
+            mAdapter.setData(data);
+
+            // The list should now be shown.
+            setListShown(true);
+        }
+
+        @Override public void onLoaderReset(Loader<List<AppEntry>> loader) {
+            // Clear the data in the adapter.
+            mAdapter.setData(null);
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.java b/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.java
new file mode 100644
index 0000000..1c4c839
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.java
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+//BEGIN_INCLUDE(complete)
+import android.app.Activity;
+import android.app.FragmentManager;
+import android.app.ListFragment;
+import android.app.LoaderManager;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.BaseColumns;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+
+import java.util.HashMap;
+
+/**
+ * Demonstration of bottom to top implementation of a content provider holding
+ * structured data through displaying it in the UI, using throttling to reduce
+ * the number of queries done when its data changes.
+ */
+public class LoaderThrottle extends Activity {
+    // Debugging.
+    static final String TAG = "LoaderThrottle";
+
+    /**
+     * The authority we use to get to our sample provider.
+     */
+    public static final String AUTHORITY = "com.example.android.apis.app.LoaderThrottle";
+
+    /**
+     * Definition of the contract for the main table of our provider.
+     */
+    public static final class MainTable implements BaseColumns {
+
+        // This class cannot be instantiated
+        private MainTable() {}
+
+        /**
+         * The table name offered by this provider
+         */
+        public static final String TABLE_NAME = "main";
+
+        /**
+         * The content:// style URL for this table
+         */
+        public static final Uri CONTENT_URI =  Uri.parse("content://" + AUTHORITY + "/main");
+
+        /**
+         * The content URI base for a single row of data. Callers must
+         * append a numeric row id to this Uri to retrieve a row
+         */
+        public static final Uri CONTENT_ID_URI_BASE
+                = Uri.parse("content://" + AUTHORITY + "/main/");
+
+        /**
+         * The MIME type of {@link #CONTENT_URI}.
+         */
+        public static final String CONTENT_TYPE
+                = "vnd.android.cursor.dir/vnd.example.api-demos-throttle";
+
+        /**
+         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single row.
+         */
+        public static final String CONTENT_ITEM_TYPE
+                = "vnd.android.cursor.item/vnd.example.api-demos-throttle";
+        /**
+         * The default sort order for this table
+         */
+        public static final String DEFAULT_SORT_ORDER = "data COLLATE LOCALIZED ASC";
+
+        /**
+         * Column name for the single column holding our data.
+         * <P>Type: TEXT</P>
+         */
+        public static final String COLUMN_NAME_DATA = "data";
+    }
+
+    /**
+     * This class helps open, create, and upgrade the database file.
+     */
+   static class DatabaseHelper extends SQLiteOpenHelper {
+
+       private static final String DATABASE_NAME = "loader_throttle.db";
+       private static final int DATABASE_VERSION = 2;
+
+       DatabaseHelper(Context context) {
+
+           // calls the super constructor, requesting the default cursor factory.
+           super(context, DATABASE_NAME, null, DATABASE_VERSION);
+       }
+
+       /**
+        *
+        * Creates the underlying database with table name and column names taken from the
+        * NotePad class.
+        */
+       @Override
+       public void onCreate(SQLiteDatabase db) {
+           db.execSQL("CREATE TABLE " + MainTable.TABLE_NAME + " ("
+                   + MainTable._ID + " INTEGER PRIMARY KEY,"
+                   + MainTable.COLUMN_NAME_DATA + " TEXT"
+                   + ");");
+       }
+
+       /**
+        *
+        * Demonstrates that the provider must consider what happens when the
+        * underlying datastore is changed. In this sample, the database is upgraded the database
+        * by destroying the existing data.
+        * A real application should upgrade the database in place.
+        */
+       @Override
+       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+           // Logs that the database is being upgraded
+           Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                   + newVersion + ", which will destroy all old data");
+
+           // Kills the table and existing data
+           db.execSQL("DROP TABLE IF EXISTS notes");
+
+           // Recreates the database with a new version
+           onCreate(db);
+       }
+   }
+
+    /**
+     * A very simple implementation of a content provider.
+     */
+    public static class SimpleProvider extends ContentProvider {
+        // A projection map used to select columns from the database
+        private final HashMap<String, String> mNotesProjectionMap;
+        // Uri matcher to decode incoming URIs.
+        private final UriMatcher mUriMatcher;
+
+        // The incoming URI matches the main table URI pattern
+        private static final int MAIN = 1;
+        // The incoming URI matches the main table row ID URI pattern
+        private static final int MAIN_ID = 2;
+
+        // Handle to a new DatabaseHelper.
+        private DatabaseHelper mOpenHelper;
+
+        /**
+         * Global provider initialization.
+         */
+        public SimpleProvider() {
+            // Create and initialize URI matcher.
+            mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+            mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME, MAIN);
+            mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME + "/#", MAIN_ID);
+
+            // Create and initialize projection map for all columns.  This is
+            // simply an identity mapping.
+            mNotesProjectionMap = new HashMap<String, String>();
+            mNotesProjectionMap.put(MainTable._ID, MainTable._ID);
+            mNotesProjectionMap.put(MainTable.COLUMN_NAME_DATA, MainTable.COLUMN_NAME_DATA);
+        }
+
+        /**
+         * Perform provider creation.
+         */
+        @Override
+        public boolean onCreate() {
+            mOpenHelper = new DatabaseHelper(getContext());
+            // Assumes that any failures will be reported by a thrown exception.
+            return true;
+        }
+
+        /**
+         * Handle incoming queries.
+         */
+        @Override
+        public Cursor query(Uri uri, String[] projection, String selection,
+                String[] selectionArgs, String sortOrder) {
+
+            // Constructs a new query builder and sets its table name
+            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setTables(MainTable.TABLE_NAME);
+
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    // If the incoming URI is for main table.
+                    qb.setProjectionMap(mNotesProjectionMap);
+                    break;
+
+                case MAIN_ID:
+                    // The incoming URI is for a single row.
+                    qb.setProjectionMap(mNotesProjectionMap);
+                    qb.appendWhere(MainTable._ID + "=?");
+                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
+                            new String[] { uri.getLastPathSegment() });
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+
+            if (TextUtils.isEmpty(sortOrder)) {
+                sortOrder = MainTable.DEFAULT_SORT_ORDER;
+            }
+
+            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+            Cursor c = qb.query(db, projection, selection, selectionArgs,
+                    null /* no group */, null /* no filter */, sortOrder);
+
+            c.setNotificationUri(getContext().getContentResolver(), uri);
+            return c;
+        }
+
+        /**
+         * Return the MIME type for an known URI in the provider.
+         */
+        @Override
+        public String getType(Uri uri) {
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    return MainTable.CONTENT_TYPE;
+                case MAIN_ID:
+                    return MainTable.CONTENT_ITEM_TYPE;
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+        }
+
+        /**
+         * Handler inserting new data.
+         */
+        @Override
+        public Uri insert(Uri uri, ContentValues initialValues) {
+            if (mUriMatcher.match(uri) != MAIN) {
+                // Can only insert into to main URI.
+                throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+            ContentValues values;
+
+            if (initialValues != null) {
+                values = new ContentValues(initialValues);
+            } else {
+                values = new ContentValues();
+            }
+
+            if (values.containsKey(MainTable.COLUMN_NAME_DATA) == false) {
+                values.put(MainTable.COLUMN_NAME_DATA, "");
+            }
+
+            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+            long rowId = db.insert(MainTable.TABLE_NAME, null, values);
+
+            // If the insert succeeded, the row ID exists.
+            if (rowId > 0) {
+                Uri noteUri = ContentUris.withAppendedId(MainTable.CONTENT_ID_URI_BASE, rowId);
+                getContext().getContentResolver().notifyChange(noteUri, null);
+                return noteUri;
+            }
+
+            throw new SQLException("Failed to insert row into " + uri);
+        }
+
+        /**
+         * Handle deleting data.
+         */
+        @Override
+        public int delete(Uri uri, String where, String[] whereArgs) {
+            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+            String finalWhere;
+
+            int count;
+
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    // If URI is main table, delete uses incoming where clause and args.
+                    count = db.delete(MainTable.TABLE_NAME, where, whereArgs);
+                    break;
+
+                    // If the incoming URI matches a single note ID, does the delete based on the
+                    // incoming data, but modifies the where clause to restrict it to the
+                    // particular note ID.
+                case MAIN_ID:
+                    // If URI is for a particular row ID, delete is based on incoming
+                    // data but modified to restrict to the given ID.
+                    finalWhere = DatabaseUtils.concatenateWhere(
+                            MainTable._ID + " = " + ContentUris.parseId(uri), where);
+                    count = db.delete(MainTable.TABLE_NAME, finalWhere, whereArgs);
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+            getContext().getContentResolver().notifyChange(uri, null);
+
+            return count;
+        }
+
+        /**
+         * Handle updating data.
+         */
+        @Override
+        public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
+            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+            int count;
+            String finalWhere;
+
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    // If URI is main table, update uses incoming where clause and args.
+                    count = db.update(MainTable.TABLE_NAME, values, where, whereArgs);
+                    break;
+
+                case MAIN_ID:
+                    // If URI is for a particular row ID, update is based on incoming
+                    // data but modified to restrict to the given ID.
+                    finalWhere = DatabaseUtils.concatenateWhere(
+                            MainTable._ID + " = " + ContentUris.parseId(uri), where);
+                    count = db.update(MainTable.TABLE_NAME, values, finalWhere, whereArgs);
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+            getContext().getContentResolver().notifyChange(uri, null);
+
+            return count;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        FragmentManager fm = getFragmentManager();
+
+        // Create the list fragment and add it as our sole content.
+        if (fm.findFragmentById(android.R.id.content) == null) {
+            ThrottledLoaderListFragment list = new ThrottledLoaderListFragment();
+            fm.beginTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+    public static class ThrottledLoaderListFragment extends ListFragment
+            implements LoaderManager.LoaderCallbacks<Cursor> {
+
+        // Menu identifiers
+        static final int POPULATE_ID = Menu.FIRST;
+        static final int CLEAR_ID = Menu.FIRST+1;
+
+        // This is the Adapter being used to display the list's data.
+        SimpleCursorAdapter mAdapter;
+
+        // If non-null, this is the current filter the user has provided.
+        String mCurFilter;
+
+        // Task we have running to populate the database.
+        AsyncTask<Void, Void, Void> mPopulatingTask;
+
+        @Override public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            setEmptyText("No data.  Select 'Populate' to fill with data from Z to A at a rate of 4 per second.");
+            setHasOptionsMenu(true);
+
+            // Create an empty adapter we will use to display the loaded data.
+            mAdapter = new SimpleCursorAdapter(getActivity(),
+                    android.R.layout.simple_list_item_1, null,
+                    new String[] { MainTable.COLUMN_NAME_DATA },
+                    new int[] { android.R.id.text1 }, 0);
+            setListAdapter(mAdapter);
+
+            // Prepare the loader.  Either re-connect with an existing one,
+            // or start a new one.
+            getLoaderManager().initLoader(0, null, this);
+        }
+
+        @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            menu.add(Menu.NONE, POPULATE_ID, 0, "Populate")
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            menu.add(Menu.NONE, CLEAR_ID, 0, "Clear")
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        }
+
+        @Override public boolean onOptionsItemSelected(MenuItem item) {
+            final ContentResolver cr = getActivity().getContentResolver();
+
+            switch (item.getItemId()) {
+                case POPULATE_ID:
+                    if (mPopulatingTask != null) {
+                        mPopulatingTask.cancel(false);
+                    }
+                    mPopulatingTask = new AsyncTask<Void, Void, Void>() {
+                        @Override protected Void doInBackground(Void... params) {
+                            for (char c='Z'; c>='A'; c--) {
+                                if (isCancelled()) {
+                                    break;
+                                }
+                                StringBuilder builder = new StringBuilder("Data ");
+                                builder.append(c);
+                                ContentValues values = new ContentValues();
+                                values.put(MainTable.COLUMN_NAME_DATA, builder.toString());
+                                cr.insert(MainTable.CONTENT_URI, values);
+                                // Wait a bit between each insert.
+                                try {
+                                    Thread.sleep(250);
+                                } catch (InterruptedException e) {
+                                }
+                            }
+                            return null;
+                        }
+                    };
+                    mPopulatingTask.executeOnExecutor(
+                            AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
+                    return true;
+
+                case CLEAR_ID:
+                    if (mPopulatingTask != null) {
+                        mPopulatingTask.cancel(false);
+                        mPopulatingTask = null;
+                    }
+                    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+                        @Override protected Void doInBackground(Void... params) {
+                            cr.delete(MainTable.CONTENT_URI, null, null);
+                            return null;
+                        }
+                    };
+                    task.execute((Void[])null);
+                    return true;
+
+                default:
+                    return super.onOptionsItemSelected(item);
+            }
+        }
+
+        @Override public void onListItemClick(ListView l, View v, int position, long id) {
+            // Insert desired behavior here.
+            Log.i(TAG, "Item clicked: " + id);
+        }
+
+        // These are the rows that we will retrieve.
+        static final String[] PROJECTION = new String[] {
+            MainTable._ID,
+            MainTable.COLUMN_NAME_DATA,
+        };
+
+        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+            CursorLoader cl = new CursorLoader(getActivity(), MainTable.CONTENT_URI,
+                    PROJECTION, null, null, null);
+            cl.setUpdateThrottle(2000); // update at most every 2 seconds.
+            return cl;
+        }
+
+        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+            mAdapter.swapCursor(data);
+        }
+
+        public void onLoaderReset(Loader<Cursor> loader) {
+            mAdapter.swapCursor(null);
+        }
+    }
+}
+//END_INCLUDE(complete)
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java b/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java
deleted file mode 100644
index 967c181..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.app;
-
-import com.example.android.apis.R;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.preference.Preference;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.TextView;
-
-/**
- * This is an example of a custom preference type. The preference counts the
- * number of clicks it has received and stores/retrieves it from the storage.
- */
-public class MyPreference extends Preference {
-    private int mClickCounter;
-    
-    // This is the constructor called by the inflater
-    public MyPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        
-        setWidgetLayoutResource(R.layout.preference_widget_mypreference);        
-    }
-
-    @Override
-    protected void onBindView(View view) {
-        super.onBindView(view);
-        
-        // Set our custom views inside the layout
-        final TextView myTextView = (TextView) view.findViewById(R.id.mypreference_widget);
-        if (myTextView != null) {
-            myTextView.setText(String.valueOf(mClickCounter));
-        }
-    }
-
-    @Override
-    protected void onClick() {
-        int newValue = mClickCounter + 1;
-        // Give the client a chance to ignore this change if they deem it
-        // invalid
-        if (!callChangeListener(newValue)) {
-            // They don't want the value to be set
-            return;
-        }
-        
-        // Increment counter
-        mClickCounter = newValue;
-        
-        // Save to persistent storage (this method will make sure this
-        // preference should be persistent, along with other useful checks)
-        persistInt(mClickCounter);
-        
-        // Data has changed, notify so UI can be refreshed!
-        notifyChanged();
-    }
-
-    @Override
-    protected Object onGetDefaultValue(TypedArray a, int index) {
-        // This preference type's value type is Integer, so we read the default
-        // value from the attributes as an Integer.
-        return a.getInteger(index, 0);
-    }
-
-    @Override
-    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
-        if (restoreValue) {
-            // Restore state
-            mClickCounter = getPersistedInt(mClickCounter);
-        } else {
-            // Set state
-            int value = (Integer) defaultValue;
-            mClickCounter = value;
-            persistInt(value);
-        }
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        /*
-         * Suppose a client uses this preference type without persisting. We
-         * must save the instance state so it is able to, for example, survive
-         * orientation changes.
-         */
-        
-        final Parcelable superState = super.onSaveInstanceState();
-        if (isPersistent()) {
-            // No need to save instance state since it's persistent
-            return superState;
-        }
-
-        // Save the instance state
-        final SavedState myState = new SavedState(superState);
-        myState.clickCounter = mClickCounter;
-        return myState;
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        if (!state.getClass().equals(SavedState.class)) {
-            // Didn't save state for us in onSaveInstanceState
-            super.onRestoreInstanceState(state);
-            return;
-        }
-     
-        // Restore the instance state
-        SavedState myState = (SavedState) state;
-        super.onRestoreInstanceState(myState.getSuperState());
-        mClickCounter = myState.clickCounter;
-        notifyChanged();
-    }
-    
-    /**
-     * SavedState, a subclass of {@link BaseSavedState}, will store the state
-     * of MyPreference, a subclass of Preference.
-     * <p>
-     * It is important to always call through to super methods.
-     */
-    private static class SavedState extends BaseSavedState {
-        int clickCounter;
-        
-        public SavedState(Parcel source) {
-            super(source);
-            
-            // Restore the click counter
-            clickCounter = source.readInt();
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            super.writeToParcel(dest, flags);
-            
-            // Save the click counter
-            dest.writeInt(clickCounter);
-        }
-
-        public SavedState(Parcelable superState) {
-            super(superState);
-        }
-
-        public static final Parcelable.Creator<SavedState> CREATOR =
-                new Parcelable.Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-    
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
deleted file mode 100644
index 27c22de..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.app;
-
-import com.example.android.apis.R;
-
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-
-public class PreferenceDependencies extends PreferenceActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        addPreferencesFromResource(R.xml.preference_dependencies);
-    }
-
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java
deleted file mode 100644
index be22b49..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.app;
-
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.net.Uri;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
-import android.preference.ListPreference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceCategory;
-import android.preference.PreferenceScreen;
-
-import com.example.android.apis.R;
-
-public class PreferencesFromCode extends PreferenceActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        setPreferenceScreen(createPreferenceHierarchy());
-    }
-
-    private PreferenceScreen createPreferenceHierarchy() {
-        // Root
-        PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
-        
-        // Inline preferences 
-        PreferenceCategory inlinePrefCat = new PreferenceCategory(this);
-        inlinePrefCat.setTitle(R.string.inline_preferences);
-        root.addPreference(inlinePrefCat);
-        
-        // Toggle preference
-        CheckBoxPreference togglePref = new CheckBoxPreference(this);
-        togglePref.setKey("toggle_preference");
-        togglePref.setTitle(R.string.title_toggle_preference);
-        togglePref.setSummary(R.string.summary_toggle_preference);
-        inlinePrefCat.addPreference(togglePref);
-                
-        // Dialog based preferences
-        PreferenceCategory dialogBasedPrefCat = new PreferenceCategory(this);
-        dialogBasedPrefCat.setTitle(R.string.dialog_based_preferences);
-        root.addPreference(dialogBasedPrefCat);
-
-        // Edit text preference
-        EditTextPreference editTextPref = new EditTextPreference(this);
-        editTextPref.setDialogTitle(R.string.dialog_title_edittext_preference);
-        editTextPref.setKey("edittext_preference");
-        editTextPref.setTitle(R.string.title_edittext_preference);
-        editTextPref.setSummary(R.string.summary_edittext_preference);
-        dialogBasedPrefCat.addPreference(editTextPref);
-        
-        // List preference
-        ListPreference listPref = new ListPreference(this);
-        listPref.setEntries(R.array.entries_list_preference);
-        listPref.setEntryValues(R.array.entryvalues_list_preference);
-        listPref.setDialogTitle(R.string.dialog_title_list_preference);
-        listPref.setKey("list_preference");
-        listPref.setTitle(R.string.title_list_preference);
-        listPref.setSummary(R.string.summary_list_preference);
-        dialogBasedPrefCat.addPreference(listPref);
-        
-        // Launch preferences
-        PreferenceCategory launchPrefCat = new PreferenceCategory(this);
-        launchPrefCat.setTitle(R.string.launch_preferences);
-        root.addPreference(launchPrefCat);
-
-        /*
-         * The Preferences screenPref serves as a screen break (similar to page
-         * break in word processing). Like for other preference types, we assign
-         * a key here so that it is able to save and restore its instance state.
-         */
-        // Screen preference
-        PreferenceScreen screenPref = getPreferenceManager().createPreferenceScreen(this);
-        screenPref.setKey("screen_preference");
-        screenPref.setTitle(R.string.title_screen_preference);
-        screenPref.setSummary(R.string.summary_screen_preference);
-        launchPrefCat.addPreference(screenPref);
-        
-        /*
-         * You can add more preferences to screenPref that will be shown on the
-         * next screen.
-         */
-        
-        // Example of next screen toggle preference
-        CheckBoxPreference nextScreenCheckBoxPref = new CheckBoxPreference(this);
-        nextScreenCheckBoxPref.setKey("next_screen_toggle_preference");
-        nextScreenCheckBoxPref.setTitle(R.string.title_next_screen_toggle_preference);
-        nextScreenCheckBoxPref.setSummary(R.string.summary_next_screen_toggle_preference);
-        screenPref.addPreference(nextScreenCheckBoxPref);
-        
-        // Intent preference
-        PreferenceScreen intentPref = getPreferenceManager().createPreferenceScreen(this);
-        intentPref.setIntent(new Intent().setAction(Intent.ACTION_VIEW)
-                .setData(Uri.parse("http://www.android.com")));
-        intentPref.setTitle(R.string.title_intent_preference);
-        intentPref.setSummary(R.string.summary_intent_preference);
-        launchPrefCat.addPreference(intentPref);
-        
-        // Preference attributes
-        PreferenceCategory prefAttrsCat = new PreferenceCategory(this);
-        prefAttrsCat.setTitle(R.string.preference_attributes);
-        root.addPreference(prefAttrsCat);
-        
-        // Visual parent toggle preference
-        CheckBoxPreference parentCheckBoxPref = new CheckBoxPreference(this);
-        parentCheckBoxPref.setTitle(R.string.title_parent_preference);
-        parentCheckBoxPref.setSummary(R.string.summary_parent_preference);
-        prefAttrsCat.addPreference(parentCheckBoxPref);
-        
-        // Visual child toggle preference
-        // See res/values/attrs.xml for the <declare-styleable> that defines
-        // TogglePrefAttrs.
-        TypedArray a = obtainStyledAttributes(R.styleable.TogglePrefAttrs);
-        CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this);
-        childCheckBoxPref.setTitle(R.string.title_child_preference);
-        childCheckBoxPref.setSummary(R.string.summary_child_preference);
-        childCheckBoxPref.setLayoutResource(
-                a.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild,
-                        0));
-        prefAttrsCat.addPreference(childCheckBoxPref);
-        a.recycle();
-        
-        return root;
-    }
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
deleted file mode 100644
index 63bbac2..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.app;
-
-import com.example.android.apis.R;
-
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-
-public class PreferencesFromXml extends PreferenceActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        // Load the preferences from an XML resource
-        addPreferencesFromResource(R.xml.preferences);
-    }
-
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SoftInputModes.java b/samples/ApiDemos/src/com/example/android/apis/app/SoftInputModes.java
new file mode 100644
index 0000000..8c6dcc3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SoftInputModes.java
@@ -0,0 +1,67 @@
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+/**
+ * Demonstrates how the various soft input modes impact window resizing.
+ */
+public class SoftInputModes extends Activity {
+    Spinner mResizeMode;
+    final CharSequence[] mResizeModeLabels = new CharSequence[] {
+            "Unspecified", "Resize", "Pan", "Nothing"
+    };
+    final int[] mResizeModeValues = new int[] {
+            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED,
+            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN,
+            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING,
+    };
+    
+    /**
+     * Initialization of the Activity after it is first created.  Here we use
+     * {@link android.app.Activity#setContentView setContentView()} to set up
+     * the Activity's content, and retrieve the EditText widget whose state we
+     * will persistent.
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/save_restore_state.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.soft_input_modes);
+        
+        mResizeMode = (Spinner)findViewById(R.id.resize_mode);
+        ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
+                android.R.layout.simple_spinner_item, mResizeModeLabels);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mResizeMode.setAdapter(adapter);
+        mResizeMode.setSelection(0);
+        mResizeMode.setOnItemSelectedListener(
+                new OnItemSelectedListener() {
+                    public void onItemSelected(
+                            AdapterView<?> parent, View view, int position, long id) {
+                        getWindow().setSoftInputMode(mResizeModeValues[position]);
+                    }
+
+                    public void onNothingSelected(AdapterView<?> parent) {
+                        getWindow().setSoftInputMode(mResizeModeValues[0]);
+                    }
+                });
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java b/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
index 9b911cc..7179b25 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
@@ -22,6 +22,7 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -148,15 +149,47 @@
         // The PendingIntent to launch our activity if the user selects this
         // notification.  Note the use of FLAG_UPDATE_CURRENT so that if there
         // is already an active matching pending intent, we will update its
-        // extras to be the ones passed in here.
+        // extras (and other Intents in the array) to be the ones passed in here.
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
-                new Intent(this, NotificationDisplay.class)
-                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-                        .putExtra("moodimg", moodId),
+                new Intent(this, NotificationDisplay.class).putExtra("moodimg", moodId),
                 PendingIntent.FLAG_UPDATE_CURRENT);
         return contentIntent;
     }
     
+//BEGIN_INCLUDE(intent_array)
+    private PendingIntent makeDefaultIntent() {
+        // A typical convention for notifications is to launch the user deeply
+        // into an application representing the data in the notification; to
+        // accomplish this, we can build an array of intents to insert the back
+        // stack stack history above the item being displayed.
+        Intent[] intents = new Intent[4];
+
+        // First: root activity of ApiDemos.
+        // This is a convenient way to make the proper Intent to launch and
+        // reset an application's task.
+        intents[0] = Intent.makeRestartActivityTask(new ComponentName(this,
+                com.example.android.apis.ApiDemos.class));
+
+        // "App"
+        intents[1] = new Intent(this, com.example.android.apis.ApiDemos.class);
+        intents[1].putExtra("com.example.android.apis.Path", "App");
+        // "App/Notification"
+        intents[2] = new Intent(this, com.example.android.apis.ApiDemos.class);
+        intents[2].putExtra("com.example.android.apis.Path", "App/Notification");
+
+        // Now the activity to display to the user.
+        intents[3] = new Intent(this, StatusBarNotifications.class);
+
+        // The PendingIntent to launch our activity if the user selects this
+        // notification.  Note the use of FLAG_UPDATE_CURRENT so that if there
+        // is already an active matching pending intent, we will update its
+        // extras (and other Intents in the array) to be the ones passed in here.
+        PendingIntent contentIntent = PendingIntent.getActivities(this, 0,
+                intents, PendingIntent.FLAG_UPDATE_CURRENT);
+        return contentIntent;
+    }
+//END_INCLUDE(intent_array)
+
     private void setMood(int moodId, int textId, boolean showTicker) {
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(textId);
@@ -210,8 +243,7 @@
         // This method sets the defaults on the notification before posting it.
         
         // This is who should be launched if the user selects our notification.
-        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
-                new Intent(this, StatusBarNotifications.class), 0);
+        PendingIntent contentIntent = makeDefaultIntent();
 
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(R.string.status_bar_notifications_happy_message);
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/_index.html b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
index fff5ce2..71ccb54 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
@@ -1,5 +1,18 @@
 
-<h3>Activity</h3>
+<p>This section includes samples for:</p>
+<ul>
+  <li><a href="#Activity">Activity</a></li>
+  <li><a href="#Fragment">Fragment</a></li>
+  <li><a href="#ActionBar">Action Bar</a></li>
+  <li><a href="#LoaderManager">LoaderManager</a></li>
+  <li><a href="#Alarm">Alarm</a></li>
+  <li><a href="#Notification">Notification</a></li>
+  <li><a href="#Search">Search</a></li>
+  <li><a href="#Misc">Misc</a></li>
+</ul>
+
+
+<h3 id="Activity">Activity</h3>
 <dl>
   <dt><a href="HelloWorld.html">Hello World</a></dt>
   <dd>Demonstrates a basic screen activity.
@@ -37,47 +50,166 @@
   <dt><a href="TranslucentBlurActivity.html">TranslucentBlur</a></dt>
   <dd>Demonstrates how to make an activity with a transparent background with
   a special effect (blur). </dd>
+
+  <dt><a href="DialogActivity.html">Dialog Activity</a></dt>
+  <dd>An Activity that sets its theme to android:style/Theme.Dialog so that
+  it looks like a Dialog.</dd>
+
+  <dt><a href="CustomTitle.html">Custom Title</a></dt>
+  <dd>An Activity that places a custom UI in its title.</dd>
+
+  <dt><a href="Animation.html">Animation</a></dt>
+  <dd>Demonstrates how to use custom animations when moving between activities. </dd>
+
+  <dt><a href="ActivityRecreate.html">Activity Recreate</a></dt>
+  <dd>Demonstrates how an Activity can cause itself to be recreated.</dd>
+
+  <dt><a href="ScreenOrientation.html">Screen Orientation</a></dt>
+  <dd>Demonstrates the different screen orientations an Activity can request.</dd>
+
+  <dt><a href="SoftInputModes.html">Soft Input Modes</a></dt>
+  <dd>Demonstrates how different soft input modes set in an Activity's
+  window impacts how it adjusts to accommodate an IME.</dd>
+
+  <dt><a href="IntentActivityFlags.html">Intent Activity Flags</a></dt>
+  <dd>Demonstrates various uses of Intent flags to modify an application
+  task's activity stack in common ways.</dd>
+
+  <dt><a href="ReorderOnLaunch.html">Reorder on Launch</a></dt>
+  <dd>Demonstrates how the activities in a task can be reordered.  UI flow
+  goes through the activities <a href="ReorderOnLaunch.html">ReorderOnLaunch</a>,
+  <a href="ReorderTwo.html">ReorderTwo</a>, <a href="ReorderThree.html">ReorderThree</a>,
+  and <a href="ReorderFour.html">ReorderFour</a>.</dd>
+
+  <dt><a href="WallpaperActivity.html">Wallpaper Activity</a></dt>
+  <dd>An Activity that uses android:style/Theme.Wallpaper to be displayed
+  on top of the system wallpaper.</dd>
 </dl>
 
-<h3>Service</h3>
+<h3 id="Fragment">Fragment</h3>
 <dl>
-  <dt><a href="LocalService.html">Local Service Controller and
-        Local Service Binding</a></dt>
+  <dt><a href="FragmentAlertDialog.html">Fragment Alert Dialog</a></dt>
+  <dd>Demonstrates how to use a DialogFragment to show and manage an
+  AlertDialog.</dd>
+  
+  <dt><a href="FragmentArguments.html">Fragment Arguments</a></dt>
+  <dd>Demonstrates how a fragment can be initialized with arguments,
+  supplying them either as an argument Bundle at runtime or XML attributes
+  in a &lt;fragment> tag.</dd>
+  
+  <dt><a href="FragmentContextMenu.html">Fragment Context Menu</a></dt>
+  <dd>Demonstrates how to display and respond to a context menu that is
+  display from a fragment's view hierarchy.</dd>
+  
+  <dt><a href="FragmentDialog.html">Fragment Dialog</a></dt>
+  <dd>Demonstrates use of DialogFragment to show various types of dialogs.</dd>
+  
+  <dt><a href="FragmentDialogOrActivity.html">Fragment Dialog or Activity</a></dt>
+  <dd>Demonstrates how the same Fragment implementation can be used to provide the UI
+  for either an Activity or Dialog.</dd>
+  
+  <dt><a href="FragmentHideShow.html">Fragment Hide Show</a></dt>
+  <dd>Demonstrates hiding and showing fragments.</dd>
+  
+  <dt><a href="FragmentLayout.html">Fragment Layout</a></dt>
+  <dd>Demonstrates use of the &lt;fragment&gt; tag to embed a Fragment in
+  an Activity's content view layout, and making the layout change based on
+  configuration to achieve different UI flows.</dd>
+  
+  <dt><a href="FragmentListArray.html">Fragment List Array</a></dt>
+  <dd>Demonstrates use of ListFragment to show the contents of a simple ArrayAdapter.</dd>
+  
+  <dt><a href="FragmentMenu.html">Fragment Menu</a></dt>
+  <dd>Demonstrates populating custom menu items from a Fragment.</dd>
+  
+  <dt><a href="FragmentReceiveResult.html">Fragment Receive Result</a></dt>
+  <dd>Demonstrates starting a new Activity from a Fragment, and receiving
+  a result back from it.</dd>
+  
+  <dt><a href="FragmentRetainInstance.html">Fragment Retain Instance</a></dt>
+  <dd>Demonstrates a Fragment can be used to easily retain active state across
+  an Activity's configuration change.</dd>
+  
+  <dt><a href="FragmentStack.html">Fragment Stack</a></dt>
+  <dd>Demonstrates creating a stack of Fragment instances similar to the
+  traditional stack of activities.</dd>
+  
+</dl>
+
+
+<h3 id="ActionBar">Action Bar</h3>
+<dl>
+  <dt><a href="ActionBarMechanics.html">Action Bar Mechanics</a></dt>
+  <dd>Demonstrates the basics of the Action Bar and how it interoperates with the standard options
+menu. This demo is for informative purposes only; see Usage for an example of using the
+Action Bar in a more idiomatic manner.</dd>
+  <dt><a href="ActionBarTabs.html">Action Bar Tabs</a></dt>
+  <dd>Demonstrates the use of Action Bar tabs and how they interact with other action bar
+features.</dd>
+  <dt><a href="ActionBarUsage.html">Action Bar Usage</a></dt>
+  <dd>Demonstrates imple usage of the Action Bar, including a SearchView as an action item. The
+default Honeycomb theme includes the Action Bar by default and a menu resource is used to populate
+the menu data itself. If you'd like to see how these things work under the hood, see
+Mechanics.</dd>
+  <dt><a href="ActionBarDisplayOptions.html">Display Options</a></dt>
+  <dd>Shows how various Action Bar display option flags can be combined and their effects.</dd>
+</dl>
+
+
+<h3 id="LoaderManager">LoaderManager</h3>
+<dl>
+  <dt><a href="LoaderCursor.html">Loader Cursor</a></dt>
+  <dd>Demonstrates use of LoaderManager to perform a query for a Cursor that
+  populates a ListFragment.</dd>
+
+  <dt><a href="LoaderThrottle.html">Loader Throttle</a></dt>
+  <dd>Complete end-to-end demonstration of a simple content provider that
+  populates data in a list through a cursor loader.  The UI allows the list
+  to be populated with a series of items, showing how AsyncTaskLoader's
+  throttling facility can be used to control how much a Loader is refreshed
+  in this case.</dd>
+</dl>
+  
+<h3 id="Service">Service</h3>
+<dl>
+  <dt><a href="LocalService.html">Local Service</a></dt>
   <dd>Demonstrate the implementation of a service that runs in the same
   process as its client(s).  Shows how those clients can either start/stop it
-  with {@link android.content.Context#startService
-  Context.startService} and {@link android.content.Context#stopService
-  Context.stopService}, or bind and call it with
-  {@link android.content.Context#bindService Context.bindService} and
-  {@link android.content.Context#unbindService Context.unindService}.
+  with Context.startService and Context.stopService, or bind and call it with
+  Context.bindService and Context.unindService.
   This also shows how you can simplify working
-  with a service when you know it will only run in your own process.</dd>
+  with a service when you know it will only run in your own process.  The client
+  code for interacting with the service is in
+  <a href="LocalServiceActivities.html">Local Service Activities</a>.</dd>
+  
+  <dt><a href="MessengerService.html">Messenger Service</a></dt>
+  <dd>Demonstrates binding to a Service whose interface is implemented with
+  the Messenger class.  This is often an easier way to do remote communication
+  with a Service than using a raw AIDL interface.  The client
+  code for interacting with the service is in
+  <a href="MessengerServiceActivities.html">Messenger Service Activities</a>.</dd>
   
   <dt><a href="RemoteService.html">Remote Service Controller and
         Remove Service Binding</a></dt>
   <dd>Demonstrates starting a service in a separate process, by assigning
   <code>android:process=&quot;:remote&quot;</code> to the service in the
   AndroidManifest.xml file.  Shows how those clients can either start/stop it
-  with {@link android.content.Context#startService
-  Context.startService} and {@link android.content.Context#stopService
-  Context.stopService}, or bind and call it with
-  {@link android.content.Context#bindService Context.bindService} and
-  {@link android.content.Context#unbindService Context.unindService}.
+  with Context.startService and Context.stopService, or bind and call it with
+  Context.bindService and Context.unindService.
   Binding is similar to the local service sample,
   but illustrates the additional work (defining aidl
   interfaces) needed to interact with a service in another process.  Also
   shows how a service can publish multiple interfaces and implement
   callbacks to its clients.</dd>
 
-  <dt><a href="ServiceStartArguments.html">Service Start Arguments Controller</a></dt>
+  <dt><a href="ServiceStartArguments.html">Service Start Arguments</a></dt>
   <dd>Demonstrates how you can use a Service as a job queue, where you 
-  submit jobs to it with {@link android.content.Context#startService
-  Context.startService} instead of binding to the service.  Such a service
+  submit jobs to it with Context.startService instead of binding to the service.  Such a service
   automatically stops itself once all jobs have been processed.  This can be
   a very convenient way to interact with a service when you do not need
   a result back from it.</dd>
   
-  <dt><a href="ForegroundService.html">Foreground Service Controller</a></dt>
+  <dt><a href="ForegroundService.html">Foreground Service</a></dt>
   <dd>Shows how you
   can write a Service that runs in the foreground and works on both pre-2.0
   and post-2.0 versions of the platform.  This example will selectively use
@@ -86,7 +218,7 @@
 
 </dl>
 
-<h3>Alarm</h3>
+<h3 id="Alarm">Alarm</h3>
 <dl>
   <dt><a href="AlarmController.html">Alarm Controller</a></dt>
   <dd>Demonstrates two ways you can schedule alarms: a one-shot alarm that
@@ -119,16 +251,20 @@
   </dd>
 </dl>
 
-<h3>Notification</h3>
+<h3 id="Notification">Notification</h3>
 <dl>
   <dt><a href="NotifyWithText.html">NotifyWithText</a></dt>
   <dd>Demonstrates popup notifications of varying length.</dd>
 
   <dt><a href="IncomingMessage.html">IncomingMessage</a></dt>
   <dd> Demonstrates sending persistent and transient notifications, with a View object in the notification. It also demonstrated inflating a View object from an XML layout resource. </dd>
+
+  <dt><a href="StatusBarNotifications.html">Status Bar Notifications</a></dt>
+  <dd> Demonstrates a variety of different notifications that can be posted in
+  the status bar, and a standard way for handling them.</dd>
 </dl>
 
-<h3>Search</h3>
+<h3 id="Search">Search</h3>
 <dl>
   <dt><a href="SearchInvoke.html">SearchInvoke</a></dt>
   <dd>Demonstrates various ways in which activities can launch the Search UI.</dd>
@@ -141,3 +277,12 @@
 </dl>
 
 
+<h3 id="Misc">Misc</h3>
+<dl>
+  <dt><a href="AlertDialogSamples.html">Alert Dialog Samples</a></dt>
+  <dd>Demonstrates various styles of alert dialogs.</dd>
+  
+  <dt><a href="DeviceAdminSample.html">Device Admin Sample</a></dt>
+  <dd>Demonstration of the implementation of a simple device administrator
+  and its use of the DevicePolicyManager.</dd>
+</dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.java b/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.java
new file mode 100644
index 0000000..e988902
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.java
@@ -0,0 +1,144 @@
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.content;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+public class ClipboardSample extends Activity {
+    ClipboardManager mClipboard;
+
+    Spinner mSpinner;
+    TextView mMimeTypes;
+    EditText mEditText;
+
+    CharSequence mStyledText;
+    String mPlainText;
+
+    ClipboardManager.OnPrimaryClipChangedListener mPrimaryChangeListener
+            = new ClipboardManager.OnPrimaryClipChangedListener() {
+        public void onPrimaryClipChanged() {
+            updateClipData();
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mClipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
+
+        // See res/any/layout/resources.xml for this view layout definition.
+        setContentView(R.layout.clipboard);
+
+        TextView tv;
+
+        mStyledText = getText(R.string.styled_text);
+        tv = (TextView)findViewById(R.id.styled_text);
+        tv.setText(mStyledText);
+
+        mPlainText = mStyledText.toString();
+        tv = (TextView)findViewById(R.id.plain_text);
+        tv.setText(mPlainText);
+
+        mSpinner = (Spinner) findViewById(R.id.clip_type);
+        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
+                this, R.array.clip_data_types, android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mSpinner.setAdapter(adapter);
+        mSpinner.setOnItemSelectedListener(
+                new OnItemSelectedListener() {
+                    public void onItemSelected(
+                            AdapterView<?> parent, View view, int position, long id) {
+                    }
+                    public void onNothingSelected(AdapterView<?> parent) {
+                    }
+                });
+
+        mMimeTypes = (TextView)findViewById(R.id.clip_mime_types);
+        mEditText = (EditText)findViewById(R.id.clip_text);
+
+        mClipboard.addPrimaryClipChangedListener(mPrimaryChangeListener);
+        updateClipData();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mClipboard.removePrimaryClipChangedListener(mPrimaryChangeListener);
+    }
+
+    public void pasteStyledText(View button) {
+        mClipboard.setPrimaryClip(ClipData.newPlainText("Styled Text", mStyledText));
+    }
+
+    public void pastePlainText(View button) {
+        mClipboard.setPrimaryClip(ClipData.newPlainText("Styled Text", mPlainText));
+    }
+
+    public void pasteIntent(View button) {
+        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.android.com/"));
+        mClipboard.setPrimaryClip(ClipData.newIntent("VIEW intent", intent));
+    }
+
+    public void pasteUri(View button) {
+        mClipboard.setPrimaryClip(ClipData.newRawUri("URI", Uri.parse("http://www.android.com/")));
+    }
+
+    void updateClipData() {
+        ClipData clip = mClipboard.getPrimaryClip();
+        String[] mimeTypes = clip != null ? clip.getDescription().filterMimeTypes("*/*") : null;
+        mMimeTypes.setText("");
+        if (mimeTypes != null) {
+            for (int i=0; i<mimeTypes.length; i++) {
+                mMimeTypes.append(mimeTypes[i]);
+                mMimeTypes.append("\n");
+            }
+        }
+        if (clip == null) {
+            mSpinner.setSelection(0);
+            mEditText.setText("");
+        } else if (clip.getItemAt(0).getText() != null) {
+            mSpinner.setSelection(1);
+            mEditText.setText(clip.getItemAt(0).getText());
+        } else if (clip.getItemAt(0).getIntent() != null) {
+            mSpinner.setSelection(2);
+            mEditText.setText(clip.getItemAt(0).getIntent().toUri(0));
+        } else if (clip.getItemAt(0).getUri() != null) {
+            mSpinner.setSelection(3);
+            mEditText.setText(clip.getItemAt(0).getUri().toString());
+        } else {
+            mSpinner.setSelection(0);
+            mEditText.setText("Clip containing no data");
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ResourcesSample.java b/samples/ApiDemos/src/com/example/android/apis/content/ResourcesSample.java
index f38be0f..d46a851 100755
--- a/samples/ApiDemos/src/com/example/android/apis/content/ResourcesSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ResourcesSample.java
@@ -38,11 +38,9 @@
  * @see StyledText for more depth about using styled text, both with getString()
  *                 and in the layout xml files.
  */
-public class ResourcesSample extends Activity
-{
+public class ResourcesSample extends Activity {
     @Override
-	protected void onCreate(Bundle savedInstanceState)
-    {
+	protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         // See res/any/layout/resources.xml for this view layout definition.
@@ -54,8 +52,8 @@
 
         // ====== Using the Context.getString() convenience method ===========
 
-        // Using the getString() conevenience method, retrieve a string
-        // resource that hapepns to have style information.  Note the use of
+        // Using the getString() convenience method, retrieve a string
+        // resource that happens to have style information.  Note the use of
         // CharSequence instead of String so we don't lose the style info.
         cs = getText(R.string.styled_text);
         tv = (TextView)findViewById(R.id.styled_text);
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ResourcesWidthAndHeight.java b/samples/ApiDemos/src/com/example/android/apis/content/ResourcesWidthAndHeight.java
new file mode 100644
index 0000000..6c64e95
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ResourcesWidthAndHeight.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.content;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class ResourcesWidthAndHeight extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // This layout uses different configurations to adjust
+        // what is shown based on the current screen width and height.
+        setContentView(R.layout.resources_width_and_height);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
index fcfd28f..321eb08 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
@@ -68,8 +68,6 @@
         public MyView(Context c) {
             super(c);
 
-            mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
-            mCanvas = new Canvas(mBitmap);
             mPath = new Path();
             mBitmapPaint = new Paint(Paint.DITHER_FLAG);
         }
@@ -77,6 +75,8 @@
         @Override
         protected void onSizeChanged(int w, int h, int oldw, int oldh) {
             super.onSizeChanged(w, h, oldw, oldh);
+            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+            mCanvas = new Canvas(mBitmap);
         }
 
         @Override
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
index 7d7cd4a..f678324 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
@@ -26,8 +26,10 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mGLView = new GLSurfaceView(this);
-        mGLView.setEGLConfigChooser(false);
         mGLView.setRenderer(new StaticTriangleRenderer(this));
+        /*ImageView imageView = new ImageView(this);
+        imageView.setImageResource(R.raw.robot);
+        setContentView(imageView);*/
         setContentView(mGLView);
     }
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.java b/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.java
index f29c268..3fefe0f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.java
+++ b/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.java
@@ -87,6 +87,7 @@
     @Override
     public void onPause() {
         super.onPause();
-        mAdapter.disableForegroundDispatch(this);
+        //mAdapter.disableForegroundDispatch(this);
+        throw new RuntimeException("onPause not implemented to fix build");
     }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/AdvancedPreferences.java b/samples/ApiDemos/src/com/example/android/apis/preference/AdvancedPreferences.java
new file mode 100644
index 0000000..0328b03
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/AdvancedPreferences.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.R;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceActivity;
+import android.preference.CheckBoxPreference;
+import android.widget.Toast;
+
+/**
+ * Example that shows finding a preference from the hierarchy and a custom preference type.
+ */
+public class AdvancedPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {
+    public static final String KEY_MY_PREFERENCE = "my_preference";
+    public static final String KEY_ADVANCED_CHECKBOX_PREFERENCE = "advanced_checkbox_preference";
+
+    private CheckBoxPreference mCheckBoxPreference;
+    private Handler mHandler = new Handler();
+
+    /**
+     * This is a simple example of controlling a preference from code.
+     */
+    private Runnable mForceCheckBoxRunnable = new Runnable() {
+        public void run() {
+            if (mCheckBoxPreference != null) {
+                mCheckBoxPreference.setChecked(!mCheckBoxPreference.isChecked());
+            }
+
+            // Force toggle again in a second
+            mHandler.postDelayed(this, 1000);
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Load the XML preferences file
+        addPreferencesFromResource(R.xml.advanced_preferences);
+
+        // Get a reference to the checkbox preference
+        mCheckBoxPreference = (CheckBoxPreference)getPreferenceScreen().findPreference(
+                KEY_ADVANCED_CHECKBOX_PREFERENCE);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // Start the force toggle
+        mForceCheckBoxRunnable.run();
+
+        // Set up a listener whenever a key changes
+        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // Unregister the listener whenever a key changes
+        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+
+        mHandler.removeCallbacks(mForceCheckBoxRunnable);
+    }
+
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        // Let's do something when my counter preference value changes
+        if (key.equals(KEY_MY_PREFERENCE)) {
+            Toast.makeText(this, "Thanks! You increased my count to "
+                    + sharedPreferences.getInt(key, 0), Toast.LENGTH_SHORT).show();
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/DefaultValues.java b/samples/ApiDemos/src/com/example/android/apis/preference/DefaultValues.java
new file mode 100644
index 0000000..69cf499
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/DefaultValues.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.ApiDemosApplication;
+import com.example.android.apis.R;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+/**
+ * This activity is an example of a simple settings screen that has default
+ * values.
+ * <p>
+ * In order for the default values to be populated into the
+ * {@link SharedPreferences} (from the preferences XML file), the client must
+ * call
+ * {@link PreferenceManager#setDefaultValues(android.content.Context, int, boolean)}.
+ * <p>
+ * This should be called early, typically when the application is first created.
+ * This ensures any of the application's activities, services, etc. will have
+ * the default values present, even if the user has not wandered into the
+ * application's settings. For ApiDemos, this is {@link ApiDemosApplication},
+ * and you can find the call to
+ * {@link PreferenceManager#setDefaultValues(android.content.Context, int, boolean)}
+ * in its {@link ApiDemosApplication#onCreate() onCreate}.
+ */
+public class DefaultValues extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.default_values);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java b/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java
new file mode 100644
index 0000000..6e9c614
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+
+/**
+ * Demonstration of PreferenceFragment, showing a single fragment in an
+ * activity.
+ */
+public class FragmentPreferences extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Display the fragment as the main content.
+        getFragmentManager().beginTransaction().replace(android.R.id.content,
+                new PrefsFragment()).commit();
+    }
+
+//BEGIN_INCLUDE(fragment)
+    public static class PrefsFragment extends PreferenceFragment {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            // Load the preferences from an XML resource
+            addPreferencesFromResource(R.xml.preferences);
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/LaunchingPreferences.java b/samples/ApiDemos/src/com/example/android/apis/preference/LaunchingPreferences.java
new file mode 100644
index 0000000..066477b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/LaunchingPreferences.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.LinearLayout.LayoutParams;
+
+/**
+ * Demonstrates launching a PreferenceActivity and grabbing a value it saved.
+ */
+public class LaunchingPreferences extends Activity implements OnClickListener {
+
+    private static final int REQUEST_CODE_PREFERENCES = 1;
+
+    private TextView mCounterText;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        /*
+         * If this were my app's main activity, I would load the default values
+         * so they're set even if the user does not go into the preferences
+         * screen. Another good place to call this method would be from a
+         * subclass of Application, so your default values would be loaded
+         * regardless of entry into your application (for example, a service or
+         * activity).
+         */
+        PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
+
+        // Simple layout
+        LinearLayout layout = new LinearLayout(this);
+        layout.setOrientation(LinearLayout.VERTICAL);
+        setContentView(layout);
+
+        // Create a simple button that will launch the preferences
+        Button launchPreferences = new Button(this);
+        launchPreferences.setText(getString(R.string.launch_preference_activity));
+        launchPreferences.setOnClickListener(this);
+        layout.addView(launchPreferences, new LayoutParams(LayoutParams.MATCH_PARENT,
+                LayoutParams.WRAP_CONTENT));
+
+        mCounterText = new TextView(this);
+        layout.addView(mCounterText, new LayoutParams(LayoutParams.MATCH_PARENT,
+                LayoutParams.WRAP_CONTENT));
+
+        updateCounterText();
+    }
+
+    public void onClick(View v) {
+
+        // When the button is clicked, launch an activity through this intent
+        Intent launchPreferencesIntent = new Intent().setClass(this, AdvancedPreferences.class);
+
+        // Make it a subactivity so we know when it returns
+        startActivityForResult(launchPreferencesIntent, REQUEST_CODE_PREFERENCES);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        // The preferences returned if the request code is what we had given
+        // earlier in startSubActivity
+        if (requestCode == REQUEST_CODE_PREFERENCES) {
+            // Read a sample value they have set
+            updateCounterText();
+        }
+    }
+
+    private void updateCounterText() {
+        // Since we're in the same package, we can use this context to get
+        // the default shared preferences
+        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+        final int counter = sharedPref.getInt(AdvancedPreferences.KEY_MY_PREFERENCE, 0);
+        mCounterText.setText(getString(R.string.counter_value_is) + " " + counter);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/MyPreference.java b/samples/ApiDemos/src/com/example/android/apis/preference/MyPreference.java
new file mode 100644
index 0000000..aeb8bf9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/MyPreference.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * This is an example of a custom preference type. The preference counts the
+ * number of clicks it has received and stores/retrieves it from the storage.
+ */
+public class MyPreference extends Preference {
+    private int mClickCounter;
+
+    // This is the constructor called by the inflater
+    public MyPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        setWidgetLayoutResource(R.layout.preference_widget_mypreference);
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        // Set our custom views inside the layout
+        final TextView myTextView = (TextView) view.findViewById(R.id.mypreference_widget);
+        if (myTextView != null) {
+            myTextView.setText(String.valueOf(mClickCounter));
+        }
+    }
+
+    @Override
+    protected void onClick() {
+        int newValue = mClickCounter + 1;
+        // Give the client a chance to ignore this change if they deem it
+        // invalid
+        if (!callChangeListener(newValue)) {
+            // They don't want the value to be set
+            return;
+        }
+
+        // Increment counter
+        mClickCounter = newValue;
+
+        // Save to persistent storage (this method will make sure this
+        // preference should be persistent, along with other useful checks)
+        persistInt(mClickCounter);
+
+        // Data has changed, notify so UI can be refreshed!
+        notifyChanged();
+    }
+
+    @Override
+    protected Object onGetDefaultValue(TypedArray a, int index) {
+        // This preference type's value type is Integer, so we read the default
+        // value from the attributes as an Integer.
+        return a.getInteger(index, 0);
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        if (restoreValue) {
+            // Restore state
+            mClickCounter = getPersistedInt(mClickCounter);
+        } else {
+            // Set state
+            int value = (Integer) defaultValue;
+            mClickCounter = value;
+            persistInt(value);
+        }
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        /*
+         * Suppose a client uses this preference type without persisting. We
+         * must save the instance state so it is able to, for example, survive
+         * orientation changes.
+         */
+
+        final Parcelable superState = super.onSaveInstanceState();
+        if (isPersistent()) {
+            // No need to save instance state since it's persistent
+            return superState;
+        }
+
+        // Save the instance state
+        final SavedState myState = new SavedState(superState);
+        myState.clickCounter = mClickCounter;
+        return myState;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (!state.getClass().equals(SavedState.class)) {
+            // Didn't save state for us in onSaveInstanceState
+            super.onRestoreInstanceState(state);
+            return;
+        }
+
+        // Restore the instance state
+        SavedState myState = (SavedState) state;
+        super.onRestoreInstanceState(myState.getSuperState());
+        mClickCounter = myState.clickCounter;
+        notifyChanged();
+    }
+
+    /**
+     * SavedState, a subclass of {@link BaseSavedState}, will store the state
+     * of MyPreference, a subclass of Preference.
+     * <p>
+     * It is important to always call through to super methods.
+     */
+    private static class SavedState extends BaseSavedState {
+        int clickCounter;
+
+        public SavedState(Parcel source) {
+            super(source);
+
+            // Restore the click counter
+            clickCounter = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+
+            // Save the click counter
+            dest.writeInt(clickCounter);
+        }
+
+        public SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceDependencies.java b/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceDependencies.java
new file mode 100644
index 0000000..3aa4e39
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceDependencies.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.R;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class PreferenceDependencies extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.preference_dependencies);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceWithHeaders.java b/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceWithHeaders.java
new file mode 100644
index 0000000..6437e1e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceWithHeaders.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.R;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.util.Log;
+import android.widget.Button;
+
+import java.util.List;
+
+/**
+ * Demonstration of PreferenceActivity to make a top-level preference
+ * panel with headers.
+ */
+//BEGIN_INCLUDE(activity)
+public class PreferenceWithHeaders extends PreferenceActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Add a button to the header list.
+        if (hasHeaders()) {
+            Button button = new Button(this);
+            button.setText("Some action");
+            setListFooter(button);
+        }
+    }
+    
+    /**
+     * Populate the activity with the top-level headers.
+     */
+    @Override
+    public void onBuildHeaders(List<Header> target) {
+        loadHeadersFromResource(R.xml.preference_headers, target);
+    }
+
+    /**
+     * This fragment shows the preferences for the first header.
+     */
+    public static class Prefs1Fragment extends PreferenceFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            // Load the preferences from an XML resource
+            addPreferencesFromResource(R.xml.fragmented_preferences);
+        }
+    }
+
+    /**
+     * This fragment contains a second-level set of preference that you
+     * can get to by tapping an item in the first preferences fragment.
+     */
+    public static class Prefs1FragmentInner extends PreferenceFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            // Can retrieve arguments from preference XML.
+            Log.i("args", "Arguments: " + getArguments());
+            
+            // Load the preferences from an XML resource
+            addPreferencesFromResource(R.xml.fragmented_preferences_inner);
+        }
+    }
+
+    /**
+     * This fragment shows the preferences for the second header.
+     */
+    public static class Prefs2Fragment extends PreferenceFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            // Can retrieve arguments from headers XML.
+            Log.i("args", "Arguments: " + getArguments());
+            
+            // Load the preferences from an XML resource
+            addPreferencesFromResource(R.xml.preference_dependencies);
+        }
+    }
+}
+//END_INCLUDE(activity)
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromCode.java b/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromCode.java
new file mode 100644
index 0000000..8ce6b42
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromCode.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+
+import com.example.android.apis.R;
+
+public class PreferencesFromCode extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setPreferenceScreen(createPreferenceHierarchy());
+    }
+
+    private PreferenceScreen createPreferenceHierarchy() {
+        // Root
+        PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
+
+        // Inline preferences
+        PreferenceCategory inlinePrefCat = new PreferenceCategory(this);
+        inlinePrefCat.setTitle(R.string.inline_preferences);
+        root.addPreference(inlinePrefCat);
+
+        // Toggle preference
+        CheckBoxPreference togglePref = new CheckBoxPreference(this);
+        togglePref.setKey("toggle_preference");
+        togglePref.setTitle(R.string.title_toggle_preference);
+        togglePref.setSummary(R.string.summary_toggle_preference);
+        inlinePrefCat.addPreference(togglePref);
+
+        // Dialog based preferences
+        PreferenceCategory dialogBasedPrefCat = new PreferenceCategory(this);
+        dialogBasedPrefCat.setTitle(R.string.dialog_based_preferences);
+        root.addPreference(dialogBasedPrefCat);
+
+        // Edit text preference
+        EditTextPreference editTextPref = new EditTextPreference(this);
+        editTextPref.setDialogTitle(R.string.dialog_title_edittext_preference);
+        editTextPref.setKey("edittext_preference");
+        editTextPref.setTitle(R.string.title_edittext_preference);
+        editTextPref.setSummary(R.string.summary_edittext_preference);
+        dialogBasedPrefCat.addPreference(editTextPref);
+
+        // List preference
+        ListPreference listPref = new ListPreference(this);
+        listPref.setEntries(R.array.entries_list_preference);
+        listPref.setEntryValues(R.array.entryvalues_list_preference);
+        listPref.setDialogTitle(R.string.dialog_title_list_preference);
+        listPref.setKey("list_preference");
+        listPref.setTitle(R.string.title_list_preference);
+        listPref.setSummary(R.string.summary_list_preference);
+        dialogBasedPrefCat.addPreference(listPref);
+
+        // Launch preferences
+        PreferenceCategory launchPrefCat = new PreferenceCategory(this);
+        launchPrefCat.setTitle(R.string.launch_preferences);
+        root.addPreference(launchPrefCat);
+
+        /*
+         * The Preferences screenPref serves as a screen break (similar to page
+         * break in word processing). Like for other preference types, we assign
+         * a key here so that it is able to save and restore its instance state.
+         */
+        // Screen preference
+        PreferenceScreen screenPref = getPreferenceManager().createPreferenceScreen(this);
+        screenPref.setKey("screen_preference");
+        screenPref.setTitle(R.string.title_screen_preference);
+        screenPref.setSummary(R.string.summary_screen_preference);
+        launchPrefCat.addPreference(screenPref);
+
+        /*
+         * You can add more preferences to screenPref that will be shown on the
+         * next screen.
+         */
+
+        // Example of next screen toggle preference
+        CheckBoxPreference nextScreenCheckBoxPref = new CheckBoxPreference(this);
+        nextScreenCheckBoxPref.setKey("next_screen_toggle_preference");
+        nextScreenCheckBoxPref.setTitle(R.string.title_next_screen_toggle_preference);
+        nextScreenCheckBoxPref.setSummary(R.string.summary_next_screen_toggle_preference);
+        screenPref.addPreference(nextScreenCheckBoxPref);
+
+        // Intent preference
+        PreferenceScreen intentPref = getPreferenceManager().createPreferenceScreen(this);
+        intentPref.setIntent(new Intent().setAction(Intent.ACTION_VIEW)
+                .setData(Uri.parse("http://www.android.com")));
+        intentPref.setTitle(R.string.title_intent_preference);
+        intentPref.setSummary(R.string.summary_intent_preference);
+        launchPrefCat.addPreference(intentPref);
+
+        // Preference attributes
+        PreferenceCategory prefAttrsCat = new PreferenceCategory(this);
+        prefAttrsCat.setTitle(R.string.preference_attributes);
+        root.addPreference(prefAttrsCat);
+
+        // Visual parent toggle preference
+        CheckBoxPreference parentCheckBoxPref = new CheckBoxPreference(this);
+        parentCheckBoxPref.setTitle(R.string.title_parent_preference);
+        parentCheckBoxPref.setSummary(R.string.summary_parent_preference);
+        prefAttrsCat.addPreference(parentCheckBoxPref);
+
+        // Visual child toggle preference
+        // See res/values/attrs.xml for the <declare-styleable> that defines
+        // TogglePrefAttrs.
+        TypedArray a = obtainStyledAttributes(R.styleable.TogglePrefAttrs);
+        CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this);
+        childCheckBoxPref.setTitle(R.string.title_child_preference);
+        childCheckBoxPref.setSummary(R.string.summary_child_preference);
+        childCheckBoxPref.setLayoutResource(
+                a.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild,
+                        0));
+        prefAttrsCat.addPreference(childCheckBoxPref);
+        a.recycle();
+
+        return root;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromXml.java b/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromXml.java
new file mode 100644
index 0000000..868e33c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromXml.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.preference;
+
+import com.example.android.apis.R;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class PreferencesFromXml extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Load the preferences from an XML resource
+        addPreferencesFromResource(R.xml.preferences);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/_index.html b/samples/ApiDemos/src/com/example/android/apis/support/_index.html
new file mode 100644
index 0000000..806a571
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/_index.html
@@ -0,0 +1,76 @@
+
+<p>This section includes samples showing the use of Android's
+static support library.  This library contains code that you can
+build in to your application to access new features and common
+utilities while being able to run down to version 1.6 (API 4)
+of the platform.</p>
+<ul>
+  <li><a href="#Fragment">Fragment</a></li>
+  <li><a href="#LoaderManager">LoaderManager</a></li>
+</ul>
+
+
+<h3 id="Fragment">Fragment</h3>
+<dl>
+  <dt><a href="app/FragmentAlertDialogSupport.html">Fragment Alert Dialog</a></dt>
+  <dd>Demonstrates how to use a DialogFragment to show and manage an
+  AlertDialog.</dd>
+  
+  <dt><a href="app/FragmentArgumentsSupport.html">Fragment Arguments</a></dt>
+  <dd>Demonstrates how a fragment can be initialized with arguments,
+  supplying them either as an argument Bundle at runtime or XML attributes
+  in a &lt;fragment> tag.</dd>
+  
+  <dt><a href="app/FragmentContextMenuSupport.html">Fragment Context Menu</a></dt>
+  <dd>Demonstrates how to display and respond to a context menu that is
+  display from a fragment's view hierarchy.</dd>
+  
+  <dt><a href="app/FragmentDialogSupport.html">Fragment Dialog</a></dt>
+  <dd>Demonstrates use of DialogFragment to show various types of dialogs.</dd>
+  
+  <dt><a href="app/FragmentDialogOrActivitySupport.html">Fragment Dialog or Activity</a></dt>
+  <dd>Demonstrates how the same Fragment implementation can be used to provide the UI
+  for either an Activity or Dialog.</dd>
+  
+  <dt><a href="app/FragmentHideShowSupport.html">Fragment Hide Show</a></dt>
+  <dd>Demonstrates hiding and showing fragments.</dd>
+  
+  <dt><a href="app/FragmentLayoutSupport.html">Fragment Layout</a></dt>
+  <dd>Demonstrates use of the &lt;fragment&gt; tag to embed a Fragment in
+  an Activity's content view layout, and making the layout change based on
+  configuration to achieve different UI flows.</dd>
+  
+  <dt><a href="app/FragmentListArraySupport.html">Fragment List Array</a></dt>
+  <dd>Demonstrates use of ListFragment to show the contents of a simple ArrayAdapter.</dd>
+  
+  <dt><a href="app/FragmentListCursorLoaderSupport.html">Fragment List Cursor Loader</a></dt>
+  <dd>Demonstrates use of LoaderManager to perform a query for a Cursor that
+  populates a ListFragment.</dd>
+  
+  <dt><a href="app/FragmentMenuSupport.html">Fragment Menu</a></dt>
+  <dd>Demonstrates populating custom menu items from a Fragment.</dd>
+  
+  <dt><a href="app/FragmentReceiveResultSupport.html">Fragment Receive Result</a></dt>
+  <dd>Demonstrates starting a new Activity from a Fragment, and receiving
+  a result back from it.</dd>
+  
+  <dt><a href="app/FragmentRetainInstanceSupport.html">Fragment Retain Instance</a></dt>
+  <dd>Demonstrates a Fragment can be used to easily retain active state across
+  an Activity's configuration change.</dd>
+  
+  <dt><a href="app/FragmentStackSupport.html">Fragment Stack</a></dt>
+  <dd>Demonstrates creating a stack of Fragment instances similar to the
+  traditional stack of activities.</dd>
+  
+</dl>
+
+<h3 id="LoaderManager">LoaderManager</h3>
+<dl>
+  <dt><a href="app/LoaderThrottleSupport.html">Loader Throttle</a></dt>
+  <dd>Complete end-to-end demonstration of a simple content provider that
+  populates data in a list through a cursor loader.  The UI allows the list
+  to be populated with a series of items, showing how AsyncTaskLoader's
+  throttling facility can be used to control how much a Loader is refreshed
+  in this case.</dd>
+</dl>
+  
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentAlertDialogSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentAlertDialogSupport.java
new file mode 100644
index 0000000..d7f6ae9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentAlertDialogSupport.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstrates how to show an AlertDialog that is managed by a Fragment.
+ */
+public class FragmentAlertDialogSupport extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_dialog);
+
+        View tv = findViewById(R.id.text);
+        ((TextView)tv).setText("Example of displaying an alert dialog with a DialogFragment");
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.show);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog();
+            }
+        });
+    }
+
+//BEGIN_INCLUDE(activity)
+    void showDialog() {
+        DialogFragment newFragment = MyAlertDialogFragment.newInstance(
+                R.string.alert_dialog_two_buttons_title);
+        newFragment.show(getSupportFragmentManager(), "dialog");
+    }
+
+    public void doPositiveClick() {
+        // Do stuff here.
+        Log.i("FragmentAlertDialog", "Positive click!");
+    }
+
+    public void doNegativeClick() {
+        // Do stuff here.
+        Log.i("FragmentAlertDialog", "Negative click!");
+    }
+//END_INCLUDE(activity)
+
+//BEGIN_INCLUDE(dialog)
+    public static class MyAlertDialogFragment extends DialogFragment {
+
+        public static MyAlertDialogFragment newInstance(int title) {
+            MyAlertDialogFragment frag = new MyAlertDialogFragment();
+            Bundle args = new Bundle();
+            args.putInt("title", title);
+            frag.setArguments(args);
+            return frag;
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            int title = getArguments().getInt("title");
+
+            return new AlertDialog.Builder(getActivity())
+                    .setIcon(R.drawable.alert_dialog_icon)
+                    .setTitle(title)
+                    .setPositiveButton(R.string.alert_dialog_ok,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                ((FragmentAlertDialogSupport)getActivity()).doPositiveClick();
+                            }
+                        }
+                    )
+                    .setNegativeButton(R.string.alert_dialog_cancel,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                ((FragmentAlertDialogSupport)getActivity()).doNegativeClick();
+                            }
+                        }
+                    )
+                    .create();
+        }
+    }
+//END_INCLUDE(dialog)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentArgumentsSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentArgumentsSupport.java
new file mode 100644
index 0000000..1ff7185
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentArgumentsSupport.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+
+import android.app.Activity;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Demonstrates a fragment that can be configured through both Bundle arguments
+ * and layout attributes.
+ */
+public class FragmentArgumentsSupport extends FragmentActivity {
+//BEGIN_INCLUDE(create)
+    @Override protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_arguments_support);
+
+        if (savedInstanceState == null) {
+            // First-time init; create fragment to embed in activity.
+            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+            Fragment newFragment = MyFragment.newInstance("From Arguments");
+            ft.add(R.id.created, newFragment);
+            ft.commit();
+        }
+    }
+//END_INCLUDE(create)
+
+//BEGIN_INCLUDE(fragment)
+    public static class MyFragment extends Fragment {
+        CharSequence mLabel;
+
+        /**
+         * Create a new instance of MyFragment that will be initialized
+         * with the given arguments.
+         */
+        static MyFragment newInstance(CharSequence label) {
+            MyFragment f = new MyFragment();
+            Bundle b = new Bundle();
+            b.putCharSequence("label", label);
+            f.setArguments(b);
+            return f;
+        }
+
+        /**
+         * Parse attributes during inflation from a view hierarchy into the
+         * arguments we handle.
+         */
+        @Override public void onInflate(Activity activity, AttributeSet attrs,
+                Bundle savedInstanceState) {
+            super.onInflate(activity, attrs, savedInstanceState);
+
+            TypedArray a = activity.obtainStyledAttributes(attrs,
+                    R.styleable.FragmentArguments);
+            mLabel = a.getText(R.styleable.FragmentArguments_android_label);
+            a.recycle();
+        }
+
+        /**
+         * During creation, if arguments have been supplied to the fragment
+         * then parse those out.
+         */
+        @Override public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            Bundle args = getArguments();
+            if (args != null) {
+                CharSequence label = args.getCharSequence("label");
+                if (label != null) {
+                    mLabel = label;
+                }
+            }
+        }
+
+        /**
+         * Create the view for this fragment, using the arguments given to it.
+         */
+        @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText(mLabel != null ? mLabel : "(no label)");
+            tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+            return v;
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentContextMenuSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentContextMenuSupport.java
new file mode 100644
index 0000000..a934145
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentContextMenuSupport.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+
+/**
+ * Demonstration of displaying a context menu from a fragment.
+ */
+public class FragmentContextMenuSupport extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create the list fragment and add it as our sole content.
+        ContextMenuFragment content = new ContextMenuFragment();
+        getSupportFragmentManager().beginTransaction().add(
+                android.R.id.content, content).commit();
+    }
+
+    public static class ContextMenuFragment extends Fragment {
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View root = inflater.inflate(R.layout.fragment_context_menu, container, false);
+            registerForContextMenu(root.findViewById(R.id.long_press));
+            return root;
+        }
+
+        @Override
+        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+            super.onCreateContextMenu(menu, v, menuInfo);
+            menu.add(Menu.NONE, R.id.a_item, Menu.NONE, "Menu A");
+            menu.add(Menu.NONE, R.id.b_item, Menu.NONE, "Menu B");
+        }
+
+        @Override
+        public boolean onContextItemSelected(MenuItem item) {
+            switch (item.getItemId()) {
+                case R.id.a_item:
+                    Log.i("ContextMenu", "Item 1a was chosen");
+                    return true;
+                case R.id.b_item:
+                    Log.i("ContextMenu", "Item 1b was chosen");
+                    return true;
+            }
+            return super.onContextItemSelected(item);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentDialogOrActivitySupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentDialogOrActivitySupport.java
new file mode 100644
index 0000000..fe677aa
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentDialogOrActivitySupport.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentDialogOrActivitySupport extends FragmentActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_dialog_or_activity);
+
+        if (savedInstanceState == null) {
+            // First-time init; create fragment to embed in activity.
+//BEGIN_INCLUDE(embed)
+            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+            DialogFragment newFragment = MyDialogFragment.newInstance();
+            ft.add(R.id.embedded, newFragment);
+            ft.commit();
+//END_INCLUDE(embed)
+        }
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.show_dialog);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog();
+            }
+        });
+    }
+
+//BEGIN_INCLUDE(show_dialog)
+    void showDialog() {
+        // Create the fragment and show it as a dialog.
+        DialogFragment newFragment = MyDialogFragment.newInstance();
+        newFragment.show(getSupportFragmentManager(), "dialog");
+    }
+//END_INCLUDE(show_dialog)
+
+//BEGIN_INCLUDE(dialog)
+    public static class MyDialogFragment extends DialogFragment {
+        static MyDialogFragment newInstance() {
+            return new MyDialogFragment();
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("This is an instance of MyDialogFragment");
+            return v;
+        }
+    }
+//END_INCLUDE(dialog)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentDialogSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentDialogSupport.java
new file mode 100644
index 0000000..666151d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentDialogSupport.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentDialogSupport extends FragmentActivity {
+    int mStackLevel = 0;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_dialog);
+
+        View tv = findViewById(R.id.text);
+        ((TextView)tv).setText("Example of displaying dialogs with a DialogFragment.  "
+                + "Press the show button below to see the first dialog; pressing "
+                + "successive show buttons will display other dialog styles as a "
+                + "stack, with dismissing or back going to the previous dialog.");
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.show);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog();
+            }
+        });
+
+        if (savedInstanceState != null) {
+            mStackLevel = savedInstanceState.getInt("level");
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("level", mStackLevel);
+    }
+
+//BEGIN_INCLUDE(add_dialog)
+    void showDialog() {
+        mStackLevel++;
+
+        // DialogFragment.show() will take care of adding the fragment
+        // in a transaction.  We also want to remove any currently showing
+        // dialog, so make our own transaction and take care of that here.
+        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+        Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
+        if (prev != null) {
+            ft.remove(prev);
+        }
+        ft.addToBackStack(null);
+
+        // Create and show the dialog.
+        DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
+        newFragment.show(ft, "dialog");
+    }
+//END_INCLUDE(add_dialog)
+
+    static String getNameForNum(int num) {
+        switch ((num-1)%6) {
+            case 1: return "STYLE_NO_TITLE";
+            case 2: return "STYLE_NO_FRAME";
+            case 3: return "STYLE_NO_INPUT (this window can't receive input, so "
+                    + "you will need to press the bottom show button)";
+            case 4: return "STYLE_NORMAL with dark fullscreen theme";
+            case 5: return "STYLE_NORMAL with light theme";
+            case 6: return "STYLE_NO_TITLE with light theme";
+            case 7: return "STYLE_NO_FRAME with light theme";
+            case 8: return "STYLE_NORMAL with light fullscreen theme";
+        }
+        return "STYLE_NORMAL";
+    }
+
+//BEGIN_INCLUDE(dialog)
+    public static class MyDialogFragment extends DialogFragment {
+        int mNum;
+
+        /**
+         * Create a new instance of MyDialogFragment, providing "num"
+         * as an argument.
+         */
+        static MyDialogFragment newInstance(int num) {
+            MyDialogFragment f = new MyDialogFragment();
+
+            // Supply num input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("num", num);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNum = getArguments().getInt("num");
+
+            // Pick a style based on the num.
+            int style = DialogFragment.STYLE_NORMAL, theme = 0;
+            switch ((mNum-1)%6) {
+                case 1: style = DialogFragment.STYLE_NO_TITLE; break;
+                case 2: style = DialogFragment.STYLE_NO_FRAME; break;
+                case 3: style = DialogFragment.STYLE_NO_INPUT; break;
+                case 4: style = DialogFragment.STYLE_NORMAL; break;
+                case 5: style = DialogFragment.STYLE_NO_TITLE; break;
+                case 6: style = DialogFragment.STYLE_NO_FRAME; break;
+                case 7: style = DialogFragment.STYLE_NORMAL; break;
+            }
+            switch ((mNum-1)%6) {
+                case 2: theme = android.R.style.Theme_Panel; break;
+                case 4: theme = android.R.style.Theme; break;
+                case 5: theme = android.R.style.Theme_Light; break;
+                case 6: theme = android.R.style.Theme_Light_Panel; break;
+                case 7: theme = android.R.style.Theme_Light; break;
+            }
+            setStyle(style, theme);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.fragment_dialog, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("Dialog #" + mNum + ": using style "
+                    + getNameForNum(mNum));
+
+            // Watch for button clicks.
+            Button button = (Button)v.findViewById(R.id.show);
+            button.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    // When button is clicked, call up to owning activity.
+                    ((FragmentDialogSupport)getActivity()).showDialog();
+                }
+            });
+
+            return v;
+        }
+    }
+//END_INCLUDE(dialog)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentHideShowSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentHideShowSupport.java
new file mode 100644
index 0000000..d347160
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentHideShowSupport.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstration of hiding and showing fragments.
+ */
+public class FragmentHideShowSupport extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_hide_show_support);
+
+        // The content view embeds two fragments; now retrieve them and attach
+        // their "hide" button.
+        FragmentManager fm = getSupportFragmentManager();
+        addShowHideListener(R.id.frag1hide, fm.findFragmentById(R.id.fragment1));
+        addShowHideListener(R.id.frag2hide, fm.findFragmentById(R.id.fragment2));
+    }
+
+    void addShowHideListener(int buttonId, final Fragment fragment) {
+        final Button button = (Button)findViewById(buttonId);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+                ft.setCustomAnimations(android.R.anim.fade_in,
+                        android.R.anim.fade_out);
+                if (fragment.isHidden()) {
+                    ft.show(fragment);
+                    button.setText("Hide");
+                } else {
+                    ft.hide(fragment);
+                    button.setText("Show");
+                }
+                ft.commit();
+            }
+        });
+    }
+
+    public static class FirstFragment extends Fragment {
+        TextView mTextView;
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.labeled_text_edit, container, false);
+            View tv = v.findViewById(R.id.msg);
+            ((TextView)tv).setText("The fragment saves and restores this text.");
+
+            // Retrieve the text editor, and restore the last saved state if needed.
+            mTextView = (TextView)v.findViewById(R.id.saved);
+            if (savedInstanceState != null) {
+                mTextView.setText(savedInstanceState.getCharSequence("text"));
+            }
+            return v;
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+
+            // Remember the current text, to restore if we later restart.
+            outState.putCharSequence("text", mTextView.getText());
+        }
+    }
+
+    public static class SecondFragment extends Fragment {
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.labeled_text_edit, container, false);
+            View tv = v.findViewById(R.id.msg);
+            ((TextView)tv).setText("The TextView saves and restores this text.");
+
+            // Retrieve the text editor and tell it to save and restore its state.
+            // Note that you will often set this in the layout XML, but since
+            // we are sharing our layout with the other fragment we will customize
+            // it here.
+            ((TextView)v.findViewById(R.id.saved)).setSaveEnabled(true);
+            return v;
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentLayoutSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentLayoutSupport.java
new file mode 100644
index 0000000..e1c63ae
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentLayoutSupport.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+import com.example.android.apis.Shakespeare;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.app.ListFragment;
+
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+/**
+ * Demonstration of using fragments to implement different activity layouts.
+ * This sample provides a different layout (and activity flow) when run in
+ * landscape.
+ */
+public class FragmentLayoutSupport extends FragmentActivity {
+
+//BEGIN_INCLUDE(main)
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.fragment_layout_support);
+    }
+//END_INCLUDE(main)
+
+    /**
+     * This is a secondary activity, to show what the user has selected
+     * when the screen is not large enough to show it all in one activity.
+     */
+//BEGIN_INCLUDE(details_activity)
+    public static class DetailsActivity extends FragmentActivity {
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            if (getResources().getConfiguration().orientation
+                    == Configuration.ORIENTATION_LANDSCAPE) {
+                // If the screen is now in landscape mode, we can show the
+                // dialog in-line with the list so we don't need this activity.
+                finish();
+                return;
+            }
+
+            if (savedInstanceState == null) {
+                // During initial setup, plug in the details fragment.
+                DetailsFragment details = new DetailsFragment();
+                details.setArguments(getIntent().getExtras());
+                getSupportFragmentManager().beginTransaction().add(
+                        android.R.id.content, details).commit();
+            }
+        }
+    }
+//END_INCLUDE(details_activity)
+
+    /**
+     * This is the "top-level" fragment, showing a list of items that the
+     * user can pick.  Upon picking an item, it takes care of displaying the
+     * data to the user as appropriate based on the currrent UI layout.
+     */
+//BEGIN_INCLUDE(titles)
+    public static class TitlesFragment extends ListFragment {
+        boolean mDualPane;
+        int mCurCheckPosition = 0;
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            // Populate list with our static array of titles.
+            setListAdapter(new ArrayAdapter<String>(getActivity(),
+                    R.layout.simple_list_item_checkable_1,
+                    android.R.id.text1, Shakespeare.TITLES));
+
+            // Check to see if we have a frame in which to embed the details
+            // fragment directly in the containing UI.
+            View detailsFrame = getActivity().findViewById(R.id.details);
+            mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;
+
+            if (savedInstanceState != null) {
+                // Restore last state for checked position.
+                mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
+            }
+
+            if (mDualPane) {
+                // In dual-pane mode, the list view highlights the selected item.
+                getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+                // Make sure our UI is in the correct state.
+                showDetails(mCurCheckPosition);
+            }
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            outState.putInt("curChoice", mCurCheckPosition);
+        }
+
+        @Override
+        public void onListItemClick(ListView l, View v, int position, long id) {
+            showDetails(position);
+        }
+
+        /**
+         * Helper function to show the details of a selected item, either by
+         * displaying a fragment in-place in the current UI, or starting a
+         * whole new activity in which it is displayed.
+         */
+        void showDetails(int index) {
+            mCurCheckPosition = index;
+
+            if (mDualPane) {
+                // We can display everything in-place with fragments, so update
+                // the list to highlight the selected item and show the data.
+                getListView().setItemChecked(index, true);
+
+                // Check what fragment is currently shown, replace if needed.
+                DetailsFragment details = (DetailsFragment)
+                        getFragmentManager().findFragmentById(R.id.details);
+                if (details == null || details.getShownIndex() != index) {
+                    // Make new fragment to show this selection.
+                    details = DetailsFragment.newInstance(index);
+
+                    // Execute a transaction, replacing any existing fragment
+                    // with this one inside the frame.
+                    FragmentTransaction ft = getFragmentManager().beginTransaction();
+                    ft.replace(R.id.details, details);
+                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+                    ft.commit();
+                }
+
+            } else {
+                // Otherwise we need to launch a new activity to display
+                // the dialog fragment with selected text.
+                Intent intent = new Intent();
+                intent.setClass(getActivity(), DetailsActivity.class);
+                intent.putExtra("index", index);
+                startActivity(intent);
+            }
+        }
+    }
+//END_INCLUDE(titles)
+
+    /**
+     * This is the secondary fragment, displaying the details of a particular
+     * item.
+     */
+//BEGIN_INCLUDE(details)
+    public static class DetailsFragment extends Fragment {
+        /**
+         * Create a new instance of DetailsFragment, initialized to
+         * show the text at 'index'.
+         */
+        public static DetailsFragment newInstance(int index) {
+            DetailsFragment f = new DetailsFragment();
+
+            // Supply index input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("index", index);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        public int getShownIndex() {
+            return getArguments().getInt("index", 0);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            if (container == null) {
+                // We have different layouts, and in one of them this
+                // fragment's containing frame doesn't exist.  The fragment
+                // may still be created from its saved state, but there is
+                // no reason to try to create its view hierarchy because it
+                // won't be displayed.  Note this is not needed -- we could
+                // just run the code below, where we would create and return
+                // the view hierarchy; it would just never be used.
+                return null;
+            }
+
+            ScrollView scroller = new ScrollView(getActivity());
+            TextView text = new TextView(getActivity());
+            int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    4, getActivity().getResources().getDisplayMetrics());
+            text.setPadding(padding, padding, padding, padding);
+            scroller.addView(text);
+            text.setText(Shakespeare.DIALOGUE[getShownIndex()]);
+            return scroller;
+        }
+    }
+//END_INCLUDE(details)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentListArraySupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentListArraySupport.java
new file mode 100644
index 0000000..2bcc018
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentListArraySupport.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.support.app;
+
+import com.example.android.apis.Shakespeare;
+
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.ListFragment;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * Demonstration of using ListFragment to show a list of items
+ * from a canned array.
+ */
+public class FragmentListArraySupport extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create the list fragment and add it as our sole content.
+        if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
+            ArrayListFragment list = new ArrayListFragment();
+            getSupportFragmentManager().beginTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+    public static class ArrayListFragment extends ListFragment {
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+            setListAdapter(new ArrayAdapter<String>(getActivity(),
+                    android.R.layout.simple_list_item_1, Shakespeare.TITLES));
+        }
+
+        @Override
+        public void onListItemClick(ListView l, View v, int position, long id) {
+            Log.i("FragmentList", "Item clicked: " + id);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentMenuSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentMenuSupport.java
new file mode 100644
index 0000000..5ac309a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentMenuSupport.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.view.MenuCompat;
+
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.CheckBox;
+
+/**
+ * Demonstrates how fragments can participate in the options menu.
+ */
+public class FragmentMenuSupport extends FragmentActivity {
+    Fragment mFragment1;
+    Fragment mFragment2;
+    CheckBox mCheckBox1;
+    CheckBox mCheckBox2;
+
+    // Update fragment visibility when check boxes are changed.
+    final OnClickListener mClickListener = new OnClickListener() {
+        public void onClick(View v) {
+            updateFragmentVisibility();
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_menu);
+
+        // Make sure the two menu fragments are created.
+        FragmentManager fm = getSupportFragmentManager();
+        FragmentTransaction ft = fm.beginTransaction();
+        mFragment1 = fm.findFragmentByTag("f1");
+        if (mFragment1 == null) {
+            mFragment1 = new MenuFragment();
+            ft.add(mFragment1, "f1");
+        }
+        mFragment2 = fm.findFragmentByTag("f2");
+        if (mFragment2 == null) {
+            mFragment2 = new Menu2Fragment();
+            ft.add(mFragment2, "f2");
+        }
+        ft.commit();
+
+        // Watch check box clicks.
+        mCheckBox1 = (CheckBox)findViewById(R.id.menu1);
+        mCheckBox1.setOnClickListener(mClickListener);
+        mCheckBox2 = (CheckBox)findViewById(R.id.menu2);
+        mCheckBox2.setOnClickListener(mClickListener);
+
+        // Make sure fragments start out with correct visibility.
+        updateFragmentVisibility();
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        // Make sure fragments are updated after check box view state is restored.
+        updateFragmentVisibility();
+    }
+
+    // Update fragment visibility based on current check box state.
+    void updateFragmentVisibility() {
+        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+        if (mCheckBox1.isChecked()) ft.show(mFragment1);
+        else ft.hide(mFragment1);
+        if (mCheckBox2.isChecked()) ft.show(mFragment2);
+        else ft.hide(mFragment2);
+        ft.commit();
+    }
+
+    /**
+     * A fragment that displays a menu.  This fragment happens to not
+     * have a UI (it does not implement onCreateView), but it could also
+     * have one if it wanted.
+     */
+    public static class MenuFragment extends Fragment {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setHasOptionsMenu(true);
+        }
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            MenuItem item;
+            item = menu.add("Menu 1a");
+            MenuCompat.setShowAsAction(item, MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            item = menu.add("Menu 1b");
+            MenuCompat.setShowAsAction(item, MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        }
+    }
+
+    /**
+     * Second fragment with a menu.
+     */
+    public static class Menu2Fragment extends Fragment {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setHasOptionsMenu(true);
+        }
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            MenuItem item;
+            item = menu.add("Menu 2");
+            MenuCompat.setShowAsAction(item, MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentPagerSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentPagerSupport.java
new file mode 100644
index 0000000..46d29ac
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentPagerSupport.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+import com.example.android.apis.Shakespeare;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentPager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.app.ListFragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class FragmentPagerSupport extends FragmentActivity
+        implements FragmentPager.Adapter {
+    static final int NUM_ITEMS = 10;
+
+    FragmentPager mPager;
+    int mCurPos;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_pager);
+
+        mPager = (FragmentPager)findViewById(R.id.pager);
+        mPager.setAdapter(this);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.new_fragment);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                mCurPos++;
+                if (mCurPos < NUM_ITEMS) {
+                    mPager.setCurrentItem(mCurPos);
+                } else {
+                    mCurPos--;
+                }
+            }
+        });
+    }
+
+    @Override
+    public int getCount() {
+        return NUM_ITEMS;
+    }
+
+    @Override
+    public Fragment getItem(int position) {
+        return ArrayListFragment.newInstance(position);
+    }
+
+    public static class ArrayListFragment extends ListFragment {
+        int mNum;
+
+        /**
+         * Create a new instance of CountingFragment, providing "num"
+         * as an argument.
+         */
+        static ArrayListFragment newInstance(int num) {
+            ArrayListFragment f = new ArrayListFragment();
+
+            // Supply num input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("num", num);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        /**
+         * When creating, retrieve this instance's number from its arguments.
+         */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNum = getArguments() != null ? getArguments().getInt("num") : 1;
+        }
+
+        /**
+         * The Fragment's UI is just a simple text view showing its
+         * instance number.
+         */
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("Fragment #" + mNum);
+            return v;
+        }
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+            setListAdapter(new ArrayAdapter<String>(getActivity(),
+                    android.R.layout.simple_list_item_1, Shakespeare.TITLES));
+        }
+
+        @Override
+        public void onListItemClick(ListView l, View v, int position, long id) {
+            Log.i("FragmentList", "Item clicked: " + id);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentReceiveResultSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentReceiveResultSupport.java
new file mode 100644
index 0000000..f430e69
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentReceiveResultSupport.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+import com.example.android.apis.app.SendResult;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+public class FragmentReceiveResultSupport extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        FrameLayout frame = new FrameLayout(this);
+        frame.setId(R.id.simple_fragment);
+        setContentView(frame, lp);
+
+        if (savedInstanceState == null) {
+            // Do first time initialization -- add fragment.
+            Fragment newFragment = new ReceiveResultFragment();
+            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+            ft.add(R.id.simple_fragment, newFragment).commit();
+        }
+    }
+
+    public static class ReceiveResultFragment extends Fragment {
+        // Definition of the one requestCode we use for receiving resuls.
+        static final private int GET_CODE = 0;
+
+        private TextView mResults;
+
+        private OnClickListener mGetListener = new OnClickListener() {
+            public void onClick(View v) {
+                // Start the activity whose result we want to retrieve.  The
+                // result will come back with request code GET_CODE.
+                Intent intent = new Intent(getActivity(), SendResult.class);
+                startActivityForResult(intent, GET_CODE);
+            }
+        };
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.receive_result, container, false);
+
+            // Retrieve the TextView widget that will display results.
+            mResults = (TextView)v.findViewById(R.id.results);
+
+            // This allows us to later extend the text buffer.
+            mResults.setText(mResults.getText(), TextView.BufferType.EDITABLE);
+
+            // Watch for button clicks.
+            Button getButton = (Button)v.findViewById(R.id.get);
+            getButton.setOnClickListener(mGetListener);
+
+            return v;
+        }
+
+        /**
+         * This method is called when the sending activity has finished, with the
+         * result it supplied.
+         */
+        @Override
+        public void onActivityResult(int requestCode, int resultCode, Intent data) {
+            // You can use the requestCode to select between multiple child
+            // activities you may have started.  Here there is only one thing
+            // we launch.
+            if (requestCode == GET_CODE) {
+
+                // We will be adding to our text.
+                Editable text = (Editable)mResults.getText();
+
+                // This is a standard resultCode that is sent back if the
+                // activity doesn't supply an explicit result.  It will also
+                // be returned if the activity failed to launch.
+                if (resultCode == RESULT_CANCELED) {
+                    text.append("(cancelled)");
+
+                // Our protocol with the sending activity is that it will send
+                // text in 'data' as its result.
+                } else {
+                    text.append("(okay ");
+                    text.append(Integer.toString(resultCode));
+                    text.append(") ");
+                    if (data != null) {
+                        text.append(data.getAction());
+                    }
+                }
+
+                text.append("\n");
+            }
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentRetainInstanceSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentRetainInstanceSupport.java
new file mode 100644
index 0000000..dbf0cfb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentRetainInstanceSupport.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ProgressBar;
+
+/**
+ * This example shows how you can use a Fragment to easily propagate state
+ * (such as threads) across activity instances when an activity needs to be
+ * restarted due to, for example, a configuration change.  This is a lot
+ * easier than using the raw Activity.onRetainNonConfiguratinInstance() API.
+ */
+public class FragmentRetainInstanceSupport extends FragmentActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // First time init, create the UI.
+        if (savedInstanceState == null) {
+            getSupportFragmentManager().beginTransaction().add(android.R.id.content,
+                    new UiFragment()).commit();
+        }
+    }
+
+    /**
+     * This is a fragment showing UI that will be updated from work done
+     * in the retained fragment.
+     */
+    public static class UiFragment extends Fragment {
+        RetainedFragment mWorkFragment;
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.fragment_retain_instance, container, false);
+
+            // Watch for button clicks.
+            Button button = (Button)v.findViewById(R.id.restart);
+            button.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    mWorkFragment.restart();
+                }
+            });
+
+            return v;
+        }
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            FragmentManager fm = getFragmentManager();
+
+            // Check to see if we have retained the worker fragment.
+            mWorkFragment = (RetainedFragment)fm.findFragmentByTag("work");
+
+            // If not retained (or first time running), we need to create it.
+            if (mWorkFragment == null) {
+                mWorkFragment = new RetainedFragment();
+                // Tell it who it is working with.
+                mWorkFragment.setTargetFragment(this, 0);
+                fm.beginTransaction().add(mWorkFragment, "work").commit();
+            }
+        }
+
+    }
+
+    /**
+     * This is the Fragment implementation that will be retained across
+     * activity instances.  It represents some ongoing work, here a thread
+     * we have that sits around incrementing a progress indicator.
+     */
+    public static class RetainedFragment extends Fragment {
+        ProgressBar mProgressBar;
+        int mPosition;
+        boolean mReady = false;
+        boolean mQuiting = false;
+
+        /**
+         * This is the thread that will do our work.  It sits in a loop running
+         * the progress up until it has reached the top, then stops and waits.
+         */
+        final Thread mThread = new Thread() {
+            @Override
+            public void run() {
+                // We'll figure the real value out later.
+                int max = 10000;
+
+                // This thread runs almost forever.
+                while (true) {
+
+                    // Update our shared state with the UI.
+                    synchronized (this) {
+                        // Our thread is stopped if the UI is not ready
+                        // or it has completed its work.
+                        while (!mReady || mPosition >= max) {
+                            if (mQuiting) {
+                                return;
+                            }
+                            try {
+                                wait();
+                            } catch (InterruptedException e) {
+                            }
+                        }
+
+                        // Now update the progress.  Note it is important that
+                        // we touch the progress bar with the lock held, so it
+                        // doesn't disappear on us.
+                        mPosition++;
+                        max = mProgressBar.getMax();
+                        mProgressBar.setProgress(mPosition);
+                    }
+
+                    // Normally we would be doing some work, but put a kludge
+                    // here to pretend like we are.
+                    synchronized (this) {
+                        try {
+                            wait(50);
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                }
+            }
+        };
+
+        /**
+         * Fragment initialization.  We way we want to be retained and
+         * start our thread.
+         */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            // Tell the framework to try to keep this fragment around
+            // during a configuration change.
+            setRetainInstance(true);
+
+            // Start up the worker thread.
+            mThread.start();
+        }
+
+        /**
+         * This is called when the Fragment's Activity is ready to go, after
+         * its content view has been installed; it is called both after
+         * the initial fragment creation and after the fragment is re-attached
+         * to a new activity.
+         */
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            // Retrieve the progress bar from the target's view hierarchy.
+            mProgressBar = (ProgressBar)getTargetFragment().getView().findViewById(
+                    R.id.progress_horizontal);
+
+            // We are ready for our thread to go.
+            synchronized (mThread) {
+                mReady = true;
+                mThread.notify();
+            }
+        }
+
+        /**
+         * This is called when the fragment is going away.  It is NOT called
+         * when the fragment is being propagated between activity instances.
+         */
+        @Override
+        public void onDestroy() {
+            // Make the thread go away.
+            synchronized (mThread) {
+                mReady = false;
+                mQuiting = true;
+                mThread.notify();
+            }
+
+            super.onDestroy();
+        }
+
+        /**
+         * This is called right before the fragment is detached from its
+         * current activity instance.
+         */
+        @Override
+        public void onDetach() {
+            // This fragment is being detached from its activity.  We need
+            // to make sure its thread is not going to touch any activity
+            // state after returning from this function.
+            synchronized (mThread) {
+                mProgressBar = null;
+                mReady = false;
+                mThread.notify();
+            }
+
+            super.onDetach();
+        }
+
+        /**
+         * API for our UI to restart the progress thread.
+         */
+        public void restart() {
+            synchronized (mThread) {
+                mPosition = 0;
+                mThread.notify();
+            }
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentStackSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentStackSupport.java
new file mode 100644
index 0000000..404721b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/FragmentStackSupport.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+import com.example.android.apis.R;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentStackSupport extends FragmentActivity {
+    int mStackLevel = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_stack);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.new_fragment);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                addFragmentToStack();
+            }
+        });
+
+        if (savedInstanceState == null) {
+            // Do first time initialization -- add initial fragment.
+            Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+            ft.add(R.id.simple_fragment, newFragment).commit();
+        } else {
+            mStackLevel = savedInstanceState.getInt("level");
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("level", mStackLevel);
+    }
+
+//BEGIN_INCLUDE(add_stack)
+    void addFragmentToStack() {
+        mStackLevel++;
+
+        // Instantiate a new fragment.
+        Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+
+        // Add the fragment to the activity, pushing this transaction
+        // on to the back stack.
+        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+        ft.replace(R.id.simple_fragment, newFragment);
+        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+        ft.addToBackStack(null);
+        ft.commit();
+    }
+//END_INCLUDE(add_stack)
+
+//BEGIN_INCLUDE(fragment)
+    public static class CountingFragment extends Fragment {
+        int mNum;
+
+        /**
+         * Create a new instance of CountingFragment, providing "num"
+         * as an argument.
+         */
+        static CountingFragment newInstance(int num) {
+            CountingFragment f = new CountingFragment();
+
+            // Supply num input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("num", num);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        /**
+         * When creating, retrieve this instance's number from its arguments.
+         */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNum = getArguments() != null ? getArguments().getInt("num") : 1;
+        }
+
+        /**
+         * The Fragment's UI is just a simple text view showing its
+         * instance number.
+         */
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("Fragment #" + mNum);
+            tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+            return v;
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/LoaderCursorSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/LoaderCursorSupport.java
new file mode 100644
index 0000000..491ae0e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/LoaderCursorSupport.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.support.app;
+
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.ListFragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v4.widget.SimpleCursorAdapter;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+
+/**
+ * Demonstration of the use of a CursorLoader to load and display contacts
+ * data in a fragment.
+ */
+public class LoaderCursorSupport extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        FragmentManager fm = getSupportFragmentManager();
+
+        // Create the list fragment and add it as our sole content.
+        if (fm.findFragmentById(android.R.id.content) == null) {
+            CursorLoaderListFragment list = new CursorLoaderListFragment();
+            fm.beginTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+//BEGIN_INCLUDE(fragment_cursor)
+    public static class CursorLoaderListFragment extends ListFragment
+            implements LoaderManager.LoaderCallbacks<Cursor> {
+
+        // This is the Adapter being used to display the list's data.
+        SimpleCursorAdapter mAdapter;
+
+        // If non-null, this is the current filter the user has provided.
+        String mCurFilter;
+
+        @Override public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            // Give some text to display if there is no data.  In a real
+            // application this would come from a resource.
+            setEmptyText("No phone numbers");
+
+            // We have a menu item to show in action bar.
+            setHasOptionsMenu(true);
+
+            // Create an empty adapter we will use to display the loaded data.
+            mAdapter = new SimpleCursorAdapter(getActivity(),
+                    android.R.layout.simple_list_item_2, null,
+                    new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
+                    new int[] { android.R.id.text1, android.R.id.text2 }, 0);
+            setListAdapter(mAdapter);
+
+            // Prepare the loader.  Either re-connect with an existing one,
+            // or start a new one.
+            getLoaderManager().initLoader(0, null, this);
+        }
+
+        @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            // Place an action bar item for searching.
+            //MenuItem item = menu.add("Search");
+            //item.setIcon(android.R.drawable.ic_menu_search);
+            //item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            //SearchView sv = new SearchView(getActivity());
+            //sv.setOnQueryTextListener(this);
+            //item.setActionView(sv);
+        }
+
+        public boolean onQueryTextChange(String newText) {
+            // Called when the action bar search text has changed.  Update
+            // the search filter, and restart the loader to do a new query
+            // with this filter.
+            mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+            getLoaderManager().restartLoader(0, null, this);
+            return true;
+        }
+
+        @Override public void onListItemClick(ListView l, View v, int position, long id) {
+            // Insert desired behavior here.
+            Log.i("FragmentComplexList", "Item clicked: " + id);
+        }
+
+        // These are the Contacts rows that we will retrieve.
+        static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
+            Contacts._ID,
+            Contacts.DISPLAY_NAME,
+            Contacts.CONTACT_STATUS,
+            Contacts.CONTACT_PRESENCE,
+            Contacts.PHOTO_ID,
+            Contacts.LOOKUP_KEY,
+        };
+
+        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+            // This is called when a new Loader needs to be created.  This
+            // sample only has one Loader, so we don't care about the ID.
+            // First, pick the base URI to use depending on whether we are
+            // currently filtering.
+            Uri baseUri;
+            if (mCurFilter != null) {
+                baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+                        Uri.encode(mCurFilter));
+            } else {
+                baseUri = Contacts.CONTENT_URI;
+            }
+
+            // Now create and return a CursorLoader that will take care of
+            // creating a Cursor for the data being displayed.
+            String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+                    + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+                    + Contacts.DISPLAY_NAME + " != '' ))";
+            return new CursorLoader(getActivity(), baseUri,
+                    CONTACTS_SUMMARY_PROJECTION, select, null,
+                    Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
+        }
+
+        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+            // Swap the new cursor in.  (The framework will take care of closing the
+            // old cursor once we return.)
+            mAdapter.swapCursor(data);
+        }
+
+        public void onLoaderReset(Loader<Cursor> loader) {
+            // This is called when the last Cursor provided to onLoadFinished()
+            // above is about to be closed.  We need to make sure we are no
+            // longer using it.
+            mAdapter.swapCursor(null);
+        }
+    }
+//END_INCLUDE(fragment_cursor)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/support/app/LoaderThrottleSupport.java b/samples/ApiDemos/src/com/example/android/apis/support/app/LoaderThrottleSupport.java
new file mode 100644
index 0000000..e8f4af5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/support/app/LoaderThrottleSupport.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.support.app;
+
+//BEGIN_INCLUDE(complete)
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.ListFragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v4.widget.SimpleCursorAdapter;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.BaseColumns;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+
+import java.util.HashMap;
+
+/**
+ * Demonstration of bottom to top implementation of a content provider holding
+ * structured data through displaying it in the UI, using throttling to reduce
+ * the number of queries done when its data changes.
+ */
+public class LoaderThrottleSupport extends FragmentActivity {
+    // Debugging.
+    static final String TAG = "LoaderThrottle";
+
+    /**
+     * The authority we use to get to our sample provider.
+     */
+    public static final String AUTHORITY = "com.example.android.apis.support.app.LoaderThrottle";
+
+    /**
+     * Definition of the contract for the main table of our provider.
+     */
+    public static final class MainTable implements BaseColumns {
+
+        // This class cannot be instantiated
+        private MainTable() {}
+
+        /**
+         * The table name offered by this provider
+         */
+        public static final String TABLE_NAME = "main";
+
+        /**
+         * The content:// style URL for this table
+         */
+        public static final Uri CONTENT_URI =  Uri.parse("content://" + AUTHORITY + "/main");
+
+        /**
+         * The content URI base for a single row of data. Callers must
+         * append a numeric row id to this Uri to retrieve a row
+         */
+        public static final Uri CONTENT_ID_URI_BASE
+                = Uri.parse("content://" + AUTHORITY + "/main/");
+
+        /**
+         * The MIME type of {@link #CONTENT_URI}.
+         */
+        public static final String CONTENT_TYPE
+                = "vnd.android.cursor.dir/vnd.example.api-demos-throttle";
+
+        /**
+         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single row.
+         */
+        public static final String CONTENT_ITEM_TYPE
+                = "vnd.android.cursor.item/vnd.example.api-demos-throttle";
+        /**
+         * The default sort order for this table
+         */
+        public static final String DEFAULT_SORT_ORDER = "data COLLATE LOCALIZED ASC";
+
+        /**
+         * Column name for the single column holding our data.
+         * <P>Type: TEXT</P>
+         */
+        public static final String COLUMN_NAME_DATA = "data";
+    }
+
+    /**
+     * This class helps open, create, and upgrade the database file.
+     */
+   static class DatabaseHelper extends SQLiteOpenHelper {
+
+       private static final String DATABASE_NAME = "loader_throttle.db";
+       private static final int DATABASE_VERSION = 2;
+
+       DatabaseHelper(Context context) {
+
+           // calls the super constructor, requesting the default cursor factory.
+           super(context, DATABASE_NAME, null, DATABASE_VERSION);
+       }
+
+       /**
+        *
+        * Creates the underlying database with table name and column names taken from the
+        * NotePad class.
+        */
+       @Override
+       public void onCreate(SQLiteDatabase db) {
+           db.execSQL("CREATE TABLE " + MainTable.TABLE_NAME + " ("
+                   + MainTable._ID + " INTEGER PRIMARY KEY,"
+                   + MainTable.COLUMN_NAME_DATA + " TEXT"
+                   + ");");
+       }
+
+       /**
+        *
+        * Demonstrates that the provider must consider what happens when the
+        * underlying datastore is changed. In this sample, the database is upgraded the database
+        * by destroying the existing data.
+        * A real application should upgrade the database in place.
+        */
+       @Override
+       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+           // Logs that the database is being upgraded
+           Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                   + newVersion + ", which will destroy all old data");
+
+           // Kills the table and existing data
+           db.execSQL("DROP TABLE IF EXISTS notes");
+
+           // Recreates the database with a new version
+           onCreate(db);
+       }
+   }
+
+    /**
+     * A very simple implementation of a content provider.
+     */
+    public static class SimpleProvider extends ContentProvider {
+        // A projection map used to select columns from the database
+        private final HashMap<String, String> mNotesProjectionMap;
+        // Uri matcher to decode incoming URIs.
+        private final UriMatcher mUriMatcher;
+
+        // The incoming URI matches the main table URI pattern
+        private static final int MAIN = 1;
+        // The incoming URI matches the main table row ID URI pattern
+        private static final int MAIN_ID = 2;
+
+        // Handle to a new DatabaseHelper.
+        private DatabaseHelper mOpenHelper;
+
+        /**
+         * Global provider initialization.
+         */
+        public SimpleProvider() {
+            // Create and initialize URI matcher.
+            mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+            mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME, MAIN);
+            mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME + "/#", MAIN_ID);
+
+            // Create and initialize projection map for all columns.  This is
+            // simply an identity mapping.
+            mNotesProjectionMap = new HashMap<String, String>();
+            mNotesProjectionMap.put(MainTable._ID, MainTable._ID);
+            mNotesProjectionMap.put(MainTable.COLUMN_NAME_DATA, MainTable.COLUMN_NAME_DATA);
+        }
+
+        /**
+         * Perform provider creation.
+         */
+        @Override
+        public boolean onCreate() {
+            mOpenHelper = new DatabaseHelper(getContext());
+            // Assumes that any failures will be reported by a thrown exception.
+            return true;
+        }
+
+        /**
+         * Handle incoming queries.
+         */
+        @Override
+        public Cursor query(Uri uri, String[] projection, String selection,
+                String[] selectionArgs, String sortOrder) {
+
+            // Constructs a new query builder and sets its table name
+            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setTables(MainTable.TABLE_NAME);
+
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    // If the incoming URI is for main table.
+                    qb.setProjectionMap(mNotesProjectionMap);
+                    break;
+
+                case MAIN_ID:
+                    // The incoming URI is for a single row.
+                    qb.setProjectionMap(mNotesProjectionMap);
+                    qb.appendWhere(MainTable._ID + "=?");
+                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
+                            new String[] { uri.getLastPathSegment() });
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+
+            if (TextUtils.isEmpty(sortOrder)) {
+                sortOrder = MainTable.DEFAULT_SORT_ORDER;
+            }
+
+            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+            Cursor c = qb.query(db, projection, selection, selectionArgs,
+                    null /* no group */, null /* no filter */, sortOrder);
+
+            c.setNotificationUri(getContext().getContentResolver(), uri);
+            return c;
+        }
+
+        /**
+         * Return the MIME type for an known URI in the provider.
+         */
+        @Override
+        public String getType(Uri uri) {
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    return MainTable.CONTENT_TYPE;
+                case MAIN_ID:
+                    return MainTable.CONTENT_ITEM_TYPE;
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+        }
+
+        /**
+         * Handler inserting new data.
+         */
+        @Override
+        public Uri insert(Uri uri, ContentValues initialValues) {
+            if (mUriMatcher.match(uri) != MAIN) {
+                // Can only insert into to main URI.
+                throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+            ContentValues values;
+
+            if (initialValues != null) {
+                values = new ContentValues(initialValues);
+            } else {
+                values = new ContentValues();
+            }
+
+            if (values.containsKey(MainTable.COLUMN_NAME_DATA) == false) {
+                values.put(MainTable.COLUMN_NAME_DATA, "");
+            }
+
+            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+            long rowId = db.insert(MainTable.TABLE_NAME, null, values);
+
+            // If the insert succeeded, the row ID exists.
+            if (rowId > 0) {
+                Uri noteUri = ContentUris.withAppendedId(MainTable.CONTENT_ID_URI_BASE, rowId);
+                getContext().getContentResolver().notifyChange(noteUri, null);
+                return noteUri;
+            }
+
+            throw new SQLException("Failed to insert row into " + uri);
+        }
+
+        /**
+         * Handle deleting data.
+         */
+        @Override
+        public int delete(Uri uri, String where, String[] whereArgs) {
+            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+            String finalWhere;
+
+            int count;
+
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    // If URI is main table, delete uses incoming where clause and args.
+                    count = db.delete(MainTable.TABLE_NAME, where, whereArgs);
+                    break;
+
+                    // If the incoming URI matches a single note ID, does the delete based on the
+                    // incoming data, but modifies the where clause to restrict it to the
+                    // particular note ID.
+                case MAIN_ID:
+                    // If URI is for a particular row ID, delete is based on incoming
+                    // data but modified to restrict to the given ID.
+                    finalWhere = DatabaseUtils.concatenateWhere(
+                            MainTable._ID + " = " + ContentUris.parseId(uri), where);
+                    count = db.delete(MainTable.TABLE_NAME, finalWhere, whereArgs);
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+            getContext().getContentResolver().notifyChange(uri, null);
+
+            return count;
+        }
+
+        /**
+         * Handle updating data.
+         */
+        @Override
+        public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
+            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+            int count;
+            String finalWhere;
+
+            switch (mUriMatcher.match(uri)) {
+                case MAIN:
+                    // If URI is main table, update uses incoming where clause and args.
+                    count = db.update(MainTable.TABLE_NAME, values, where, whereArgs);
+                    break;
+
+                case MAIN_ID:
+                    // If URI is for a particular row ID, update is based on incoming
+                    // data but modified to restrict to the given ID.
+                    finalWhere = DatabaseUtils.concatenateWhere(
+                            MainTable._ID + " = " + ContentUris.parseId(uri), where);
+                    count = db.update(MainTable.TABLE_NAME, values, finalWhere, whereArgs);
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+
+            getContext().getContentResolver().notifyChange(uri, null);
+
+            return count;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        FragmentManager fm = getSupportFragmentManager();
+
+        // Create the list fragment and add it as our sole content.
+        if (fm.findFragmentById(android.R.id.content) == null) {
+            ThrottledLoaderListFragment list = new ThrottledLoaderListFragment();
+            fm.beginTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+    public static class ThrottledLoaderListFragment extends ListFragment
+            implements LoaderManager.LoaderCallbacks<Cursor> {
+
+        // Menu identifiers
+        static final int POPULATE_ID = Menu.FIRST;
+        static final int CLEAR_ID = Menu.FIRST+1;
+
+        // This is the Adapter being used to display the list's data.
+        SimpleCursorAdapter mAdapter;
+
+        // If non-null, this is the current filter the user has provided.
+        String mCurFilter;
+
+        // Task we have running to populate the database.
+        AsyncTask<Void, Void, Void> mPopulatingTask;
+
+        @Override public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            setEmptyText("No data.  Select 'Populate' to fill with data from Z to A at a rate of 4 per second.");
+            setHasOptionsMenu(true);
+
+            // Create an empty adapter we will use to display the loaded data.
+            mAdapter = new SimpleCursorAdapter(getActivity(),
+                    android.R.layout.simple_list_item_1, null,
+                    new String[] { MainTable.COLUMN_NAME_DATA },
+                    new int[] { android.R.id.text1 }, 0);
+            setListAdapter(mAdapter);
+
+            // Prepare the loader.  Either re-connect with an existing one,
+            // or start a new one.
+            getLoaderManager().initLoader(0, null, this);
+        }
+
+        @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            menu.add(Menu.NONE, POPULATE_ID, 0, "Populate")
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            menu.add(Menu.NONE, CLEAR_ID, 0, "Clear")
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        }
+
+        @Override public boolean onOptionsItemSelected(MenuItem item) {
+            final ContentResolver cr = getActivity().getContentResolver();
+
+            switch (item.getItemId()) {
+                case POPULATE_ID:
+                    if (mPopulatingTask != null) {
+                        mPopulatingTask.cancel(false);
+                    }
+                    mPopulatingTask = new AsyncTask<Void, Void, Void>() {
+                        @Override protected Void doInBackground(Void... params) {
+                            for (char c='Z'; c>='A'; c--) {
+                                if (isCancelled()) {
+                                    break;
+                                }
+                                StringBuilder builder = new StringBuilder("Data ");
+                                builder.append(c);
+                                ContentValues values = new ContentValues();
+                                values.put(MainTable.COLUMN_NAME_DATA, builder.toString());
+                                cr.insert(MainTable.CONTENT_URI, values);
+                                // Wait a bit between each insert.
+                                try {
+                                    Thread.sleep(250);
+                                } catch (InterruptedException e) {
+                                }
+                            }
+                            return null;
+                        }
+                    };
+                    mPopulatingTask.executeOnExecutor(
+                            AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
+                    return true;
+
+                case CLEAR_ID:
+                    if (mPopulatingTask != null) {
+                        mPopulatingTask.cancel(false);
+                        mPopulatingTask = null;
+                    }
+                    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+                        @Override protected Void doInBackground(Void... params) {
+                            cr.delete(MainTable.CONTENT_URI, null, null);
+                            return null;
+                        }
+                    };
+                    task.execute((Void[])null);
+                    return true;
+
+                default:
+                    return super.onOptionsItemSelected(item);
+            }
+        }
+
+        @Override public void onListItemClick(ListView l, View v, int position, long id) {
+            // Insert desired behavior here.
+            Log.i(TAG, "Item clicked: " + id);
+        }
+
+        // These are the rows that we will retrieve.
+        static final String[] PROJECTION = new String[] {
+            MainTable._ID,
+            MainTable.COLUMN_NAME_DATA,
+        };
+
+        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+            CursorLoader cl = new CursorLoader(getActivity(), MainTable.CONTENT_URI,
+                    PROJECTION, null, null, null);
+            cl.setUpdateThrottle(2000); // update at most every 2 seconds.
+            return cl;
+        }
+
+        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+            mAdapter.swapCursor(data);
+        }
+
+        public void onLoaderReset(Loader<Cursor> loader) {
+            mAdapter.swapCursor(null);
+        }
+    }
+}
+//END_INCLUDE(complete)
diff --git a/samples/ApiDemos/src/com/example/android/apis/text/_index.html b/samples/ApiDemos/src/com/example/android/apis/text/_index.html
index ee1020b..c995a0c 100644
--- a/samples/ApiDemos/src/com/example/android/apis/text/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/text/_index.html
@@ -1,6 +1,8 @@
 <dl>
   <dt><a href="Link.html">Linkify</a></dt>
-  <dd>Demonstrates the {@link android.text.util.Linkify Linkify} class, which converts URLs in a block of text into hyperlinks. </dd>
+  <dd>Demonstrates the <a                                                                            
+href="../../../../../../../../../reference/android/text/util/Linkify.html"><code>Linkify</code>
+class, which converts URLs in a block of text into hyperlinks. </dd>
 </dl>
 
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/CheckableFrameLayout.java b/samples/ApiDemos/src/com/example/android/apis/view/CheckableFrameLayout.java
new file mode 100644
index 0000000..ecb222f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/CheckableFrameLayout.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.content.Context;
+import android.graphics.drawable.ColorDrawable;
+import android.util.AttributeSet;
+import android.widget.Checkable;
+import android.widget.FrameLayout;
+
+public class CheckableFrameLayout extends FrameLayout implements Checkable {
+    private boolean mChecked;
+
+    public CheckableFrameLayout(Context context) {
+        super(context);
+    }
+
+    public CheckableFrameLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setChecked(boolean checked) {
+        mChecked = checked;
+        setBackgroundDrawable(checked ? new ColorDrawable(0xff0000a0) : null);
+    }
+
+    public boolean isChecked() {
+        return mChecked;
+    }
+
+    public void toggle() {
+        setChecked(!mChecked);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Cheeses.java b/samples/ApiDemos/src/com/example/android/apis/view/Cheeses.java
new file mode 100644
index 0000000..bcf7d61
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Cheeses.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+
+public class Cheeses {
+
+    public static final String[] sCheeseStrings = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+            "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+            "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+            "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+            "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+            "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+            "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+            "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+            "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+            "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+            "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+            "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+            "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+            "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+            "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+            "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+            "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+            "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+            "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+            "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+            "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+            "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+            "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+            "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+            "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+            "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+            "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+            "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+            "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+            "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+            "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+            "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+            "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+            "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+            "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+            "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+            "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+            "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+            "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+            "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+            "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+            "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+            "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+            "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+            "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+            "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+            "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+            "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+            "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+            "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+            "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+            "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+            "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+            "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+            "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+            "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+            "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+            "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+            "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+            "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+            "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+            "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+            "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+            "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+            "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+            "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+            "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+            "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+            "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+            "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+            "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+            "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+            "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+            "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+            "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+            "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+            "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+            "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+            "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+            "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+            "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+            "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+            "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+            "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+            "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+            "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+            "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+            "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+            "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+            "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+            "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+    };
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls1.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls1.java
index e2d348f..2b5a3f5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Controls1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls1.java
@@ -22,8 +22,9 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import android.widget.Spinner;
 import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.Spinner;
 
 
 /**
@@ -37,6 +38,9 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.controls_1);
 
+        Button disabledButton = (Button) findViewById(R.id.button_disabled);
+        disabledButton.setEnabled(false);
+
         Spinner s1 = (Spinner) findViewById(R.id.spinner1);
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_spinner_item, mStrings);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls2.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls2.java
index 4f4024b..42bc297 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Controls2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls2.java
@@ -16,35 +16,4 @@
 
 package com.example.android.apis.view;
 
-// Need the following import to get access to the app resources, since this
-// class is in a sub-package.
-import com.example.android.apis.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.widget.Spinner;
-import android.widget.ArrayAdapter;
-
-
-/**
- * A gallery of basic controls: Button, EditText, RadioButton, Checkbox,
- * Spinner. This example uses the default theme.
- */
-public class Controls2 extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.controls_1);
-
-        Spinner s1 = (Spinner) findViewById(R.id.spinner1);
-        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
-                android.R.layout.simple_spinner_item, mStrings);
-        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        s1.setAdapter(adapter);
-    }
-
-    private static final String[] mStrings = {
-	    "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"
-    };
-}
+public class Controls2 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java
new file mode 100644
index 0000000..407767f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+public class Controls3 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java
new file mode 100644
index 0000000..3dcf310
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+public class Controls4 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls5.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls5.java
new file mode 100644
index 0000000..dcc515b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls5.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.view;
+
+public class Controls5 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls6.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls6.java
new file mode 100644
index 0000000..3002259
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls6.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.view;
+
+public class Controls6 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.java b/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.java
new file mode 100644
index 0000000..e1f3b56
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.DragEvent;
+import android.view.View;
+import android.widget.TextView;
+
+public class DragAndDropDemo extends Activity {
+    TextView mResultText;
+    DraggableDot mHiddenDot;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.drag_layout);
+
+        TextView text = (TextView) findViewById(R.id.drag_text);
+        DraggableDot dot = (DraggableDot) findViewById(R.id.drag_dot_1);
+        dot.setReportView(text);
+        dot = (DraggableDot) findViewById(R.id.drag_dot_2);
+        dot.setReportView(text);
+        dot = (DraggableDot) findViewById(R.id.drag_dot_3);
+        dot.setReportView(text);
+
+        mHiddenDot = (DraggableDot) findViewById(R.id.drag_dot_hidden);
+        mHiddenDot.setReportView(text);
+
+        mResultText = (TextView) findViewById(R.id.drag_result_text);
+        mResultText.setOnDragListener(new View.OnDragListener() {
+            public boolean onDrag(View v, DragEvent event) {
+                final int action = event.getAction();
+                switch (action) {
+                    case DragEvent.ACTION_DRAG_STARTED: {
+                        // Bring up a fourth draggable dot on the fly. Note that it
+                        // is properly notified about the ongoing drag, and lights up
+                        // to indicate that it can handle the current content.
+                        mHiddenDot.setVisibility(View.VISIBLE);
+                    } break;
+
+                    case DragEvent.ACTION_DRAG_ENDED: {
+                        // Hide the surprise again
+                        mHiddenDot.setVisibility(View.INVISIBLE);
+
+                        // Report the drop/no-drop result to the user
+                        final boolean dropped = event.getResult();
+                        mResultText.setText(dropped ? "Dropped!" : "No drop");
+                    } break;
+                }
+                return false;
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.java b/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.java
new file mode 100644
index 0000000..5ac4ea5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.content.ClipData;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.*;
+import android.os.SystemClock;
+import android.text.TextPaint;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.DragEvent;
+import android.view.View;
+import android.widget.TextView;
+
+public class DraggableDot extends View {
+    static final String TAG = "DraggableDot";
+
+    private boolean mDragInProgress;
+    private boolean mHovering;
+    private boolean mAcceptsDrag;
+    TextView mReportView;
+
+    private Paint mPaint;
+    private TextPaint mLegendPaint;
+    private Paint mGlow;
+    private static final int NUM_GLOW_STEPS = 10;
+    private static final int GREEN_STEP = 0x0000FF00 / NUM_GLOW_STEPS;
+    private static final int WHITE_STEP = 0x00FFFFFF / NUM_GLOW_STEPS;
+    private static final int ALPHA_STEP = 0xFF000000 / NUM_GLOW_STEPS;
+
+    int mRadius;
+    int mAnrType;
+    CharSequence mLegend;
+
+    static final int ANR_NONE = 0;
+    static final int ANR_SHADOW = 1;
+    static final int ANR_DROP = 2;
+
+    void sleepSixSeconds() {
+        // hang forever; good for producing ANRs
+        long start = SystemClock.uptimeMillis();
+        do {
+            try { Thread.sleep(1000); } catch (InterruptedException e) {}
+        } while (SystemClock.uptimeMillis() < start + 6000);
+    }
+
+    // Shadow builder that can ANR if desired
+    class ANRShadowBuilder extends DragShadowBuilder {
+        boolean mDoAnr;
+
+        public ANRShadowBuilder(View view, boolean doAnr) {
+            super(view);
+            mDoAnr = doAnr;
+        }
+
+        @Override
+        public void onDrawShadow(Canvas canvas) {
+            if (mDoAnr) {
+                sleepSixSeconds();
+            }
+            super.onDrawShadow(canvas);
+        }
+    }
+
+    public DraggableDot(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        setFocusable(true);
+        setClickable(true);
+
+        mLegend = "";
+
+        mPaint = new Paint();
+        mPaint.setAntiAlias(true);
+        mPaint.setStrokeWidth(6);
+        mPaint.setColor(0xFFD00000);
+
+        mLegendPaint = new TextPaint();
+        mLegendPaint.setAntiAlias(true);
+        mLegendPaint.setTextAlign(Paint.Align.CENTER);
+        mLegendPaint.setColor(0xFFF0F0FF);
+
+        mGlow = new Paint();
+        mGlow.setAntiAlias(true);
+        mGlow.setStrokeWidth(1);
+        mGlow.setStyle(Paint.Style.STROKE);
+
+        // look up any layout-defined attributes
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.DraggableDot);
+
+        final int N = a.getIndexCount();
+        for (int i = 0; i < N; i++) {
+            int attr = a.getIndex(i);
+            switch (attr) {
+            case R.styleable.DraggableDot_radius: {
+                mRadius = a.getDimensionPixelSize(attr, 0);
+            } break;
+
+            case R.styleable.DraggableDot_legend: {
+                mLegend = a.getText(attr);
+            } break;
+
+            case R.styleable.DraggableDot_anr: {
+                mAnrType = a.getInt(attr, 0);
+            } break;
+            }
+        }
+
+        Log.i(TAG, "DraggableDot @ " + this + " : radius=" + mRadius + " legend='" + mLegend
+                + "' anr=" + mAnrType);
+
+        setOnLongClickListener(new View.OnLongClickListener() {
+            public boolean onLongClick(View v) {
+                ClipData data = ClipData.newPlainText("dot", "Dot : " + v.toString());
+                v.startDrag(data, new ANRShadowBuilder(v, mAnrType == ANR_SHADOW),
+                        (Object)v, 0);
+                return true;
+            }
+        });
+    }
+
+    void setReportView(TextView view) {
+        mReportView = view;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        float wf = getWidth();
+        float hf = getHeight();
+        final float cx = wf/2;
+        final float cy = hf/2;
+        wf -= getPaddingLeft() + getPaddingRight();
+        hf -= getPaddingTop() + getPaddingBottom();
+        float rad = (wf < hf) ? wf/2 : hf/2;
+        canvas.drawCircle(cx, cy, rad, mPaint);
+
+        if (mLegend != null && mLegend.length() > 0) {
+            canvas.drawText(mLegend, 0, mLegend.length(),
+                    cx, cy + mLegendPaint.getFontSpacing()/2,
+                    mLegendPaint);
+        }
+
+        // if we're in the middle of a drag, light up as a potential target
+        if (mDragInProgress && mAcceptsDrag) {
+            for (int i = NUM_GLOW_STEPS; i > 0; i--) {
+                int color = (mHovering) ? WHITE_STEP : GREEN_STEP;
+                color = i*(color | ALPHA_STEP);
+                mGlow.setColor(color);
+                canvas.drawCircle(cx, cy, rad, mGlow);
+                rad -= 0.5f;
+                canvas.drawCircle(cx, cy, rad, mGlow);
+                rad -= 0.5f;
+            }
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        int totalDiameter = 2*mRadius + getPaddingLeft() + getPaddingRight();
+        setMeasuredDimension(totalDiameter, totalDiameter);
+    }
+
+    /**
+     * Drag and drop
+     */
+    @Override
+    public boolean onDragEvent(DragEvent event) {
+        boolean result = false;
+        switch (event.getAction()) {
+        case DragEvent.ACTION_DRAG_STARTED: {
+            // claim to accept any dragged content
+            Log.i(TAG, "Drag started, event=" + event);
+            // cache whether we accept the drag to return for LOCATION events
+            mDragInProgress = true;
+            mAcceptsDrag = result = true;
+            // Redraw in the new visual state if we are a potential drop target
+            if (mAcceptsDrag) {
+                invalidate();
+            }
+        } break;
+
+        case DragEvent.ACTION_DRAG_ENDED: {
+            Log.i(TAG, "Drag ended.");
+            if (mAcceptsDrag) {
+                invalidate();
+            }
+            mDragInProgress = false;
+            mHovering = false;
+        } break;
+
+        case DragEvent.ACTION_DRAG_LOCATION: {
+            // we returned true to DRAG_STARTED, so return true here
+            Log.i(TAG, "... seeing drag locations ...");
+            result = mAcceptsDrag;
+        } break;
+
+        case DragEvent.ACTION_DROP: {
+            Log.i(TAG, "Got a drop! dot=" + this + " event=" + event);
+            if (mAnrType == ANR_DROP) {
+                sleepSixSeconds();
+            }
+            processDrop(event);
+            result = true;
+        } break;
+
+        case DragEvent.ACTION_DRAG_ENTERED: {
+            Log.i(TAG, "Entered dot @ " + this);
+            mHovering = true;
+            invalidate();
+        } break;
+
+        case DragEvent.ACTION_DRAG_EXITED: {
+            Log.i(TAG, "Exited dot @ " + this);
+            mHovering = false;
+            invalidate();
+        } break;
+
+        default:
+            Log.i(TAG, "other drag event: " + event);
+            result = mAcceptsDrag;
+            break;
+        }
+
+        return result;
+    }
+
+    private void processDrop(DragEvent event) {
+        final ClipData data = event.getClipData();
+        final int N = data.getItemCount();
+        for (int i = 0; i < N; i++) {
+            ClipData.Item item = data.getItemAt(i);
+            Log.i(TAG, "Dropped item " + i + " : " + item);
+            if (mReportView != null) {
+                String text = item.coerceToText(getContext()).toString();
+                if (event.getLocalState() == (Object) this) {
+                    text += " : Dropped on self!";
+                }
+                mReportView.setText(text);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
index b6cce29..8b2cb43 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
@@ -17,71 +17,122 @@
 package com.example.android.apis.view;
 
 import android.app.ExpandableListActivity;
+import android.content.AsyncQueryHandler;
+import android.content.ContentUris;
 import android.content.Context;
 import android.database.Cursor;
+import android.net.Uri;
 import android.os.Bundle;
-import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.widget.ExpandableListAdapter;
+import android.provider.ContactsContract.Contacts;
+import android.widget.CursorTreeAdapter;
 import android.widget.SimpleCursorTreeAdapter;
 
 /**
  * Demonstrates expandable lists backed by Cursors
  */
 public class ExpandableList2 extends ExpandableListActivity {
-    private static final int COLUMN_CONTACT_ID = 0;
 
-    private static final String[] CONTACT_PROJECTION = new String[] {
+    private static final String[] CONTACTS_PROJECTION = new String[] {
         Contacts._ID,
         Contacts.DISPLAY_NAME
     };
+    private static final int GROUP_ID_COLUMN_INDEX = 0;
 
-    private static final String[] PHONE_PROJECTION = new String[] {
-        Phone._ID,
-        Phone.CONTACT_ID,
-        Phone.NUMBER
+    private static final String[] PHONE_NUMBER_PROJECTION = new String[] {
+            Phone._ID,
+            Phone.NUMBER
     };
 
-    private ExpandableListAdapter mAdapter;
+    private static final int TOKEN_GROUP = 0;
+    private static final int TOKEN_CHILD = 1;
 
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+    private static final class QueryHandler extends AsyncQueryHandler {
+        private CursorTreeAdapter mAdapter;
 
-        // Query for people
-        Cursor groupCursor = managedQuery(Contacts.CONTENT_URI,
-                CONTACT_PROJECTION, null, null, null);
+        public QueryHandler(Context context, CursorTreeAdapter adapter) {
+            super(context.getContentResolver());
+            this.mAdapter = adapter;
+        }
 
-        // Set up our adapter
-        mAdapter = new MyExpandableListAdapter(groupCursor,
-                this,
-                android.R.layout.simple_expandable_list_item_1,
-                android.R.layout.simple_expandable_list_item_1,
-                new String[] {Contacts.DISPLAY_NAME}, // Name for group layouts
-                new int[] {android.R.id.text1},
-                new String[] {Phone.NUMBER}, // Number for child layouts
-                new int[] {android.R.id.text1});
-        setListAdapter(mAdapter);
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            switch (token) {
+            case TOKEN_GROUP:
+                mAdapter.setGroupCursor(cursor);
+                break;
+
+            case TOKEN_CHILD:
+                int groupPosition = (Integer) cookie;
+                mAdapter.setChildrenCursor(groupPosition, cursor);
+                break;
+            }
+        }
     }
 
     public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
 
-        public MyExpandableListAdapter(Cursor cursor, Context context, int groupLayout,
+        // Note that the constructor does not take a Cursor. This is done to avoid querying the 
+        // database on the main thread.
+        public MyExpandableListAdapter(Context context, int groupLayout,
                 int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
                 int[] childrenTo) {
-            super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
+
+            super(context, null, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
                     childrenTo);
         }
 
         @Override
         protected Cursor getChildrenCursor(Cursor groupCursor) {
-            int contactId = groupCursor.getInt(COLUMN_CONTACT_ID);
-            // The returned Cursor MUST be managed by us, so we use Activity's helper
-            // functionality to manage it for us.
-            return managedQuery(Phone.CONTENT_URI,
-                    PHONE_PROJECTION,
-                    Phone.CONTACT_ID + " = " + contactId,
-                    null, null);
+            // Given the group, we return a cursor for all the children within that group 
+
+            // Return a cursor that points to this contact's phone numbers
+            Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();
+            ContentUris.appendId(builder, groupCursor.getLong(GROUP_ID_COLUMN_INDEX));
+            builder.appendEncodedPath(Contacts.Data.CONTENT_DIRECTORY);
+            Uri phoneNumbersUri = builder.build();
+
+            mQueryHandler.startQuery(TOKEN_CHILD, groupCursor.getPosition(), phoneNumbersUri, 
+                    PHONE_NUMBER_PROJECTION, Phone.MIMETYPE + "=?", 
+                    new String[] { Phone.CONTENT_ITEM_TYPE }, null);
+
+            return null;
         }
     }
-}
\ No newline at end of file
+
+    private QueryHandler mQueryHandler;
+    private CursorTreeAdapter mAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Set up our adapter
+        mAdapter = new MyExpandableListAdapter(
+                this,
+                android.R.layout.simple_expandable_list_item_1,
+                android.R.layout.simple_expandable_list_item_1,
+                new String[] { Contacts.DISPLAY_NAME }, // Name for group layouts
+                new int[] { android.R.id.text1 },
+                new String[] { Phone.NUMBER }, // Number for child layouts
+                new int[] { android.R.id.text1 });
+
+        setListAdapter(mAdapter);
+
+        mQueryHandler = new QueryHandler(this, mAdapter);
+
+        // Query for people
+        mQueryHandler.startQuery(TOKEN_GROUP, null, Contacts.CONTENT_URI, CONTACTS_PROJECTION, 
+                Contacts.HAS_PHONE_NUMBER + "=1", null, null);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        // Null out the group cursor. This will cause the group cursor and all of the child cursors
+        // to be closed.
+        mAdapter.changeCursor(null);
+        mAdapter = null;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Focus5.java b/samples/ApiDemos/src/com/example/android/apis/view/Focus5.java
new file mode 100644
index 0000000..728671c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Focus5.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+import com.example.android.apis.R;
+
+public class Focus5 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.focus_5);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
index 7aaaaef..b252d5a 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
@@ -71,8 +71,25 @@
     }
 
     public class ImageAdapter extends BaseAdapter {
-        int mGalleryItemBackground;
-        
+        private static final int ITEM_WIDTH = 136;
+        private static final int ITEM_HEIGHT = 88;
+
+        private final int mGalleryItemBackground;
+        private final Context mContext;
+
+        private final Integer[] mImageIds = {
+                R.drawable.gallery_photo_1,
+                R.drawable.gallery_photo_2,
+                R.drawable.gallery_photo_3,
+                R.drawable.gallery_photo_4,
+                R.drawable.gallery_photo_5,
+                R.drawable.gallery_photo_6,
+                R.drawable.gallery_photo_7,
+                R.drawable.gallery_photo_8
+        };
+
+        private final float mDensity;
+
         public ImageAdapter(Context c) {
             mContext = c;
             // See res/values/attrs.xml for the <declare-styleable> that defines
@@ -81,6 +98,8 @@
             mGalleryItemBackground = a.getResourceId(
                     R.styleable.Gallery1_android_galleryItemBackground, 0);
             a.recycle();
+
+            mDensity = c.getResources().getDisplayMetrics().density;
         }
 
         public int getCount() {
@@ -96,30 +115,25 @@
         }
 
         public View getView(int position, View convertView, ViewGroup parent) {
-            ImageView i = new ImageView(mContext);
+            ImageView imageView;
+            if (convertView == null) {
+                convertView = new ImageView(mContext);
 
-            i.setImageResource(mImageIds[position]);
-            i.setScaleType(ImageView.ScaleType.FIT_XY);
-            i.setLayoutParams(new Gallery.LayoutParams(136, 88));
+                imageView = (ImageView) convertView;
+                imageView.setScaleType(ImageView.ScaleType.FIT_XY);
+                imageView.setLayoutParams(new Gallery.LayoutParams(
+                        (int) (ITEM_WIDTH * mDensity + 0.5f),
+                        (int) (ITEM_HEIGHT * mDensity + 0.5f)));
             
-            // The preferred Gallery item background
-            i.setBackgroundResource(mGalleryItemBackground);
-            
-            return i;
+                // The preferred Gallery item background
+                imageView.setBackgroundResource(mGalleryItemBackground);
+            } else {
+                imageView = (ImageView) convertView;
+            }
+
+            imageView.setImageResource(mImageIds[position]);
+
+            return imageView;
         }
-
-        private Context mContext;
-
-        private Integer[] mImageIds = {
-                R.drawable.gallery_photo_1,
-                R.drawable.gallery_photo_2,
-                R.drawable.gallery_photo_3,
-                R.drawable.gallery_photo_4,
-                R.drawable.gallery_photo_5,
-                R.drawable.gallery_photo_6,
-                R.drawable.gallery_photo_7,
-                R.drawable.gallery_photo_8
-        };
     }
-
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/GameControllerInput.java b/samples/ApiDemos/src/com/example/android/apis/view/GameControllerInput.java
new file mode 100644
index 0000000..8aea949
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/GameControllerInput.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.InputDevice.MotionRange;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+
+
+/**
+ * Demonstrates how to process input events received from game controllers.
+ *
+ * This activity displays button states and joystick positions.
+ * Also writes detailed information about relevant input events to the log.
+ *
+ * The game controller is also uses to control a very simple game.  See {@link GameView}
+ * for the game itself.
+ */
+public class GameControllerInput extends Activity {
+    private static final String TAG = "GameControllerInput";
+
+    private SparseArray<InputDeviceState> mInputDeviceStates;
+    private GameView mGame;
+    private ListView mSummaryList;
+    private SummaryAdapter mSummaryAdapter;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mInputDeviceStates = new SparseArray<InputDeviceState>();
+        mSummaryAdapter = new SummaryAdapter(this, getResources());
+
+        setContentView(R.layout.game_controller_input);
+
+        mGame = (GameView) findViewById(R.id.game);
+
+        mSummaryList = (ListView) findViewById(R.id.summary);
+        mSummaryList.setAdapter(mSummaryAdapter);
+        mSummaryList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                mSummaryAdapter.onItemClick(position);
+            }
+        });
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+
+        mGame.requestFocus();
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        // Update device state for visualization and logging.
+        InputDeviceState state = getInputDeviceState(event);
+        if (state != null) {
+            switch (event.getAction()) {
+                case KeyEvent.ACTION_DOWN:
+                    if (state.onKeyDown(event)) {
+                        mSummaryAdapter.show(state);
+                    }
+                    break;
+                case KeyEvent.ACTION_UP:
+                    if (state.onKeyUp(event)) {
+                        mSummaryAdapter.show(state);
+                    }
+                    break;
+            }
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
+    @Override
+    public boolean dispatchGenericMotionEvent(MotionEvent event) {
+        // Check that the event came from a joystick since a generic motion event
+        // could be almost anything.
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0
+                && event.getAction() == MotionEvent.ACTION_MOVE) {
+            // Update device state for visualization and logging.
+            InputDeviceState state = getInputDeviceState(event);
+            if (state != null && state.onJoystickMotion(event)) {
+                mSummaryAdapter.show(state);
+            }
+        }
+        return super.dispatchGenericMotionEvent(event);
+    }
+
+    private InputDeviceState getInputDeviceState(InputEvent event) {
+        final int deviceId = event.getDeviceId();
+        InputDeviceState state = mInputDeviceStates.get(deviceId);
+        if (state == null) {
+            final InputDevice device = event.getDevice();
+            if (device == null) {
+                return null;
+            }
+            state = new InputDeviceState(device);
+            mInputDeviceStates.put(deviceId, state);
+
+            Log.i(TAG, device.toString());
+        }
+        return state;
+    }
+
+    /**
+     * Tracks the state of joystick axes and game controller buttons for a particular
+     * input device for diagnostic purposes.
+     */
+    private static class InputDeviceState {
+        private final InputDevice mDevice;
+        private final int[] mAxes;
+        private final float[] mAxisValues;
+        private final SparseIntArray mKeys;
+
+        public InputDeviceState(InputDevice device) {
+            mDevice = device;
+
+            int numAxes = 0;
+            for (MotionRange range : device.getMotionRanges()) {
+                if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+                    numAxes += 1;
+                }
+            }
+
+            mAxes = new int[numAxes];
+            mAxisValues = new float[numAxes];
+            int i = 0;
+            for (MotionRange range : device.getMotionRanges()) {
+                if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+                    numAxes += 1;
+                }
+                mAxes[i++] = range.getAxis();
+            }
+
+            mKeys = new SparseIntArray();
+        }
+
+        public InputDevice getDevice() {
+            return mDevice;
+        }
+
+        public int getAxisCount() {
+            return mAxes.length;
+        }
+
+        public int getAxis(int axisIndex) {
+            return mAxes[axisIndex];
+        }
+
+        public float getAxisValue(int axisIndex) {
+            return mAxisValues[axisIndex];
+        }
+
+        public int getKeyCount() {
+            return mKeys.size();
+        }
+
+        public int getKeyCode(int keyIndex) {
+            return mKeys.keyAt(keyIndex);
+        }
+
+        public boolean isKeyPressed(int keyIndex) {
+            return mKeys.valueAt(keyIndex) != 0;
+        }
+
+        public boolean onKeyDown(KeyEvent event) {
+            final int keyCode = event.getKeyCode();
+            if (isGameKey(keyCode)) {
+                if (event.getRepeatCount() == 0) {
+                    final String symbolicName = KeyEvent.keyCodeToString(keyCode);
+                    mKeys.put(keyCode, 1);
+                    Log.i(TAG, mDevice.getName() + " - Key Down: " + symbolicName);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        public boolean onKeyUp(KeyEvent event) {
+            final int keyCode = event.getKeyCode();
+            if (isGameKey(keyCode)) {
+                int index = mKeys.indexOfKey(keyCode);
+                if (index >= 0) {
+                    final String symbolicName = KeyEvent.keyCodeToString(keyCode);
+                    mKeys.put(keyCode, 0);
+                    Log.i(TAG, mDevice.getName() + " - Key Up: " + symbolicName);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        public boolean onJoystickMotion(MotionEvent event) {
+            StringBuilder message = new StringBuilder();
+            message.append(mDevice.getName()).append(" - Joystick Motion:\n");
+
+            final int historySize = event.getHistorySize();
+            for (int i = 0; i < mAxes.length; i++) {
+                final int axis = mAxes[i];
+                final float value = event.getAxisValue(axis);
+                mAxisValues[i] = value;
+                message.append("  ").append(MotionEvent.axisToString(axis)).append(": ");
+
+                // Append all historical values in the batch.
+                for (int historyPos = 0; historyPos < historySize; historyPos++) {
+                    message.append(event.getHistoricalAxisValue(axis, historyPos));
+                    message.append(", ");
+                }
+
+                // Append the current value.
+                message.append(value);
+                message.append("\n");
+            }
+            Log.i(TAG, message.toString());
+            return true;
+        }
+
+        // Check whether this is a key we care about.
+        // In a real game, we would probably let the user configure which keys to use
+        // instead of hardcoding the keys like this.
+        private static boolean isGameKey(int keyCode) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_DPAD_UP:
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                case KeyEvent.KEYCODE_DPAD_CENTER:
+                case KeyEvent.KEYCODE_SPACE:
+                    return true;
+                default:
+                    return KeyEvent.isGamepadButton(keyCode);
+            }
+        }
+    }
+
+    /**
+     * A list adapter that displays a summary of the device state.
+     */
+    private static class SummaryAdapter extends BaseAdapter {
+        private static final int BASE_ID_HEADING = 1 << 10;
+        private static final int BASE_ID_DEVICE_ITEM = 2 << 10;
+        private static final int BASE_ID_AXIS_ITEM = 3 << 10;
+        private static final int BASE_ID_KEY_ITEM = 4 << 10;
+
+        private final Context mContext;
+        private final Resources mResources;
+
+        private final SparseArray<Item> mDataItems = new SparseArray<Item>();
+        private final ArrayList<Item> mVisibleItems = new ArrayList<Item>();
+
+        private final Heading mDeviceHeading;
+        private final TextColumn mDeviceNameTextColumn;
+
+        private final Heading mAxesHeading;
+        private final Heading mKeysHeading;
+
+        private InputDeviceState mState;
+
+        public SummaryAdapter(Context context, Resources resources) {
+            mContext = context;
+            mResources = resources;
+
+            mDeviceHeading = new Heading(BASE_ID_HEADING | 0,
+                    mResources.getString(R.string.game_controller_input_heading_device));
+            mDeviceNameTextColumn = new TextColumn(BASE_ID_DEVICE_ITEM | 0,
+                    mResources.getString(R.string.game_controller_input_label_device_name));
+
+            mAxesHeading = new Heading(BASE_ID_HEADING | 1,
+                    mResources.getString(R.string.game_controller_input_heading_axes));
+            mKeysHeading = new Heading(BASE_ID_HEADING | 2,
+                    mResources.getString(R.string.game_controller_input_heading_keys));
+        }
+
+        public void onItemClick(int position) {
+            if (mState != null) {
+                Toast toast = Toast.makeText(
+                        mContext, mState.getDevice().toString(), Toast.LENGTH_LONG);
+                toast.show();
+            }
+        }
+
+        public void show(InputDeviceState state) {
+            mState = state;
+            mVisibleItems.clear();
+
+            // Populate device information.
+            mVisibleItems.add(mDeviceHeading);
+            mDeviceNameTextColumn.setContent(state.getDevice().getName());
+            mVisibleItems.add(mDeviceNameTextColumn);
+
+            // Populate axes.
+            mVisibleItems.add(mAxesHeading);
+            final int axisCount = state.getAxisCount();
+            for (int i = 0; i < axisCount; i++) {
+                final int axis = state.getAxis(i);
+                final int id = BASE_ID_AXIS_ITEM | axis;
+                TextColumn column = (TextColumn) mDataItems.get(id);
+                if (column == null) {
+                    column = new TextColumn(id, MotionEvent.axisToString(axis));
+                    mDataItems.put(id, column);
+                }
+                column.setContent(Float.toString(state.getAxisValue(i)));
+                mVisibleItems.add(column);
+            }
+
+            // Populate keys.
+            mVisibleItems.add(mKeysHeading);
+            final int keyCount = state.getKeyCount();
+            for (int i = 0; i < keyCount; i++) {
+                final int keyCode = state.getKeyCode(i);
+                final int id = BASE_ID_KEY_ITEM | keyCode;
+                TextColumn column = (TextColumn) mDataItems.get(id);
+                if (column == null) {
+                    column = new TextColumn(id, KeyEvent.keyCodeToString(keyCode));
+                    mDataItems.put(id, column);
+                }
+                column.setContent(mResources.getString(state.isKeyPressed(i)
+                        ? R.string.game_controller_input_key_pressed
+                        : R.string.game_controller_input_key_released));
+                mVisibleItems.add(column);
+            }
+
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        @Override
+        public int getCount() {
+            return mVisibleItems.size();
+        }
+
+        @Override
+        public Item getItem(int position) {
+            return mVisibleItems.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return getItem(position).getItemId();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            return getItem(position).getView(convertView, parent);
+        }
+
+        private static abstract class Item {
+            private final int mItemId;
+            private final int mLayoutResourceId;
+            private View mView;
+
+            public Item(int itemId, int layoutResourceId) {
+                mItemId = itemId;
+                mLayoutResourceId = layoutResourceId;
+            }
+
+            public long getItemId() {
+                return mItemId;
+            }
+
+            public View getView(View convertView, ViewGroup parent) {
+                if (mView == null) {
+                    LayoutInflater inflater = (LayoutInflater)
+                            parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                    mView = inflater.inflate(mLayoutResourceId, parent, false);
+                    initView(mView);
+                }
+                updateView(mView);
+                return mView;
+            }
+
+            protected void initView(View view) {
+            }
+
+            protected void updateView(View view) {
+            }
+        }
+
+        private static class Heading extends Item {
+            private final String mLabel;
+
+            public Heading(int itemId, String label) {
+                super(itemId, R.layout.game_controller_input_heading);
+                mLabel = label;
+            }
+
+            @Override
+            public void initView(View view) {
+                TextView textView = (TextView) view;
+                textView.setText(mLabel);
+            }
+        }
+
+        private static class TextColumn extends Item {
+            private final String mLabel;
+
+            private String mContent;
+            private TextView mContentView;
+
+            public TextColumn(int itemId, String label) {
+                super(itemId, R.layout.game_controller_input_text_column);
+                mLabel = label;
+            }
+
+            public void setContent(String content) {
+                mContent = content;
+            }
+
+            @Override
+            public void initView(View view) {
+                TextView textView = (TextView) view.findViewById(R.id.label);
+                textView.setText(mLabel);
+
+                mContentView = (TextView) view.findViewById(R.id.content);
+            }
+
+            @Override
+            public void updateView(View view) {
+                mContentView.setText(mContent);
+            }
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/GameView.java b/samples/ApiDemos/src/com/example/android/apis/view/GameView.java
new file mode 100644
index 0000000..9fe236c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/GameView.java
@@ -0,0 +1,747 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Paint.Style;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * A trivial joystick based physics game to demonstrate joystick handling.
+ *
+ * @see GameControllerInput
+ */
+public class GameView extends View {
+    private final long ANIMATION_TIME_STEP = 1000 / 60;
+    private final int MAX_OBSTACLES = 12;
+
+    private final Random mRandom;
+    private Ship mShip;
+    private final List<Bullet> mBullets;
+    private final List<Obstacle> mObstacles;
+
+    private long mLastStepTime;
+    private InputDevice mLastInputDevice;
+
+    private static final int DPAD_STATE_LEFT  = 1 << 0;
+    private static final int DPAD_STATE_RIGHT = 1 << 1;
+    private static final int DPAD_STATE_UP    = 1 << 2;
+    private static final int DPAD_STATE_DOWN  = 1 << 3;
+
+    private int mDPadState;
+
+    private float mShipSize;
+    private float mMaxShipThrust;
+    private float mMaxShipSpeed;
+
+    private float mBulletSize;
+    private float mBulletSpeed;
+
+    private float mMinObstacleSize;
+    private float mMaxObstacleSize;
+    private float mMinObstacleSpeed;
+    private float mMaxObstacleSpeed;
+
+    private final Runnable mAnimationRunnable = new Runnable() {
+        public void run() {
+            animateFrame();
+        }
+    };
+
+    public GameView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mRandom = new Random();
+        mBullets = new ArrayList<Bullet>();
+        mObstacles = new ArrayList<Obstacle>();
+
+        setFocusable(true);
+        setFocusableInTouchMode(true);
+
+        float baseSize = getContext().getResources().getDisplayMetrics().density * 5f;
+        float baseSpeed = baseSize * 3;
+
+        mShipSize = baseSize * 3;
+        mMaxShipThrust = baseSpeed * 0.25f;
+        mMaxShipSpeed = baseSpeed * 12;
+
+        mBulletSize = baseSize;
+        mBulletSpeed = baseSpeed * 12;
+
+        mMinObstacleSize = baseSize * 2;
+        mMaxObstacleSize = baseSize * 12;
+        mMinObstacleSpeed = baseSpeed;
+        mMaxObstacleSpeed = baseSpeed * 3;
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        // Reset the game when the view changes size.
+        reset();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        ensureInitialized();
+
+        // Handle DPad keys and fire button on initial down but not on auto-repeat.
+        boolean handled = false;
+        if (event.getRepeatCount() == 0) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                    mShip.setHeadingX(-1);
+                    mDPadState |= DPAD_STATE_LEFT;
+                    handled = true;
+                    break;
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                    mShip.setHeadingX(1);
+                    mDPadState |= DPAD_STATE_RIGHT;
+                    handled = true;
+                    break;
+                case KeyEvent.KEYCODE_DPAD_UP:
+                    mShip.setHeadingY(-1);
+                    mDPadState |= DPAD_STATE_UP;
+                    handled = true;
+                    break;
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                    mShip.setHeadingY(1);
+                    mDPadState |= DPAD_STATE_DOWN;
+                    handled = true;
+                    break;
+                default:
+                    if (isFireKey(keyCode)) {
+                        fire();
+                        handled = true;
+                    }
+                    break;
+            }
+        }
+        if (handled) {
+            step(event.getEventTime());
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        ensureInitialized();
+
+        // Handle keys going up.
+        boolean handled = false;
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+                mShip.setHeadingX(0);
+                mDPadState &= ~DPAD_STATE_LEFT;
+                handled = true;
+                break;
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+                mShip.setHeadingX(0);
+                mDPadState &= ~DPAD_STATE_RIGHT;
+                handled = true;
+                break;
+            case KeyEvent.KEYCODE_DPAD_UP:
+                mShip.setHeadingY(0);
+                mDPadState &= ~DPAD_STATE_UP;
+                handled = true;
+                break;
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                mShip.setHeadingY(0);
+                mDPadState &= ~DPAD_STATE_DOWN;
+                handled = true;
+                break;
+            default:
+                if (isFireKey(keyCode)) {
+                    handled = true;
+                }
+                break;
+        }
+        if (handled) {
+            step(event.getEventTime());
+            return true;
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+
+    private static boolean isFireKey(int keyCode) {
+        return KeyEvent.isGamepadButton(keyCode)
+                || keyCode == KeyEvent.KEYCODE_DPAD_CENTER
+                || keyCode == KeyEvent.KEYCODE_SPACE;
+    }
+
+    @Override
+    public boolean onGenericMotionEvent(MotionEvent event) {
+        ensureInitialized();
+
+        // Check that the event came from a joystick since a generic motion event
+        // could be almost anything.
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0
+                && event.getAction() == MotionEvent.ACTION_MOVE) {
+            // Cache the most recently obtained device information.
+            // The device information may change over time but it can be
+            // somewhat expensive to query.
+            if (mLastInputDevice == null || mLastInputDevice.getId() != event.getDeviceId()) {
+                mLastInputDevice = event.getDevice();
+                // It's possible for the device id to be invalid.
+                // In that case, getDevice() will return null.
+                if (mLastInputDevice == null) {
+                    return false;
+                }
+            }
+
+            // Ignore joystick while the DPad is pressed to avoid conflicting motions.
+            if (mDPadState != 0) {
+                return true;
+            }
+
+            // Process all historical movement samples in the batch.
+            final int historySize = event.getHistorySize();
+            for (int i = 0; i < historySize; i++) {
+                processJoystickInput(event, i);
+            }
+
+            // Process the current movement sample in the batch.
+            processJoystickInput(event, -1);
+            return true;
+        }
+        return super.onGenericMotionEvent(event);
+    }
+
+    private void processJoystickInput(MotionEvent event, int historyPos) {
+        // Get joystick position.
+        // Many game pads with two joysticks report the position of the second joystick
+        // using the Z and RZ axes so we also handle those.
+        // In a real game, we would allow the user to configure the axes manually.
+        float x = getCenteredAxis(event, mLastInputDevice, MotionEvent.AXIS_X, historyPos);
+        if (x == 0) {
+            x = getCenteredAxis(event, mLastInputDevice, MotionEvent.AXIS_HAT_X, historyPos);
+        }
+        if (x == 0) {
+            x = getCenteredAxis(event, mLastInputDevice, MotionEvent.AXIS_Z, historyPos);
+        }
+
+        float y = getCenteredAxis(event, mLastInputDevice, MotionEvent.AXIS_Y, historyPos);
+        if (y == 0) {
+            y = getCenteredAxis(event, mLastInputDevice, MotionEvent.AXIS_HAT_Y, historyPos);
+        }
+        if (y == 0) {
+            y = getCenteredAxis(event, mLastInputDevice, MotionEvent.AXIS_RZ, historyPos);
+        }
+
+        // Set the ship heading.
+        mShip.setHeading(x, y);
+        step(historyPos < 0 ? event.getEventTime() : event.getHistoricalEventTime(historyPos));
+    }
+
+    private static float getCenteredAxis(MotionEvent event, InputDevice device,
+            int axis, int historyPos) {
+        final InputDevice.MotionRange range = device.getMotionRange(axis, event.getSource());
+        if (range != null) {
+            final float flat = range.getFlat();
+            final float value = historyPos < 0 ? event.getAxisValue(axis)
+                    : event.getHistoricalAxisValue(axis, historyPos);
+
+            // Ignore axis values that are within the 'flat' region of the joystick axis center.
+            // A joystick at rest does not always report an absolute position of (0,0).
+            if (Math.abs(value) > flat) {
+                return value;
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        // Turn on and off animations based on the window focus.
+        // Alternately, we could update the game state using the Activity onResume()
+        // and onPause() lifecycle events.
+        if (hasWindowFocus) {
+            getHandler().postDelayed(mAnimationRunnable, ANIMATION_TIME_STEP);
+            mLastStepTime = SystemClock.uptimeMillis();
+        } else {
+            getHandler().removeCallbacks(mAnimationRunnable);
+
+            mDPadState = 0;
+            if (mShip != null) {
+                mShip.setHeading(0, 0);
+                mShip.setVelocity(0, 0);
+            }
+        }
+
+        super.onWindowFocusChanged(hasWindowFocus);
+    }
+
+    private void fire() {
+        if (mShip != null && !mShip.isDestroyed()) {
+            Bullet bullet = new Bullet();
+            bullet.setPosition(mShip.getBulletInitialX(), mShip.getBulletInitialY());
+            bullet.setVelocity(mShip.getBulletVelocityX(mBulletSpeed),
+                    mShip.getBulletVelocityY(mBulletSpeed));
+            mBullets.add(bullet);
+        }
+    }
+
+    private void ensureInitialized() {
+        if (mShip == null) {
+            reset();
+        }
+    }
+
+    private void reset() {
+        mShip = new Ship();
+        mBullets.clear();
+        mObstacles.clear();
+    }
+
+    void animateFrame() {
+        long currentStepTime = SystemClock.uptimeMillis();
+        step(currentStepTime);
+
+        Handler handler = getHandler();
+        if (handler != null) {
+            handler.postAtTime(mAnimationRunnable, currentStepTime + ANIMATION_TIME_STEP);
+            invalidate();
+        }
+    }
+
+    private void step(long currentStepTime) {
+        float tau = (currentStepTime - mLastStepTime) * 0.001f;
+        mLastStepTime = currentStepTime;
+
+        ensureInitialized();
+
+        // Move the ship.
+        mShip.accelerate(tau, mMaxShipThrust, mMaxShipSpeed);
+        if (!mShip.step(tau)) {
+            reset();
+        }
+
+        // Move the bullets.
+        int numBullets = mBullets.size();
+        for (int i = 0; i < numBullets; i++) {
+            final Bullet bullet = mBullets.get(i);
+            if (!bullet.step(tau)) {
+                mBullets.remove(i);
+                i -= 1;
+                numBullets -= 1;
+            }
+        }
+
+        // Move obstacles.
+        int numObstacles = mObstacles.size();
+        for (int i = 0; i < numObstacles; i++) {
+            final Obstacle obstacle = mObstacles.get(i);
+            if (!obstacle.step(tau)) {
+                mObstacles.remove(i);
+                i -= 1;
+                numObstacles -= 1;
+            }
+        }
+
+        // Check for collisions between bullets and obstacles.
+        for (int i = 0; i < numBullets; i++) {
+            final Bullet bullet = mBullets.get(i);
+            for (int j = 0; j < numObstacles; j++) {
+                final Obstacle obstacle = mObstacles.get(j);
+                if (bullet.collidesWith(obstacle)) {
+                    bullet.destroy();
+                    obstacle.destroy();
+                    break;
+                }
+            }
+        }
+
+        // Check for collisions between the ship and obstacles.
+        for (int i = 0; i < numObstacles; i++) {
+            final Obstacle obstacle = mObstacles.get(i);
+            if (mShip.collidesWith(obstacle)) {
+                mShip.destroy();
+                obstacle.destroy();
+                break;
+            }
+        }
+
+        // Spawn more obstacles offscreen when needed.
+        // Avoid putting them right on top of the ship.
+        OuterLoop: while (mObstacles.size() < MAX_OBSTACLES) {
+            final float minDistance = mShipSize * 4;
+            float size = mRandom.nextFloat() * (mMaxObstacleSize - mMinObstacleSize)
+                    + mMinObstacleSize;
+            float positionX, positionY;
+            int tries = 0;
+            do {
+                int edge = mRandom.nextInt(4);
+                switch (edge) {
+                    case 0:
+                        positionX = -size;
+                        positionY = mRandom.nextInt(getHeight());
+                        break;
+                    case 1:
+                        positionX = getWidth() + size;
+                        positionY = mRandom.nextInt(getHeight());
+                        break;
+                    case 2:
+                        positionX = mRandom.nextInt(getWidth());
+                        positionY = -size;
+                        break;
+                    default:
+                        positionX = mRandom.nextInt(getWidth());
+                        positionY = getHeight() + size;
+                        break;
+                }
+                if (++tries > 10) {
+                    break OuterLoop;
+                }
+            } while (mShip.distanceTo(positionX, positionY) < minDistance);
+
+            float direction = mRandom.nextFloat() * (float) Math.PI * 2;
+            float speed = mRandom.nextFloat() * (mMaxObstacleSpeed - mMinObstacleSpeed)
+                    + mMinObstacleSpeed;
+            float velocityX = (float) Math.cos(direction) * speed;
+            float velocityY = (float) Math.sin(direction) * speed;
+
+            Obstacle obstacle = new Obstacle();
+            obstacle.setPosition(positionX, positionY);
+            obstacle.setSize(size);
+            obstacle.setVelocity(velocityX, velocityY);
+            mObstacles.add(obstacle);
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        // Draw the ship.
+        if (mShip != null) {
+            mShip.draw(canvas);
+        }
+
+        // Draw bullets.
+        int numBullets = mBullets.size();
+        for (int i = 0; i < numBullets; i++) {
+            final Bullet bullet = mBullets.get(i);
+            bullet.draw(canvas);
+        }
+
+        // Draw obstacles.
+        int numObstacles = mObstacles.size();
+        for (int i = 0; i < numObstacles; i++) {
+            final Obstacle obstacle = mObstacles.get(i);
+            obstacle.draw(canvas);
+        }
+    }
+
+    static float pythag(float x, float y) {
+        return (float) Math.sqrt(x * x + y * y);
+    }
+
+    static int blend(float alpha, int from, int to) {
+        return from + (int) ((to - from) * alpha);
+    }
+
+    static void setPaintARGBBlend(Paint paint, float alpha,
+            int a1, int r1, int g1, int b1,
+            int a2, int r2, int g2, int b2) {
+        paint.setARGB(blend(alpha, a1, a2), blend(alpha, r1, r2),
+                blend(alpha, g1, g2), blend(alpha, b1, b2));
+    }
+
+    private abstract class Sprite {
+        protected float mPositionX;
+        protected float mPositionY;
+        protected float mVelocityX;
+        protected float mVelocityY;
+        protected float mSize;
+        protected boolean mDestroyed;
+        protected float mDestroyAnimProgress;
+
+        public void setPosition(float x, float y) {
+            mPositionX = x;
+            mPositionY = y;
+        }
+
+        public void setVelocity(float x, float y) {
+            mVelocityX = x;
+            mVelocityY = y;
+        }
+
+        public void setSize(float size) {
+            mSize = size;
+        }
+
+        public float distanceTo(float x, float y) {
+            return pythag(mPositionX - x, mPositionY - y);
+        }
+
+        public float distanceTo(Sprite other) {
+            return distanceTo(other.mPositionX, other.mPositionY);
+        }
+
+        public boolean collidesWith(Sprite other) {
+            // Really bad collision detection.
+            return !mDestroyed && !other.mDestroyed
+                    && distanceTo(other) <= Math.max(mSize, other.mSize)
+                            + Math.min(mSize, other.mSize) * 0.5f;
+        }
+
+        public boolean isDestroyed() {
+            return mDestroyed;
+        }
+
+        public boolean step(float tau) {
+            mPositionX += mVelocityX * tau;
+            mPositionY += mVelocityY * tau;
+
+            if (mDestroyed) {
+                mDestroyAnimProgress += tau / getDestroyAnimDuration();
+                if (mDestroyAnimProgress >= 1.0f) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public abstract void draw(Canvas canvas);
+
+        public abstract float getDestroyAnimDuration();
+
+        protected boolean isOutsidePlayfield() {
+            final int width = GameView.this.getWidth();
+            final int height = GameView.this.getHeight();
+            return mPositionX < 0 || mPositionX >= width
+                    || mPositionY < 0 || mPositionY >= height;
+        }
+
+        protected void wrapAtPlayfieldBoundary() {
+            final int width = GameView.this.getWidth();
+            final int height = GameView.this.getHeight();
+            while (mPositionX <= -mSize) {
+                mPositionX += width + mSize * 2;
+            }
+            while (mPositionX >= width + mSize) {
+                mPositionX -= width + mSize * 2;
+            }
+            while (mPositionY <= -mSize) {
+                mPositionY += height + mSize * 2;
+            }
+            while (mPositionY >= height + mSize) {
+                mPositionY -= height + mSize * 2;
+            }
+        }
+
+        public void destroy() {
+            mDestroyed = true;
+            step(0);
+        }
+    }
+
+    private class Ship extends Sprite {
+        private static final float CORNER_ANGLE = (float) Math.PI * 2 / 3;
+        private static final float TO_DEGREES = (float) (180.0 / Math.PI);
+
+        private float mHeadingX;
+        private float mHeadingY;
+        private float mHeadingAngle;
+        private float mHeadingMagnitude;
+        private final Paint mPaint;
+        private final Path mPath;
+
+
+        public Ship() {
+            mPaint = new Paint();
+            mPaint.setStyle(Style.FILL);
+
+            setPosition(getWidth() * 0.5f, getHeight() * 0.5f);
+            setVelocity(0, 0);
+            setSize(mShipSize);
+
+            mPath = new Path();
+            mPath.moveTo(0, 0);
+            mPath.lineTo((float)Math.cos(-CORNER_ANGLE) * mSize,
+                    (float)Math.sin(-CORNER_ANGLE) * mSize);
+            mPath.lineTo(mSize, 0);
+            mPath.lineTo((float)Math.cos(CORNER_ANGLE) * mSize,
+                    (float)Math.sin(CORNER_ANGLE) * mSize);
+            mPath.lineTo(0, 0);
+        }
+
+        public void setHeadingX(float x) {
+            mHeadingX = x;
+            updateHeading();
+        }
+
+        public void setHeadingY(float y) {
+            mHeadingY = y;
+            updateHeading();
+        }
+
+        public void setHeading(float x, float y) {
+            mHeadingX = x;
+            mHeadingY = y;
+            updateHeading();
+        }
+
+        private void updateHeading() {
+            mHeadingMagnitude = pythag(mHeadingX, mHeadingY);
+            if (mHeadingMagnitude > 0.1f) {
+                mHeadingAngle = (float) Math.atan2(mHeadingY, mHeadingX);
+            }
+        }
+
+        private float polarX(float radius) {
+            return (float) Math.cos(mHeadingAngle) * radius;
+        }
+
+        private float polarY(float radius) {
+            return (float) Math.sin(mHeadingAngle) * radius;
+        }
+
+        public float getBulletInitialX() {
+            return mPositionX + polarX(mSize);
+        }
+
+        public float getBulletInitialY() {
+            return mPositionY + polarY(mSize);
+        }
+
+        public float getBulletVelocityX(float relativeSpeed) {
+            return mVelocityX + polarX(relativeSpeed);
+        }
+
+        public float getBulletVelocityY(float relativeSpeed) {
+            return mVelocityY + polarY(relativeSpeed);
+        }
+
+        public void accelerate(float tau, float maxThrust, float maxSpeed) {
+            final float thrust = mHeadingMagnitude * maxThrust;
+            mVelocityX += polarX(thrust);
+            mVelocityY += polarY(thrust);
+
+            final float speed = pythag(mVelocityX, mVelocityY);
+            if (speed > maxSpeed) {
+                final float scale = maxSpeed / speed;
+                mVelocityX = mVelocityX * scale;
+                mVelocityY = mVelocityY * scale;
+            }
+        }
+
+        @Override
+        public boolean step(float tau) {
+            if (!super.step(tau)) {
+                return false;
+            }
+            wrapAtPlayfieldBoundary();
+            return true;
+        }
+
+        public void draw(Canvas canvas) {
+            setPaintARGBBlend(mPaint, mDestroyAnimProgress,
+                    255, 63, 255, 63,
+                    0, 255, 0, 0);
+
+            canvas.save(Canvas.MATRIX_SAVE_FLAG);
+            canvas.translate(mPositionX, mPositionY);
+            canvas.rotate(mHeadingAngle * TO_DEGREES);
+            canvas.drawPath(mPath, mPaint);
+            canvas.restore();
+        }
+
+        @Override
+        public float getDestroyAnimDuration() {
+            return 1.0f;
+        }
+    }
+
+    private class Bullet extends Sprite {
+        private final Paint mPaint;
+
+        public Bullet() {
+            mPaint = new Paint();
+            mPaint.setStyle(Style.FILL);
+
+            setSize(mBulletSize);
+        }
+
+        @Override
+        public boolean step(float tau) {
+            if (!super.step(tau)) {
+                return false;
+            }
+            return !isOutsidePlayfield();
+        }
+
+        public void draw(Canvas canvas) {
+            setPaintARGBBlend(mPaint, mDestroyAnimProgress,
+                    255, 255, 255, 0,
+                    0, 255, 255, 255);
+            canvas.drawCircle(mPositionX, mPositionY, mSize, mPaint);
+        }
+
+        @Override
+        public float getDestroyAnimDuration() {
+            return 0.125f;
+        }
+    }
+
+    private class Obstacle extends Sprite {
+        private final Paint mPaint;
+
+        public Obstacle() {
+            mPaint = new Paint();
+            mPaint.setARGB(255, 127, 127, 255);
+            mPaint.setStyle(Style.FILL);
+        }
+
+        @Override
+        public boolean step(float tau) {
+            if (!super.step(tau)) {
+                return false;
+            }
+            wrapAtPlayfieldBoundary();
+            return true;
+        }
+
+        public void draw(Canvas canvas) {
+            setPaintARGBBlend(mPaint, mDestroyAnimProgress,
+                    255, 127, 127, 255,
+                    0, 255, 0, 0);
+            canvas.drawCircle(mPositionX, mPositionY,
+                    mSize * (1.0f - mDestroyAnimProgress), mPaint);
+        }
+
+        @Override
+        public float getDestroyAnimDuration() {
+            return 0.25f;
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Grid3.java b/samples/ApiDemos/src/com/example/android/apis/view/Grid3.java
new file mode 100644
index 0000000..3b853e10
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Grid3.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Checkable;
+import android.widget.FrameLayout;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+/**
+ * This demo illustrates the use of CHOICE_MODE_MULTIPLE_MODAL, a.k.a. selection mode on GridView.
+ */
+public class Grid3 extends Activity {
+
+    GridView mGrid;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        loadApps();
+
+        setContentView(R.layout.grid_1);
+        mGrid = (GridView) findViewById(R.id.myGrid);
+        mGrid.setAdapter(new AppsAdapter());
+        mGrid.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
+        mGrid.setMultiChoiceModeListener(new MultiChoiceModeListener());
+    }
+
+    private List<ResolveInfo> mApps;
+
+    private void loadApps() {
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        mApps = getPackageManager().queryIntentActivities(mainIntent, 0);
+    }
+
+    public class AppsAdapter extends BaseAdapter {
+        public AppsAdapter() {
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            CheckableLayout l;
+            ImageView i;
+
+            if (convertView == null) {
+                i = new ImageView(Grid3.this);
+                i.setScaleType(ImageView.ScaleType.FIT_CENTER);
+                i.setLayoutParams(new ViewGroup.LayoutParams(50, 50));
+                l = new CheckableLayout(Grid3.this);
+                l.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT,
+                        GridView.LayoutParams.WRAP_CONTENT));
+                l.addView(i);
+            } else {
+                l = (CheckableLayout) convertView;
+                i = (ImageView) l.getChildAt(0);
+            }
+
+            ResolveInfo info = mApps.get(position);
+            i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
+
+            return l;
+        }
+
+
+        public final int getCount() {
+            return mApps.size();
+        }
+
+        public final Object getItem(int position) {
+            return mApps.get(position);
+        }
+
+        public final long getItemId(int position) {
+            return position;
+        }
+    }
+
+    public class CheckableLayout extends FrameLayout implements Checkable {
+        private boolean mChecked;
+
+        public CheckableLayout(Context context) {
+            super(context);
+        }
+
+        public void setChecked(boolean checked) {
+            mChecked = checked;
+            setBackgroundDrawable(checked ?
+                    getResources().getDrawable(R.drawable.blue)
+                    : null);
+        }
+
+        public boolean isChecked() {
+            return mChecked;
+        }
+
+        public void toggle() {
+            setChecked(!mChecked);
+        }
+
+    }
+
+    public class MultiChoiceModeListener implements GridView.MultiChoiceModeListener {
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            mode.setTitle("Select Items");
+            mode.setSubtitle("One item selected");
+            return true;
+        }
+
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            return true;
+        }
+
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            return true;
+        }
+
+        public void onDestroyActionMode(ActionMode mode) {
+        }
+
+        public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
+                boolean checked) {
+            int selectCount = mGrid.getCheckedItemCount();
+            switch (selectCount) {
+            case 1:
+                mode.setSubtitle("One item selected");
+                break;
+            default:
+                mode.setSubtitle("" + selectCount + " items selected");
+                break;
+            }
+        }
+
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/HorizontalScrollView1.java b/samples/ApiDemos/src/com/example/android/apis/view/HorizontalScrollView1.java
new file mode 100644
index 0000000..758ab01
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/HorizontalScrollView1.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+import com.example.android.apis.R;
+
+
+public class HorizontalScrollView1 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.horizontal_scroll_view1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List1.java b/samples/ApiDemos/src/com/example/android/apis/view/List1.java
index 5861923..f103e51 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List1.java
@@ -38,135 +38,5 @@
         getListView().setTextFilterEnabled(true);
     }
 
-    private String[] mStrings = {
-            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
-            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
-            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
-            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
-            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
-            "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
-            "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
-            "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
-            "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
-            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
-            "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
-            "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
-            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
-            "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
-            "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
-            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
-            "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
-            "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
-            "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
-            "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
-            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
-            "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
-            "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
-            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
-            "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
-            "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
-            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
-            "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
-            "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
-            "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
-            "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
-            "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
-            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
-            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
-            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
-            "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
-            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
-            "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
-            "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
-            "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
-            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
-            "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
-            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
-            "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
-            "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
-            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
-            "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
-            "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
-            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
-            "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
-            "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
-            "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
-            "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
-            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
-            "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
-            "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
-            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
-            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
-            "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
-            "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
-            "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
-            "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
-            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
-            "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
-            "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
-            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
-            "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
-            "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
-            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
-            "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
-            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
-            "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
-            "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
-            "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
-            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
-            "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
-            "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
-            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
-            "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
-            "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
-            "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
-            "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
-            "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
-            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
-            "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
-            "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
-            "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
-            "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
-            "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
-            "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
-            "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
-            "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
-            "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
-            "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
-            "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
-            "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
-            "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
-            "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
-            "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
-            "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
-            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
-            "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
-            "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
-            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
-            "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
-            "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
-            "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
-            "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
-            "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
-            "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
-            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
-            "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
-            "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
-            "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
-            "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
-            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
-            "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
-            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
-            "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
-            "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
-            "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
-            "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
-            "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
-            "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
-            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
-            "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
-            "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
-            "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
-            "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
-            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+    private String[] mStrings = Cheeses.sCheeseStrings;
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List14.java b/samples/ApiDemos/src/com/example/android/apis/view/List14.java
index 41eb481..55f3b22 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List14.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List14.java
@@ -137,178 +137,5 @@
         setListAdapter(new EfficientAdapter(this));
     }
 
-    private static final String[] DATA = {
-            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
-            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
-            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
-            "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
-            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh",
-            "Anthoriro", "Appenzell", "Aragon", "Ardi Gasna", "Ardrahan",
-            "Armenian String", "Aromes au Gene de Marc", "Asadero", "Asiago",
-            "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", "Babybel",
-            "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal",
-            "Banon", "Barry's Bay Cheddar", "Basing", "Basket Cheese",
-            "Bath Cheese", "Bavarian Bergkase", "Baylough", "Beaufort",
-            "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
-            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir",
-            "Bierkase", "Bishop Kennedy", "Blarney", "Bleu d'Auvergne",
-            "Bleu de Gex", "Bleu de Laqueuille", "Bleu de Septmoncel",
-            "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
-            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini",
-            "Bocconcini (Australian)", "Boeren Leidenkaas", "Bonchester",
-            "Bosworth", "Bougon", "Boule Du Roves", "Boulette d'Avesnes",
-            "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
-            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois",
-            "Brebis du Puyfaucon", "Bresse Bleu", "Brick", "Brie",
-            "Brie de Meaux", "Brie de Melun", "Brillat-Savarin", "Brin",
-            "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
-            "Briquette de Brebis", "Briquette du Forez", "Broccio",
-            "Broccio Demi-Affine", "Brousse du Rove", "Bruder Basil",
-            "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
-            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase",
-            "Button (Innes)", "Buxton Blue", "Cabecou", "Caboc", "Cabrales",
-            "Cachaille", "Caciocavallo", "Caciotta", "Caerphilly",
-            "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
-            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux",
-            "Capricorn Goat", "Capriole Banon", "Carre de l'Est",
-            "Casciotta di Urbino", "Cashel Blue", "Castellano", "Castelleno",
-            "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
-            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou",
-            "Chabichou du Poitou", "Chabis de Gatine", "Chaource", "Charolais",
-            "Chaumes", "Cheddar", "Cheddar Clothbound", "Cheshire", "Chevres",
-            "Chevrotin des Aravis", "Chontaleno", "Civray",
-            "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby",
-            "Cold Pack", "Comte", "Coolea", "Cooleney", "Coquetdale",
-            "Corleggy", "Cornish Pepper", "Cotherstone", "Cotija",
-            "Cottage Cheese", "Cottage Cheese (Australian)", "Cougar Gold",
-            "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
-            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche",
-            "Crescenza", "Croghan", "Crottin de Chavignol",
-            "Crottin du Chavignol", "Crowdie", "Crowley", "Cuajada", "Curd",
-            "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
-            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo",
-            "Danish Fontina", "Daralagjazsky", "Dauphin", "Delice des Fiouves",
-            "Denhany Dorset Drum", "Derby", "Dessertnyj Belyj", "Devon Blue",
-            "Devon Garland", "Dolcelatte", "Doolin", "Doppelrhamstufel",
-            "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
-            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra",
-            "Dunlop", "Dunsyre Blue", "Duroblando", "Durrus",
-            "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
-            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne",
-            "Esbareich", "Esrom", "Etorki", "Evansdale Farmhouse Brie",
-            "Evora De L'Alentejo", "Exmoor Blue", "Explorateur", "Feta",
-            "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
-            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis",
-            "Flor de Guia", "Flower Marie", "Folded",
-            "Folded cheese with mint", "Fondant de Brebis", "Fontainebleau",
-            "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
-            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire",
-            "Fourme de Montbrison", "Fresh Jack", "Fresh Mozzarella",
-            "Fresh Ricotta", "Fresh Truffles", "Fribourgeois", "Friesekaas",
-            "Friesian", "Friesla", "Frinault", "Fromage a Raclette",
-            "Fromage Corse", "Fromage de Montagne de Savoie", "Fromage Frais",
-            "Fruit Cream Cheese", "Frying Cheese", "Fynbo", "Gabriel",
-            "Galette du Paludier", "Galette Lyonnaise",
-            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail",
-            "Garrotxa", "Gastanberra", "Geitost", "Gippsland Blue", "Gjetost",
-            "Gloucester", "Golden Cross", "Gorgonzola", "Gornyaltajski",
-            "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
-            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
-            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh",
-            "Greve", "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny",
-            "Halloumi", "Halloumy (Australian)", "Haloumi-Style Cheese",
-            "Harbourne Blue", "Havarti", "Heidi Gruyere", "Hereford Hop",
-            "Herrgardsost", "Herriot Farmhouse", "Herve", "Hipi Iti",
-            "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
-            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu",
-            "Isle of Mull", "Jarlsberg", "Jermi Tortes", "Jibneh Arabieh",
-            "Jindi Brie", "Jubilee Blue", "Juustoleipa", "Kadchgall", "Kaseri",
-            "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
-            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold",
-            "Klosterkaese", "Knockalara", "Kugelkase", "L'Aveyronnais",
-            "L'Ecir de l'Aubrac", "La Taupiniere", "La Vache Qui Rit",
-            "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
-            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin",
-            "Le Fium Orbo", "Le Lacandou", "Le Roule", "Leafield", "Lebbene",
-            "Leerdammer", "Leicester", "Leyden", "Limburger",
-            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer",
-            "Little Rydings", "Livarot", "Llanboidy", "Llanglofan Farmhouse",
-            "Loch Arthur Farmhouse", "Loddiswell Avondale", "Longhorn",
-            "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam", "Macconais",
-            "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
-            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses",
-            "Maredsous", "Margotin", "Maribo", "Maroilles", "Mascares",
-            "Mascarpone", "Mascarpone (Australian)", "Mascarpone Torta",
-            "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
-            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)",
-            "Meyer Vintage Gouda", "Mihalic Peynir", "Milleens", "Mimolette",
-            "Mine-Gabhar", "Mini Baby Bells", "Mixte", "Molbo",
-            "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
-            "Monterey Jack", "Monterey Jack Dry", "Morbier",
-            "Morbier Cru de Montagne", "Mothais a la Feuille", "Mozzarella",
-            "Mozzarella (Australian)", "Mozzarella di Bufala",
-            "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
-            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais",
-            "Neufchatel", "Neufchatel (Australian)", "Niolo", "Nokkelost",
-            "Northumberland", "Oaxaca", "Olde York", "Olivet au Foin",
-            "Olivet Bleu", "Olivet Cendre", "Orkney Extra Mature Cheddar",
-            "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty", "Oszczypek",
-            "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer",
-            "Panela", "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)",
-            "Parmigiano Reggiano", "Pas de l'Escalette", "Passendale",
-            "Pasteurized Processed", "Pate de Fromage", "Patefine Fort",
-            "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac",
-            "Pave du Berry", "Pecorino", "Pecorino in Walnut Leaves",
-            "Pecorino Romano", "Peekskill Pyramid", "Pelardon des Cevennes",
-            "Pelardon des Corbieres", "Penamellera", "Penbryn", "Pencarreg",
-            "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
-            "Picodon de Chevre", "Picos de Europa", "Piora",
-            "Pithtviers au Foin", "Plateau de Herve", "Plymouth Cheese",
-            "Podhalanski", "Poivre d'Ane", "Polkolbin", "Pont l'Eveque",
-            "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
-            "Pourly", "Prastost", "Pressato", "Prince-Jean",
-            "Processed Cheddar", "Provolone", "Provolone (Australian)",
-            "Pyengana Cheddar", "Pyramide", "Quark", "Quark (Australian)",
-            "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
-            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango",
-            "Queso de Murcia", "Queso del Montsec", "Queso del Tietar",
-            "Queso Fresco", "Queso Fresco (Adobera)", "Queso Iberico",
-            "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
-            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette",
-            "Ragusano", "Raschera", "Reblochon", "Red Leicester",
-            "Regal de la Dombes", "Reggianito", "Remedou", "Requeson",
-            "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata",
-            "Ridder", "Rigotte", "Rocamadour", "Rollot", "Romano",
-            "Romans Part Dieu", "Roncal", "Roquefort", "Roule",
-            "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu",
-            "Saaland Pfarr", "Saanenkaese", "Saga", "Sage Derby",
-            "Sainte Maure", "Saint-Marcellin", "Saint-Nectaire",
-            "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
-            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza",
-            "Schabzieger", "Schloss", "Selles sur Cher", "Selva", "Serat",
-            "Seriously Strong Cheddar", "Serra da Estrela", "Sharpam",
-            "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene",
-            "Smoked Gouda", "Somerset Brie", "Sonoma Jack",
-            "Sottocenare al Tartufo", "Soumaintrain", "Sourire Lozerien",
-            "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
-            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote",
-            "Sveciaost", "Swaledale", "Sweet Style Swiss", "Swiss",
-            "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
-            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea",
-            "Testouri", "Tete de Moine", "Tetilla", "Texas Goat Cheese",
-            "Tibet", "Tillamook Cheddar", "Tilsit", "Timboon Brie", "Toma",
-            "Tomme Brulee", "Tomme d'Abondance", "Tomme de Chevre",
-            "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans",
-            "Tommes", "Torta del Casar", "Toscanello", "Touree de L'Aubier",
-            "Tourmalet", "Trappe (Veritable)", "Trois Cornes De Vendee",
-            "Tronchon", "Trou du Cru", "Truffe", "Tupi", "Turunmaa",
-            "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
-            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco",
-            "Vendomois", "Vieux Corse", "Vignotte", "Vulscombe",
-            "Waimata Farmhouse Blue", "Washed Rind Cheese (Australian)",
-            "Waterloo", "Weichkaese", "Wellington", "Wensleydale",
-            "White Stilton", "Whitestone Farmhouse", "Wigmore",
-            "Woodside Cabecou", "Xanadu", "Xynotyro", "Yarg Cornish",
-            "Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
-            "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+    private static final String[] DATA = Cheeses.sCheeseStrings;
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List15.java b/samples/ApiDemos/src/com/example/android/apis/view/List15.java
new file mode 100644
index 0000000..9fa7c64
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List15.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+/**
+ * This demo illustrates the use of CHOICE_MODE_MULTIPLE_MODAL, a.k.a. selection mode on ListView.
+ */
+public class List15 extends ListActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ListView lv = getListView();
+        lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+        lv.setMultiChoiceModeListener(new ModeCallback());
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_checked, mStrings));
+    }
+    
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        getActionBar().setSubtitle("Long press to start selection");
+    }
+    
+    private class ModeCallback implements ListView.MultiChoiceModeListener {
+
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            MenuInflater inflater = getMenuInflater();
+            inflater.inflate(R.menu.list_select_menu, menu);
+            mode.setTitle("Select Items");
+            setSubtitle(mode);
+            return true;
+        }
+
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            return true;
+        }
+
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            switch (item.getItemId()) {
+            case R.id.share:
+                Toast.makeText(List15.this, "Shared " + getListView().getCheckedItemCount() +
+                        " items", Toast.LENGTH_SHORT).show();
+                mode.finish();
+                break;
+            default:
+                Toast.makeText(List15.this, "Clicked " + item.getTitle(),
+                        Toast.LENGTH_SHORT).show();
+                break;
+            }
+            return true;
+        }
+
+        public void onDestroyActionMode(ActionMode mode) {
+        }
+
+        public void onItemCheckedStateChanged(ActionMode mode,
+                int position, long id, boolean checked) {
+            setSubtitle(mode);
+        }
+
+        private void setSubtitle(ActionMode mode) {
+            final int checkedCount = getListView().getCheckedItemCount();
+            switch (checkedCount) {
+                case 0:
+                    mode.setSubtitle(null);
+                    break;
+                case 1:
+                    mode.setSubtitle("One item selected");
+                    break;
+                default:
+                    mode.setSubtitle("" + checkedCount + " items selected");
+                    break;
+            }
+        }
+    }
+
+    private String[] mStrings = Cheeses.sCheeseStrings;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List16.java b/samples/ApiDemos/src/com/example/android/apis/view/List16.java
new file mode 100644
index 0000000..bfea6ed
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List16.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+/**
+ * This demo illustrates the use of CHOICE_MODE_MULTIPLE_MODAL, a.k.a. selection mode on ListView
+ * couple with the new simple_list_item_activated_1 which uses a highlighted border for selected
+ * items.
+ */
+public class List16 extends ListActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ListView lv = getListView();
+        lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+        lv.setMultiChoiceModeListener(new ModeCallback());
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_activated_1, Cheeses.sCheeseStrings));
+    }
+    
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        getActionBar().setSubtitle("Long press to start selection");
+    }
+    
+    private class ModeCallback implements ListView.MultiChoiceModeListener {
+
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            MenuInflater inflater = getMenuInflater();
+            inflater.inflate(R.menu.list_select_menu, menu);
+            mode.setTitle("Select Items");
+            return true;
+        }
+
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            return true;
+        }
+
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            switch (item.getItemId()) {
+            case R.id.share:
+                Toast.makeText(List16.this, "Shared " + getListView().getCheckedItemCount() +
+                        " items", Toast.LENGTH_SHORT).show();
+                mode.finish();
+                break;
+            default:
+                Toast.makeText(List16.this, "Clicked " + item.getTitle(),
+                        Toast.LENGTH_SHORT).show();
+                break;
+            }
+            return true;
+        }
+
+        public void onDestroyActionMode(ActionMode mode) {
+        }
+
+        public void onItemCheckedStateChanged(ActionMode mode,
+                int position, long id, boolean checked) {
+            final int checkedCount = getListView().getCheckedItemCount();
+            switch (checkedCount) {
+                case 0:
+                    mode.setSubtitle(null);
+                    break;
+                case 1:
+                    mode.setSubtitle("One item selected");
+                    break;
+                default:
+                    mode.setSubtitle("" + checkedCount + " items selected");
+                    break;
+            }
+        }
+        
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List17.java b/samples/ApiDemos/src/com/example/android/apis/view/List17.java
new file mode 100644
index 0000000..67fa0bd
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List17.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+
+/**
+ * A list view where the last item the user clicked is placed in
+ * the "activated" state, causing its background to highlight.
+ */
+public class List17 extends ListActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Use the built-in layout for showing a list item with a single
+        // line of text whose background is changes when activated.
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_activated_1, mStrings));
+        getListView().setTextFilterEnabled(true);
+        
+        // Tell the list view to show one checked/activated item at a time.
+        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        
+        // Start with first item activated.
+        // Make the newly clicked item the currently selected one.
+        getListView().setItemChecked(0, true);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        // Make the newly clicked item the currently selected one.
+        getListView().setItemChecked(position, true);
+    }
+
+    private String[] mStrings = Cheeses.sCheeseStrings;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List4.java b/samples/ApiDemos/src/com/example/android/apis/view/List4.java
index a140e60..9c18a5d 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List4.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List4.java
@@ -16,8 +16,8 @@
 
 package com.example.android.apis.view;
 
-//Need the following import to get access to the app resources, since this
-//class is in a sub-package.
+import com.example.android.apis.Shakespeare;
+
 import android.app.ListActivity;
 import android.content.Context;
 import android.os.Bundle;
@@ -59,7 +59,7 @@
          * @see android.widget.ListAdapter#getCount()
          */
         public int getCount() {
-            return mTitles.length;
+            return Shakespeare.TITLES.length;
         }
 
         /**
@@ -92,12 +92,12 @@
         public View getView(int position, View convertView, ViewGroup parent) {
             SpeechView sv;
             if (convertView == null) {
-                sv = new SpeechView(mContext, mTitles[position],
-                        mDialogue[position]);
+                sv = new SpeechView(mContext, Shakespeare.TITLES[position],
+                        Shakespeare.DIALOGUE[position]);
             } else {
                 sv = (SpeechView) convertView;
-                sv.setTitle(mTitles[position]);
-                sv.setDialogue(mDialogue[position]);
+                sv.setTitle(Shakespeare.TITLES[position]);
+                sv.setDialogue(Shakespeare.DIALOGUE[position]);
             }
 
             return sv;
@@ -107,226 +107,6 @@
          * Remember our context so we can use it when constructing views.
          */
         private Context mContext;
-        
-        /**
-         * Our data, part 1.
-         */
-        private String[] mTitles = 
-        {
-                "Henry IV (1)",   
-                "Henry V",
-                "Henry VIII",       
-                "Richard II",
-                "Richard III",
-                "Merchant of Venice",  
-                "Othello",
-                "King Lear"
-        };
-        
-        /**
-         * Our data, part 2.
-         */
-        private String[] mDialogue = 
-        {
-                "So shaken as we are, so wan with care," +
-                "Find we a time for frighted peace to pant," +
-                "And breathe short-winded accents of new broils" +
-                "To be commenced in strands afar remote." +
-                "No more the thirsty entrance of this soil" +
-                "Shall daub her lips with her own children's blood;" +
-                "Nor more shall trenching war channel her fields," +
-                "Nor bruise her flowerets with the armed hoofs" +
-                "Of hostile paces: those opposed eyes," +
-                "Which, like the meteors of a troubled heaven," +
-                "All of one nature, of one substance bred," +
-                "Did lately meet in the intestine shock" +
-                "And furious close of civil butchery" +
-                "Shall now, in mutual well-beseeming ranks," +
-                "March all one way and be no more opposed" +
-                "Against acquaintance, kindred and allies:" +
-                "The edge of war, like an ill-sheathed knife," +
-                "No more shall cut his master. Therefore, friends," +
-                "As far as to the sepulchre of Christ," +
-                "Whose soldier now, under whose blessed cross" +
-                "We are impressed and engaged to fight," +
-                "Forthwith a power of English shall we levy;" +
-                "Whose arms were moulded in their mothers' womb" +
-                "To chase these pagans in those holy fields" +
-                "Over whose acres walk'd those blessed feet" +
-                "Which fourteen hundred years ago were nail'd" +
-                "For our advantage on the bitter cross." +
-                "But this our purpose now is twelve month old," +
-                "And bootless 'tis to tell you we will go:" +
-                "Therefore we meet not now. Then let me hear" +
-                "Of you, my gentle cousin Westmoreland," +
-                "What yesternight our council did decree" +
-                "In forwarding this dear expedience.",
-                
-                "Hear him but reason in divinity," + 
-                "And all-admiring with an inward wish" + 
-                "You would desire the king were made a prelate:" + 
-                "Hear him debate of commonwealth affairs," + 
-                "You would say it hath been all in all his study:" + 
-                "List his discourse of war, and you shall hear" + 
-                "A fearful battle render'd you in music:" + 
-                "Turn him to any cause of policy," + 
-                "The Gordian knot of it he will unloose," + 
-                "Familiar as his garter: that, when he speaks," + 
-                "The air, a charter'd libertine, is still," + 
-                "And the mute wonder lurketh in men's ears," + 
-                "To steal his sweet and honey'd sentences;" + 
-                "So that the art and practic part of life" + 
-                "Must be the mistress to this theoric:" + 
-                "Which is a wonder how his grace should glean it," + 
-                "Since his addiction was to courses vain," + 
-                "His companies unletter'd, rude and shallow," + 
-                "His hours fill'd up with riots, banquets, sports," + 
-                "And never noted in him any study," + 
-                "Any retirement, any sequestration" + 
-                "From open haunts and popularity.",
-
-                "I come no more to make you laugh: things now," +
-                "That bear a weighty and a serious brow," +
-                "Sad, high, and working, full of state and woe," +
-                "Such noble scenes as draw the eye to flow," +
-                "We now present. Those that can pity, here" +
-                "May, if they think it well, let fall a tear;" +
-                "The subject will deserve it. Such as give" +
-                "Their money out of hope they may believe," +
-                "May here find truth too. Those that come to see" +
-                "Only a show or two, and so agree" +
-                "The play may pass, if they be still and willing," +
-                "I'll undertake may see away their shilling" +
-                "Richly in two short hours. Only they" +
-                "That come to hear a merry bawdy play," +
-                "A noise of targets, or to see a fellow" +
-                "In a long motley coat guarded with yellow," +
-                "Will be deceived; for, gentle hearers, know," +
-                "To rank our chosen truth with such a show" +
-                "As fool and fight is, beside forfeiting" +
-                "Our own brains, and the opinion that we bring," +
-                "To make that only true we now intend," +
-                "Will leave us never an understanding friend." +
-                "Therefore, for goodness' sake, and as you are known" +
-                "The first and happiest hearers of the town," +
-                "Be sad, as we would make ye: think ye see" +
-                "The very persons of our noble story" +
-                "As they were living; think you see them great," +
-                "And follow'd with the general throng and sweat" +
-                "Of thousand friends; then in a moment, see" +
-                "How soon this mightiness meets misery:" +
-                "And, if you can be merry then, I'll say" +
-                "A man may weep upon his wedding-day.",
-                
-                "First, heaven be the record to my speech!" + 
-                "In the devotion of a subject's love," + 
-                "Tendering the precious safety of my prince," + 
-                "And free from other misbegotten hate," + 
-                "Come I appellant to this princely presence." + 
-                "Now, Thomas Mowbray, do I turn to thee," + 
-                "And mark my greeting well; for what I speak" + 
-                "My body shall make good upon this earth," + 
-                "Or my divine soul answer it in heaven." + 
-                "Thou art a traitor and a miscreant," + 
-                "Too good to be so and too bad to live," + 
-                "Since the more fair and crystal is the sky," + 
-                "The uglier seem the clouds that in it fly." + 
-                "Once more, the more to aggravate the note," + 
-                "With a foul traitor's name stuff I thy throat;" + 
-                "And wish, so please my sovereign, ere I move," + 
-                "What my tongue speaks my right drawn sword may prove.",
-                
-                "Now is the winter of our discontent" + 
-                "Made glorious summer by this sun of York;" + 
-                "And all the clouds that lour'd upon our house" + 
-                "In the deep bosom of the ocean buried." + 
-                "Now are our brows bound with victorious wreaths;" + 
-                "Our bruised arms hung up for monuments;" + 
-                "Our stern alarums changed to merry meetings," + 
-                "Our dreadful marches to delightful measures." + 
-                "Grim-visaged war hath smooth'd his wrinkled front;" + 
-                "And now, instead of mounting barded steeds" + 
-                "To fright the souls of fearful adversaries," + 
-                "He capers nimbly in a lady's chamber" + 
-                "To the lascivious pleasing of a lute." + 
-                "But I, that am not shaped for sportive tricks," + 
-                "Nor made to court an amorous looking-glass;" + 
-                "I, that am rudely stamp'd, and want love's majesty" + 
-                "To strut before a wanton ambling nymph;" + 
-                "I, that am curtail'd of this fair proportion," + 
-                "Cheated of feature by dissembling nature," + 
-                "Deformed, unfinish'd, sent before my time" + 
-                "Into this breathing world, scarce half made up," + 
-                "And that so lamely and unfashionable" + 
-                "That dogs bark at me as I halt by them;" + 
-                "Why, I, in this weak piping time of peace," + 
-                "Have no delight to pass away the time," + 
-                "Unless to spy my shadow in the sun" + 
-                "And descant on mine own deformity:" + 
-                "And therefore, since I cannot prove a lover," + 
-                "To entertain these fair well-spoken days," + 
-                "I am determined to prove a villain" + 
-                "And hate the idle pleasures of these days." + 
-                "Plots have I laid, inductions dangerous," + 
-                "By drunken prophecies, libels and dreams," + 
-                "To set my brother Clarence and the king" + 
-                "In deadly hate the one against the other:" + 
-                "And if King Edward be as true and just" + 
-                "As I am subtle, false and treacherous," + 
-                "This day should Clarence closely be mew'd up," + 
-                "About a prophecy, which says that 'G'" + 
-                "Of Edward's heirs the murderer shall be." + 
-                "Dive, thoughts, down to my soul: here" + 
-                "Clarence comes.",
-                
-                "To bait fish withal: if it will feed nothing else," + 
-                "it will feed my revenge. He hath disgraced me, and" + 
-                "hindered me half a million; laughed at my losses," + 
-                "mocked at my gains, scorned my nation, thwarted my" + 
-                "bargains, cooled my friends, heated mine" + 
-                "enemies; and what's his reason? I am a Jew. Hath" + 
-                "not a Jew eyes? hath not a Jew hands, organs," + 
-                "dimensions, senses, affections, passions? fed with" + 
-                "the same food, hurt with the same weapons, subject" + 
-                "to the same diseases, healed by the same means," + 
-                "warmed and cooled by the same winter and summer, as" + 
-                "a Christian is? If you prick us, do we not bleed?" + 
-                "if you tickle us, do we not laugh? if you poison" + 
-                "us, do we not die? and if you wrong us, shall we not" + 
-                "revenge? If we are like you in the rest, we will" + 
-                "resemble you in that. If a Jew wrong a Christian," + 
-                "what is his humility? Revenge. If a Christian" + 
-                "wrong a Jew, what should his sufferance be by" + 
-                "Christian example? Why, revenge. The villany you" + 
-                "teach me, I will execute, and it shall go hard but I" + 
-                "will better the instruction.",
-                
-                "Virtue! a fig! 'tis in ourselves that we are thus" + 
-                "or thus. Our bodies are our gardens, to the which" + 
-                "our wills are gardeners: so that if we will plant" + 
-                "nettles, or sow lettuce, set hyssop and weed up" + 
-                "thyme, supply it with one gender of herbs, or" + 
-                "distract it with many, either to have it sterile" + 
-                "with idleness, or manured with industry, why, the" + 
-                "power and corrigible authority of this lies in our" + 
-                "wills. If the balance of our lives had not one" + 
-                "scale of reason to poise another of sensuality, the" + 
-                "blood and baseness of our natures would conduct us" + 
-                "to most preposterous conclusions: but we have" + 
-                "reason to cool our raging motions, our carnal" + 
-                "stings, our unbitted lusts, whereof I take this that" + 
-                "you call love to be a sect or scion.",
-
-                "Blow, winds, and crack your cheeks! rage! blow!" + 
-                "You cataracts and hurricanoes, spout" + 
-                "Till you have drench'd our steeples, drown'd the cocks!" + 
-                "You sulphurous and thought-executing fires," + 
-                "Vaunt-couriers to oak-cleaving thunderbolts," + 
-                "Singe my white head! And thou, all-shaking thunder," + 
-                "Smite flat the thick rotundity o' the world!" + 
-                "Crack nature's moulds, an germens spill at once," + 
-                "That make ingrateful man!"
-        };
     }
     
     /**
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List9.java b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
index b2aea05..b50bd52 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List9.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
@@ -140,178 +140,5 @@
         }
     }
 
-    private String[] mStrings = {
-            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
-            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
-            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
-            "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
-            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh",
-            "Anthoriro", "Appenzell", "Aragon", "Ardi Gasna", "Ardrahan",
-            "Armenian String", "Aromes au Gene de Marc", "Asadero", "Asiago",
-            "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", "Babybel",
-            "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal",
-            "Banon", "Barry's Bay Cheddar", "Basing", "Basket Cheese",
-            "Bath Cheese", "Bavarian Bergkase", "Baylough", "Beaufort",
-            "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
-            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir",
-            "Bierkase", "Bishop Kennedy", "Blarney", "Bleu d'Auvergne",
-            "Bleu de Gex", "Bleu de Laqueuille", "Bleu de Septmoncel",
-            "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
-            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini",
-            "Bocconcini (Australian)", "Boeren Leidenkaas", "Bonchester",
-            "Bosworth", "Bougon", "Boule Du Roves", "Boulette d'Avesnes",
-            "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
-            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois",
-            "Brebis du Puyfaucon", "Bresse Bleu", "Brick", "Brie",
-            "Brie de Meaux", "Brie de Melun", "Brillat-Savarin", "Brin",
-            "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
-            "Briquette de Brebis", "Briquette du Forez", "Broccio",
-            "Broccio Demi-Affine", "Brousse du Rove", "Bruder Basil",
-            "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
-            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase",
-            "Button (Innes)", "Buxton Blue", "Cabecou", "Caboc", "Cabrales",
-            "Cachaille", "Caciocavallo", "Caciotta", "Caerphilly",
-            "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
-            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux",
-            "Capricorn Goat", "Capriole Banon", "Carre de l'Est",
-            "Casciotta di Urbino", "Cashel Blue", "Castellano", "Castelleno",
-            "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
-            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou",
-            "Chabichou du Poitou", "Chabis de Gatine", "Chaource", "Charolais",
-            "Chaumes", "Cheddar", "Cheddar Clothbound", "Cheshire", "Chevres",
-            "Chevrotin des Aravis", "Chontaleno", "Civray",
-            "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby",
-            "Cold Pack", "Comte", "Coolea", "Cooleney", "Coquetdale",
-            "Corleggy", "Cornish Pepper", "Cotherstone", "Cotija",
-            "Cottage Cheese", "Cottage Cheese (Australian)", "Cougar Gold",
-            "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
-            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche",
-            "Crescenza", "Croghan", "Crottin de Chavignol",
-            "Crottin du Chavignol", "Crowdie", "Crowley", "Cuajada", "Curd",
-            "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
-            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo",
-            "Danish Fontina", "Daralagjazsky", "Dauphin", "Delice des Fiouves",
-            "Denhany Dorset Drum", "Derby", "Dessertnyj Belyj", "Devon Blue",
-            "Devon Garland", "Dolcelatte", "Doolin", "Doppelrhamstufel",
-            "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
-            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra",
-            "Dunlop", "Dunsyre Blue", "Duroblando", "Durrus",
-            "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
-            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne",
-            "Esbareich", "Esrom", "Etorki", "Evansdale Farmhouse Brie",
-            "Evora De L'Alentejo", "Exmoor Blue", "Explorateur", "Feta",
-            "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
-            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis",
-            "Flor de Guia", "Flower Marie", "Folded",
-            "Folded cheese with mint", "Fondant de Brebis", "Fontainebleau",
-            "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
-            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire",
-            "Fourme de Montbrison", "Fresh Jack", "Fresh Mozzarella",
-            "Fresh Ricotta", "Fresh Truffles", "Fribourgeois", "Friesekaas",
-            "Friesian", "Friesla", "Frinault", "Fromage a Raclette",
-            "Fromage Corse", "Fromage de Montagne de Savoie", "Fromage Frais",
-            "Fruit Cream Cheese", "Frying Cheese", "Fynbo", "Gabriel",
-            "Galette du Paludier", "Galette Lyonnaise",
-            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail",
-            "Garrotxa", "Gastanberra", "Geitost", "Gippsland Blue", "Gjetost",
-            "Gloucester", "Golden Cross", "Gorgonzola", "Gornyaltajski",
-            "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
-            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
-            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh",
-            "Greve", "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny",
-            "Halloumi", "Halloumy (Australian)", "Haloumi-Style Cheese",
-            "Harbourne Blue", "Havarti", "Heidi Gruyere", "Hereford Hop",
-            "Herrgardsost", "Herriot Farmhouse", "Herve", "Hipi Iti",
-            "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
-            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu",
-            "Isle of Mull", "Jarlsberg", "Jermi Tortes", "Jibneh Arabieh",
-            "Jindi Brie", "Jubilee Blue", "Juustoleipa", "Kadchgall", "Kaseri",
-            "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
-            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold",
-            "Klosterkaese", "Knockalara", "Kugelkase", "L'Aveyronnais",
-            "L'Ecir de l'Aubrac", "La Taupiniere", "La Vache Qui Rit",
-            "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
-            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin",
-            "Le Fium Orbo", "Le Lacandou", "Le Roule", "Leafield", "Lebbene",
-            "Leerdammer", "Leicester", "Leyden", "Limburger",
-            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer",
-            "Little Rydings", "Livarot", "Llanboidy", "Llanglofan Farmhouse",
-            "Loch Arthur Farmhouse", "Loddiswell Avondale", "Longhorn",
-            "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam", "Macconais",
-            "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
-            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses",
-            "Maredsous", "Margotin", "Maribo", "Maroilles", "Mascares",
-            "Mascarpone", "Mascarpone (Australian)", "Mascarpone Torta",
-            "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
-            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)",
-            "Meyer Vintage Gouda", "Mihalic Peynir", "Milleens", "Mimolette",
-            "Mine-Gabhar", "Mini Baby Bells", "Mixte", "Molbo",
-            "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
-            "Monterey Jack", "Monterey Jack Dry", "Morbier",
-            "Morbier Cru de Montagne", "Mothais a la Feuille", "Mozzarella",
-            "Mozzarella (Australian)", "Mozzarella di Bufala",
-            "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
-            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais",
-            "Neufchatel", "Neufchatel (Australian)", "Niolo", "Nokkelost",
-            "Northumberland", "Oaxaca", "Olde York", "Olivet au Foin",
-            "Olivet Bleu", "Olivet Cendre", "Orkney Extra Mature Cheddar",
-            "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty", "Oszczypek",
-            "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer",
-            "Panela", "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)",
-            "Parmigiano Reggiano", "Pas de l'Escalette", "Passendale",
-            "Pasteurized Processed", "Pate de Fromage", "Patefine Fort",
-            "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac",
-            "Pave du Berry", "Pecorino", "Pecorino in Walnut Leaves",
-            "Pecorino Romano", "Peekskill Pyramid", "Pelardon des Cevennes",
-            "Pelardon des Corbieres", "Penamellera", "Penbryn", "Pencarreg",
-            "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
-            "Picodon de Chevre", "Picos de Europa", "Piora",
-            "Pithtviers au Foin", "Plateau de Herve", "Plymouth Cheese",
-            "Podhalanski", "Poivre d'Ane", "Polkolbin", "Pont l'Eveque",
-            "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
-            "Pourly", "Prastost", "Pressato", "Prince-Jean",
-            "Processed Cheddar", "Provolone", "Provolone (Australian)",
-            "Pyengana Cheddar", "Pyramide", "Quark", "Quark (Australian)",
-            "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
-            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango",
-            "Queso de Murcia", "Queso del Montsec", "Queso del Tietar",
-            "Queso Fresco", "Queso Fresco (Adobera)", "Queso Iberico",
-            "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
-            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette",
-            "Ragusano", "Raschera", "Reblochon", "Red Leicester",
-            "Regal de la Dombes", "Reggianito", "Remedou", "Requeson",
-            "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata",
-            "Ridder", "Rigotte", "Rocamadour", "Rollot", "Romano",
-            "Romans Part Dieu", "Roncal", "Roquefort", "Roule",
-            "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu",
-            "Saaland Pfarr", "Saanenkaese", "Saga", "Sage Derby",
-            "Sainte Maure", "Saint-Marcellin", "Saint-Nectaire",
-            "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
-            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza",
-            "Schabzieger", "Schloss", "Selles sur Cher", "Selva", "Serat",
-            "Seriously Strong Cheddar", "Serra da Estrela", "Sharpam",
-            "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene",
-            "Smoked Gouda", "Somerset Brie", "Sonoma Jack",
-            "Sottocenare al Tartufo", "Soumaintrain", "Sourire Lozerien",
-            "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
-            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote",
-            "Sveciaost", "Swaledale", "Sweet Style Swiss", "Swiss",
-            "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
-            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea",
-            "Testouri", "Tete de Moine", "Tetilla", "Texas Goat Cheese",
-            "Tibet", "Tillamook Cheddar", "Tilsit", "Timboon Brie", "Toma",
-            "Tomme Brulee", "Tomme d'Abondance", "Tomme de Chevre",
-            "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans",
-            "Tommes", "Torta del Casar", "Toscanello", "Touree de L'Aubier",
-            "Tourmalet", "Trappe (Veritable)", "Trois Cornes De Vendee",
-            "Tronchon", "Trou du Cru", "Truffe", "Tupi", "Turunmaa",
-            "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
-            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco",
-            "Vendomois", "Vieux Corse", "Vignotte", "Vulscombe",
-            "Waimata Farmhouse Blue", "Washed Rind Cheese (Australian)",
-            "Waterloo", "Weichkaese", "Wellington", "Wensleydale",
-            "White Stilton", "Whitestone Farmhouse", "Wigmore",
-            "Woodside Cabecou", "Xanadu", "Xynotyro", "Yarg Cornish",
-            "Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
-            "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+    private String[] mStrings = Cheeses.sCheeseStrings;
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/PopupMenu1.java b/samples/ApiDemos/src/com/example/android/apis/view/PopupMenu1.java
new file mode 100644
index 0000000..161e8e6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/PopupMenu1.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.PopupMenu;
+import android.widget.Toast;
+
+import com.example.android.apis.R;
+
+/**
+ * This demonstrates the use of the PopupMenu class. Clicking the button will inflate and
+ * show a popup menu from an XML resource.
+ */
+public class PopupMenu1 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.popup_menu_1);
+    }
+
+    public void onPopupButtonClick(View button) {
+        PopupMenu popup = new PopupMenu(this, button);
+        popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());
+
+        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+            public boolean onMenuItemClick(MenuItem item) {
+                Toast.makeText(PopupMenu1.this, "Clicked popup menu item " + item.getTitle(),
+                        Toast.LENGTH_SHORT).show();
+                return true;
+            }
+        });
+
+        popup.show();
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/RotatingButton.java b/samples/ApiDemos/src/com/example/android/apis/view/RotatingButton.java
new file mode 100644
index 0000000..e92763c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RotatingButton.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.SeekBar;
+
+/**
+ * This application demonstrates the ability to transform views in 2D and 3D, scaling them,
+ * translating them, and rotating them (in 2D and 3D). Use the seek bars to set the various
+ * transform properties of the button.
+ */
+public class RotatingButton extends Activity {
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.rotating_view);
+        final Button rotatingButton = (Button) findViewById(R.id.rotatingButton);
+        SeekBar seekBar;
+        seekBar = (SeekBar) findViewById(R.id.translationX);
+        seekBar.setMax(400);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                rotatingButton.setTranslationX((float)progress);
+            }
+        });
+        seekBar = (SeekBar) findViewById(R.id.translationY);
+        seekBar.setMax(800);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                rotatingButton.setTranslationY((float)progress);
+            }
+        });
+        seekBar = (SeekBar) findViewById(R.id.scaleX);
+        seekBar.setMax(50);
+        seekBar.setProgress(10);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                rotatingButton.setScaleX((float)progress/10f);
+            }
+        });
+        seekBar = (SeekBar) findViewById(R.id.scaleY);
+        seekBar.setMax(50);
+        seekBar.setProgress(10);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                rotatingButton.setScaleY((float)progress/10f);
+            }
+        });
+        seekBar = (SeekBar) findViewById(R.id.rotationX);
+        seekBar.setMax(360);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                // prevent seeking on app creation
+                rotatingButton.setRotationX((float)progress);
+            }
+        });
+        seekBar = (SeekBar) findViewById(R.id.rotationY);
+        seekBar.setMax(360);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                // prevent seeking on app creation
+                rotatingButton.setRotationY((float)progress);
+            }
+        });
+        seekBar = (SeekBar) findViewById(R.id.rotationZ);
+        seekBar.setMax(360);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onProgressChanged(SeekBar seekBar, int progress,
+                    boolean fromUser) {
+                // prevent seeking on app creation
+                rotatingButton.setRotation((float)progress);
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
new file mode 100644
index 0000000..7488fcc
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.app.SearchableInfo;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.SearchView;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * This demonstrates the usage of SearchView in an ActionBar as a menu item.
+ * It sets a SearchableInfo on the SearchView for suggestions and submitting queries to.
+ */
+public class SearchViewActionBar extends Activity implements SearchView.OnQueryTextListener,
+        SearchView.OnCloseListener, Button.OnClickListener {
+
+    private SearchView mSearchView;
+    private Button mOpenButton;
+    private Button mCloseButton;
+    private TextView mStatusView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
+
+        setContentView(R.layout.searchview_actionbar);
+
+        mStatusView = (TextView) findViewById(R.id.status_text);
+        mOpenButton = (Button) findViewById(R.id.open_button);
+        mCloseButton = (Button) findViewById(R.id.close_button);
+        mOpenButton.setOnClickListener(this);
+        mCloseButton.setOnClickListener(this);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.searchview_in_menu, menu);
+        mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
+        setupSearchView();
+
+        return true;
+    }
+
+    private void setupSearchView() {
+
+        mSearchView.setIconifiedByDefault(true);
+
+        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+        if (searchManager != null) {
+            List<SearchableInfo> searchables = searchManager.getSearchablesInGlobalSearch();
+
+            // Try to use the "applications" global search provider
+            SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
+            for (SearchableInfo inf : searchables) {
+                if (inf.getSuggestAuthority() != null
+                        && inf.getSuggestAuthority().startsWith("applications")) {
+                    info = inf;
+                }
+            }
+            mSearchView.setSearchableInfo(info);
+        }
+
+        mSearchView.setOnQueryTextListener(this);
+        mSearchView.setOnCloseListener(this);
+    }
+
+    public boolean onQueryTextChange(String newText) {
+        mStatusView.setText("Query = " + newText);
+        return false;
+    }
+
+    public boolean onQueryTextSubmit(String query) {
+        mStatusView.setText("Query = " + query + " : submitted");
+        return false;
+    }
+
+    public boolean onClose() {
+        mStatusView.setText("Closed!");
+        return false;
+    }
+
+    public void onClick(View view) {
+        if (view == mCloseButton) {
+            mSearchView.setIconified(true);
+        } else if (view == mOpenButton) {
+            mSearchView.setIconified(false);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewFilterMode.java b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewFilterMode.java
new file mode 100644
index 0000000..1764b2e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewFilterMode.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.Window;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.SearchView;
+
+
+/**
+ * Shows a list that can be filtered in-place with a SearchView in non-iconified mode.
+ */
+public class SearchViewFilterMode extends Activity implements SearchView.OnQueryTextListener {
+
+    private static final String TAG = "SearchViewFilterMode";
+
+    private SearchView mSearchView;
+    private ListView mListView;
+    private ArrayAdapter<String> mAdapter;
+
+    private final String[] mStrings = Cheeses.sCheeseStrings;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
+
+        setContentView(R.layout.searchview_filter);
+
+        mSearchView = (SearchView) findViewById(R.id.search_view);
+        mListView = (ListView) findViewById(R.id.list_view);
+        mListView.setAdapter(mAdapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1,
+                mStrings));
+        mListView.setTextFilterEnabled(true);
+        setupSearchView();
+    }
+
+    private void setupSearchView() {
+        mSearchView.setIconifiedByDefault(false);
+        mSearchView.setOnQueryTextListener(this);
+        mSearchView.setSubmitButtonEnabled(false);
+        mSearchView.setQueryHint(getString(R.string.cheese_hunt_hint));
+    }
+
+    public boolean onQueryTextChange(String newText) {
+        if (TextUtils.isEmpty(newText)) {
+            mListView.clearTextFilter();
+        } else {
+            mListView.setFilterText(newText.toString());
+        }
+        return true;
+    }
+
+    public boolean onQueryTextSubmit(String query) {
+        return false;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SplitTouchView.java b/samples/ApiDemos/src/com/example/android/apis/view/SplitTouchView.java
new file mode 100644
index 0000000..4b7b5c9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SplitTouchView.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+import android.widget.AdapterView.OnItemClickListener;
+
+
+/**
+ * Demonstrates splitting touch events across multiple views within a view group.
+ */
+public class SplitTouchView extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.split_touch_view);
+        ListView list1 = (ListView) findViewById(R.id.list1);
+        ListView list2 = (ListView) findViewById(R.id.list2);
+        ListAdapter adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, Cheeses.sCheeseStrings);
+        list1.setAdapter(adapter);
+        list2.setAdapter(adapter);
+
+        list1.setOnItemClickListener(itemClickListener);
+        list2.setOnItemClickListener(itemClickListener);
+    }
+
+    private int responseIndex = 0;
+
+    private final OnItemClickListener itemClickListener = new OnItemClickListener() {
+        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+            String[] responses = getResources().getStringArray(R.array.cheese_responses);
+            String response = responses[responseIndex++ % responses.length];
+
+            String message = getResources().getString(R.string.split_touch_view_cheese_toast,
+                    Cheeses.sCheeseStrings[position], response);
+
+            Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT);
+            toast.show();
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.java
index 795a86b..f52a8c5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.java
@@ -16,12 +16,13 @@
 
 package com.example.android.apis.view;
 
+import com.example.android.apis.R;
+
 import android.app.TabActivity;
 import android.os.Bundle;
+import android.view.View;
 import android.widget.TabHost;
 import android.widget.TextView;
-import android.view.View;
-import com.example.android.apis.R;
 
 /**
  * Example of using a tab content factory for the content via {@link TabHost.TabSpec#setContent(android.widget.TabHost.TabContentFactory)}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.java
index e09f041..587bfe8 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.java
@@ -44,7 +44,7 @@
         // the tab is clicked.
         tabHost.addTab(tabHost.newTabSpec("tab3")
                 .setIndicator("destroy")
-                .setContent(new Intent(this, Controls2.class)
+                .setContent(new Intent(this, Controls1.class)
                         .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
     }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs4.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs4.java
new file mode 100644
index 0000000..fed7275
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs4.java
@@ -0,0 +1,23 @@
+/*
+ * 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.example.android.apis.view;
+
+
+/**
+ * Identical to Tabs2. The change is in the theme used in the manifest file.
+ */
+public class Tabs4 extends Tabs2 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs5.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs5.java
new file mode 100644
index 0000000..8329df5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs5.java
@@ -0,0 +1,54 @@
+/*
+ * 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.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.TabActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TabHost;
+import android.widget.TextView;
+
+/**
+ * Demonstrates the Tab scrolling when too many tabs are displayed to fit in the screen.
+ */
+public class Tabs5 extends TabActivity implements TabHost.TabContentFactory {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.tabs_scroll);
+
+        final TabHost tabHost = getTabHost();
+
+        for (int i=1; i <= 30; i++) {
+            String name = "Tab " + i;
+            tabHost.addTab(tabHost.newTabSpec(name)
+                    .setIndicator(name)
+                    .setContent(this));
+        }
+    }
+
+    /** {@inheritDoc} */
+    public View createTabContent(String tag) {
+        final TextView tv = new TextView(this);
+        tv.setText("Content for tab with tag " + tag);
+        return tv;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs6.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs6.java
new file mode 100644
index 0000000..253aebd
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs6.java
@@ -0,0 +1,55 @@
+/*
+ * 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.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.TabActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TabHost;
+import android.widget.TextView;
+
+/**
+ * Uses a right gravity for the TabWidget.
+ */
+public class Tabs6 extends TabActivity implements TabHost.TabContentFactory {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.tabs_right_gravity);
+
+        final TabHost tabHost = getTabHost();
+        tabHost.addTab(tabHost.newTabSpec("tab1")
+                .setIndicator("tab1", getResources().getDrawable(R.drawable.star_big_on))
+                .setContent(this));
+        tabHost.addTab(tabHost.newTabSpec("tab2")
+                .setIndicator("tab2")
+                .setContent(this));
+        tabHost.addTab(tabHost.newTabSpec("tab3")
+                .setIndicator("tab3")
+                .setContent(this));
+    }
+
+    public View createTabContent(String tag) {
+        final TextView tv = new TextView(this);
+        tv.setText("Content for tab with tag " + tag);
+        return tv;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/_index.html b/samples/ApiDemos/src/com/example/android/apis/view/_index.html
index a462bc1..c5c7ed2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/view/_index.html
@@ -163,6 +163,30 @@
   
   <dt><a href="List8.html">8. Photos</a></dt>
   <dd> Demonstrates a list activity that uses a custom ListAdapter, setting the view for an empty item, and also how to customize the layout of a ListActivity. </dd>
+
+  <dt><a href="List9.html">9. Array (Overlay)</a></dt>
+  <dd> </dd>
+
+  <dt><a href="List10.html">10. Single choice list</a></dt>
+  <dd> </dd>
+
+  <dt><a href="List11.html">11. Multiple choice list</a></dt>
+  <dd> </dd>
+
+  <dt><a href="List12.html">12. Transcript</a></dt>
+  <dd> </dd>
+
+  <dt><a href="List13.html">13. Slow Adapter</a></dt>
+  <dd> </dd>
+
+  <dt><a href="List14.html">14. Efficient Adapter</a></dt>
+  <dd> </dd>
+
+  <dt><a href="List15.html">15. Selection Mode</a></dt>
+  <dd> Demonstrates the use of selection Contextual Action mode to select multiple items in a list activity. </dd>
+
+  <dt><a href="List16.html">16. Border selection mode</a></dt>
+  <dd> Demonstrates a multi-select list activity that uses the <code>simple_selectable_list_item</code> border layout for selected items. </dd>
 </dl>
 
 
@@ -233,15 +257,40 @@
   <dd>Demonstrates a variety of transformations (android.view.animation.Animation), including fading, motion, and rotation. </dd>
 </dl>
 
+<h3>Drag and Drop</h3>
+<dl>
+  <dt><a href="DragAndDropDemo.html">Drag and Drop Demo</a></dt>
+  <dd>Demonstrates how to perform drag and drop using an OnDragListener. (Uses the <a
+href="DraggableDot.html"><code>DraggableDot</code></a> class.) </dd>
+</dl>
+
 <h3>Controls</h3>
 <dl>
-  <dt><a href="Controls1.html">1. Theme White</a></dt>
-  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using the white theme. </dd>
+  <dt><a href="Controls1.html">1. Light Theme</a></dt>
+  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using the light theme. </dd>
 </dl>
 <dl>
-  <dt><a href="Controls2.html">2. Theme Dark</a></dt>
+  <dt><a href="Controls1.html">2. Dark Theme</a></dt>
   <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using the dark theme. </dd>
 </dl>
+<dl>
+  <dt><a href="Controls1.html">3. Holographic Light Theme</a></dt>
+  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using the light holographic theme. </dd>
+</dl>
+<dl>
+  <dt><a href="Controls1.html">4. Holographic Dark Theme</a></dt>
+  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using the dark holographic theme. </dd>
+</dl>
+<dl>
+  <dt><a href="Controls1.html">5. Custom Theme</a></dt>
+  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using a custom
+  theme based on the light theme. </dd>
+</dl>
+<dl>
+  <dt><a href="Controls1.html">6. Holo or Old Theme</a></dt>
+  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using a custom
+  theme that uses either the traditional or holo theme depending on the version of the platform. </dd>
+</dl>
 
 <h3>Auto Complete</h3>
 <dl>
diff --git a/samples/BackupRestore/Android.mk b/samples/BackupRestore/Android.mk
index c164a6c..abe2526 100644
--- a/samples/BackupRestore/Android.mk
+++ b/samples/BackupRestore/Android.mk
@@ -10,4 +10,6 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
 include $(BUILD_PACKAGE)
diff --git a/samples/BackupRestore/proguard.flags b/samples/BackupRestore/proguard.flags
new file mode 100644
index 0000000..f487abc
--- /dev/null
+++ b/samples/BackupRestore/proguard.flags
@@ -0,0 +1,3 @@
+-keepclassmembers class com.example.android.backuprestore.BackupRestoreActivity {
+    public void onRestoreButtonClick(android.view.View);
+}
diff --git a/samples/BackupRestore/res/layout/backup_restore.xml b/samples/BackupRestore/res/layout/backup_restore.xml
index 1459d42..9e61b00 100644
--- a/samples/BackupRestore/res/layout/backup_restore.xml
+++ b/samples/BackupRestore/res/layout/backup_restore.xml
@@ -16,58 +16,72 @@
 
 <!-- Layout description of the BackupRestore sample's main activity -->
 
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
 
-    <LinearLayout
+    <ScrollView
         android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_weight="1">
 
-        <TextView android:text="@string/filling_text"
-            android:textSize="20dp"
-            android:layout_marginTop="20dp"
-            android:layout_marginBottom="10dp"
+        <LinearLayout
+            android:orientation="vertical"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content">
 
-        <RadioGroup android:id="@+id/filling_group"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="20dp"
-            android:orientation="vertical">
+            <TextView android:text="@string/filling_text"
+                android:textSize="20dp"
+                android:layout_marginTop="20dp"
+                android:layout_marginBottom="10dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
 
-            <RadioButton android:id="@+id/bacon"
-                android:text="@string/bacon_label"/>
-            <RadioButton android:id="@+id/pastrami"
-                android:text="@string/pastrami_label"/>
-            <RadioButton android:id="@+id/hummus"
-                android:text="@string/hummus_label"/>
+            <RadioGroup android:id="@+id/filling_group"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="20dp"
+                android:orientation="vertical">
 
-        </RadioGroup>
+                <RadioButton android:id="@+id/bacon"
+                    android:text="@string/bacon_label"/>
+                <RadioButton android:id="@+id/pastrami"
+                    android:text="@string/pastrami_label"/>
+                <RadioButton android:id="@+id/hummus"
+                    android:text="@string/hummus_label"/>
 
-        <TextView android:text="@string/extras_text"
-            android:textSize="20dp"
-            android:layout_marginTop="20dp"
-            android:layout_marginBottom="10dp"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            </RadioGroup>
 
-        <CheckBox android:id="@+id/mayo"
-            android:text="@string/mayo_text"
-            android:layout_marginLeft="20dp"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            <TextView android:text="@string/extras_text"
+                android:textSize="20dp"
+                android:layout_marginTop="20dp"
+                android:layout_marginBottom="10dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
 
-        <CheckBox android:id="@+id/tomato"
-            android:text="@string/tomato_text"
-            android:layout_marginLeft="20dp"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            <CheckBox android:id="@+id/mayo"
+                android:text="@string/mayo_text"
+                android:layout_marginLeft="20dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
 
-    </LinearLayout>
+            <CheckBox android:id="@+id/tomato"
+                android:text="@string/tomato_text"
+                android:layout_marginLeft="20dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
 
-</ScrollView>
\ No newline at end of file
+        </LinearLayout>
+
+    </ScrollView>
+
+    <Button android:id="@+id/restore_button"
+        android:text="@string/restore_text"
+        android:onClick="onRestoreButtonClick"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_weight="0" />
+
+</LinearLayout>
diff --git a/samples/BackupRestore/res/values/strings.xml b/samples/BackupRestore/res/values/strings.xml
index 64cd7a2..b785243 100644
--- a/samples/BackupRestore/res/values/strings.xml
+++ b/samples/BackupRestore/res/values/strings.xml
@@ -23,4 +23,6 @@
   <string name="extras_text">Extras:</string>
   <string name="mayo_text">Mayonnaise\?</string>
   <string name="tomato_text">Tomato\?</string>
+
+  <string name="restore_text">Restore last data</string>
 </resources>
diff --git a/samples/BackupRestore/src/com/example/android/backuprestore/BackupRestoreActivity.java b/samples/BackupRestore/src/com/example/android/backuprestore/BackupRestoreActivity.java
index 01c10ae..37c2f36 100644
--- a/samples/BackupRestore/src/com/example/android/backuprestore/BackupRestoreActivity.java
+++ b/samples/BackupRestore/src/com/example/android/backuprestore/BackupRestoreActivity.java
@@ -18,8 +18,10 @@
 
 import android.app.Activity;
 import android.app.backup.BackupManager;
+import android.app.backup.RestoreObserver;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.View;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.RadioGroup;
@@ -249,4 +251,21 @@
 
         mBackupManager.dataChanged();
     }
-}
\ No newline at end of file
+
+    /**
+     * Click handler, designated in the layout, that runs a restore of the app's
+     * most recent data when the button is pressed.
+     */
+    public void onRestoreButtonClick(View v) {
+        Log.v(TAG, "Requesting restore of our most recent data");
+        mBackupManager.requestRestore(
+                new RestoreObserver() {
+                    public void restoreFinished(int error) {
+                        /** Done with the restore!  Now draw the new state of our data */
+                        Log.v(TAG, "Restore finished, error = " + error);
+                        populateUI();
+                    }
+                }
+        );
+    }
+}
diff --git a/samples/BasicGLSurfaceView/AndroidManifest.xml b/samples/BasicGLSurfaceView/AndroidManifest.xml
index 5dc7df4..b0375aa 100644
--- a/samples/BasicGLSurfaceView/AndroidManifest.xml
+++ b/samples/BasicGLSurfaceView/AndroidManifest.xml
@@ -21,6 +21,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.basicglsurfaceview">
     <uses-feature android:glEsVersion="0x00020000" />
+    <uses-sdk android:targetSdkVersion="11"/>
     <application
             android:label="@string/app_name">
         <activity android:name="BasicGLSurfaceViewActivity"
diff --git a/samples/BluetoothChat/AndroidManifest.xml b/samples/BluetoothChat/AndroidManifest.xml
index 199c6a5..895e633 100644
--- a/samples/BluetoothChat/AndroidManifest.xml
+++ b/samples/BluetoothChat/AndroidManifest.xml
@@ -33,7 +33,7 @@
         </activity>
         <activity android:name=".DeviceListActivity"
                   android:label="@string/select_device"
-                  android:theme="@android:style/Theme.Dialog"
+                  android:theme="@android:style/Theme.Holo.Dialog"
                   android:configChanges="orientation|keyboardHidden" />
     </application>
 </manifest>
diff --git a/samples/BluetoothChat/res/menu/option_menu.xml b/samples/BluetoothChat/res/menu/option_menu.xml
index 18de725..d003708 100644
--- a/samples/BluetoothChat/res/menu/option_menu.xml
+++ b/samples/BluetoothChat/res/menu/option_menu.xml
@@ -16,11 +16,14 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:id="@+id/secure_connect_scan"
           android:icon="@android:drawable/ic_menu_search"
-          android:title="@string/secure_connect" />
+          android:title="@string/secure_connect"
+          android:showAsAction="ifRoom|withText" />
     <item android:id="@+id/insecure_connect_scan"
           android:icon="@android:drawable/ic_menu_search"
-          android:title="@string/insecure_connect" />
+          android:title="@string/insecure_connect"
+          android:showAsAction="ifRoom|withText" />
     <item android:id="@+id/discoverable"
           android:icon="@android:drawable/ic_menu_mylocation"
-          android:title="@string/discoverable" />
+          android:title="@string/discoverable"
+          android:showAsAction="ifRoom|withText" />
 </menu>
diff --git a/samples/BluetoothChat/res/values/strings.xml b/samples/BluetoothChat/res/values/strings.xml
index 53af2a3..17b8e45 100644
--- a/samples/BluetoothChat/res/values/strings.xml
+++ b/samples/BluetoothChat/res/values/strings.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name">Bluetooth Chat</string>
 
     <!--  BluetoothChat -->
@@ -22,7 +22,7 @@
     <string name="not_connected">You are not connected to a device</string>
     <string name="bt_not_enabled_leaving">Bluetooth was not enabled. Leaving Bluetooth Chat.</string>
     <string name="title_connecting">connecting...</string>
-    <string name="title_connected_to">connected: </string>
+    <string name="title_connected_to">connected to <xliff:g id="device_name">%1$s</xliff:g></string>
     <string name="title_not_connected">not connected</string>
 
     <!--  DeviceListActivity -->
diff --git a/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChat.java b/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChat.java
index 429f2dd..2d26ee1 100644
--- a/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChat.java
+++ b/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChat.java
@@ -16,6 +16,7 @@
 
 package com.example.android.BluetoothChat;
 
+import android.app.ActionBar;
 import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
@@ -64,7 +65,6 @@
     private static final int REQUEST_ENABLE_BT = 3;
 
     // Layout Views
-    private TextView mTitle;
     private ListView mConversationView;
     private EditText mOutEditText;
     private Button mSendButton;
@@ -87,14 +87,7 @@
         if(D) Log.e(TAG, "+++ ON CREATE +++");
 
         // Set up the window layout
-        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
         setContentView(R.layout.main);
-        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
-
-        // Set up the custom title
-        mTitle = (TextView) findViewById(R.id.title_left_text);
-        mTitle.setText(R.string.app_name);
-        mTitle = (TextView) findViewById(R.id.title_right_text);
 
         // Get local Bluetooth adapter
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -237,6 +230,16 @@
         }
     };
 
+    private final void setStatus(int resId) {
+        final ActionBar actionBar = getActionBar();
+        actionBar.setSubtitle(resId);
+    }
+
+    private final void setStatus(CharSequence subTitle) {
+        final ActionBar actionBar = getActionBar();
+        actionBar.setSubtitle(subTitle);
+    }
+
     // The Handler that gets information back from the BluetoothChatService
     private final Handler mHandler = new Handler() {
         @Override
@@ -246,16 +249,15 @@
                 if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
                 switch (msg.arg1) {
                 case BluetoothChatService.STATE_CONNECTED:
-                    mTitle.setText(R.string.title_connected_to);
-                    mTitle.append(mConnectedDeviceName);
+                    setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
                     mConversationArrayAdapter.clear();
                     break;
                 case BluetoothChatService.STATE_CONNECTING:
-                    mTitle.setText(R.string.title_connecting);
+                    setStatus(R.string.title_connecting);
                     break;
                 case BluetoothChatService.STATE_LISTEN:
                 case BluetoothChatService.STATE_NONE:
-                    mTitle.setText(R.string.title_not_connected);
+                    setStatus(R.string.title_not_connected);
                     break;
                 }
                 break;
@@ -306,7 +308,7 @@
                 // Bluetooth is now enabled, so set up a chat session
                 setupChat();
             } else {
-                // User did not enable Bluetooth or an error occured
+                // User did not enable Bluetooth or an error occurred
                 Log.d(TAG, "BT not enabled");
                 Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
                 finish();
@@ -318,7 +320,7 @@
         // Get the device MAC address
         String address = data.getExtras()
             .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
-        // Get the BLuetoothDevice object
+        // Get the BluetoothDevice object
         BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
         // Attempt to connect to the device
         mChatService.connect(device, secure);
diff --git a/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java b/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
index 46d4bcb..c1b3cd6 100644
--- a/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
+++ b/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
@@ -459,6 +459,8 @@
                 } catch (IOException e) {
                     Log.e(TAG, "disconnected", e);
                     connectionLost();
+                    // Start the service over to restart listening mode
+                    BluetoothChatService.this.start();
                     break;
                 }
             }
diff --git a/samples/BluetoothChat/src/com/example/android/BluetoothChat/DeviceListActivity.java b/samples/BluetoothChat/src/com/example/android/BluetoothChat/DeviceListActivity.java
index fa722a2..3aefa12 100644
--- a/samples/BluetoothChat/src/com/example/android/BluetoothChat/DeviceListActivity.java
+++ b/samples/BluetoothChat/src/com/example/android/BluetoothChat/DeviceListActivity.java
@@ -64,7 +64,7 @@
         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
         setContentView(R.layout.device_list);
 
-        // Set result CANCELED incase the user backs out
+        // Set result CANCELED in case the user backs out
         setResult(Activity.RESULT_CANCELED);
 
         // Initialize the button to perform device discovery
diff --git a/samples/BrowserPlugin/Android.mk b/samples/BrowserPlugin/Android.mk
new file mode 100644
index 0000000..827700f
--- /dev/null
+++ b/samples/BrowserPlugin/Android.mk
@@ -0,0 +1,38 @@
+# 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.
+#
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build application
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_PACKAGE_NAME := SampleBrowserPlugin
+
+LOCAL_JNI_SHARED_LIBRARIES := libsampleplugin
+
+include $(BUILD_PACKAGE)
+
+# ============================================================
+
+# Also build all of the sub-targets under this one: the shared library.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/BrowserPlugin/AndroidManifest.xml b/samples/BrowserPlugin/AndroidManifest.xml
new file mode 100644
index 0000000..d926729
--- /dev/null
+++ b/samples/BrowserPlugin/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.android.sampleplugin"
+      android:versionCode="1"
+      android:versionName="1.0">
+
+    <uses-permission android:name="android.webkit.permission.PLUGIN"/>
+
+    <uses-sdk android:minSdkVersion="3" />
+
+    <application android:icon="@drawable/sample_browser_plugin"
+                 android:label="@string/sample_browser_plugin">
+        <service android:name=".SamplePlugin">
+            <intent-filter>
+                <action android:name="android.webkit.PLUGIN" />
+            </intent-filter>
+            <meta-data android:name="type" android:value="native" />
+        </service>
+    </application>
+
+</manifest>
diff --git a/apps/GraphicsLab/MODULE_LICENSE_APACHE2 b/samples/BrowserPlugin/MODULE_LICENSE_APACHE2
similarity index 100%
rename from apps/GraphicsLab/MODULE_LICENSE_APACHE2
rename to samples/BrowserPlugin/MODULE_LICENSE_APACHE2
diff --git a/apps/GraphicsLab/NOTICE b/samples/BrowserPlugin/NOTICE
similarity index 100%
rename from apps/GraphicsLab/NOTICE
rename to samples/BrowserPlugin/NOTICE
diff --git a/samples/BrowserPlugin/README b/samples/BrowserPlugin/README
new file mode 100644
index 0000000..29797b2
--- /dev/null
+++ b/samples/BrowserPlugin/README
@@ -0,0 +1,177 @@
+# 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.
+#
+
+##############################
+######### CONTENTS ###########
+A. INTRODUCTION
+B. PLUGIN STRUCTURE
+C. HOW TO DEPLOY
+D. SUB-PLUGINS
+    1. ANIMATION
+    2. AUDIO
+    3. BACKGROUND
+    4. FORM
+    5. PAINT
+
+
+##############################
+## (A) INTRODUCTION ##########
+
+The sample plugin is intended to give plugin developers a point of reference to
+see how an android browser plugin is created and how to use the available APIs.
+A plugin is packaged like a standard apk and can be installed either via the 
+market or adb.  The sample plugin attempts to exercise as many of the APIs as
+possible but unfortunately not all are covered. 
+
+Trying to have a single plugin demonstrate all possible API interactions on one
+screen was not practical. On the other hand we also didn't want a separate
+plugin for each interction, as that would result in many separate apk's that
+would need to be maintained.  To solve this problem we developed the idea to use
+"sub-plugins". With a sub-plugin only one specific feature of the plugin would
+be active at a time, but they would all share as much common code as possible.
+A detailed description of each sub-plugin and its function can be found in the
+sub-plugins section.
+
+##############################
+## (B) PLUGIN STRUCTURE ######
+
+The sample plugin is packaged as one plugin but contains many unique sub-plugins
+(e.g. audio and paint).  The package consists of two pieces: (1) Java code
+containing the config; (2) C++ shared library containing the brower/plugin
+bindings and the sub-plugin classes.  
+
+~~~~ (1) JAVA ~~~~~
+Android.mk: specifies the name of the APK (SampleBrowserPlugin) as well as which
+            shared libraries to include.
+
+AndroidManifest.xml: similar to a standard android manifest file, except that it
+                     must contain the "uses-permission" and "service"
+                     elements that are plugin specific. The "service" element
+                     contains sub-elements that describe the java component of
+                     the service.
+
+src/*: location of the java source files.  This contains the SamplePlugin.class
+       which is the java component of our plugin.  The component must exist and
+       implement the required interfaces, though simply returning null is valid.
+
+res/*: location of the static resources (e.g. an icon for the plugin)
+
+~~~~ (2) C++ ~~~~~
+jni/Android.mk: specifies the build parameters for the shared library that is to
+                be included with the apk. The library contains all the bindings
+                between the plugin and the browser.
+
+jni/main.*: this code is the binding point between the plugin and the browser.
+            It supports all of the functions required for a standard netscape
+            style plugin as well as all the android specific APIs. The initial
+            starting point for the plugin is the NP_Initialize function. The
+            NPP_New function is responsible for reading the input args and
+            selecting the appropriate sub-plugin to instantiate. Most other
+            functions either return fixed values or pass their inputs to the
+            sub-plugin for processing.
+
+jni/PluginObject.*: The pluginObject provides a convenient container in which to
+                    store variables (the plugin's state).  This objects two main
+                    responsibilities are (1) to construct and store the NPClass 
+                    object (done using code provided by Apple) and (2) provide
+                    the abstract class for the sub-plugin objects and a place to 
+                    store the sub-plugin after it is instantiated.  
+
+jni/*/*: Each of the sub-plugins has a folder that contains its class definition
+         and logic. The sub-plugin receives events from the browser and it can
+         also communicate with the browser using the netscape plugin functions
+         as well as the specialized android interfaces.
+
+
+##############################
+## (C) HOW TO DEPLOY #########
+
+To compile and install a plugin on a device/emulator simply...
+
+1. run "make SampleBrowserPlugin" (compiles libsampleplugin.so and builds the apk)
+2. the previous command produces an apk file so record its location
+3. run "adb install [apk_file]" to install it on a device/emulator
+4. the browser will auto recognize the plugin is available
+
+Now that the plugin is installed you can manage it just like you would any other
+application via Settings -> Applications -> Manage applications. To execute the
+plugin you need to include an html snippet (similar to the one found below) in
+a document that is accessible by the browser.  The mime-type cannot change but
+you can change the width, height, and parameters.  The parameters are used to
+notify the plugin which sub-plugin to execute and which drawing model to use.
+
+<object type="application/x-testbrowserplugin" height=50 width=250>
+    <param name="DrawingModel" value="Surface" />
+    <param name="PluginType" value="Background" />
+</object>
+
+
+##############################
+## (D) SUB-PLUGINS ###########
+
+Each sub-plugin corresponds to exactly one plugin type and can support one or
+more drawing models. In the subsections below there are descriptions of each of
+the sub-plugins as well as the information required to create the html snippets. 
+
+#######################
+## (D1) ANIMATION #####
+
+PLUGIN TYPE: Animation
+DRAWING MODEL: Bitmap
+
+This plugin draws a ball bouncing around the screen. If the plugin is not entirely
+on the screen and it it touched, then it will attempt to center itself on screen.
+
+#######################
+## (D2) AUDIO #########
+
+PLUGIN TYPE: Audio
+DRAWING MODEL: Bitmap
+
+This plugin plays a raw audio file located at /sdcard/sample.raw (need to supply
+your own). It uses touch to trigger the play, pause, and stop buttons.
+
+#######################
+## (D3) BACKGROUND ####
+
+PLUGIN TYPE: Background
+DRAWING MODEL: Surface
+
+This plugin has minimal visual components but mainly runs API tests in the 
+background. The  plugin handles scaling its own bitmap on zoom which in this
+case is a simple string of text. The output of this plugin is found in the logs
+as it prints errors if it detects any API failures. Some of the API's tested are
+timers, javascript access, and bitmap formatting.
+
+#######################
+## (D4) FORM ##########
+
+PLUGIN TYPE: Form
+DRAWING MODEL: Bitmap
+
+This plugin mimics a simple username/password form. You can select a textbox by
+either touching it or using the navigation keys.  Once selected the box will
+highlight and the keyboard will appear. If the textbox selected is not fully
+in view then the plugin will ensure it is centered on the screen.  
+
+#######################
+## (D5) PAINT #########
+
+PLUGIN TYPE: Paint
+DRAWING MODEL: Surface
+
+This plugin provides a surface that the user can "paint" on.  The inputs method
+can be toggled between mouse (dots) and touch (lines).  This plugin has a fixed
+surface and allows the browser to scale the surface when zooming. 
diff --git a/samples/BrowserPlugin/jni/Android.mk b/samples/BrowserPlugin/jni/Android.mk
new file mode 100644
index 0000000..b153e37
--- /dev/null
+++ b/samples/BrowserPlugin/jni/Android.mk
@@ -0,0 +1,76 @@
+##
+##
+## Copyright 2008, The Android Open Source Project
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+##  * Redistributions of source code must retain the above copyright
+##    notice, this list of conditions and the following disclaimer.
+##  * Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+##
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	main.cpp \
+	PluginObject.cpp \
+	RenderingThread.cpp \
+	animation/AnimationPlugin.cpp \
+	animation/AnimationThread.cpp \
+	audio/AudioPlugin.cpp \
+	background/BackgroundPlugin.cpp \
+	form/FormPlugin.cpp \
+	navigation/NavigationPlugin.cpp \
+	paint/PaintPlugin.cpp \
+	video/VideoPlugin.cpp \
+	jni-bridge.cpp \
+
+LOCAL_C_INCLUDES += \
+	$(JNI_H_INCLUDE) \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/animation \
+	$(LOCAL_PATH)/audio \
+	$(LOCAL_PATH)/background \
+	$(LOCAL_PATH)/form \
+	$(LOCAL_PATH)/navigation \
+	$(LOCAL_PATH)/paint \
+	$(LOCAL_PATH)/video \
+	external/webkit/WebCore/bridge \
+	external/webkit/WebCore/plugins \
+	external/webkit/WebCore/platform/android/JavaVM \
+	external/webkit/WebKit/android/plugins \
+	external/skia/include/core
+
+LOCAL_SHARED_LIBRARIES := \
+	libnativehelper \
+	libutils \
+	libcutils \
+	libEGL \
+	libGLESv2 \
+	libskia
+
+LOCAL_CFLAGS += -fvisibility=hidden 
+LOCAL_PRELINK_MODULE:=false
+
+LOCAL_MODULE:= libsampleplugin
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp
new file mode 100644
index 0000000..16925c8
--- /dev/null
+++ b/samples/BrowserPlugin/jni/PluginObject.cpp
@@ -0,0 +1,215 @@
+/*
+ IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
+ consideration of your agreement to the following terms, and your use, installation,
+ modification or redistribution of this Apple software constitutes acceptance of these
+ terms.  If you do not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject to these
+ terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
+ this original Apple software (the "Apple Software"), to use, reproduce, modify and
+ redistribute the Apple Software, with or without modifications, in source and/or binary
+ forms; provided that if you redistribute the Apple Software in its entirety and without
+ modifications, you must retain this notice and the following text and disclaimers in all
+ such redistributions of the Apple Software.  Neither the name, trademarks, service marks
+ or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
+ the Apple Software without specific prior written permission from Apple. Except as expressly
+ stated in this notice, no other rights or licenses, express or implied, are granted by Apple
+ herein, including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO WARRANTIES,
+ EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
+ USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+          OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
+ REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
+ WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
+ OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include "main.h"
+#include "PluginObject.h"
+
+int SubPlugin::getPluginWidth() {
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    return obj->window->width;
+}
+
+int SubPlugin::getPluginHeight() {
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    return obj->window->height;
+}
+
+SurfaceSubPlugin::~SurfaceSubPlugin() {
+    setContext(NULL);
+}
+
+bool SurfaceSubPlugin::supportsDrawingModel(ANPDrawingModel model) {
+    return (model == kSurface_ANPDrawingModel);
+}
+
+void SurfaceSubPlugin::setContext(jobject context) {
+    JNIEnv* env = NULL;
+    if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+
+        // if one exists then free its global reference
+        if (m_context) {
+            env->DeleteGlobalRef(m_context);
+            m_context = NULL;
+        }
+
+        // create a new global ref
+        if (context) {
+            context = env->NewGlobalRef(context);
+        }
+
+        // set the value
+        m_context = context;
+    }
+}
+
+static void pluginInvalidate(NPObject *obj);
+static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
+static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
+static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
+static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
+static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
+static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
+static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
+static void pluginDeallocate(NPObject *obj);
+static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name);
+static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
+
+
+
+static NPClass pluginClass = {
+    NP_CLASS_STRUCT_VERSION,
+    pluginAllocate,
+    pluginDeallocate,
+    pluginInvalidate,
+    pluginHasMethod,
+    pluginInvoke,
+    pluginInvokeDefault,
+    pluginHasProperty,
+    pluginGetProperty,
+    pluginSetProperty,
+    pluginRemoveProperty,
+    pluginEnumerate
+};
+
+NPClass *getPluginClass(void)
+{
+    return &pluginClass;
+}
+
+static bool identifiersInitialized = false;
+
+#define ID_TESTFILE_PROPERTY            0
+#define NUM_PROPERTY_IDENTIFIERS        1
+
+static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
+static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
+    "testfile"
+};
+
+#define ID_GETTESTFILE_METHOD                   0
+#define NUM_METHOD_IDENTIFIERS                  1
+
+static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
+static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
+    "getTestFile"
+};
+
+static void initializeIdentifiers(void)
+{
+    browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
+    browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
+}
+
+static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
+{
+    int i;
+    for (i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
+        if (name == pluginPropertyIdentifiers[i])
+            return true;
+    return false;
+}
+
+static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
+{
+    int i;
+    for (i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
+        if (name == pluginMethodIdentifiers[i])
+            return true;
+    return false;
+}
+
+static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
+{
+    PluginObject *plugin = (PluginObject *)obj;
+    if (name == pluginPropertyIdentifiers[ID_TESTFILE_PROPERTY]) {
+        BOOLEAN_TO_NPVARIANT(true, *variant);
+        return true;
+    }
+    return false;
+}
+
+static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
+{
+    return false;
+}
+
+static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
+{
+    PluginObject *plugin = (PluginObject *)obj;
+    if (name == pluginMethodIdentifiers[ID_GETTESTFILE_METHOD]) {
+        return true;
+    }
+    return false;
+}
+
+static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
+{
+    return false;
+}
+
+static void pluginInvalidate(NPObject *obj)
+{
+    // Release any remaining references to JavaScript objects.
+}
+
+static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
+{
+    PluginObject *newInstance = (PluginObject*) malloc(sizeof(PluginObject));
+    newInstance->header._class = theClass;
+    newInstance->header.referenceCount = 1;
+
+    if (!identifiersInitialized) {
+        identifiersInitialized = true;
+        initializeIdentifiers();
+    }
+
+    newInstance->npp = npp;
+
+    return &newInstance->header;
+}
+
+static void pluginDeallocate(NPObject *obj)
+{
+    free(obj);
+}
+
+static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name)
+{
+    return false;
+}
+
+static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
+{
+    return false;
+}
diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h
new file mode 100644
index 0000000..e0f4424
--- /dev/null
+++ b/samples/BrowserPlugin/jni/PluginObject.h
@@ -0,0 +1,99 @@
+/*
+ IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
+ consideration of your agreement to the following terms, and your use, installation,
+ modification or redistribution of this Apple software constitutes acceptance of these
+ terms.  If you do not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject to these
+ terms, Apple grants you a personal, non-exclusive license, under Apple�s copyrights in
+ this original Apple software (the "Apple Software"), to use, reproduce, modify and
+ redistribute the Apple Software, with or without modifications, in source and/or binary
+ forms; provided that if you redistribute the Apple Software in its entirety and without
+ modifications, you must retain this notice and the following text and disclaimers in all
+ such redistributions of the Apple Software.  Neither the name, trademarks, service marks
+ or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
+ the Apple Software without specific prior written permission from Apple. Except as expressly
+ stated in this notice, no other rights or licenses, express or implied, are granted by Apple
+ herein, including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO WARRANTIES,
+ EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
+ USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+          OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
+ REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
+ WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
+ OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginObject__DEFINED
+#define PluginObject__DEFINED
+
+#include "main.h"
+#include <jni.h>
+
+enum CustomEventTypes {
+    kSurfaceCreated_CustomEvent     = 0,
+    kSurfaceChanged_CustomEvent     = 1,
+    kSurfaceDestroyed_CustomEvent   = 2,
+};
+typedef int32_t CustomEventType;
+
+class SubPlugin {
+public:
+    SubPlugin(NPP inst) : m_inst(inst) {}
+    virtual ~SubPlugin() {}
+    virtual int16_t handleEvent(const ANPEvent* evt) = 0;
+    virtual bool supportsDrawingModel(ANPDrawingModel) = 0;
+
+    int getPluginWidth();
+    int getPluginHeight();
+
+    NPP inst() const { return m_inst; }
+
+private:
+    NPP m_inst;
+};
+
+class SurfaceSubPlugin : public SubPlugin {
+public:
+    SurfaceSubPlugin(NPP inst) : SubPlugin(inst) { m_context = NULL; }
+    virtual ~SurfaceSubPlugin();
+    virtual jobject getSurface() = 0;
+    virtual bool supportsDrawingModel(ANPDrawingModel);
+
+    void setContext(jobject context);
+
+    jobject m_context;
+};
+
+enum PluginTypes {
+    kAnimation_PluginType  = 1,
+    kAudio_PluginType      = 2,
+    kBackground_PluginType = 3,
+    kForm_PluginType       = 4,
+    kText_PluginType       = 5,
+    kPaint_PluginType      = 6,
+    kVideo_PluginType      = 7,
+    kNavigation_PluginType = 8,
+};
+typedef uint32_t PluginType;
+
+typedef struct PluginObject {
+    NPObject header;
+    NPP npp;
+    NPWindow* window;
+
+    PluginType pluginType;
+    SubPlugin* activePlugin;
+
+} PluginObject;
+
+NPClass *getPluginClass(void);
+
+#endif // PluginObject__DEFINED
diff --git a/samples/BrowserPlugin/jni/RenderingThread.cpp b/samples/BrowserPlugin/jni/RenderingThread.cpp
new file mode 100644
index 0000000..7f267ed
--- /dev/null
+++ b/samples/BrowserPlugin/jni/RenderingThread.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "RenderingThread.h"
+
+#include "ANPOpenGL_npapi.h"
+
+extern ANPLogInterfaceV0       gLogI;
+extern ANPOpenGLInterfaceV0    gOpenGLI;
+
+RenderingThread::RenderingThread(NPP npp) : android::Thread() {
+    m_npp = npp;
+    m_width = -1;
+    m_height = -1;
+    gLogI.log(kError_ANPLogType, "Created Rendering Thread");
+}
+
+android::status_t RenderingThread::readyToRun() {
+
+    gLogI.log(kError_ANPLogType, "in ready to run");
+
+    EGLContext context = gOpenGLI.acquireContext(m_npp);
+
+    gLogI.log(kError_ANPLogType, "context: %p", context);
+
+    if (context == EGL_NO_CONTEXT) {
+        gLogI.log(kError_ANPLogType, "Unable to create EGLContext for a TextureProducer thread");
+        return android::UNKNOWN_ERROR;
+    }
+    return android::NO_ERROR;
+}
+
+void RenderingThread::setDimensions(int width, int height) {
+    android::Mutex::Autolock lock(m_sync);
+    m_width = width;
+    m_height = height;
+}
+
+void RenderingThread::getDimensions(int& width, int& height) {
+    android::Mutex::Autolock lock(m_sync);
+    width = m_width;
+    height = m_height;
+}
+
+void RenderingThread::printGLString(const char *name, GLenum s) {
+    const char *v = (const char *) glGetString(s);
+    gLogI.log(kError_ANPLogType, "GL %s = %s\n", name, v);
+}
+
+void RenderingThread::checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        gLogI.log(kError_ANPLogType, "after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+GLenum RenderingThread::getInternalFormat(SkBitmap::Config config)
+{
+    switch(config) {
+        case SkBitmap::kA8_Config:
+            return GL_ALPHA;
+        case SkBitmap::kARGB_4444_Config:
+            return GL_RGBA;
+        case SkBitmap::kARGB_8888_Config:
+            return GL_RGBA;
+        case SkBitmap::kRGB_565_Config:
+            return GL_RGB;
+        default:
+            return -1;
+    }
+}
+
+GLenum RenderingThread::getType(SkBitmap::Config config)
+{
+    switch(config) {
+        case SkBitmap::kA8_Config:
+            return GL_UNSIGNED_BYTE;
+        case SkBitmap::kARGB_4444_Config:
+            return GL_UNSIGNED_SHORT_4_4_4_4;
+        case SkBitmap::kARGB_8888_Config:
+            return GL_UNSIGNED_BYTE;
+        case SkBitmap::kIndex8_Config:
+            return -1; // No type for compressed data.
+        case SkBitmap::kRGB_565_Config:
+            return GL_UNSIGNED_SHORT_5_6_5;
+        default:
+            return -1;
+    }
+}
+
+void RenderingThread::createTextureWithBitmap(GLuint texture, SkBitmap& bitmap) {
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    checkGlError("glBindTexture");
+    SkBitmap::Config config = bitmap.getConfig();
+    int internalformat = getInternalFormat(config);
+    int type = getType(config);
+    bitmap.lockPixels();
+    glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(),
+                 0, internalformat, type, bitmap.getPixels());
+    bitmap.unlockPixels();
+    checkGlError("glTexImage2D");
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+}
+
+void RenderingThread::updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap) {
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    checkGlError("glBindTexture");
+    SkBitmap::Config config = bitmap.getConfig();
+    int internalformat = getInternalFormat(config);
+    int type = getType(config);
+    bitmap.lockPixels();
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+                    internalformat, type, bitmap.getPixels());
+    bitmap.unlockPixels();
+    checkGlError("glTexSubImage2D");
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+}
diff --git a/samples/BrowserPlugin/jni/RenderingThread.h b/samples/BrowserPlugin/jni/RenderingThread.h
new file mode 100644
index 0000000..41f0ce8
--- /dev/null
+++ b/samples/BrowserPlugin/jni/RenderingThread.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "android_npapi.h"
+#include "SkCanvas.h"
+#include "SkBitmap.h"
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+
+#ifndef RenderingThread__DEFINED
+#define RenderingThread__DEFINED
+
+
+class RenderingThread : public android::Thread {
+public:
+    RenderingThread(NPP npp);
+    virtual ~RenderingThread() {};
+    virtual android::status_t readyToRun();
+
+    void setDimensions(int width, int height);
+    void getDimensions(int& width, int& height);
+
+protected:
+    NPP m_npp;
+
+    static void printGLString(const char *name, GLenum s);
+    static void checkGlError(const char* op);
+    static GLenum getInternalFormat(SkBitmap::Config config);
+    static GLenum getType(SkBitmap::Config config);
+    static void createTextureWithBitmap(GLuint texture, SkBitmap& bitmap);
+    static void updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap);
+
+private:
+    virtual bool threadLoop() = 0;
+
+    android::Mutex m_sync;
+    int m_width;
+    int m_height;
+};
+
+
+
+
+#endif // RenderingThread__DEFINED
diff --git a/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp b/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
new file mode 100644
index 0000000..f9af879
--- /dev/null
+++ b/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "AnimationPlugin.h"
+
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*        browser;
+extern ANPLogInterfaceV0       gLogI;
+extern ANPCanvasInterfaceV0    gCanvasI;
+extern ANPPaintInterfaceV0     gPaintI;
+extern ANPPathInterfaceV0      gPathI;
+extern ANPSystemInterfaceV0    gSystemI;
+extern ANPWindowInterfaceV1    gWindowI;
+
+static uint16_t rnd16(float x, int inset) {
+    int ix = (int)roundf(x) + inset;
+    if (ix < 0) {
+        ix = 0;
+    }
+    return static_cast<uint16_t>(ix);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+BallAnimation::BallAnimation(NPP inst) : SurfaceSubPlugin(inst) {
+    //register for touch events
+    ANPEventFlags flags = kTouch_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(kError_ANPLogType, "Error selecting input events.");
+    }
+
+    gLogI.log(kError_ANPLogType, "Starting Rendering Thread");
+
+    //start a thread and do your drawing there
+    m_renderingThread = new AnimationThread(inst);
+    m_renderingThread->incStrong(inst);
+    m_renderingThread->run("AnimationThread");
+}
+
+BallAnimation::~BallAnimation() {
+    m_renderingThread->requestExitAndWait();
+    destroySurface();
+}
+
+bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) {
+    return (model == kOpenGL_ANPDrawingModel);
+}
+
+jobject BallAnimation::getSurface() {
+
+    if (m_surface) {
+        return m_surface;
+    }
+
+    // load the appropriate java class and instantiate it
+    JNIEnv* env = NULL;
+    if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
+        return NULL;
+    }
+
+    const char* className = "com.android.sampleplugin.AnimationSurface";
+    jclass fullScreenClass = gSystemI.loadJavaClass(inst(), className);
+
+    if(!fullScreenClass) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
+        return NULL;
+    }
+
+    jmethodID constructor = env->GetMethodID(fullScreenClass, "<init>", "(Landroid/content/Context;)V");
+    jobject fullScreenSurface = env->NewObject(fullScreenClass, constructor, m_context);
+
+    if(!fullScreenSurface) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
+        return NULL;
+    }
+
+    gLogI.log(kError_ANPLogType, " ---- object %p", fullScreenSurface);
+
+    m_surface = env->NewGlobalRef(fullScreenSurface);
+    return m_surface;
+}
+
+void BallAnimation::destroySurface() {
+    JNIEnv* env = NULL;
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+        env->DeleteGlobalRef(m_surface);
+        m_surface = NULL;
+    }
+}
+
+void BallAnimation::showEntirePluginOnScreen() {
+    NPP instance = this->inst();
+    PluginObject *obj = (PluginObject*) instance->pdata;
+    NPWindow *window = obj->window;
+
+    // log the current visible rect
+    ANPRectI visibleRect = gWindowI.visibleRect(instance);
+    gLogI.log(kDebug_ANPLogType, "Current VisibleRect: (%d,%d,%d,%d)",
+            visibleRect.left, visibleRect.top, visibleRect.right, visibleRect.bottom);
+
+    ANPRectI visibleRects[1];
+
+    visibleRects[0].left = 0;
+    visibleRects[0].top = 0;
+    visibleRects[0].right = window->width;
+    visibleRects[0].bottom = window->height;
+
+    gWindowI.setVisibleRects(instance, visibleRects, 1);
+    gWindowI.clearVisibleRects(instance);
+}
+
+int16_t BallAnimation::handleEvent(const ANPEvent* evt) {
+    NPP instance = this->inst();
+
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+            switch (evt->data.draw.model) {
+                case kOpenGL_ANPDrawingModel: {
+                    //send the width and height to the rendering thread
+                    int width = evt->data.draw.data.surface.width;
+                    int height = evt->data.draw.data.surface.height;
+                    gLogI.log(kError_ANPLogType, "New Dimensions (%d,%d)", width, height);
+                    m_renderingThread->setDimensions(width, height);
+                    return 1;
+                }
+                default:
+                    return 0;   // unknown drawing model
+            }
+        case kTouch_ANPEventType:
+             if (kDown_ANPTouchAction == evt->data.touch.action) {
+                 showEntirePluginOnScreen();
+             }
+            else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) {
+                browser->geturl(inst(), "javascript:alert('Detected double tap event.')", 0);
+                gWindowI.requestFullScreen(inst());
+            }
+            return 1;
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
diff --git a/samples/BrowserPlugin/jni/animation/AnimationPlugin.h b/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
new file mode 100644
index 0000000..870b67c
--- /dev/null
+++ b/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+#include "AnimationThread.h"
+
+#ifndef pluginGraphics__DEFINED
+#define pluginGraphics__DEFINED
+
+class BallAnimation : public SurfaceSubPlugin {
+public:
+    BallAnimation(NPP inst);
+    virtual ~BallAnimation();
+    virtual bool supportsDrawingModel(ANPDrawingModel);
+    virtual int16_t handleEvent(const ANPEvent* evt);
+
+    virtual jobject getSurface();
+private:
+    void showEntirePluginOnScreen();
+    void destroySurface();
+
+    jobject          m_surface;
+    AnimationThread* m_renderingThread;
+};
+
+#endif // pluginGraphics__DEFINED
diff --git a/samples/BrowserPlugin/jni/animation/AnimationThread.cpp b/samples/BrowserPlugin/jni/animation/AnimationThread.cpp
new file mode 100644
index 0000000..9e6342d
--- /dev/null
+++ b/samples/BrowserPlugin/jni/animation/AnimationThread.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "AnimationThread.h"
+#include "ANPOpenGL_npapi.h"
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <utils/SystemClock.h>
+
+extern ANPLogInterfaceV0       gLogI;
+extern ANPOpenGLInterfaceV0    gOpenGLI;
+
+AnimationThread::AnimationThread(NPP npp) : RenderingThread(npp) {
+    m_counter = 0;
+    m_lastPrintTime = android::uptimeMillis();
+    m_executionTime = 0;
+    m_idleTime = 0;
+
+    m_x = m_y = 0;
+    m_dx = 0;
+    m_dy = 0;
+
+    memset(&m_oval, 0, sizeof(m_oval));
+
+    m_paint = new SkPaint;
+    m_paint->setAntiAlias(true);
+
+    m_bitmap = constructBitmap(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+    m_canvas = new SkCanvas(*m_bitmap);
+
+    m_startExecutionTime = 0;
+    m_startTime = android::uptimeMillis();
+}
+
+AnimationThread::~AnimationThread() {
+    delete m_paint;
+    delete m_canvas;
+    delete m_bitmap;
+}
+
+SkBitmap* AnimationThread::constructBitmap(int width, int height) {
+    SkBitmap* bitmap = new SkBitmap;
+    bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
+    bitmap->allocPixels();
+    bitmap->eraseColor(0x00000000);
+    return bitmap;
+}
+
+static void bounce(float* x, float* dx, const float max) {
+    *x += *dx;
+    if (*x < 0) {
+        *x = 0;
+        if (*dx < 0) {
+            *dx = -*dx;
+        }
+    } else if (*x > max) {
+        *x = max;
+        if (*dx > 0) {
+            *dx = -*dx;
+        }
+    }
+}
+
+bool AnimationThread::threadLoop() {
+
+    m_startIdleTime = android::uptimeMillis();
+
+    ANPTextureInfo textureInfo = gOpenGLI.lockTexture(m_npp);
+    GLuint textureId = textureInfo.textureId;
+
+    m_idleTime += android::uptimeMillis() - m_startIdleTime;
+    m_startExecutionTime = android::uptimeMillis();
+
+    int width, height;
+    getDimensions(width, height);
+
+    if (width <= 0)
+        width = DEFAULT_WIDTH;
+    if (height <= 0)
+        height = DEFAULT_HEIGHT;
+
+    if (m_bitmap->width() != width || m_bitmap->height() != height) {
+        delete m_canvas;
+        delete m_bitmap;
+        m_bitmap = constructBitmap(width, height);
+        m_canvas = new SkCanvas(*m_bitmap);
+
+        // change the ball's speed to match the size
+        m_dx = width * .005f;
+        m_dy = height * .007f;
+    }
+
+    // setup variables
+    const float OW = width * .125f;
+    const float OH = height * .125f;
+
+    // clear the old oval
+    m_bitmap->eraseColor(0x880000FF);
+
+    // update the coordinates of the oval
+    bounce(&m_x, &m_dx, width - OW);
+    bounce(&m_y, &m_dy, height - OH);
+
+    // draw the new oval
+    m_oval.fLeft = m_x;
+    m_oval.fTop = m_y;
+    m_oval.fRight = m_x + OW;
+    m_oval.fBottom = m_y + OH;
+    m_paint->setColor(0xAAFF0000);
+    m_canvas->drawOval(m_oval, *m_paint);
+
+    if (textureInfo.width == width && textureInfo.height == height) {
+        updateTextureWithBitmap(textureId, *m_bitmap);
+    } else {
+        createTextureWithBitmap(textureId, *m_bitmap);
+        textureInfo.width = width;
+        textureInfo.height = height;
+        textureInfo.internalFormat = GL_RGBA;
+    }
+
+    m_executionTime += android::uptimeMillis() - m_startExecutionTime;
+    m_counter++;
+
+    gOpenGLI.releaseTexture(m_npp, &textureInfo);
+
+    if (android::uptimeMillis() - m_lastPrintTime > 5000) {
+        float fps = m_counter / ((android::uptimeMillis() - m_startTime) / 1000);
+        float spf = ((android::uptimeMillis() - m_startTime)) / m_counter;
+        float lpf = (m_idleTime) / m_counter;
+        float exe = (m_executionTime) / m_counter;
+        gLogI.log(kError_ANPLogType, "TEXT: counter(%d) fps(%f) spf(%f) lock(%f) execution(%f)\n", (int)m_counter, fps, spf, lpf, exe);
+        m_lastPrintTime = android::uptimeMillis();
+
+        m_counter = 0;
+        m_executionTime = 0;
+        m_idleTime = 0;
+        m_startExecutionTime = 0;
+        m_startTime = android::uptimeMillis();
+    }
+
+    return true;
+}
diff --git a/samples/BrowserPlugin/jni/animation/AnimationThread.h b/samples/BrowserPlugin/jni/animation/AnimationThread.h
new file mode 100644
index 0000000..4f74e94
--- /dev/null
+++ b/samples/BrowserPlugin/jni/animation/AnimationThread.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "RenderingThread.h"
+#include "SkCanvas.h"
+#include "SkBitmap.h"
+#include "SkRect.h"
+#include "SkPaint.h"
+
+#ifndef AnimationThread__DEFINED
+#define AnimationThread__DEFINED
+
+class AnimationThread : public RenderingThread {
+public:
+    AnimationThread(NPP npp);
+    virtual ~AnimationThread();
+
+private:
+    virtual bool threadLoop();
+    SkBitmap* constructBitmap(int width, int height);
+
+    float m_counter;
+
+    int64_t m_lastPrintTime;
+    int64_t m_executionTime;
+    int64_t m_idleTime;
+    int64_t m_startTime;
+    int64_t m_startExecutionTime;
+    int64_t m_startIdleTime;
+
+    float m_x;
+    float m_y;
+    float m_dx;
+    float m_dy;
+
+    SkRect m_oval;
+    SkPaint* m_paint;
+    SkBitmap* m_bitmap;
+    SkCanvas* m_canvas;
+
+    static const unsigned int DEFAULT_WIDTH = 400;
+    static const unsigned int DEFAULT_HEIGHT = 400;
+};
+
+
+
+#endif // AnimationThread__DEFINED
diff --git a/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp b/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp
new file mode 100644
index 0000000..8defef4
--- /dev/null
+++ b/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "AudioPlugin.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*         browser;
+extern ANPLogInterfaceV0        gLogI;
+extern ANPCanvasInterfaceV0     gCanvasI;
+extern ANPPaintInterfaceV0      gPaintI;
+extern ANPAudioTrackInterfaceV0 gSoundI;
+extern ANPTypefaceInterfaceV0   gTypefaceI;
+
+
+static void inval(NPP instance) {
+    browser->invalidaterect(instance, NULL);
+}
+
+static uint16_t rnd16(float x, int inset) {
+    int ix = (int)roundf(x) + inset;
+    if (ix < 0) {
+        ix = 0;
+    }
+    return static_cast<uint16_t>(ix);
+}
+
+static void inval(NPP instance, const ANPRectF& r, bool doAA) {
+    const int inset = doAA ? -1 : 0;
+
+    PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
+    NPRect inval;
+    inval.left = rnd16(r.left, inset);
+    inval.top = rnd16(r.top, inset);
+    inval.right = rnd16(r.right, -inset);
+    inval.bottom = rnd16(r.bottom, -inset);
+    browser->invalidaterect(instance, &inval);
+}
+
+static void audioCallback(ANPAudioEvent evt, void* user, ANPAudioBuffer* buffer) {
+    switch (evt) {
+        case kMoreData_ANPAudioEvent: {
+            SoundPlay* play = reinterpret_cast<SoundPlay*>(user);
+            size_t amount = fread(buffer->bufferData, 1, buffer->size, play->file);
+            buffer->size = amount;
+            if (amount == 0) {
+                gSoundI.stop(play->track);
+                fclose(play->file);
+                play->file = NULL;
+                // TODO need to notify our main thread to delete the track now
+            }
+
+            if (play->fileSize > 0) {
+                // TODO we need to properly update the progress value
+                play->progress = 1;
+                inval(play->instance);
+            }
+
+
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+AudioPlugin::AudioPlugin(NPP inst) : SubPlugin(inst) {
+
+    const char path[] = "/sdcard/sample.raw";
+
+    // open a file stream
+    FILE* f = fopen(path, "r");
+    gLogI.log(kDebug_ANPLogType, "--- path %s FILE %p", path, f);
+
+    // setup our private audio struct's default values
+    m_soundPlay = new SoundPlay;
+    m_soundPlay->instance = inst;
+    m_soundPlay->progress = 0;
+    m_soundPlay->fileSize = 0;
+    m_soundPlay->file = f;
+    m_soundPlay->track = NULL;
+
+    // create the audio track
+    if (f) {
+        m_soundPlay->track = gSoundI.newTrack(44100, kPCM16Bit_ANPSampleFormat, 2, audioCallback, m_soundPlay);
+        if (!m_soundPlay->track) {
+            fclose(f);
+            m_soundPlay->file = NULL;
+        }
+    }
+
+    // get the audio file's size
+    int fileDescriptor = open(path, O_RDONLY);
+    struct stat fileStatus;
+
+    if(fileDescriptor <= 0) {
+        gLogI.log(kError_ANPLogType, "fopen error");
+    }
+    else if (fstat(fileDescriptor, &fileStatus) != 0) {
+        gLogI.log(kDebug_ANPLogType, "File Size: %d", fileStatus.st_size);
+        m_soundPlay->fileSize = fileStatus.st_size;
+    } else {
+        gLogI.log(kError_ANPLogType, "fstat error");
+    }
+
+    // configure the UI elements
+    m_activeTouch = false;
+
+    memset(&m_trackRect, 0, sizeof(m_trackRect));
+    memset(&m_playRect,  0, sizeof(m_playRect));
+    memset(&m_pauseRect, 0, sizeof(m_pauseRect));
+    memset(&m_stopRect,  0, sizeof(m_stopRect));
+
+    m_paintTrack = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintTrack, gPaintI.getFlags(m_paintTrack) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintTrack, 0xFFC0C0C0);
+
+    m_paintRect = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintRect, gPaintI.getFlags(m_paintRect) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintRect, 0xFFA8A8A8);
+
+    m_paintText = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintText, 0xFF2F4F4F);
+    gPaintI.setTextSize(m_paintText, 18);
+
+    m_paintTrackProgress = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintTrackProgress, gPaintI.getFlags(m_paintTrackProgress) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintTrackProgress, 0xFF545454);
+
+    m_paintActiveRect = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintActiveRect, gPaintI.getFlags(m_paintActiveRect) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintActiveRect, 0xFF545454);
+
+    ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
+    gPaintI.setTypeface(m_paintText, tf);
+    gTypefaceI.unref(tf);
+
+    //register for touch events
+    ANPEventFlags flags = kTouch_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+AudioPlugin::~AudioPlugin() {
+    gPaintI.deletePaint(m_paintTrack);
+    gPaintI.deletePaint(m_paintRect);
+    gPaintI.deletePaint(m_paintText);
+    gPaintI.deletePaint(m_paintTrackProgress);
+    gPaintI.deletePaint(m_paintActiveRect);
+    if(m_soundPlay->track)
+        gSoundI.deleteTrack(m_soundPlay->track);
+    delete m_soundPlay;
+}
+
+bool AudioPlugin::supportsDrawingModel(ANPDrawingModel model) {
+    return (model == kBitmap_ANPDrawingModel);
+}
+
+void AudioPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
+    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+
+    ANPRectF clipR;
+    clipR.left = clip.left;
+    clipR.top = clip.top;
+    clipR.right = clip.right;
+    clipR.bottom = clip.bottom;
+    gCanvasI.clipRect(canvas, &clipR);
+
+    draw(canvas);
+    gCanvasI.deleteCanvas(canvas);
+}
+
+void AudioPlugin::draw(ANPCanvas* canvas) {
+
+    PluginObject *obj = (PluginObject*) this->inst()->pdata;
+
+    gLogI.log(kError_ANPLogType, "Drawing");
+
+    const float trackHeight = 30;
+    const float buttonWidth = 60;
+    const float buttonHeight = 30;
+    const int W = obj->window->width;
+    const int H = obj->window->height;
+
+    // color the plugin canvas
+    gCanvasI.drawColor(canvas, 0xFFCDCDCD);
+
+    // get font metrics
+    ANPFontMetrics fontMetrics;
+    gPaintI.getFontMetrics(m_paintText, &fontMetrics);
+
+    // draw the track box (1 px from the edge)
+    m_trackRect.left = 1;
+    m_trackRect.top = 1;
+    m_trackRect.right = W - 2;
+    m_trackRect.bottom = 1 + trackHeight;
+    gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrack);
+
+    // draw the progress bar
+    if (m_soundPlay->progress > 0) {
+        // TODO need to draw progress bar to cover the proper percentage of the track bar
+        gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrackProgress);
+    }
+
+    // draw the play box (under track box)
+    m_playRect.left = m_trackRect.left + 5;
+    m_playRect.top = m_trackRect.bottom + 10;
+    m_playRect.right = m_playRect.left + buttonWidth;
+    m_playRect.bottom = m_playRect.top + buttonHeight;
+    gCanvasI.drawRect(canvas, &m_playRect, getPaint(&m_playRect));
+    // draw the play box (under track box)
+    const char playText[] = "Play";
+    gCanvasI.drawText(canvas, playText, sizeof(playText)-1, m_playRect.left + 5,
+                      m_playRect.top - fontMetrics.fTop, m_paintText);
+
+    // draw the pause box (under track box)
+    m_pauseRect.left = m_playRect.right + 20;
+    m_pauseRect.top = m_trackRect.bottom + 10;
+    m_pauseRect.right = m_pauseRect.left + buttonWidth;
+    m_pauseRect.bottom = m_pauseRect.top + buttonHeight;
+    gCanvasI.drawRect(canvas, &m_pauseRect, getPaint(&m_pauseRect));
+    // draw the text in the pause box
+    const char pauseText[] = "Pause";
+    gCanvasI.drawText(canvas, pauseText, sizeof(pauseText)-1, m_pauseRect.left + 5,
+                      m_pauseRect.top - fontMetrics.fTop, m_paintText);
+
+    // draw the stop box (under track box)
+    m_stopRect.left = m_pauseRect.right + 20;
+    m_stopRect.top = m_trackRect.bottom + 10;
+    m_stopRect.right = m_stopRect.left + buttonWidth;
+    m_stopRect.bottom = m_stopRect.top + buttonHeight;
+    gCanvasI.drawRect(canvas, &m_stopRect, getPaint(&m_stopRect));
+    // draw the text in the pause box
+    const char stopText[] = "Stop";
+    gCanvasI.drawText(canvas, stopText, sizeof(stopText)-1, m_stopRect.left + 5,
+                      m_stopRect.top - fontMetrics.fTop, m_paintText);
+}
+
+ANPPaint* AudioPlugin::getPaint(ANPRectF* input) {
+    return (input == m_activeRect) ? m_paintActiveRect : m_paintRect;
+}
+
+int16_t AudioPlugin::handleEvent(const ANPEvent* evt) {
+    NPP instance = this->inst();
+
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+            switch (evt->data.draw.model) {
+                case kBitmap_ANPDrawingModel:
+                    drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
+                    return 1;
+                default:
+                    break;   // unknown drawing model
+            }
+
+        case kTouch_ANPEventType: {
+            int x = evt->data.touch.x;
+            int y = evt->data.touch.y;
+            if (kDown_ANPTouchAction == evt->data.touch.action) {
+
+                m_activeTouchRect = validTouch(x,y);
+                if(m_activeTouchRect) {
+                    m_activeTouch = true;
+                    return 1;
+                }
+
+            } else if (kUp_ANPTouchAction == evt->data.touch.action && m_activeTouch) {
+                handleTouch(x, y);
+                m_activeTouch = false;
+                return 1;
+            } else if (kCancel_ANPTouchAction == evt->data.touch.action) {
+                m_activeTouch = false;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
+
+void AudioPlugin::invalActiveRect() {
+
+}
+
+ANPRectF* AudioPlugin::validTouch(int x, int y) {
+
+    if (m_playRect.left && x < m_playRect.right && y > m_playRect.top && y < m_playRect.bottom)
+        return &m_playRect;
+    else if (m_pauseRect.left && x < m_pauseRect.right && y > m_pauseRect.top && y < m_pauseRect.bottom)
+        return &m_pauseRect;
+    else if (x > m_stopRect.left && x < m_stopRect.right && y > m_stopRect.top && y < m_stopRect.bottom)
+        return &m_stopRect;
+    else
+        return NULL;
+}
+
+void AudioPlugin::handleTouch(int x, int y) {
+    NPP instance = this->inst();
+
+    // if the track is null then return
+    if (NULL == m_soundPlay->track) {
+        gLogI.log(kError_ANPLogType, "---- %p unable to create track",
+                  instance);
+        return;
+    }
+
+    // check to make sure the currentRect matches the activeRect
+    ANPRectF* currentRect = validTouch(x,y);
+    if (m_activeTouchRect != currentRect)
+        return;
+
+    if (currentRect == &m_playRect) {
+
+        gLogI.log(kDebug_ANPLogType, "---- %p starting track (%d)",
+                  m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
+
+        if (gSoundI.isStopped(m_soundPlay->track)) {
+            gSoundI.start(m_soundPlay->track);
+        }
+    }
+    else if (currentRect == &m_pauseRect) {
+
+        gLogI.log(kDebug_ANPLogType, "---- %p pausing track (%d)",
+                  m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
+
+        if (!gSoundI.isStopped(m_soundPlay->track)) {
+            gSoundI.pause(m_soundPlay->track);
+        }
+    }
+    else if (currentRect == &m_stopRect) {
+
+        gLogI.log(kDebug_ANPLogType, "---- %p stopping track (%d)",
+                  m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
+
+        if (!gSoundI.isStopped(m_soundPlay->track)) {
+            gSoundI.stop(m_soundPlay->track);
+        }
+        if (m_soundPlay->file) {
+            fseek(m_soundPlay->file, 0, SEEK_SET);
+        }
+    }
+    else {
+        return;
+    }
+
+    // set the currentRect to be the activeRect
+    m_activeRect = currentRect;
+    inval(instance);
+}
diff --git a/samples/BrowserPlugin/jni/audio/AudioPlugin.h b/samples/BrowserPlugin/jni/audio/AudioPlugin.h
new file mode 100644
index 0000000..0f88a92
--- /dev/null
+++ b/samples/BrowserPlugin/jni/audio/AudioPlugin.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+#include <stdio.h>
+
+#ifndef audioPlugin__DEFINED
+#define audioPlugin__DEFINED
+
+struct SoundPlay {
+    NPP             instance;
+    ANPAudioTrack*  track;
+    FILE*           file;
+    int             fileSize;
+    int             progress; // value between 0 and 100
+};
+
+class AudioPlugin : public SubPlugin {
+public:
+    AudioPlugin(NPP inst);
+    virtual ~AudioPlugin();
+    virtual bool supportsDrawingModel(ANPDrawingModel);
+    virtual int16_t handleEvent(const ANPEvent* evt);
+private:
+    void draw(ANPCanvas*);
+    void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
+
+    void handleTouch(int x, int y);
+    void invalActiveRect();
+    ANPPaint* getPaint(ANPRectF*);
+    ANPRectF* validTouch(int x, int y);
+
+    ANPRectF    m_trackRect;
+    ANPRectF    m_playRect;
+    ANPRectF    m_pauseRect;
+    ANPRectF    m_stopRect;
+
+    ANPPaint*   m_paintTrack;
+    ANPPaint*   m_paintRect;
+    ANPPaint*   m_paintText;
+
+    ANPPaint*   m_paintTrackProgress;
+    ANPPaint*   m_paintActiveRect;
+
+    SoundPlay*  m_soundPlay;
+
+    bool        m_activeTouch;
+    ANPRectF*   m_activeTouchRect;
+    ANPRectF*   m_activeRect;
+};
+
+#endif // audioPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
new file mode 100644
index 0000000..515acbe
--- /dev/null
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
@@ -0,0 +1,499 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "BackgroundPlugin.h"
+#include "android_npapi.h"
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*        browser;
+extern ANPBitmapInterfaceV0    gBitmapI;
+extern ANPCanvasInterfaceV0    gCanvasI;
+extern ANPLogInterfaceV0       gLogI;
+extern ANPPaintInterfaceV0     gPaintI;
+extern ANPSurfaceInterfaceV0   gSurfaceI;
+extern ANPSystemInterfaceV0    gSystemI;
+extern ANPTypefaceInterfaceV0  gTypefaceI;
+extern ANPWindowInterfaceV0    gWindowI;
+
+#define ARRAY_COUNT(array)      (sizeof(array) / sizeof(array[0]))
+
+static uint32_t getMSecs() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return (uint32_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000 ); // microseconds to milliseconds
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
+
+    // initialize the drawing surface
+    m_surface = NULL;
+
+    //initialize bitmap transparency variables
+    mFinishedStageOne   = false;
+    mFinishedStageTwo   = false;
+    mFinishedStageThree = false;
+
+    // test basic plugin functionality
+    test_logging(); // android logging
+    test_timers();  // plugin timers
+    test_bitmaps(); // android bitmaps
+    test_domAccess();
+    test_javascript();
+    test_loadJavaClass();
+
+    //register for touch events
+    ANPEventFlags flags = kTouch_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+BackgroundPlugin::~BackgroundPlugin() {
+    setContext(NULL);
+    destroySurface();
+}
+
+jobject BackgroundPlugin::getSurface() {
+
+    if (m_surface) {
+        return m_surface;
+    }
+
+    // load the appropriate java class and instantiate it
+    JNIEnv* env = NULL;
+    if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
+        return NULL;
+    }
+
+    const char* className = "com.android.sampleplugin.BackgroundSurface";
+    jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
+
+    if(!backgroundClass) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
+        return NULL;
+    }
+
+    jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "(Landroid/content/Context;)V");
+    jobject backgroundSurface = env->NewObject(backgroundClass, constructor, m_context);
+
+    if(!backgroundSurface) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
+        return NULL;
+    }
+
+    m_surface = env->NewGlobalRef(backgroundSurface);
+    return m_surface;
+}
+
+void BackgroundPlugin::destroySurface() {
+    JNIEnv* env = NULL;
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+        env->DeleteGlobalRef(m_surface);
+        m_surface = NULL;
+    }
+}
+
+void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
+
+    // get the plugin's dimensions according to the DOM
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    const int W = obj->window->width;
+    const int H = obj->window->height;
+
+    // compute the current zoom level
+    const float zoomFactorW = static_cast<float>(surfaceWidth) / W;
+    const float zoomFactorH = static_cast<float>(surfaceHeight) / H;
+
+    // check to make sure the zoom level is uniform
+    if (zoomFactorW + .01 < zoomFactorH && zoomFactorW - .01 > zoomFactorH)
+        gLogI.log(kError_ANPLogType, " ------ %p zoom is out of sync (%f,%f)",
+                  inst(), zoomFactorW, zoomFactorH);
+
+    // scale the variables based on the zoom level
+    const int fontSize = (int)(zoomFactorW * 16);
+    const int leftMargin = (int)(zoomFactorW * 10);
+
+    // lock the surface
+    ANPBitmap bitmap;
+    JNIEnv* env = NULL;
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+        !gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
+        gLogI.log(kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
+        return;
+    }
+
+    // create a canvas
+    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+    gCanvasI.drawColor(canvas, 0xFFFFFFFF);
+
+    ANPPaint* paint = gPaintI.newPaint();
+    gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(paint, 0xFFFF0000);
+    gPaintI.setTextSize(paint, fontSize);
+
+    ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
+    gPaintI.setTypeface(paint, tf);
+    gTypefaceI.unref(tf);
+
+    ANPFontMetrics fm;
+    gPaintI.getFontMetrics(paint, &fm);
+
+    gPaintI.setColor(paint, 0xFF0000FF);
+    const char c[] = "This is a background plugin.";
+    gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
+
+    // clean up variables and unlock the surface
+    gPaintI.deletePaint(paint);
+    gCanvasI.deleteCanvas(canvas);
+    gSurfaceI.unlock(env, m_surface);
+}
+
+int16_t BackgroundPlugin::handleEvent(const ANPEvent* evt) {
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+            gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
+            break;
+        case kLifecycle_ANPEventType:
+            switch (evt->data.lifecycle.action)  {
+                case kOnLoad_ANPLifecycleAction:
+                    gLogI.log(kDebug_ANPLogType, " ------ %p onLoad", inst());
+                    return 1;
+                case kOnScreen_ANPLifecycleAction:
+                    gLogI.log(kDebug_ANPLogType, " ------ %p onScreen", inst());
+                    return 1;
+                case kOffScreen_ANPLifecycleAction:
+                    gLogI.log(kDebug_ANPLogType, " ------ %p offScreen", inst());
+                    return 1;
+            }
+            break; // end kLifecycle_ANPEventType
+        case kTouch_ANPEventType:
+            if (kLongPress_ANPTouchAction == evt->data.touch.action) {
+                browser->geturl(inst(), "javascript:alert('Detected long press event.')", 0);
+                gWindowI.requestFullScreen(inst());
+            }
+            else if (kDoubleTap_ANPTouchAction == evt->data.touch.action)
+                browser->geturl(inst(), "javascript:alert('Detected double tap event.')", 0);
+            break;
+        case kKey_ANPEventType:
+            gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
+            break;
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// LOGGING TESTS
+///////////////////////////////////////////////////////////////////////////////
+
+
+void BackgroundPlugin::test_logging() {
+    NPP instance = this->inst();
+
+    //LOG_ERROR(instance, " ------ %p Testing Log Error", instance);
+    gLogI.log(kError_ANPLogType, " ------ %p Testing Log Error", instance);
+    gLogI.log(kWarning_ANPLogType, " ------ %p Testing Log Warning", instance);
+    gLogI.log(kDebug_ANPLogType, " ------ %p Testing Log Debug", instance);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// TIMER TESTS
+///////////////////////////////////////////////////////////////////////////////
+
+#define TIMER_INTERVAL     50
+static void timer_oneshot(NPP instance, uint32_t timerID);
+static void timer_repeat(NPP instance, uint32_t timerID);
+static void timer_neverfires(NPP instance, uint32_t timerID);
+static void timer_latency(NPP instance, uint32_t timerID);
+
+void BackgroundPlugin::test_timers() {
+    NPP instance = this->inst();
+
+    //Setup the testing counters
+    mTimerRepeatCount = 5;
+    mTimerLatencyCount = 5;
+
+    // test for bogus timerID
+    browser->unscheduletimer(instance, 999999);
+    // test one-shot
+    browser->scheduletimer(instance, 100, false, timer_oneshot);
+    // test repeat
+    browser->scheduletimer(instance, 50, true, timer_repeat);
+    // test timer latency
+    browser->scheduletimer(instance, TIMER_INTERVAL, true, timer_latency);
+    mStartTime = mPrevTime = getMSecs();
+    // test unschedule immediately
+    uint32_t id = browser->scheduletimer(instance, 100, false, timer_neverfires);
+    browser->unscheduletimer(instance, id);
+    // test double unschedule (should be no-op)
+    browser->unscheduletimer(instance, id);
+
+}
+
+static void timer_oneshot(NPP instance, uint32_t timerID) {
+    gLogI.log(kDebug_ANPLogType, "-------- oneshot timer\n");
+}
+
+static void timer_repeat(NPP instance, uint32_t timerID) {
+    BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
+
+    gLogI.log(kDebug_ANPLogType, "-------- repeat timer %d\n",
+              obj->mTimerRepeatCount);
+    if (--obj->mTimerRepeatCount == 0) {
+        browser->unscheduletimer(instance, timerID);
+    }
+}
+
+static void timer_neverfires(NPP instance, uint32_t timerID) {
+    gLogI.log(kError_ANPLogType, "-------- timer_neverfires!!!\n");
+}
+
+static void timer_latency(NPP instance, uint32_t timerID) {
+    BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
+
+    obj->mTimerLatencyCurrentCount += 1;
+
+    uint32_t now = getMSecs();
+    uint32_t interval = now - obj->mPrevTime;
+    uint32_t dur = now - obj->mStartTime;
+    uint32_t expectedDur = obj->mTimerLatencyCurrentCount * TIMER_INTERVAL;
+    int32_t drift = dur - expectedDur;
+    int32_t avgDrift = drift / obj->mTimerLatencyCurrentCount;
+
+    obj->mPrevTime = now;
+
+    gLogI.log(kDebug_ANPLogType,
+              "-------- latency test: [%3d] interval %d expected %d, total %d expected %d, drift %d avg %d\n",
+              obj->mTimerLatencyCurrentCount, interval, TIMER_INTERVAL, dur,
+              expectedDur, drift, avgDrift);
+
+    if (--obj->mTimerLatencyCount == 0) {
+        browser->unscheduletimer(instance, timerID);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BITMAP TESTS
+///////////////////////////////////////////////////////////////////////////////
+
+static void test_formats(NPP instance);
+
+void BackgroundPlugin::test_bitmaps() {
+    test_formats(this->inst());
+}
+
+static void test_formats(NPP instance) {
+
+    // TODO pull names from enum in npapi instead of hardcoding them
+    static const struct {
+        ANPBitmapFormat fFormat;
+        const char*     fName;
+    } gRecs[] = {
+        { kUnknown_ANPBitmapFormat,   "unknown" },
+        { kRGBA_8888_ANPBitmapFormat, "8888" },
+        { kRGB_565_ANPBitmapFormat,   "565" },
+    };
+
+    ANPPixelPacking packing;
+    for (size_t i = 0; i < ARRAY_COUNT(gRecs); i++) {
+        if (gBitmapI.getPixelPacking(gRecs[i].fFormat, &packing)) {
+            gLogI.log(kDebug_ANPLogType,
+                      "pixel format [%d] %s has packing ARGB [%d %d] [%d %d] [%d %d] [%d %d]\n",
+                      gRecs[i].fFormat, gRecs[i].fName,
+                      packing.AShift, packing.ABits,
+                      packing.RShift, packing.RBits,
+                      packing.GShift, packing.GBits,
+                      packing.BShift, packing.BBits);
+        } else {
+            gLogI.log(kDebug_ANPLogType,
+                      "pixel format [%d] %s has no packing\n",
+                      gRecs[i].fFormat, gRecs[i].fName);
+        }
+    }
+}
+
+void BackgroundPlugin::test_bitmap_transparency(const ANPEvent* evt) {
+    NPP instance = this->inst();
+
+    // check default & set transparent
+    if (!mFinishedStageOne) {
+
+        gLogI.log(kDebug_ANPLogType, "BEGIN: testing bitmap transparency");
+
+        //check to make sure it is not transparent
+        if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
+            gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
+        }
+
+        //make it transparent (any non-null value will set it to true)
+        bool value = true;
+        NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, &value);
+        if (err != NPERR_NO_ERROR) {
+            gLogI.log(kError_ANPLogType, "Error setting transparency.");
+        }
+
+        mFinishedStageOne = true;
+        browser->invalidaterect(instance, NULL);
+    }
+    // check transparent & set opaque
+    else if (!mFinishedStageTwo) {
+
+        //check to make sure it is transparent
+        if (evt->data.draw.data.bitmap.format != kRGBA_8888_ANPBitmapFormat) {
+            gLogI.log(kError_ANPLogType, "bitmap did not change to transparent format");
+        }
+
+        //make it opaque
+        NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, NULL);
+        if (err != NPERR_NO_ERROR) {
+            gLogI.log(kError_ANPLogType, "Error setting transparency.");
+        }
+
+        mFinishedStageTwo = true;
+    }
+    // check opaque
+    else if (!mFinishedStageThree) {
+
+        //check to make sure it is not transparent
+        if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
+            gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
+        }
+
+        gLogI.log(kDebug_ANPLogType, "END: testing bitmap transparency");
+
+        mFinishedStageThree = true;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// DOM TESTS
+///////////////////////////////////////////////////////////////////////////////
+
+void BackgroundPlugin::test_domAccess() {
+    NPP instance = this->inst();
+
+    gLogI.log(kDebug_ANPLogType, " ------ %p Testing DOM Access", instance);
+
+    // Get the plugin's DOM object
+    NPObject* windowObject = NULL;
+    browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
+
+    if (!windowObject)
+        gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
+
+    // Retrieve a property from the plugin's DOM object
+    NPIdentifier topIdentifier = browser->getstringidentifier("top");
+    NPVariant topObjectVariant;
+    browser->getproperty(instance, windowObject, topIdentifier, &topObjectVariant);
+
+    if (topObjectVariant.type != NPVariantType_Object)
+        gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for DOM Property: %d,%d", instance, topObjectVariant.type, NPVariantType_Object);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// JAVASCRIPT TESTS
+///////////////////////////////////////////////////////////////////////////////
+
+
+void BackgroundPlugin::test_javascript() {
+    NPP instance = this->inst();
+
+    gLogI.log(kDebug_ANPLogType, " ------ %p Testing JavaScript Access", instance);
+
+    // Get the plugin's DOM object
+    NPObject* windowObject = NULL;
+    browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
+
+    if (!windowObject)
+        gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
+
+    // create a string (JS code) that is stored in memory allocated by the browser
+    const char* jsString = "1200 + 34";
+    void* stringMem = browser->memalloc(strlen(jsString));
+    memcpy(stringMem, jsString, strlen(jsString));
+
+    // execute the javascript in the plugin's DOM object
+    NPString script = { (char*)stringMem, strlen(jsString) };
+    NPVariant scriptVariant;
+    if (!browser->evaluate(instance, windowObject, &script, &scriptVariant))
+        gLogI.log(kError_ANPLogType, " ------ %p Unable to eval the JS.", instance);
+
+    if (scriptVariant.type == NPVariantType_Int32) {
+        if (scriptVariant.value.intValue != 1234)
+            gLogI.log(kError_ANPLogType, " ------ %p Invalid Value for JS Return: %d,1234", instance, scriptVariant.value.intValue);
+    } else {
+        gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for JS Return: %d,%d", instance, scriptVariant.type, NPVariantType_Int32);
+    }
+
+    // free the memory allocated within the browser
+    browser->memfree(stringMem);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Load Java Classes Tests
+///////////////////////////////////////////////////////////////////////////////
+
+void BackgroundPlugin::test_loadJavaClass() {
+
+    JNIEnv* env = NULL;
+    if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to get env");
+        return;
+    }
+
+    const char* className = "com.android.sampleplugin.BackgroundTest";
+    jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
+
+    if(!backgroundClass) {
+        gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to load class");
+        return;
+    }
+
+    jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "()V");
+    jmethodID addMethod = env->GetMethodID(backgroundClass, "addInt", "(II)I");
+    jobject backgroundObject = env->NewObject(backgroundClass, constructor);
+
+    if(!backgroundObject) {
+        gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to construct object");
+        return;
+    }
+
+    jint result = env->CallIntMethod(backgroundObject, addMethod, 2, 2);
+
+    if (result != 4) {
+        gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: invalid result (%d != 4)", result);
+    }
+}
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
new file mode 100644
index 0000000..e0b0597
--- /dev/null
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+
+#ifndef backgroundPlugin__DEFINED
+#define backgroundPlugin__DEFINED
+
+class BackgroundPlugin : public SurfaceSubPlugin {
+public:
+    BackgroundPlugin(NPP inst);
+    virtual ~BackgroundPlugin();
+    virtual int16_t handleEvent(const ANPEvent* evt);
+    virtual jobject getSurface();
+
+    // Timer Testing Variables
+    uint32_t mStartTime;
+    uint32_t mPrevTime;
+    int      mTimerRepeatCount;
+    int      mTimerLatencyCount;
+    int      mTimerLatencyCurrentCount;
+
+    // Bitmap Transparency Variables
+    bool mFinishedStageOne;   // check default & set transparent
+    bool mFinishedStageTwo;   // check transparent & set opaque
+    bool mFinishedStageThree; // check opaque
+
+private:
+    void drawPlugin(int surfaceWidth, int surfaceHeight);
+    void destroySurface();
+
+    jobject     m_surface;
+
+    void test_logging();
+    void test_timers();
+    void test_bitmaps();
+    void test_bitmap_transparency(const ANPEvent* evt);
+    void test_domAccess();
+    void test_javascript();
+    void test_loadJavaClass();
+
+};
+
+#endif // backgroundPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.cpp b/samples/BrowserPlugin/jni/form/FormPlugin.cpp
new file mode 100644
index 0000000..110afaa
--- /dev/null
+++ b/samples/BrowserPlugin/jni/form/FormPlugin.cpp
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "FormPlugin.h"
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*         browser;
+extern ANPLogInterfaceV0        gLogI;
+extern ANPCanvasInterfaceV0     gCanvasI;
+extern ANPPaintInterfaceV0      gPaintI;
+extern ANPTypefaceInterfaceV0   gTypefaceI;
+extern ANPWindowInterfaceV0     gWindowI;
+
+
+static void inval(NPP instance) {
+    browser->invalidaterect(instance, NULL);
+}
+
+static uint16_t rnd16(float x, int inset) {
+    int ix = (int)roundf(x) + inset;
+    if (ix < 0) {
+        ix = 0;
+    }
+    return static_cast<uint16_t>(ix);
+}
+
+static void inval(NPP instance, const ANPRectF& r, bool doAA) {
+    const int inset = doAA ? -1 : 0;
+
+    PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
+    NPRect inval;
+    inval.left = rnd16(r.left, inset);
+    inval.top = rnd16(r.top, inset);
+    inval.right = rnd16(r.right, -inset);
+    inval.bottom = rnd16(r.bottom, -inset);
+    browser->invalidaterect(instance, &inval);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+FormPlugin::FormPlugin(NPP inst) : SubPlugin(inst) {
+
+    m_hasFocus = false;
+    m_activeInput = NULL;
+
+    memset(&m_usernameInput, 0, sizeof(m_usernameInput));
+    memset(&m_passwordInput, 0, sizeof(m_passwordInput));
+
+    m_usernameInput.text[0] = '\0';
+    m_usernameInput.charPtr = 0;
+
+    m_passwordInput.text[0] = '\0';
+    m_passwordInput.charPtr = 0;
+
+    m_paintInput = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintInput, gPaintI.getFlags(m_paintInput) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintInput, 0xFFFFFFFF);
+
+    m_paintActive = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintActive, 0xFFFFFF00);
+
+    m_paintText = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintText, 0xFF000000);
+    gPaintI.setTextSize(m_paintText, 18);
+
+    ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
+    gPaintI.setTypeface(m_paintText, tf);
+    gTypefaceI.unref(tf);
+
+    //register for key and visibleRect events
+    ANPEventFlags flags = kKey_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+FormPlugin::~FormPlugin() {
+    gPaintI.deletePaint(m_paintInput);
+    gPaintI.deletePaint(m_paintActive);
+    gPaintI.deletePaint(m_paintText);
+}
+
+bool FormPlugin::supportsDrawingModel(ANPDrawingModel model) {
+    return (model == kBitmap_ANPDrawingModel);
+}
+
+void FormPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
+    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+
+    ANPRectF clipR;
+    clipR.left = clip.left;
+    clipR.top = clip.top;
+    clipR.right = clip.right;
+    clipR.bottom = clip.bottom;
+    gCanvasI.clipRect(canvas, &clipR);
+
+    draw(canvas);
+    gCanvasI.deleteCanvas(canvas);
+}
+
+void FormPlugin::draw(ANPCanvas* canvas) {
+    NPP instance = this->inst();
+    PluginObject *obj = (PluginObject*) instance->pdata;
+
+    const float inputWidth = 60;
+    const float inputHeight = 30;
+    const int W = obj->window->width;
+    const int H = obj->window->height;
+
+    // color the plugin canvas
+    gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
+
+    // draw the username box (5 px from the top edge)
+    m_usernameInput.rect.left = 5;
+    m_usernameInput.rect.top = 5;
+    m_usernameInput.rect.right = W - 5;
+    m_usernameInput.rect.bottom = m_usernameInput.rect.top + inputHeight;
+    gCanvasI.drawRect(canvas, &m_usernameInput.rect, getPaint(&m_usernameInput));
+    drawText(canvas, m_usernameInput);
+
+    // draw the password box (5 px from the bottom edge)
+    m_passwordInput.rect.left = 5;
+    m_passwordInput.rect.top = H - (inputHeight + 5);
+    m_passwordInput.rect.right = W - 5;
+    m_passwordInput.rect.bottom = m_passwordInput.rect.top + inputHeight;
+    gCanvasI.drawRect(canvas, &m_passwordInput.rect, getPaint(&m_passwordInput));
+    drawPassword(canvas, m_passwordInput);
+
+    //invalidate the canvas
+    //inval(instance);
+}
+
+ANPPaint* FormPlugin::getPaint(TextInput* input) {
+    return (input == m_activeInput) ? m_paintActive : m_paintInput;
+}
+
+void FormPlugin::drawText(ANPCanvas* canvas, TextInput textInput) {
+
+    // get font metrics
+    ANPFontMetrics fontMetrics;
+    gPaintI.getFontMetrics(m_paintText, &fontMetrics);
+
+    gCanvasI.drawText(canvas, textInput.text, textInput.charPtr,
+                      textInput.rect.left + 5,
+                      textInput.rect.bottom - fontMetrics.fBottom, m_paintText);
+}
+
+void FormPlugin::drawPassword(ANPCanvas* canvas, TextInput passwordInput) {
+
+    // get font metrics
+    ANPFontMetrics fontMetrics;
+    gPaintI.getFontMetrics(m_paintText, &fontMetrics);
+
+    // comput the circle dimensions and initial location
+    float initialX = passwordInput.rect.left + 5;
+    float ovalBottom = passwordInput.rect.bottom - 2;
+    float ovalTop = ovalBottom - (fontMetrics.fBottom - fontMetrics.fTop);
+    float ovalWidth = ovalBottom - ovalTop;
+    float ovalSpacing = 3;
+
+    // draw circles instead of the actual text
+    for (uint32_t x = 0; x < passwordInput.charPtr; x++) {
+        ANPRectF oval;
+        oval.left = initialX + ((ovalWidth + ovalSpacing) * (float) x);
+        oval.right = oval.left + ovalWidth;
+        oval.top = ovalTop;
+        oval.bottom = ovalBottom;
+        gCanvasI.drawOval(canvas, &oval, m_paintText);
+    }
+}
+
+int16_t FormPlugin::handleEvent(const ANPEvent* evt) {
+    NPP instance = this->inst();
+
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+            switch (evt->data.draw.model) {
+                case kBitmap_ANPDrawingModel:
+                    drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
+                    return 1;
+                default:
+                    break;   // unknown drawing model
+            }
+            break;
+
+        case kLifecycle_ANPEventType:
+            if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
+                gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
+
+                if (m_activeInput) {
+                    // hide the keyboard
+                    gWindowI.showKeyboard(instance, false);
+
+                    //reset the activeInput
+                    m_activeInput = NULL;
+                }
+
+                m_hasFocus = false;
+                inval(instance);
+                return 1;
+            }
+            else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
+                gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
+                m_hasFocus = true;
+                inval(instance);
+                return 1;
+            }
+            break;
+
+        case kMouse_ANPEventType: {
+
+            int x = evt->data.mouse.x;
+            int y = evt->data.mouse.y;
+            if (kDown_ANPMouseAction == evt->data.mouse.action) {
+
+                TextInput* currentInput = validTap(x,y);
+
+                if (currentInput)
+                    gWindowI.showKeyboard(instance, true);
+                else if (m_activeInput)
+                    gWindowI.showKeyboard(instance, false);
+
+                if (currentInput != m_activeInput)
+                    switchActiveInput(currentInput);
+
+                return 1;
+            }
+            break;
+        }
+
+        case kKey_ANPEventType:
+            if (evt->data.key.action == kDown_ANPKeyAction) {
+
+                //handle navigation keys
+                if (evt->data.key.nativeCode >= kDpadUp_ANPKeyCode
+                        && evt->data.key.nativeCode <= kDpadCenter_ANPKeyCode) {
+                    return handleNavigation(evt->data.key.nativeCode) ? 1 : 0;
+                }
+
+                if (m_activeInput) {
+                    handleTextInput(m_activeInput, evt->data.key.nativeCode,
+                                    evt->data.key.unichar);
+                    inval(instance, m_activeInput->rect, true);
+                }
+            }
+            return 1;
+
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
+
+void FormPlugin::switchActiveInput(TextInput* newInput) {
+    NPP instance = this->inst();
+
+    if (m_activeInput) {
+        inval(instance, m_activeInput->rect, true); // inval the old
+        gWindowI.clearVisibleRects(instance);
+    }
+
+    m_activeInput = newInput; // set the new active input
+
+    if (m_activeInput) {
+        inval(instance, m_activeInput->rect, true); // inval the new
+        scrollIntoView(m_activeInput);
+    }
+}
+
+bool FormPlugin::handleNavigation(ANPKeyCode keyCode) {
+    NPP instance = this->inst();
+
+    gLogI.log(kDebug_ANPLogType, "----%p Recvd Nav Key %d", instance, keyCode);
+
+    if (!m_activeInput) {
+        gWindowI.showKeyboard(instance, true);
+        switchActiveInput(&m_usernameInput);
+    }
+    else if (m_activeInput == &m_usernameInput) {
+        if (keyCode == kDpadDown_ANPKeyCode) {
+            switchActiveInput(&m_passwordInput);
+        }
+        else if (keyCode == kDpadCenter_ANPKeyCode)
+            gWindowI.showKeyboard(instance, false);
+        else if (keyCode == kDpadUp_ANPKeyCode)
+            return false;
+    }
+    else if (m_activeInput == &m_passwordInput) {
+        if (keyCode == kDpadUp_ANPKeyCode) {
+            switchActiveInput(&m_usernameInput);
+        }
+        else if (keyCode == kDpadCenter_ANPKeyCode)
+            gWindowI.showKeyboard(instance, false);
+        else if (keyCode == kDpadDown_ANPKeyCode)
+            return false;
+    }
+
+    return true;
+}
+
+void FormPlugin::handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar) {
+    NPP instance = this->inst();
+
+    //make sure the input field is in view
+    scrollIntoView(input);
+
+    //handle the delete operation
+    if (keyCode == kDel_ANPKeyCode) {
+        if (input->charPtr > 0) {
+            input->charPtr--;
+        }
+        return;
+    }
+
+    //check to see that the input is not full
+    if (input->charPtr >= (sizeof(input->text) - 1))
+        return;
+
+    //add the character
+    input->text[input->charPtr] = static_cast<char>(unichar);
+    input->charPtr++;
+
+    gLogI.log(kDebug_ANPLogType, "----%p Text:  %c", instance, unichar);
+}
+
+void FormPlugin::scrollIntoView(TextInput* input) {
+    NPP instance = this->inst();
+    PluginObject *obj = (PluginObject*) instance->pdata;
+    NPWindow *window = obj->window;
+
+    // find the textInput's global rect coordinates
+    ANPRectI visibleRects[1];
+    visibleRects[0].left = input->rect.left;
+    visibleRects[0].top = input->rect.top;
+    visibleRects[0].right = input->rect.right;
+    visibleRects[0].bottom = input->rect.bottom;
+
+    gWindowI.setVisibleRects(instance, visibleRects, 1);
+}
+
+TextInput* FormPlugin::validTap(int x, int y) {
+
+    if (x > m_usernameInput.rect.left && x < m_usernameInput.rect.right &&
+        y > m_usernameInput.rect.top && y < m_usernameInput.rect.bottom)
+        return &m_usernameInput;
+    else if (x >m_passwordInput.rect.left && x < m_passwordInput.rect.right &&
+             y > m_passwordInput.rect.top && y < m_passwordInput.rect.bottom)
+        return &m_passwordInput;
+    else
+        return NULL;
+}
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.h b/samples/BrowserPlugin/jni/form/FormPlugin.h
new file mode 100644
index 0000000..9f985a3
--- /dev/null
+++ b/samples/BrowserPlugin/jni/form/FormPlugin.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+
+#ifndef formPlugin__DEFINED
+#define formPlugin__DEFINED
+
+struct TextInput {
+    ANPRectF    rect;
+    char        text[30];
+    uint32_t    charPtr;
+};
+
+class FormPlugin : public SubPlugin {
+public:
+    FormPlugin(NPP inst);
+    virtual ~FormPlugin();
+    virtual bool supportsDrawingModel(ANPDrawingModel);
+    virtual int16_t handleEvent(const ANPEvent* evt);
+private:
+    void draw(ANPCanvas*);
+    void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
+
+    bool        m_hasFocus;
+
+    TextInput*  m_activeInput;
+    TextInput   m_usernameInput;
+    TextInput   m_passwordInput;
+
+    ANPPaint*   m_paintInput;
+    ANPPaint*   m_paintActive;
+    ANPPaint*   m_paintText;
+
+    ANPRectI    m_visibleRect;
+
+    void drawText(ANPCanvas*, TextInput);
+    void drawPassword(ANPCanvas*, TextInput);
+
+    bool handleNavigation(ANPKeyCode keyCode);
+    void handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar);
+    void scrollIntoView(TextInput* input);
+    void switchActiveInput(TextInput* input);
+
+    ANPPaint* getPaint(TextInput*);
+    TextInput* validTap(int x, int y);
+
+};
+
+#endif // formPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp
new file mode 100644
index 0000000..9ba8a32
--- /dev/null
+++ b/samples/BrowserPlugin/jni/jni-bridge.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ *
+ */
+#include <string.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <utils/Log.h>
+
+#include "PluginObject.h"
+
+#define EXPORT __attribute__((visibility("default")))
+
+extern ANPEventInterfaceV0         gEventI;
+
+static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
+
+    // send custom event
+    ANPEvent event;
+    event.inSize = sizeof(ANPEvent);
+    event.eventType = kCustom_ANPEventType;
+    event.data.other[0] = kSurfaceCreated_CustomEvent;
+
+    gEventI.postEvent((NPP)npp, &event);
+}
+
+static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) {
+    // send custom event
+    ANPEvent event;
+    event.inSize = sizeof(ANPEvent);
+    event.eventType = kCustom_ANPEventType;
+    event.data.other[0] = kSurfaceChanged_CustomEvent;
+    event.data.other[1] = width;
+    event.data.other[2] = height;
+
+    gEventI.postEvent((NPP)npp, &event);
+}
+
+static void surfaceDestroyed(JNIEnv* env, jobject thiz, jint npp) {
+    // send custom event
+    ANPEvent event;
+    event.inSize = sizeof(ANPEvent);
+    event.eventType = kCustom_ANPEventType;
+    event.data.other[0] = kSurfaceDestroyed_CustomEvent;
+
+    gEventI.postEvent((NPP)npp, &event);
+}
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gPaintSurfaceMethods[] = {
+    { "nativeSurfaceCreated", "(I)V", (void*) surfaceCreated },
+    { "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
+    { "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
+};
+
+EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+
+    JNIEnv* env = NULL;
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        return -1;
+    }
+
+    jniRegisterNativeMethods(env, "com/android/sampleplugin/PaintSurface",
+                             gPaintSurfaceMethods, NELEM(gPaintSurfaceMethods));
+
+    return JNI_VERSION_1_4;
+}
diff --git a/samples/BrowserPlugin/jni/main.cpp b/samples/BrowserPlugin/jni/main.cpp
new file mode 100644
index 0000000..9854848
--- /dev/null
+++ b/samples/BrowserPlugin/jni/main.cpp
@@ -0,0 +1,465 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "main.h"
+#include "PluginObject.h"
+#include "AnimationPlugin.h"
+#include "AudioPlugin.h"
+#include "BackgroundPlugin.h"
+#include "FormPlugin.h"
+#include "NavigationPlugin.h"
+#include "PaintPlugin.h"
+#include "VideoPlugin.h"
+
+NPNetscapeFuncs* browser;
+JavaVM* gVM;
+
+#define EXPORT __attribute__((visibility("default")))
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc,
+        char* argn[], char* argv[], NPSavedData* saved);
+NPError NPP_Destroy(NPP instance, NPSavedData** save);
+NPError NPP_SetWindow(NPP instance, NPWindow* window);
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
+        NPBool seekable, uint16_t* stype);
+NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
+int32_t   NPP_WriteReady(NPP instance, NPStream* stream);
+int32_t   NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len,
+        void* buffer);
+void    NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
+void    NPP_Print(NPP instance, NPPrint* platformPrint);
+int16_t   NPP_HandleEvent(NPP instance, void* event);
+void    NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
+        void* notifyData);
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
+
+extern "C" {
+EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env);
+EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
+EXPORT const char* NP_GetMIMEDescription(void);
+EXPORT void NP_Shutdown(void);
+};
+
+ANPAudioTrackInterfaceV0    gSoundI;
+ANPBitmapInterfaceV0        gBitmapI;
+ANPCanvasInterfaceV0        gCanvasI;
+ANPEventInterfaceV0         gEventI;
+ANPLogInterfaceV0           gLogI;
+ANPPaintInterfaceV0         gPaintI;
+ANPPathInterfaceV0          gPathI;
+ANPSurfaceInterfaceV0       gSurfaceI;
+ANPSystemInterfaceV0        gSystemI;
+ANPTypefaceInterfaceV0      gTypefaceI;
+ANPWindowInterfaceV1        gWindowI;
+ANPOpenGLInterfaceV0        gOpenGLI;
+
+#define ARRAY_COUNT(array)      (sizeof(array) / sizeof(array[0]))
+#define DEBUG_PLUGIN_EVENTS     0
+
+NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env)
+{
+    // Make sure we have a function table equal or larger than we are built against.
+    if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
+        return NPERR_GENERIC_ERROR;
+    }
+
+    // Copy the function table (structure)
+    browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
+    memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
+
+    // Build the plugin function table
+    pluginFuncs->version = 11;
+    pluginFuncs->size = sizeof(pluginFuncs);
+    pluginFuncs->newp = NPP_New;
+    pluginFuncs->destroy = NPP_Destroy;
+    pluginFuncs->setwindow = NPP_SetWindow;
+    pluginFuncs->newstream = NPP_NewStream;
+    pluginFuncs->destroystream = NPP_DestroyStream;
+    pluginFuncs->asfile = NPP_StreamAsFile;
+    pluginFuncs->writeready = NPP_WriteReady;
+    pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+    pluginFuncs->print = NPP_Print;
+    pluginFuncs->event = NPP_HandleEvent;
+    pluginFuncs->urlnotify = NPP_URLNotify;
+    pluginFuncs->getvalue = NPP_GetValue;
+    pluginFuncs->setvalue = NPP_SetValue;
+
+    static const struct {
+        NPNVariable     v;
+        uint32_t        size;
+        ANPInterface*   i;
+    } gPairs[] = {
+        { kAudioTrackInterfaceV0_ANPGetValue,   sizeof(gSoundI),    &gSoundI },
+        { kBitmapInterfaceV0_ANPGetValue,       sizeof(gBitmapI),   &gBitmapI },
+        { kCanvasInterfaceV0_ANPGetValue,       sizeof(gCanvasI),   &gCanvasI },
+        { kEventInterfaceV0_ANPGetValue,        sizeof(gEventI),    &gEventI },
+        { kLogInterfaceV0_ANPGetValue,          sizeof(gLogI),      &gLogI },
+        { kPaintInterfaceV0_ANPGetValue,        sizeof(gPaintI),    &gPaintI },
+        { kPathInterfaceV0_ANPGetValue,         sizeof(gPathI),     &gPathI },
+        { kSurfaceInterfaceV0_ANPGetValue,      sizeof(gSurfaceI),  &gSurfaceI },
+        { kSystemInterfaceV0_ANPGetValue,       sizeof(gSystemI),   &gSystemI },
+        { kTypefaceInterfaceV0_ANPGetValue,     sizeof(gTypefaceI), &gTypefaceI },
+        { kWindowInterfaceV1_ANPGetValue,       sizeof(gWindowI),   &gWindowI },
+        { kOpenGLInterfaceV0_ANPGetValue,       sizeof(gOpenGLI),   &gOpenGLI },
+    };
+    for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
+        gPairs[i].i->inSize = gPairs[i].size;
+        NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
+        if (err) {
+            return err;
+        }
+    }
+
+    // store the JavaVM for the plugin
+    JNIEnv* env = (JNIEnv*)java_env;
+    env->GetJavaVM(&gVM);
+
+    return NPERR_NO_ERROR;
+}
+
+void NP_Shutdown(void)
+{
+
+}
+
+const char *NP_GetMIMEDescription(void)
+{
+    return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
+}
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc,
+                char* argn[], char* argv[], NPSavedData* saved)
+{
+
+    /* BEGIN: STANDARD PLUGIN FRAMEWORK */
+    PluginObject *obj = NULL;
+
+    // Scripting functions appeared in NPAPI version 14
+    if (browser->version >= 14) {
+        instance->pdata = browser->createobject (instance, getPluginClass());
+        obj = static_cast<PluginObject*>(instance->pdata);
+        obj->pluginType = 0;
+    }
+    /* END: STANDARD PLUGIN FRAMEWORK */
+
+    // select the drawing model based on user input
+    ANPDrawingModel model = kBitmap_ANPDrawingModel;
+
+    for (int i = 0; i < argc; i++) {
+        if (!strcmp(argn[i], "DrawingModel")) {
+            if (!strcmp(argv[i], "Bitmap")) {
+                model = kBitmap_ANPDrawingModel;
+            }
+            else if (!strcmp(argv[i], "Surface")) {
+               model = kSurface_ANPDrawingModel;
+            }
+            else if (!strcmp(argv[i], "OpenGL")) {
+               model = kOpenGL_ANPDrawingModel;
+            }
+            gLogI.log(kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
+            break;
+        }
+    }
+
+    // notify the plugin API of the drawing model we wish to use. This must be
+    // done prior to creating certain subPlugin objects (e.g. surfaceViews)
+    NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
+                            reinterpret_cast<void*>(model));
+    if (err) {
+        gLogI.log(kError_ANPLogType, "request model %d err %d", model, err);
+        return err;
+    }
+
+    const char* path = gSystemI.getApplicationDataDirectory();
+    if (path) {
+        gLogI.log(kDebug_ANPLogType, "Application data dir is %s", path);
+    } else {
+        gLogI.log(kError_ANPLogType, "Can't find Application data dir");
+    }
+
+    // select the pluginType
+    for (int i = 0; i < argc; i++) {
+        if (!strcmp(argn[i], "PluginType")) {
+            if (!strcmp(argv[i], "Animation")) {
+                obj->pluginType = kAnimation_PluginType;
+                obj->activePlugin = new BallAnimation(instance);
+            }
+            else if (!strcmp(argv[i], "Audio")) {
+                obj->pluginType = kAudio_PluginType;
+                obj->activePlugin = new AudioPlugin(instance);
+            }
+            else if (!strcmp(argv[i], "Background")) {
+                obj->pluginType = kBackground_PluginType;
+                obj->activePlugin = new BackgroundPlugin(instance);
+            }
+            else if (!strcmp(argv[i], "Form")) {
+                obj->pluginType = kForm_PluginType;
+                obj->activePlugin = new FormPlugin(instance);
+            }
+            else if (!strcmp(argv[i], "Navigation")) {
+                obj->pluginType = kNavigation_PluginType;
+                obj->activePlugin = new NavigationPlugin(instance);
+            }
+            else if (!strcmp(argv[i], "Paint")) {
+                obj->pluginType = kPaint_PluginType;
+                obj->activePlugin = new PaintPlugin(instance);
+            }
+            else if (!strcmp(argv[i], "Video")) {
+                obj->pluginType = kVideo_PluginType;
+                obj->activePlugin = new VideoPlugin(instance);
+            }
+            break;
+        }
+    }
+
+    // if no pluginType is specified then default to Animation
+    if (!obj->pluginType) {
+        gLogI.log(kError_ANPLogType, "------ %p No PluginType attribute was found", instance);
+        obj->pluginType = kAnimation_PluginType;
+        obj->activePlugin = new BallAnimation(instance);
+    }
+
+    gLogI.log(kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
+
+    // check to ensure the pluginType supports the model
+    if (!obj->activePlugin->supportsDrawingModel(model)) {
+        gLogI.log(kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
+        return NPERR_GENERIC_ERROR;
+    }
+
+    // if the plugin uses the surface drawing model then set the java context
+    if (model == kSurface_ANPDrawingModel || model == kOpenGL_ANPDrawingModel) {
+        SurfaceSubPlugin* surfacePlugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
+
+        jobject context;
+        NPError err = browser->getvalue(instance, kJavaContext_ANPGetValue,
+                                        static_cast<void*>(&context));
+        if (err) {
+            gLogI.log(kError_ANPLogType, "request context err: %d", err);
+            return err;
+        }
+
+        surfacePlugin->setContext(context);
+    }
+
+
+    return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData** save)
+{
+    PluginObject *obj = (PluginObject*) instance->pdata;
+    if (obj) {
+        delete obj->activePlugin;
+        browser->releaseobject(&obj->header);
+    }
+
+    return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow* window)
+{
+    PluginObject *obj = (PluginObject*) instance->pdata;
+
+    // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
+    if (obj != NULL) {
+        obj->window = window;
+    }
+
+    browser->invalidaterect(instance, NULL);
+
+    return NPERR_NO_ERROR;
+}
+
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
+{
+    *stype = NP_ASFILEONLY;
+    return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
+{
+    return NPERR_NO_ERROR;
+}
+
+int32_t NPP_WriteReady(NPP instance, NPStream* stream)
+{
+    return 0;
+}
+
+int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer)
+{
+    return 0;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
+{
+}
+
+void NPP_Print(NPP instance, NPPrint* platformPrint)
+{
+}
+
+int16_t NPP_HandleEvent(NPP instance, void* event)
+{
+    PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
+    const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
+
+#if DEBUG_PLUGIN_EVENTS
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+
+            if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
+
+                static ANPBitmapFormat currentFormat = -1;
+                if (evt->data.draw.data.bitmap.format != currentFormat) {
+                    currentFormat = evt->data.draw.data.bitmap.format;
+                    gLogI.log(kDebug_ANPLogType, "---- %p Draw (bitmap)"
+                              " clip=%d,%d,%d,%d format=%d", instance,
+                              evt->data.draw.clip.left,
+                              evt->data.draw.clip.top,
+                              evt->data.draw.clip.right,
+                              evt->data.draw.clip.bottom,
+                              evt->data.draw.data.bitmap.format);
+                }
+            }
+            break;
+
+        case kKey_ANPEventType:
+            gLogI.log(kDebug_ANPLogType, "---- %p Key action=%d"
+                      " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
+                      evt->data.key.action,
+                      evt->data.key.nativeCode,
+                      evt->data.key.virtualCode,
+                      evt->data.key.unichar,
+                      evt->data.key.repeatCount,
+                      evt->data.key.modifiers);
+            break;
+
+        case kLifecycle_ANPEventType:
+            gLogI.log(kDebug_ANPLogType, "---- %p Lifecycle action=%d",
+                                instance, evt->data.lifecycle.action);
+            break;
+
+       case kTouch_ANPEventType:
+            gLogI.log(kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
+                      instance, evt->data.touch.action, evt->data.touch.x,
+                      evt->data.touch.y);
+            break;
+
+       case kMouse_ANPEventType:
+            gLogI.log(kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
+                      instance, evt->data.mouse.action, evt->data.mouse.x,
+                      evt->data.mouse.y);
+            break;
+
+       case kVisibleRect_ANPEventType:
+            gLogI.log(kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
+                      instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
+                      evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
+            break;
+
+        default:
+            gLogI.log(kError_ANPLogType, "---- %p Unknown Event [%d]",
+                      instance, evt->eventType);
+            break;
+    }
+#endif
+
+    if(!obj->activePlugin) {
+        gLogI.log(kError_ANPLogType, "the active plugin is null.");
+        return 0; // unknown or unhandled event
+    }
+    else {
+        return obj->activePlugin->handleEvent(evt);
+    }
+}
+
+void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
+{
+
+}
+
+EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
+
+    if (variable == NPPVpluginNameString) {
+        const char **str = (const char **)value;
+        *str = "Test Plugin";
+        return NPERR_NO_ERROR;
+    }
+
+    if (variable == NPPVpluginDescriptionString) {
+        const char **str = (const char **)value;
+        *str = "Description of Test Plugin";
+        return NPERR_NO_ERROR;
+    }
+
+    return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value)
+{
+    if (variable == NPPVpluginScriptableNPObject) {
+        void **v = (void **)value;
+        PluginObject *obj = (PluginObject*) instance->pdata;
+
+        if (obj)
+            browser->retainobject(&obj->header);
+
+        *v = &(obj->header);
+        return NPERR_NO_ERROR;
+    }
+
+    if (variable == kJavaSurface_ANPGetValue) {
+        //get the surface sub-plugin
+        PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+        if (obj && obj->activePlugin) {
+
+            if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)
+                    || obj->activePlugin->supportsDrawingModel(kOpenGL_ANPDrawingModel)) {
+                SurfaceSubPlugin* plugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
+                jobject* surface = static_cast<jobject*>(value);
+                *surface = plugin->getSurface();
+                return NPERR_NO_ERROR;
+            } else {
+                gLogI.log(kError_ANPLogType,
+                          "-- %p Tried to retrieve surface for non-surface plugin",
+                          instance);
+            }
+        }
+    }
+
+    return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
+{
+    return NPERR_GENERIC_ERROR;
+}
+
diff --git a/samples/BrowserPlugin/jni/main.h b/samples/BrowserPlugin/jni/main.h
new file mode 100644
index 0000000..ebfb4b2
--- /dev/null
+++ b/samples/BrowserPlugin/jni/main.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <npapi.h>
+#include <npfunctions.h>
+#include <npruntime.h>
+#include "android_npapi.h"
+#include "ANPOpenGL_npapi.h"
+#include "ANPSurface_npapi.h"
+#include "ANPSystem_npapi.h"
+
+extern NPNetscapeFuncs* browser;
+extern JavaVM* gVM;
diff --git a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp
new file mode 100644
index 0000000..01d9a79
--- /dev/null
+++ b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "NavigationPlugin.h"
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*         browser;
+extern ANPLogInterfaceV0        gLogI;
+extern ANPCanvasInterfaceV0     gCanvasI;
+extern ANPPaintInterfaceV0      gPaintI;
+extern ANPTypefaceInterfaceV0   gTypefaceI;
+extern ANPWindowInterfaceV0     gWindowI;
+
+
+static void inval(NPP instance) {
+    browser->invalidaterect(instance, NULL);
+}
+
+static uint16_t rnd16(float x, int inset) {
+    int ix = (int)roundf(x) + inset;
+    if (ix < 0) {
+        ix = 0;
+    }
+    return static_cast<uint16_t>(ix);
+}
+
+static void inval(NPP instance, const ANPRectF& r, bool doAA) {
+    const int inset = doAA ? -1 : 0;
+
+    PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
+    NPRect inval;
+    inval.left = rnd16(r.left, inset);
+    inval.top = rnd16(r.top, inset);
+    inval.right = rnd16(r.right, -inset);
+    inval.bottom = rnd16(r.bottom, -inset);
+    browser->invalidaterect(instance, &inval);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+NavigationPlugin::NavigationPlugin(NPP inst) : SubPlugin(inst) {
+
+    m_hasFocus = false;
+    m_activeNav = NULL;
+
+    m_paintDisabled = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintDisabled, gPaintI.getFlags(m_paintDisabled) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintDisabled, 0xFFFFFFFF);
+
+    m_paintActive = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintActive, 0xFFFFFF00);
+
+    //register for key events
+    ANPEventFlags flags = kKey_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+NavigationPlugin::~NavigationPlugin() {
+    gPaintI.deletePaint(m_paintDisabled);
+    gPaintI.deletePaint(m_paintActive);
+}
+
+bool NavigationPlugin::supportsDrawingModel(ANPDrawingModel model) {
+    return (model == kBitmap_ANPDrawingModel);
+}
+
+void NavigationPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
+    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+
+    ANPRectF clipR;
+    clipR.left = clip.left;
+    clipR.top = clip.top;
+    clipR.right = clip.right;
+    clipR.bottom = clip.bottom;
+    gCanvasI.clipRect(canvas, &clipR);
+
+    draw(canvas);
+    gCanvasI.deleteCanvas(canvas);
+}
+
+void NavigationPlugin::draw(ANPCanvas* canvas) {
+    NPP instance = this->inst();
+    PluginObject *obj = (PluginObject*) instance->pdata;
+
+    const int W = obj->window->width;
+    const int H = obj->window->height;
+    const int Wm = W/2;
+    const int Hm = H/2;
+
+    // color the plugin canvas
+    gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
+
+    // draw the nav up box (5 px from the top edge)
+    m_navUp.left = Wm - 15;
+    m_navUp.top = 5;
+    m_navUp.right = m_navUp.left + 30;
+    m_navUp.bottom = m_navUp.top + 30;
+    gCanvasI.drawRect(canvas, &m_navUp, getPaint(&m_navUp));
+
+    // draw the nav down box (5 px from the bottom edge)
+    m_navDown.left = Wm - 15;
+    m_navDown.top = H - (30 + 5);
+    m_navDown.right = m_navDown.left + 30;
+    m_navDown.bottom = m_navDown.top + 30;
+    gCanvasI.drawRect(canvas, &m_navDown, getPaint(&m_navDown));
+
+    // draw the nav left box (5 px from the left edge)
+    m_navLeft.left = 5;
+    m_navLeft.top = Hm - 15;
+    m_navLeft.right = m_navLeft.left + 30;
+    m_navLeft.bottom = m_navLeft.top + 30;
+    gCanvasI.drawRect(canvas, &m_navLeft, getPaint(&m_navLeft));
+
+    // draw the nav right box (5 px from the right edge)
+    m_navRight.left = W - (30 + 5);
+    m_navRight.top = Hm - 15;
+    m_navRight.right = m_navRight.left + 30;
+    m_navRight.bottom = m_navRight.top + 30;
+    gCanvasI.drawRect(canvas, &m_navRight, getPaint(&m_navRight));
+
+    // draw the nav center box
+    m_navCenter.left = Wm - 15;
+    m_navCenter.top = Hm - 15;
+    m_navCenter.right = m_navCenter.left + 30;
+    m_navCenter.bottom = m_navCenter.top + 30;
+    gCanvasI.drawRect(canvas, &m_navCenter, getPaint(&m_navCenter));
+
+    gLogI.log(kDebug_ANPLogType, "----%p Drawing Plugin", inst());
+}
+
+ANPPaint* NavigationPlugin::getPaint(ANPRectF* input) {
+    return (input == m_activeNav) ? m_paintActive : m_paintDisabled;
+}
+
+int16_t NavigationPlugin::handleEvent(const ANPEvent* evt) {
+    NPP instance = this->inst();
+
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+            switch (evt->data.draw.model) {
+                case kBitmap_ANPDrawingModel:
+                    drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
+                    return 1;
+                default:
+                    break;   // unknown drawing model
+            }
+            break;
+
+        case kLifecycle_ANPEventType:
+            if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
+                gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
+                m_hasFocus = false;
+                inval(instance);
+                return 1;
+            }
+            else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
+                gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
+                m_hasFocus = true;
+                inval(instance);
+                return 1;
+            }
+            break;
+
+        case kMouse_ANPEventType:
+            return 1;
+
+        case kKey_ANPEventType:
+            if (evt->data.key.action == kDown_ANPKeyAction) {
+            	bool result = handleNavigation(evt->data.key.nativeCode);
+            	inval(instance);
+            	return result;
+            }
+            return 1;
+
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
+
+bool NavigationPlugin::handleNavigation(ANPKeyCode keyCode) {
+    NPP instance = this->inst();
+
+    gLogI.log(kDebug_ANPLogType, "----%p Received Key %d", instance, keyCode);
+
+    switch (keyCode) {
+		case kDpadUp_ANPKeyCode:
+			m_activeNav = &m_navUp;
+			break;
+		case kDpadDown_ANPKeyCode:
+			m_activeNav = &m_navDown;
+			break;
+		case kDpadLeft_ANPKeyCode:
+			m_activeNav = &m_navLeft;
+			break;
+		case kDpadRight_ANPKeyCode:
+			m_activeNav = &m_navRight;
+			break;
+		case kDpadCenter_ANPKeyCode:
+			m_activeNav = &m_navCenter;
+			break;
+		case kQ_ANPKeyCode:
+		case kDel_ANPKeyCode:
+			m_activeNav = NULL;
+			return false;
+		default:
+			m_activeNav = NULL;
+			break;
+    }
+    return true;
+}
diff --git a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h
new file mode 100644
index 0000000..c2044bb
--- /dev/null
+++ b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+
+#ifndef navigationPlugin__DEFINED
+#define navigationPlugin__DEFINED
+
+class NavigationPlugin : public SubPlugin {
+public:
+	NavigationPlugin(NPP inst);
+    virtual ~NavigationPlugin();
+    virtual bool supportsDrawingModel(ANPDrawingModel);
+    virtual int16_t handleEvent(const ANPEvent* evt);
+private:
+    void draw(ANPCanvas*);
+    void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
+
+    bool        m_hasFocus;
+
+    ANPRectF*	m_activeNav;
+    ANPRectF	m_navUp;
+    ANPRectF	m_navDown;
+    ANPRectF	m_navLeft;
+    ANPRectF	m_navRight;
+    ANPRectF	m_navCenter;
+
+    ANPPaint*   m_paintDisabled;
+    ANPPaint*   m_paintActive;
+
+    bool handleNavigation(ANPKeyCode keyCode);
+    ANPPaint* getPaint(ANPRectF*);
+};
+
+#endif // navigationPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
new file mode 100644
index 0000000..abe6805
--- /dev/null
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PaintPlugin.h"
+
+#include <fcntl.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*         browser;
+extern ANPLogInterfaceV0        gLogI;
+extern ANPCanvasInterfaceV0     gCanvasI;
+extern ANPPaintInterfaceV0      gPaintI;
+extern ANPPathInterfaceV0       gPathI;
+extern ANPSurfaceInterfaceV0    gSurfaceI;
+extern ANPSystemInterfaceV0     gSystemI;
+extern ANPTypefaceInterfaceV0   gTypefaceI;
+extern ANPWindowInterfaceV0     gWindowI;
+
+///////////////////////////////////////////////////////////////////////////////
+
+PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
+
+    m_isTouchActive = false;
+    m_isTouchCurrentInput = true;
+    m_activePaintColor = s_redColor;
+
+    memset(&m_drawingSurface, 0, sizeof(m_drawingSurface));
+    memset(&m_inputToggle,  0, sizeof(m_inputToggle));
+    memset(&m_colorToggle, 0, sizeof(m_colorToggle));
+    memset(&m_fullScreenToggle, 0, sizeof(m_fullScreenToggle));
+    memset(&m_clearSurface,  0, sizeof(m_clearSurface));
+
+    // initialize the drawing surface
+    m_surface = NULL;
+
+    // initialize the path
+    m_touchPath = gPathI.newPath();
+    if(!m_touchPath)
+        gLogI.log(kError_ANPLogType, "----%p Unable to create the touch path", inst);
+
+    // initialize the paint colors
+    m_paintSurface = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintSurface, gPaintI.getFlags(m_paintSurface) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintSurface, 0xFFC0C0C0);
+    gPaintI.setTextSize(m_paintSurface, 18);
+
+    m_paintButton = gPaintI.newPaint();
+    gPaintI.setFlags(m_paintButton, gPaintI.getFlags(m_paintButton) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(m_paintButton, 0xFFA8A8A8);
+
+    // initialize the typeface (set the colors)
+    ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
+    gPaintI.setTypeface(m_paintSurface, tf);
+    gTypefaceI.unref(tf);
+
+    //register for touch events
+    ANPEventFlags flags = kTouch_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+PaintPlugin::~PaintPlugin() {
+    gPathI.deletePath(m_touchPath);
+    gPaintI.deletePaint(m_paintSurface);
+    gPaintI.deletePaint(m_paintButton);
+
+    setContext(NULL);
+    destroySurface();
+}
+
+ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) {
+
+    ANPBitmap bitmap;
+    JNIEnv* env = NULL;
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+        !gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
+            return NULL;
+        }
+
+    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+
+    // clip the canvas to the dirty rect b/c the surface is only required to
+    // copy a minimum of the dirty rect and may copy more. The clipped canvas
+    // however will never write to pixels outside of the clipped area.
+    if (dirtyRect) {
+        ANPRectF clipR;
+        clipR.left = dirtyRect->left;
+        clipR.top = dirtyRect->top;
+        clipR.right = dirtyRect->right;
+        clipR.bottom = dirtyRect->bottom;
+        gCanvasI.clipRect(canvas, &clipR);
+    }
+
+    return canvas;
+}
+
+ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) {
+
+    ANPRectI newRect;
+    newRect.left = (int) dirtyRect->left;
+    newRect.top = (int) dirtyRect->top;
+    newRect.right = (int) dirtyRect->right;
+    newRect.bottom = (int) dirtyRect->bottom;
+
+    return getCanvas(&newRect);
+}
+
+void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
+    JNIEnv* env = NULL;
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+        gSurfaceI.unlock(env, m_surface);
+    }
+    gCanvasI.deleteCanvas(canvas);
+}
+
+void PaintPlugin::drawCleanPlugin(ANPCanvas* canvas) {
+    NPP instance = this->inst();
+    PluginObject *obj = (PluginObject*) instance->pdata;
+
+    // if no canvas get a locked canvas
+    if (!canvas)
+        canvas = getCanvas();
+
+    if (!canvas)
+        return;
+
+    const float buttonWidth = 60;
+    const float buttonHeight = 30;
+    const int W = obj->window->width;
+    const int H = obj->window->height;
+
+    // color the plugin canvas
+    gCanvasI.drawColor(canvas, 0xFFCDCDCD);
+
+    // get font metrics
+    ANPFontMetrics fontMetrics;
+    gPaintI.getFontMetrics(m_paintSurface, &fontMetrics);
+
+    // draw the input toggle button
+    m_inputToggle.left = 5;
+    m_inputToggle.top = H - buttonHeight - 5;
+    m_inputToggle.right = m_inputToggle.left + buttonWidth;
+    m_inputToggle.bottom = m_inputToggle.top + buttonHeight;
+    gCanvasI.drawRect(canvas, &m_inputToggle, m_paintButton);
+    const char* inputText = m_isTouchCurrentInput ? "Touch" : "Mouse";
+    gCanvasI.drawText(canvas, inputText, strlen(inputText), m_inputToggle.left + 5,
+                      m_inputToggle.top - fontMetrics.fTop, m_paintSurface);
+
+    // draw the color selector button
+    m_colorToggle.left = (W/3) - (buttonWidth/2);
+    m_colorToggle.top = H - buttonHeight - 5;
+    m_colorToggle.right = m_colorToggle.left + buttonWidth;
+    m_colorToggle.bottom = m_colorToggle.top + buttonHeight;
+    gCanvasI.drawRect(canvas, &m_colorToggle, m_paintButton);
+    const char* colorText = getColorText();
+    gCanvasI.drawText(canvas, colorText, strlen(colorText), m_colorToggle.left + 5,
+                      m_colorToggle.top - fontMetrics.fTop, m_paintSurface);
+
+    // draw the full-screen toggle button
+    m_fullScreenToggle.left = ((W*2)/3) - (buttonWidth/2);
+    m_fullScreenToggle.top = H - buttonHeight - 5;
+    m_fullScreenToggle.right = m_fullScreenToggle.left + buttonWidth;
+    m_fullScreenToggle.bottom = m_fullScreenToggle.top + buttonHeight;
+    gCanvasI.drawRect(canvas, &m_fullScreenToggle, m_paintButton);
+    const char* fullScreenText = "Full";
+    gCanvasI.drawText(canvas, fullScreenText, strlen(fullScreenText),
+                      m_fullScreenToggle.left + 5,
+                      m_fullScreenToggle.top - fontMetrics.fTop, m_paintSurface);
+
+    // draw the clear canvas button
+    m_clearSurface.left = W - buttonWidth - 5;
+    m_clearSurface.top = H - buttonHeight - 5;
+    m_clearSurface.right = m_clearSurface.left + buttonWidth;
+    m_clearSurface.bottom = m_clearSurface.top + buttonHeight;
+    gCanvasI.drawRect(canvas, &m_clearSurface, m_paintButton);
+    const char* clearText = "Clear";
+    gCanvasI.drawText(canvas, clearText, strlen(clearText), m_clearSurface.left + 5,
+                      m_clearSurface.top - fontMetrics.fTop, m_paintSurface);
+
+    // draw the drawing surface box (5 px from the edge)
+    m_drawingSurface.left = 5;
+    m_drawingSurface.top = 5;
+    m_drawingSurface.right = W - 5;
+    m_drawingSurface.bottom = m_colorToggle.top - 5;
+    gCanvasI.drawRect(canvas, &m_drawingSurface, m_paintSurface);
+
+    // release the canvas
+    releaseCanvas(canvas);
+}
+
+const char* PaintPlugin::getColorText() {
+
+    if (m_activePaintColor == s_blueColor)
+        return "Blue";
+    else if (m_activePaintColor == s_greenColor)
+        return "Green";
+    else
+        return "Red";
+}
+
+jobject PaintPlugin::getSurface() {
+    if (m_surface) {
+        return m_surface;
+    }
+
+    // load the appropriate java class and instantiate it
+    JNIEnv* env = NULL;
+    if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
+        return NULL;
+    }
+
+    const char* className = "com.android.sampleplugin.PaintSurface";
+    jclass paintClass = gSystemI.loadJavaClass(inst(), className);
+
+    if(!paintClass) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
+        return NULL;
+    }
+
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    const int pW = obj->window->width;
+    const int pH = obj->window->height;
+
+    jmethodID constructor = env->GetMethodID(paintClass, "<init>", "(Landroid/content/Context;III)V");
+    jobject paintSurface = env->NewObject(paintClass, constructor, m_context, (int)inst(), pW, pH);
+
+    if(!paintSurface) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
+        return NULL;
+    }
+
+    m_surface = env->NewGlobalRef(paintSurface);
+    return m_surface;
+}
+
+void PaintPlugin::destroySurface() {
+    JNIEnv* env = NULL;
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+
+        // detach the native code from the object
+        jclass javaClass = env->GetObjectClass(m_surface);
+        jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V");
+        env->CallVoidMethod(m_surface, invalMethod);
+
+        env->DeleteGlobalRef(m_surface);
+        m_surface = NULL;
+    }
+}
+
+int16_t PaintPlugin::handleEvent(const ANPEvent* evt) {
+    switch (evt->eventType) {
+        case kTouch_ANPEventType: {
+            float x = (float) evt->data.touch.x;
+            float y = (float) evt->data.touch.y;
+            if (kDown_ANPTouchAction == evt->data.touch.action && m_isTouchCurrentInput) {
+
+                ANPRectF* rect = validTouch(evt->data.touch.x, evt->data.touch.y);
+                if(rect == &m_drawingSurface) {
+                    m_isTouchActive = true;
+                    gPathI.moveTo(m_touchPath, x, y);
+                    paintTouch();
+                    return 1;
+                }
+
+            } else if (kMove_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
+                gPathI.lineTo(m_touchPath, x, y);
+                paintTouch();
+                return 1;
+            } else if (kUp_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
+                gPathI.lineTo(m_touchPath, x, y);
+                paintTouch();
+                m_isTouchActive = false;
+                gPathI.reset(m_touchPath);
+                return 1;
+            } else if (kCancel_ANPTouchAction == evt->data.touch.action) {
+                m_isTouchActive = false;
+                gPathI.reset(m_touchPath);
+                return 1;
+            } else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) {
+                gWindowI.requestCenterFitZoom(inst());
+                return 1;
+
+            }
+            break;
+        }
+        case kMouse_ANPEventType: {
+
+            if (m_isTouchActive)
+                gLogI.log(kError_ANPLogType, "----%p Received unintended mouse event", inst());
+
+            if (kDown_ANPMouseAction == evt->data.mouse.action) {
+                ANPRectF* rect = validTouch(evt->data.mouse.x, evt->data.mouse.y);
+                if (rect == &m_drawingSurface)
+                    paintMouse(evt->data.mouse.x, evt->data.mouse.y);
+                else if (rect == &m_inputToggle)
+                    toggleInputMethod();
+                else if (rect == &m_colorToggle)
+                    togglePaintColor();
+                else if (rect == &m_fullScreenToggle)
+                    gWindowI.requestFullScreen(inst());
+                else if (rect == &m_clearSurface)
+                    drawCleanPlugin();
+            }
+            return 1;
+        }
+        case kCustom_ANPEventType: {
+
+            switch (evt->data.other[0]) {
+                case kSurfaceCreated_CustomEvent:
+                    gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceCreated");
+                    /* The second draw call is added to cover up a problem in this
+                       plugin and is not a recommended usage pattern. This plugin
+                       does not correctly make partial updates to the double
+                       buffered surface and this second call hides that problem.
+                     */
+                    drawCleanPlugin();
+                    drawCleanPlugin();
+                    break;
+                case kSurfaceChanged_CustomEvent: {
+                    gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceChanged");
+
+                    int width = evt->data.other[1];
+                    int height = evt->data.other[2];
+
+                    PluginObject *obj = (PluginObject*) inst()->pdata;
+                    const int pW = obj->window->width;
+                    const int pH = obj->window->height;
+                    // compare to the plugin's surface dimensions
+                    if (pW != width || pH != height)
+                        gLogI.log(kError_ANPLogType,
+                                  "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
+                                  inst(), pW, pH, width, height);
+                    break;
+                }
+                case kSurfaceDestroyed_CustomEvent:
+                    gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceDestroyed");
+                    break;
+            }
+            break; // end KCustom_ANPEventType
+        }
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
+
+ANPRectF* PaintPlugin::validTouch(int x, int y) {
+
+    //convert to float
+    float fx = (int) x;
+    float fy = (int) y;
+
+    if (fx > m_drawingSurface.left && fx < m_drawingSurface.right && fy > m_drawingSurface.top && fy < m_drawingSurface.bottom)
+        return &m_drawingSurface;
+    else if (fx > m_inputToggle.left && fx < m_inputToggle.right && fy > m_inputToggle.top && fy < m_inputToggle.bottom)
+        return &m_inputToggle;
+    else if (fx > m_colorToggle.left && fx < m_colorToggle.right && fy > m_colorToggle.top && fy < m_colorToggle.bottom)
+        return &m_colorToggle;
+    else if (fx > m_fullScreenToggle.left && fx < m_fullScreenToggle.right && fy > m_fullScreenToggle.top && fy < m_fullScreenToggle.bottom)
+        return &m_fullScreenToggle;
+    else if (fx > m_clearSurface.left && fx < m_clearSurface.right && fy > m_clearSurface.top && fy < m_clearSurface.bottom)
+        return &m_clearSurface;
+    else
+        return NULL;
+}
+
+void PaintPlugin::toggleInputMethod() {
+    m_isTouchCurrentInput = !m_isTouchCurrentInput;
+
+    // lock only the input toggle and redraw the canvas
+    ANPCanvas* lockedCanvas = getCanvas(&m_inputToggle);
+    drawCleanPlugin(lockedCanvas);
+}
+
+void PaintPlugin::togglePaintColor() {
+    if (m_activePaintColor == s_blueColor)
+        m_activePaintColor = s_redColor;
+    else if (m_activePaintColor == s_greenColor)
+        m_activePaintColor = s_blueColor;
+    else
+        m_activePaintColor = s_greenColor;
+
+    // lock only the color toggle and redraw the canvas
+    ANPCanvas* lockedCanvas = getCanvas(&m_colorToggle);
+    drawCleanPlugin(lockedCanvas);
+}
+
+void PaintPlugin::paintMouse(int x, int y) {
+    //TODO do not paint outside the drawing surface
+
+    //create the paint color
+    ANPPaint* fillPaint = gPaintI.newPaint();
+    gPaintI.setFlags(fillPaint, gPaintI.getFlags(fillPaint) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setStyle(fillPaint, kFill_ANPPaintStyle);
+    gPaintI.setColor(fillPaint, m_activePaintColor);
+
+    // handle the simple "mouse" paint (draw a point)
+    ANPRectF point;
+    point.left =   (float) x-3;
+    point.top =    (float) y-3;
+    point.right =  (float) x+3;
+    point.bottom = (float) y+3;
+
+    // get a canvas that is only locked around the point and draw it
+    ANPCanvas* canvas = getCanvas(&point);
+    gCanvasI.drawOval(canvas, &point, fillPaint);
+
+    // clean up
+    releaseCanvas(canvas);
+    gPaintI.deletePaint(fillPaint);
+}
+
+void PaintPlugin::paintTouch() {
+    //TODO do not paint outside the drawing surface
+
+    //create the paint color
+    ANPPaint* strokePaint = gPaintI.newPaint();
+    gPaintI.setFlags(strokePaint, gPaintI.getFlags(strokePaint) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(strokePaint, m_activePaintColor);
+    gPaintI.setStyle(strokePaint, kStroke_ANPPaintStyle);
+    gPaintI.setStrokeWidth(strokePaint, 6.0);
+    gPaintI.setStrokeCap(strokePaint, kRound_ANPPaintCap);
+    gPaintI.setStrokeJoin(strokePaint, kRound_ANPPaintJoin);
+
+    // handle the complex "touch" paint (draw a line)
+    ANPRectF bounds;
+    gPathI.getBounds(m_touchPath, &bounds);
+
+    // get a canvas that is only locked around the point and draw the path
+    ANPCanvas* canvas = getCanvas(&bounds);
+    gCanvasI.drawPath(canvas, m_touchPath, strokePaint);
+
+    // clean up
+    releaseCanvas(canvas);
+    gPaintI.deletePaint(strokePaint);
+}
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.h b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
new file mode 100644
index 0000000..ffdf624
--- /dev/null
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+#include <stdio.h>
+
+#ifndef paintPlugin__DEFINED
+#define paintPlugin__DEFINED
+
+class PaintPlugin : public SurfaceSubPlugin {
+public:
+    PaintPlugin(NPP inst);
+    virtual ~PaintPlugin();
+    virtual int16_t handleEvent(const ANPEvent* evt);
+    virtual jobject getSurface();
+
+private:
+    void        drawCleanPlugin(ANPCanvas* canvas = NULL);
+    ANPCanvas*  getCanvas(ANPRectI* dirtyRect = NULL);
+    ANPCanvas*  getCanvas(ANPRectF* dirtyRect);
+    const char* getColorText();
+    void        destroySurface();
+    void        paintMouse(int x, int y);
+    void        paintTouch();
+    void        releaseCanvas(ANPCanvas*);
+    void        toggleInputMethod();
+    void        togglePaintColor();
+    ANPRectF*   validTouch(int x, int y);
+
+    bool        m_isTouchActive;
+    bool        m_isTouchCurrentInput;
+
+    jobject     m_surface;
+    ANPPath*    m_touchPath;
+
+    ANPRectF    m_drawingSurface;
+    ANPRectF    m_inputToggle;
+    ANPRectF    m_colorToggle;
+    ANPRectF    m_fullScreenToggle;
+    ANPRectF    m_clearSurface;
+
+    ANPPaint*   m_paintSurface;
+    ANPPaint*   m_paintButton;
+
+    ANPColor    m_activePaintColor;
+    static const ANPColor s_redColor   = 0xFFFF0000;
+    static const ANPColor s_greenColor = 0xFF00FF00;
+    static const ANPColor s_blueColor  = 0xFF0000FF;
+};
+
+#endif // paintPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
new file mode 100644
index 0000000..bf3ab76
--- /dev/null
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "VideoPlugin.h"
+#include "android_npapi.h"
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*        browser;
+extern ANPBitmapInterfaceV0    gBitmapI;
+extern ANPCanvasInterfaceV0    gCanvasI;
+extern ANPLogInterfaceV0       gLogI;
+extern ANPPaintInterfaceV0     gPaintI;
+extern ANPSurfaceInterfaceV0   gSurfaceI;
+extern ANPSystemInterfaceV0    gSystemI;
+extern ANPTypefaceInterfaceV0  gTypefaceI;
+extern ANPWindowInterfaceV0    gWindowI;
+
+///////////////////////////////////////////////////////////////////////////////
+
+VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
+
+    // initialize the drawing surface
+    m_surface = NULL;
+
+    //register for touch events
+    ANPEventFlags flags = kTouch_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+VideoPlugin::~VideoPlugin() {
+    setContext(NULL);
+    destroySurface();
+}
+
+jobject VideoPlugin::getSurface() {
+
+    if (m_surface) {
+        return m_surface;
+    }
+
+    // load the appropriate java class and instantiate it
+    JNIEnv* env = NULL;
+    if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
+        return NULL;
+    }
+
+    const char* className = "com.android.sampleplugin.VideoSurface";
+    jclass videoClass = gSystemI.loadJavaClass(inst(), className);
+
+    if(!videoClass) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
+        return NULL;
+    }
+
+    jmethodID constructor = env->GetMethodID(videoClass, "<init>", "(Landroid/content/Context;)V");
+    jobject videoSurface = env->NewObject(videoClass, constructor, m_context);
+
+    if(!videoSurface) {
+        gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
+        return NULL;
+    }
+
+    m_surface = env->NewGlobalRef(videoSurface);
+    return m_surface;
+}
+
+void VideoPlugin::destroySurface() {
+    JNIEnv* env = NULL;
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+        env->DeleteGlobalRef(m_surface);
+        m_surface = NULL;
+    }
+}
+
+int16_t VideoPlugin::handleEvent(const ANPEvent* evt) {
+    switch (evt->eventType) {
+        case kLifecycle_ANPEventType: {
+            switch (evt->data.lifecycle.action) {
+                case kEnterFullScreen_ANPLifecycleAction:
+                    gLogI.log(kDebug_ANPLogType, " ---- %p entering fullscreen", inst());
+                    break;
+                case kExitFullScreen_ANPLifecycleAction:
+                    gLogI.log(kDebug_ANPLogType, " ---- %p exiting fullscreen", inst());
+                    break;
+            }
+            break; // end kLifecycle_ANPEventType
+        }
+        case kDraw_ANPEventType:
+            gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
+            break;
+        case kTouch_ANPEventType:
+            if (kDown_ANPTouchAction == evt->data.touch.action) {
+                gLogI.log(kDebug_ANPLogType, " ------ %p requesting fullscreen mode", inst());
+                gWindowI.requestFullScreen(inst());
+            }
+            return 1;
+        case kKey_ANPEventType:
+            gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
+            break;
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.h b/samples/BrowserPlugin/jni/video/VideoPlugin.h
new file mode 100644
index 0000000..fb15386
--- /dev/null
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+
+#ifndef videoPlugin__DEFINED
+#define videoPlugin__DEFINED
+
+class VideoPlugin : public SurfaceSubPlugin {
+public:
+    VideoPlugin(NPP inst);
+    virtual ~VideoPlugin();
+    virtual int16_t handleEvent(const ANPEvent* evt);
+    virtual jobject getSurface();
+
+private:
+    void destroySurface();
+
+    jobject     m_surface;
+};
+
+#endif // videoPlugin__DEFINED
diff --git a/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png b/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png
new file mode 100755
index 0000000..4d9d559
--- /dev/null
+++ b/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png
Binary files differ
diff --git a/samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png b/samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png
new file mode 100755
index 0000000..47c79d1
--- /dev/null
+++ b/samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png
Binary files differ
diff --git a/samples/BrowserPlugin/res/values/strings.xml b/samples/BrowserPlugin/res/values/strings.xml
new file mode 100644
index 0000000..1f8dd49
--- /dev/null
+++ b/samples/BrowserPlugin/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<resources>
+   <string name="sample_browser_plugin">Sample Browser Plugin</string>
+</resources>
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/AnimationSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/AnimationSurface.java
new file mode 100644
index 0000000..e3afab6
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/AnimationSurface.java
@@ -0,0 +1,22 @@
+package com.android.sampleplugin;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.util.Log;
+import android.widget.TextView;
+
+public class AnimationSurface extends TextView {
+
+    public AnimationSurface(Context context) {
+        super(context);
+
+        Log.e("AnimSurface", "IN ANIMATION SURFACE");
+        
+        this.setBackgroundColor(Color.GRAY);
+        this.setTextColor(Color.WHITE);
+        this.setText("This is a full-screen plugin");
+
+        // ensure that the view system is aware that we will be drawing
+        this.setWillNotDraw(false);
+    }
+}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java
new file mode 100644
index 0000000..5af8c8e
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java
@@ -0,0 +1,19 @@
+package com.android.sampleplugin;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.widget.TextView;
+
+public class BackgroundSurface extends TextView {
+
+    public BackgroundSurface(Context context) {
+        super(context);
+
+        this.setBackgroundColor(Color.BLACK);
+        this.setTextColor(Color.WHITE);
+        this.setText("This is a java background plugin");
+
+        // ensure that the view system is aware that we will be drawing
+        this.setWillNotDraw(false);
+    }
+}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundTest.java b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundTest.java
new file mode 100644
index 0000000..1f6b0d4
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundTest.java
@@ -0,0 +1,11 @@
+package com.android.sampleplugin;
+
+public class BackgroundTest {
+
+    public BackgroundTest() {}
+    
+    public int addInt(int x, int y) {
+        return x + y;
+    }
+    
+}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java
new file mode 100644
index 0000000..9582bcc
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.android.sampleplugin;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder.Callback;
+
+public class PaintSurface extends SurfaceView {
+
+    static {
+        //needed for jni calls
+        System.loadLibrary("sampleplugin");
+    }
+
+    private final int npp;
+
+    private boolean validNPP = true;
+    private Object nppLock = new Object();
+
+    public PaintSurface(Context context, int NPP, int width, int height) {
+        super(context);
+
+        this.npp = NPP;
+
+        this.getHolder().setFormat(PixelFormat.RGBA_8888);
+        this.getHolder().addCallback(new Callback() {
+
+            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+                synchronized (nppLock) {
+                    if (validNPP) {
+                        nativeSurfaceChanged(npp, format, width, height);
+                    }
+                }
+            }
+
+            public void surfaceCreated(SurfaceHolder holder) {
+                synchronized (nppLock) {
+                    if (validNPP) {
+                        nativeSurfaceCreated(npp);
+                    }
+                }
+            }
+
+            public void surfaceDestroyed(SurfaceHolder holder) {
+                synchronized (nppLock) {
+                    if (validNPP) {
+                        nativeSurfaceDestroyed(npp);
+                    }
+                }
+            }
+        });
+
+        // sets the plugin's surface to a fixed size
+        this.getHolder().setFixedSize(width, height);
+
+        // ensure that the view system is aware that we will be drawing
+        this.setWillNotDraw(false);
+    }
+
+    // called by JNI
+    private void invalidateNPP() {
+        synchronized (nppLock) {
+            validNPP = false;
+        }
+    }
+
+    private native void nativeSurfaceCreated(int npp);
+    private native void nativeSurfaceChanged(int npp, int format, int width, int height);
+    private native void nativeSurfaceDestroyed(int npp);
+}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java
new file mode 100644
index 0000000..b5b728e
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.android.sampleplugin;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class SamplePlugin extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java
new file mode 100644
index 0000000..a3c80cf
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.android.sampleplugin;
+
+import com.android.sampleplugin.graphics.CubeRenderer;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.MediaController;
+import android.widget.VideoView;
+
+public class VideoSurface extends FrameLayout {
+
+    public VideoSurface(Context context) {
+        super(context);
+
+        LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
+        this.setLayoutParams(fp);
+
+//        VideoView video = new VideoView(context);
+//        LayoutParams vp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
+//        vp.setLayoutParams(vp);
+
+        GLSurfaceView gl = new GLSurfaceView(context);
+        LayoutParams gp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
+        gl.setLayoutParams(gp);
+
+        this.addView(gl);
+//        this.addView(video);
+
+        // Tell the cube renderer that we want to render a translucent version
+        // of the cube:
+        gl.setRenderer(new CubeRenderer(false));
+        gl.setWindowType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY);
+
+//        video.setVideoPath("/sdcard/test_video.3gp");
+//        video.setMediaController(new MediaController(context));
+//        video.requestFocus();
+
+        // ensure that the view system is aware that we will be drawing
+        this.setWillNotDraw(false);
+    }
+}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/Cube.java b/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/Cube.java
new file mode 100644
index 0000000..9ad1410
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/Cube.java
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+package com.android.sampleplugin.graphics;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A vertex shaded cube.
+ */
+class Cube
+{
+    public Cube()
+    {
+        int one = 0x10000;
+        int vertices[] = {
+                -one, -one, -one,
+                one, -one, -one,
+                one,  one, -one,
+                -one,  one, -one,
+                -one, -one,  one,
+                one, -one,  one,
+                one,  one,  one,
+                -one,  one,  one,
+        };
+
+        int colors[] = {
+                0,    0,    0,  one,
+                one,    0,    0,  one,
+                one,  one,    0,  one,
+                0,  one,    0,  one,
+                0,    0,  one,  one,
+                one,    0,  one,  one,
+                one,  one,  one,  one,
+                0,  one,  one,  one,
+        };
+
+        byte indices[] = {
+                0, 4, 5,    0, 5, 1,
+                1, 5, 6,    1, 6, 2,
+                2, 6, 7,    2, 7, 3,
+                3, 7, 4,    3, 4, 0,
+                4, 7, 6,    4, 6, 5,
+                3, 0, 1,    3, 1, 2
+        };
+
+        // Buffers to be passed to gl*Pointer() functions
+        // must be direct, i.e., they must be placed on the
+        // native heap where the garbage collector cannot
+        // move them.
+        //
+        // Buffers with multi-byte datatypes (e.g., short, int, float)
+        // must have their byte order set to native order
+
+        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
+        vbb.order(ByteOrder.nativeOrder());
+        mVertexBuffer = vbb.asIntBuffer();
+        mVertexBuffer.put(vertices);
+        mVertexBuffer.position(0);
+
+        ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
+        cbb.order(ByteOrder.nativeOrder());
+        mColorBuffer = cbb.asIntBuffer();
+        mColorBuffer.put(colors);
+        mColorBuffer.position(0);
+
+        mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
+        mIndexBuffer.put(indices);
+        mIndexBuffer.position(0);
+    }
+
+    public void draw(GL10 gl)
+    {
+        gl.glFrontFace(gl.GL_CW);
+        gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
+        gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
+        gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
+    }
+
+    private IntBuffer   mVertexBuffer;
+    private IntBuffer   mColorBuffer;
+    private ByteBuffer  mIndexBuffer;
+}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/CubeRenderer.java b/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/CubeRenderer.java
new file mode 100644
index 0000000..246ac15
--- /dev/null
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/CubeRenderer.java
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+package com.android.sampleplugin.graphics;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLSurfaceView;
+
+/**
+ * Render a pair of tumbling cubes.
+ */
+
+public class CubeRenderer implements GLSurfaceView.Renderer {
+    public CubeRenderer(boolean useTranslucentBackground) {
+        mTranslucentBackground = useTranslucentBackground;
+        mCube = new Cube();
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear().
+         */
+
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D objects
+         */
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glTranslatef(0, 0, -3.0f);
+        gl.glRotatef(mAngle,        0, 1, 0);
+        gl.glRotatef(mAngle*0.25f,  1, 0, 0);
+
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+        mCube.draw(gl);
+
+        gl.glRotatef(mAngle*2.0f, 0, 1, 1);
+        gl.glTranslatef(0.5f, 0.5f, 0.5f);
+
+        mCube.draw(gl);
+
+        mAngle += 1.2f;
+    }
+
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+         gl.glViewport(0, 0, width, height);
+
+         /*
+          * Set our projection matrix. This doesn't have to be done
+          * each time we draw, but usually a new projection needs to
+          * be set when the viewport is resized.
+          */
+
+         float ratio = (float) width / height;
+         gl.glMatrixMode(GL10.GL_PROJECTION);
+         gl.glLoadIdentity();
+         gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        /*
+         * Some one-time OpenGL initialization can be made here
+         * probably based on features of this particular context
+         */
+         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                 GL10.GL_FASTEST);
+
+         if (mTranslucentBackground) {
+             gl.glClearColor(0,0,0,0);
+         } else {
+             gl.glClearColor(1,1,1,1);
+         }
+         gl.glEnable(GL10.GL_CULL_FACE);
+         gl.glShadeModel(GL10.GL_SMOOTH);
+         gl.glEnable(GL10.GL_DEPTH_TEST);
+    }
+    private boolean mTranslucentBackground;
+    private Cube mCube;
+    private float mAngle;
+}
diff --git a/samples/HoneycombGallery/Android.mk b/samples/HoneycombGallery/Android.mk
new file mode 100644
index 0000000..e56ae15
--- /dev/null
+++ b/samples/HoneycombGallery/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := HoneycombGallery
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/HoneycombGallery/AndroidManifest.xml b/samples/HoneycombGallery/AndroidManifest.xml
new file mode 100644
index 0000000..6e6163b
--- /dev/null
+++ b/samples/HoneycombGallery/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.hcgallery" android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="11" />
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application android:label="@string/app_name"
+        android:icon="@drawable/icon"
+        android:logo="@drawable/logo"
+        android:theme="@style/AppTheme.Light"
+        android:hardwareAccelerated="true"
+        android:debuggable="true">
+
+        <activity android:name=".MainActivity"
+            android:label="@string/app_name"
+            android:launchMode="singleTop">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="com.example.android.hcgallery.action.DIALOG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <!-- CameraSample -->
+        <activity android:name=".CameraSample"
+            android:label="@string/camera_sample"
+            android:screenOrientation="landscape" />
+      </application>
+</manifest>
diff --git a/samples/HoneycombGallery/_index.html b/samples/HoneycombGallery/_index.html
new file mode 100644
index 0000000..9b4169e
--- /dev/null
+++ b/samples/HoneycombGallery/_index.html
@@ -0,0 +1,42 @@
+<p>This is a demo application highlighting how to use some of the new APIs in
+Honeycomb, including:</p>
+
+<ul>
+  <li><a href="../../../guide/topics/fundamentals/fragments.html">Fragments</a></li>
+  <li>The <a href="../../../guide/topics/ui/actionbar.html">action bar</a>
+      and contextual action bar</li>
+  <li>Drag and drop</li>
+  <li>The new <a href="../../../reference/android/animation/package-summary.html"><code>android.animation</code></a>
+      framework</li>
+  <li>Custom notifications</li>
+  <li>For information on how to implement <a href="../../../reference/android/widget/StackView.html"><code>StackView</code></a>
+      and other adapter-based app widgets, see <a href="../StackWidget/index.html">StackView App Widget</a></li>
+</ul>
+
+<p>The image gallery shows how all these pieces can work together in one application.</p>
+
+<p>The application includes the following key classes:<p>
+<ul>
+  <li><a href="src/com/example/android/hcgallery/ContentFragment.html">ContentFragment</a>
+      A fragment responsible for containing the "content" of the application.
+      Displays images, receives drag/drop events from other fragments, and can
+      invoke the contextual action bar using
+      <a href="../../../reference/android/view/ActionMode.html">action modes</a>.</li>
+  <li><a href="src/com/example/android/hcgallery/TitlesFragment.html">TitlesFragment</a>
+      Shows a ListView of photos to display in the ContentFragment. Photos can
+      be chosen either by tapping on the listview, or dragging them from the
+      list to the content area. The list of photos displayed depends on the
+      category selected in the ActionBar.</li>
+  <li><a href="src/com/example/android/hcgallery/MainActivity.html">MainActivity</a>
+      This is the main entry point of the application. MainActivity is
+      responsible for initialization of the ActionBar, TitlesFragment, and
+      ContentFragment. MainActivity is also responsible for keeping track of
+      the currently selected theme and currently selected photo when the
+      activity is recreated, such as when the screen is rotated or an intent to
+      a separate activity is fired (such as the included Camera sample).
+      MainActivity also contains code demonstrating how to animate
+      showing/hiding fragments (in this case, the TitlesFragment) and the
+      ActionBar, demonstrating how to smoothly transition between states
+      in your application.</li></ul>
+
+<img alt="Screenshot" src="../images/hcgallery.png" />
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/btn_notification_ic_example_default.png b/samples/HoneycombGallery/res/drawable-hdpi/btn_notification_ic_example_default.png
new file mode 100644
index 0000000..aefa030
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/btn_notification_ic_example_default.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/btn_notification_ic_example_pressed.png b/samples/HoneycombGallery/res/drawable-hdpi/btn_notification_ic_example_pressed.png
new file mode 100644
index 0000000..ea42154
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/btn_notification_ic_example_pressed.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_camera_holo_dark.png b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_camera_holo_dark.png
new file mode 100644
index 0000000..c281181
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_camera_holo_dark.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_camera_holo_light.png b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_camera_holo_light.png
new file mode 100644
index 0000000..296db33
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_camera_holo_light.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_share_holo_dark.png b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_share_holo_dark.png
new file mode 100644
index 0000000..2f8e83f
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_share_holo_light.png b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_share_holo_light.png
new file mode 100644
index 0000000..505332a
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_toggle_holo_dark.png b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_toggle_holo_dark.png
new file mode 100644
index 0000000..93f51bd
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_toggle_holo_dark.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_toggle_holo_light.png b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_toggle_holo_light.png
new file mode 100644
index 0000000..090830a
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/ic_menu_toggle_holo_light.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/ic_stat_notify_example.png b/samples/HoneycombGallery/res/drawable-hdpi/ic_stat_notify_example.png
new file mode 100644
index 0000000..b1fc03c
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/ic_stat_notify_example.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/icon.png b/samples/HoneycombGallery/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..404a2a4
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/logo.png b/samples/HoneycombGallery/res/drawable-hdpi/logo.png
new file mode 100644
index 0000000..5af2f75
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/logo.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_default.9.png b/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_default.9.png
new file mode 100644
index 0000000..ce17c9c
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_default.9.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_pressed.9.png b/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_pressed.9.png
new file mode 100644
index 0000000..d5579c9
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_pressed.9.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_selected.9.png b/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_selected.9.png
new file mode 100644
index 0000000..3e02aa9
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-hdpi/picture_frame_selected.9.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-ldpi/icon.png b/samples/HoneycombGallery/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..add2163
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/btn_notification_ic_example_default.png b/samples/HoneycombGallery/res/drawable-mdpi/btn_notification_ic_example_default.png
new file mode 100644
index 0000000..540829f
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/btn_notification_ic_example_default.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/btn_notification_ic_example_pressed.png b/samples/HoneycombGallery/res/drawable-mdpi/btn_notification_ic_example_pressed.png
new file mode 100644
index 0000000..645bc5b
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/btn_notification_ic_example_pressed.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_camera_holo_dark.png b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_camera_holo_dark.png
new file mode 100644
index 0000000..6af2d1c
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_camera_holo_dark.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_camera_holo_light.png b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_camera_holo_light.png
new file mode 100644
index 0000000..4193cad
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_camera_holo_light.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_share_holo_dark.png b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_share_holo_dark.png
new file mode 100644
index 0000000..996bd88
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_share_holo_light.png b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_share_holo_light.png
new file mode 100644
index 0000000..943ba30
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_toggle_holo_dark.png b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_toggle_holo_dark.png
new file mode 100644
index 0000000..7c7cff4
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_toggle_holo_dark.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_toggle_holo_light.png b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_toggle_holo_light.png
new file mode 100644
index 0000000..91d48fa
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/ic_menu_toggle_holo_light.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/ic_stat_notify_example.png b/samples/HoneycombGallery/res/drawable-mdpi/ic_stat_notify_example.png
new file mode 100644
index 0000000..fa825ac
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/ic_stat_notify_example.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/icon.png b/samples/HoneycombGallery/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..0e62f31
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/logo.png b/samples/HoneycombGallery/res/drawable-mdpi/logo.png
new file mode 100644
index 0000000..43642eb
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/logo.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_default.9.png b/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_default.9.png
new file mode 100644
index 0000000..3588cf9
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_default.9.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_pressed.9.png b/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_pressed.9.png
new file mode 100644
index 0000000..5bb7327
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_pressed.9.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_selected.9.png b/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_selected.9.png
new file mode 100644
index 0000000..3842bc9
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-mdpi/picture_frame_selected.9.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/big_droid.JPG b/samples/HoneycombGallery/res/drawable-nodpi/big_droid.JPG
new file mode 100644
index 0000000..2bb450c
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/big_droid.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/blue_balloon.JPG b/samples/HoneycombGallery/res/drawable-nodpi/blue_balloon.JPG
new file mode 100644
index 0000000..f116574
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/blue_balloon.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/blue_bike.JPG b/samples/HoneycombGallery/res/drawable-nodpi/blue_bike.JPG
new file mode 100644
index 0000000..f424815
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/blue_bike.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/chrome_wheel.JPG b/samples/HoneycombGallery/res/drawable-nodpi/chrome_wheel.JPG
new file mode 100644
index 0000000..a748593
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/chrome_wheel.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/cupcake.JPG b/samples/HoneycombGallery/res/drawable-nodpi/cupcake.JPG
new file mode 100644
index 0000000..ba902c6
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/cupcake.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/donut.JPG b/samples/HoneycombGallery/res/drawable-nodpi/donut.JPG
new file mode 100644
index 0000000..5f5ee46
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/donut.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/eclair.JPG b/samples/HoneycombGallery/res/drawable-nodpi/eclair.JPG
new file mode 100644
index 0000000..656e6cb
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/eclair.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/froyo.JPG b/samples/HoneycombGallery/res/drawable-nodpi/froyo.JPG
new file mode 100644
index 0000000..f6c5f06
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/froyo.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/green_balloon.JPG b/samples/HoneycombGallery/res/drawable-nodpi/green_balloon.JPG
new file mode 100644
index 0000000..171e3a3
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/green_balloon.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/notification_default_largeicon.png b/samples/HoneycombGallery/res/drawable-nodpi/notification_default_largeicon.png
new file mode 100644
index 0000000..e50b97e
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/notification_default_largeicon.png
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/punk_droid.JPG b/samples/HoneycombGallery/res/drawable-nodpi/punk_droid.JPG
new file mode 100644
index 0000000..090779b
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/punk_droid.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/rainbow_bike.JPG b/samples/HoneycombGallery/res/drawable-nodpi/rainbow_bike.JPG
new file mode 100644
index 0000000..87be337
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/rainbow_bike.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/red_balloon.JPG b/samples/HoneycombGallery/res/drawable-nodpi/red_balloon.JPG
new file mode 100644
index 0000000..3e5e95c
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/red_balloon.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable-nodpi/stargazer_droid.JPG b/samples/HoneycombGallery/res/drawable-nodpi/stargazer_droid.JPG
new file mode 100644
index 0000000..e336b32
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable-nodpi/stargazer_droid.JPG
Binary files differ
diff --git a/samples/HoneycombGallery/res/drawable/btn_notification_ic_example.xml b/samples/HoneycombGallery/res/drawable/btn_notification_ic_example.xml
new file mode 100644
index 0000000..1fb298e
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable/btn_notification_ic_example.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/btn_notification_ic_example_pressed" />
+    <item android:drawable="@drawable/btn_notification_ic_example_default" />
+</selector>
diff --git a/samples/HoneycombGallery/res/drawable/picture_frame.xml b/samples/HoneycombGallery/res/drawable/picture_frame.xml
new file mode 100644
index 0000000..063abf1
--- /dev/null
+++ b/samples/HoneycombGallery/res/drawable/picture_frame.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:drawable="@drawable/picture_frame_selected" />
+    <item android:state_pressed="true" android:drawable="@drawable/picture_frame_pressed" />
+    <item android:drawable="@drawable/picture_frame_default" />
+</selector>
diff --git a/samples/HoneycombGallery/res/layout-port/main.xml b/samples/HoneycombGallery/res/layout-port/main.xml
new file mode 100644
index 0000000..a5e9970
--- /dev/null
+++ b/samples/HoneycombGallery/res/layout-port/main.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/frags">
+
+    <fragment class="com.example.android.hcgallery.TitlesFragment"
+            android:id="@+id/frag_title"
+            android:visibility="gone"
+            android:layout_marginTop="?android:attr/actionBarSize"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/titles_size"/>
+
+    <fragment class="com.example.android.hcgallery.ContentFragment"
+            android:id="@+id/frag_content"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+</LinearLayout>
diff --git a/samples/HoneycombGallery/res/layout/action_bar_custom.xml b/samples/HoneycombGallery/res/layout/action_bar_custom.xml
new file mode 100644
index 0000000..5f111d9
--- /dev/null
+++ b/samples/HoneycombGallery/res/layout/action_bar_custom.xml
@@ -0,0 +1,24 @@
+<!--
+  Copyright (C) 2011 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:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <TextView
+      android:layout_width="match_parent"
+      android:layout_height="match_parent">Hello Action Bar</TextView>
+</LinearLayout>
diff --git a/samples/HoneycombGallery/res/layout/camera_sample.xml b/samples/HoneycombGallery/res/layout/camera_sample.xml
new file mode 100644
index 0000000..dcb8867
--- /dev/null
+++ b/samples/HoneycombGallery/res/layout/camera_sample.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+
+
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <fragment android:name="com.example.android.hcgallery.CameraFragment"
+        android:id="@+id/camera_frag"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+</FrameLayout>
diff --git a/samples/HoneycombGallery/res/layout/content_welcome.xml b/samples/HoneycombGallery/res/layout/content_welcome.xml
new file mode 100644
index 0000000..189218f
--- /dev/null
+++ b/samples/HoneycombGallery/res/layout/content_welcome.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+
+<view xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.example.android.hcgallery.FitCenterFrameLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="24dp"
+    android:clickable="true">
+    <ImageView android:id="@+id/image"
+        android:background="@drawable/picture_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:duplicateParentState="true"/>
+</view>
diff --git a/samples/HoneycombGallery/res/layout/main.xml b/samples/HoneycombGallery/res/layout/main.xml
new file mode 100644
index 0000000..4987920
--- /dev/null
+++ b/samples/HoneycombGallery/res/layout/main.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/frags">
+
+    <fragment class="com.example.android.hcgallery.TitlesFragment"
+            android:id="@+id/frag_title"
+            android:visibility="gone"
+            android:layout_marginTop="?android:attr/actionBarSize"
+            android:layout_width="@dimen/titles_size"
+            android:layout_height="match_parent" />
+
+    <fragment class="com.example.android.hcgallery.ContentFragment"
+            android:id="@+id/frag_content"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+    
+</LinearLayout>
diff --git a/samples/HoneycombGallery/res/layout/notification.xml b/samples/HoneycombGallery/res/layout/notification.xml
new file mode 100644
index 0000000..3da757d
--- /dev/null
+++ b/samples/HoneycombGallery/res/layout/notification.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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:id="@+id/notificationbg"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal">
+
+    <LinearLayout
+        android:paddingLeft="16dip"
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:orientation="vertical">
+
+        <TextView android:id="@+id/notification_title"
+            style="@android:style/TextAppearance.StatusBar.EventContent.Title"
+            android:focusable="true"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:layout_gravity="left"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/notification_subtitle"
+            style="@android:style/TextAppearance.StatusBar.EventContent"
+            android:layout_gravity="left"
+            android:maxLines="2"
+            android:scrollHorizontally="true"
+            android:ellipsize="end"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/notification_text" />
+
+    </LinearLayout>
+
+    <ImageButton
+        android:id="@+id/notification_button"
+        android:src="@drawable/btn_notification_ic_example"
+        android:background="@null"
+        android:layout_weight="0"
+        android:layout_width="48dip"
+        android:layout_height="match_parent" />
+
+</LinearLayout>
diff --git a/samples/HoneycombGallery/res/layout/title_list_item.xml b/samples/HoneycombGallery/res/layout/title_list_item.xml
new file mode 100644
index 0000000..cead709
--- /dev/null
+++ b/samples/HoneycombGallery/res/layout/title_list_item.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="10dp"
+    android:gravity="bottom"
+    android:textAppearance="?android:attr/textAppearanceMedium"
+    android:background="?android:attr/activatedBackgroundIndicator" >
+</TextView>
diff --git a/samples/HoneycombGallery/res/menu/camera_menu.xml b/samples/HoneycombGallery/res/menu/camera_menu.xml
new file mode 100644
index 0000000..55184dd
--- /dev/null
+++ b/samples/HoneycombGallery/res/menu/camera_menu.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/switch_cam" android:title="Switch Camera" />
+</menu>
diff --git a/samples/HoneycombGallery/res/menu/main_menu.xml b/samples/HoneycombGallery/res/menu/main_menu.xml
new file mode 100644
index 0000000..0e27cb5
--- /dev/null
+++ b/samples/HoneycombGallery/res/menu/main_menu.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/camera"
+        android:title="Camera"
+        android:icon="?attr/menuIconCamera"
+        android:showAsAction="ifRoom" />
+    <item android:id="@+id/toggleTitles"
+        android:icon="?attr/menuIconToggle"
+        android:title="Toggle Titles"
+        android:showAsAction="ifRoom|withText" />
+    <!-- Example of items in the overflow menu -->
+    <item android:id="@+id/toggleTheme"
+        android:title="Day/Night"
+        android:showAsAction="never" />
+    <item android:id="@+id/showDialog"
+        android:title="Show a dialog"
+        android:showAsAction="never" />
+    <item android:id="@+id/showStandardNotification"
+        android:title="Show a basic notification"
+        android:showAsAction="never" />
+    <item android:id="@+id/showCustomNotification"
+        android:title="Show a custom notification"
+        android:showAsAction="never" />
+</menu>
diff --git a/samples/HoneycombGallery/res/menu/photo_context_menu.xml b/samples/HoneycombGallery/res/menu/photo_context_menu.xml
new file mode 100644
index 0000000..efe26c9
--- /dev/null
+++ b/samples/HoneycombGallery/res/menu/photo_context_menu.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/share"
+        android:title="Share"
+        android:icon="?attr/menuIconShare"
+        android:showAsAction="always|withText" />
+</menu>
diff --git a/samples/HoneycombGallery/res/values-port/dimens.xml b/samples/HoneycombGallery/res/values-port/dimens.xml
new file mode 100644
index 0000000..fc41ac9
--- /dev/null
+++ b/samples/HoneycombGallery/res/values-port/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<resources>
+    <dimen name="titles_size">200dp</dimen>
+</resources>
diff --git a/samples/HoneycombGallery/res/values/attrs.xml b/samples/HoneycombGallery/res/values/attrs.xml
new file mode 100644
index 0000000..954cbe4
--- /dev/null
+++ b/samples/HoneycombGallery/res/values/attrs.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<resources>
+    <declare-styleable name="AppTheme">
+        <attr name="listDragShadowBackground" format="reference" />
+        <attr name="menuIconCamera" format="reference" />
+        <attr name="menuIconToggle" format="reference" />
+        <attr name="menuIconShare" format="reference" />
+    </declare-styleable>
+</resources>
diff --git a/samples/HoneycombGallery/res/values/colors.xml b/samples/HoneycombGallery/res/values/colors.xml
new file mode 100644
index 0000000..d64863a
--- /dev/null
+++ b/samples/HoneycombGallery/res/values/colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<resources>
+    <color name="actionbar_background_light">#ccffffff</color>
+    <color name="actionbar_background_dark">#cc000000</color>
+    <color name="drag_active_color">#80cccccc</color>
+</resources>
diff --git a/samples/HoneycombGallery/res/values/dimens.xml b/samples/HoneycombGallery/res/values/dimens.xml
new file mode 100644
index 0000000..1f49654
--- /dev/null
+++ b/samples/HoneycombGallery/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<resources>
+    <dimen name="titles_size">300dp</dimen>
+</resources>
diff --git a/samples/HoneycombGallery/res/values/strings.xml b/samples/HoneycombGallery/res/values/strings.xml
new file mode 100644
index 0000000..5c3b355
--- /dev/null
+++ b/samples/HoneycombGallery/res/values/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2010 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ -->
+<resources>
+    <string name="app_name">Honeycomb Gallery</string>
+    <string name="camera_sample">Camera Example</string>
+    <string name="clip_label">Clip Label</string>
+
+    <string name="app_widget_name">Honeycomb Example Widget</string>
+    <string name="widget_empty_view_text">Touch to show data</string>
+
+    <string name="notification_text">Example notification text</string>
+
+    <string name="photo_selection_cab_title">Photo selection</string>
+</resources>
diff --git a/samples/HoneycombGallery/res/values/styles.xml b/samples/HoneycombGallery/res/values/styles.xml
new file mode 100644
index 0000000..7570b62
--- /dev/null
+++ b/samples/HoneycombGallery/res/values/styles.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2011 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.
+ -->
+<resources>
+    <style name="ActionBar" parent="@android:style/Widget.Holo.ActionBar" />
+
+    <style name="ActionBar.Light" parent="@style/ActionBar">
+        <item name="android:background">@color/actionbar_background_light</item>
+    </style>
+
+    <style name="ActionBar.Dark" parent="@style/ActionBar">
+        <item name="android:background">@color/actionbar_background_dark</item>
+    </style>
+
+    <style name="AppTheme.Light" parent="@android:style/Theme.Holo.Light">
+        <item name="android:actionBarStyle">@style/ActionBar.Light</item>
+        <item name="android:windowActionBarOverlay">true</item>
+        <item name="listDragShadowBackground">@android:color/background_light</item>
+        <item name="menuIconCamera">@drawable/ic_menu_camera_holo_light</item>
+        <item name="menuIconToggle">@drawable/ic_menu_toggle_holo_light</item>
+        <item name="menuIconShare">@drawable/ic_menu_share_holo_light</item>
+    </style>
+
+    <style name="AppTheme.Dark" parent="@android:style/Theme.Holo">
+        <item name="android:actionBarStyle">@style/ActionBar.Dark</item>
+        <item name="android:windowActionBarOverlay">true</item>
+        <item name="listDragShadowBackground">@android:color/background_dark</item>
+        <item name="menuIconCamera">@drawable/ic_menu_camera_holo_dark</item>
+        <item name="menuIconToggle">@drawable/ic_menu_toggle_holo_dark</item>
+        <item name="menuIconShare">@drawable/ic_menu_share_holo_dark</item>
+    </style>
+</resources>
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/CameraFragment.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/CameraFragment.java
new file mode 100644
index 0000000..19c4b47
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/CameraFragment.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import java.io.IOException;
+import java.util.List;
+
+import android.app.Fragment;
+import android.app.Activity;
+import android.app.ActionBar;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
+import android.hardware.Camera.Size;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class CameraFragment extends Fragment {
+
+    private Preview mPreview;
+    Camera mCamera;
+    int mNumberOfCameras;
+    int mCameraCurrentlyLocked;
+
+    // The first rear facing camera
+    int mDefaultCameraId;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+
+        // Create a RelativeLayout container that will hold a SurfaceView,
+        // and set it as the content of our activity.
+        mPreview = new Preview(this.getActivity());
+
+        // Find the total number of cameras available
+        mNumberOfCameras = Camera.getNumberOfCameras();
+
+        // Find the ID of the default camera
+        CameraInfo cameraInfo = new CameraInfo();
+        for (int i = 0; i < mNumberOfCameras; i++) {
+            Camera.getCameraInfo(i, cameraInfo);
+            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
+                mDefaultCameraId = i;
+            }
+        }
+        setHasOptionsMenu(mNumberOfCameras > 1);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        // Add an up arrow to the "home" button, indicating that the button will go "up"
+        // one activity in the app's Activity heirarchy.
+        // Calls to getActionBar() aren't guaranteed to return the ActionBar when called
+        // from within the Fragment's onCreate method, because the Window's decor hasn't been
+        // initialized yet.  Either call for the ActionBar reference in Activity.onCreate()
+        // (after the setContentView(...) call), or in the Fragment's onActivityCreated method.
+        Activity activity = this.getActivity();
+        ActionBar actionBar = activity.getActionBar();
+        actionBar.setDisplayHomeAsUpEnabled(true);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return mPreview;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        // Open the default i.e. the first rear facing camera.
+        mCamera = Camera.open(mDefaultCameraId);
+        mCameraCurrentlyLocked = mDefaultCameraId;
+        mPreview.setCamera(mCamera);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        // Because the Camera object is a shared resource, it's very
+        // important to release it when the activity is paused.
+        if (mCamera != null) {
+            mPreview.setCamera(null);
+            mCamera.release();
+            mCamera = null;
+        }
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        if (mNumberOfCameras > 1) {
+            // Inflate our menu which can gather user input for switching camera
+            inflater.inflate(R.menu.camera_menu, menu);
+        } else {
+            super.onCreateOptionsMenu(menu, inflater);
+        }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle item selection
+        switch (item.getItemId()) {
+        case R.id.switch_cam:
+            // Release this camera -> mCameraCurrentlyLocked
+            if (mCamera != null) {
+                mCamera.stopPreview();
+                mPreview.setCamera(null);
+                mCamera.release();
+                mCamera = null;
+            }
+
+            // Acquire the next camera and request Preview to reconfigure
+            // parameters.
+            mCamera = Camera
+                    .open((mCameraCurrentlyLocked + 1) % mNumberOfCameras);
+            mCameraCurrentlyLocked = (mCameraCurrentlyLocked + 1)
+                    % mNumberOfCameras;
+            mPreview.switchCamera(mCamera);
+
+            // Start the preview
+            mCamera.startPreview();
+            return true;
+        case android.R.id.home:
+            Intent intent = new Intent(this.getActivity(), MainActivity.class);
+            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
+            startActivity(intent);
+
+        default:
+            return super.onOptionsItemSelected(item);
+        }
+    }
+}
+
+// ----------------------------------------------------------------------
+
+/**
+ * A simple wrapper around a Camera and a SurfaceView that renders a centered
+ * preview of the Camera to the surface. We need to center the SurfaceView
+ * because not all devices have cameras that support preview sizes at the same
+ * aspect ratio as the device's display.
+ */
+class Preview extends ViewGroup implements SurfaceHolder.Callback {
+    private final String TAG = "Preview";
+
+    SurfaceView mSurfaceView;
+    SurfaceHolder mHolder;
+    Size mPreviewSize;
+    List<Size> mSupportedPreviewSizes;
+    Camera mCamera;
+
+    Preview(Context context) {
+        super(context);
+
+        mSurfaceView = new SurfaceView(context);
+        addView(mSurfaceView);
+
+        // Install a SurfaceHolder.Callback so we get notified when the
+        // underlying surface is created and destroyed.
+        mHolder = mSurfaceView.getHolder();
+        mHolder.addCallback(this);
+        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+    }
+
+    public void setCamera(Camera camera) {
+        mCamera = camera;
+        if (mCamera != null) {
+            mSupportedPreviewSizes = mCamera.getParameters()
+                    .getSupportedPreviewSizes();
+            requestLayout();
+        }
+    }
+
+    public void switchCamera(Camera camera) {
+        setCamera(camera);
+        try {
+            camera.setPreviewDisplay(mHolder);
+        } catch (IOException exception) {
+            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
+        }
+        Camera.Parameters parameters = camera.getParameters();
+        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
+        requestLayout();
+
+        camera.setParameters(parameters);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // We purposely disregard child measurements because act as a
+        // wrapper to a SurfaceView that centers the camera preview instead
+        // of stretching it.
+        final int width = resolveSize(getSuggestedMinimumWidth(),
+                widthMeasureSpec);
+        final int height = resolveSize(getSuggestedMinimumHeight(),
+                heightMeasureSpec);
+        setMeasuredDimension(width, height);
+
+        if (mSupportedPreviewSizes != null) {
+            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width,
+                    height);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        if (changed && getChildCount() > 0) {
+            final View child = getChildAt(0);
+
+            final int width = r - l;
+            final int height = b - t;
+
+            int previewWidth = width;
+            int previewHeight = height;
+            if (mPreviewSize != null) {
+                previewWidth = mPreviewSize.width;
+                previewHeight = mPreviewSize.height;
+            }
+
+            // Center the child SurfaceView within the parent.
+            if (width * previewHeight > height * previewWidth) {
+                final int scaledChildWidth = previewWidth * height
+                        / previewHeight;
+                child.layout((width - scaledChildWidth) / 2, 0,
+                        (width + scaledChildWidth) / 2, height);
+            } else {
+                final int scaledChildHeight = previewHeight * width
+                        / previewWidth;
+                child.layout(0, (height - scaledChildHeight) / 2, width,
+                        (height + scaledChildHeight) / 2);
+            }
+        }
+    }
+
+    public void surfaceCreated(SurfaceHolder holder) {
+        // The Surface has been created, acquire the camera and tell it where
+        // to draw.
+        try {
+            if (mCamera != null) {
+                mCamera.setPreviewDisplay(holder);
+            }
+        } catch (IOException exception) {
+            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
+        }
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // Surface will be destroyed when we return, so stop the preview.
+        if (mCamera != null) {
+            mCamera.stopPreview();
+        }
+    }
+
+    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
+        final double ASPECT_TOLERANCE = 0.1;
+        double targetRatio = (double) w / h;
+        if (sizes == null)
+            return null;
+
+        Size optimalSize = null;
+        double minDiff = Double.MAX_VALUE;
+
+        int targetHeight = h;
+
+        // Try to find an size match aspect ratio and size
+        for (Size size : sizes) {
+            double ratio = (double) size.width / size.height;
+            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
+                continue;
+            if (Math.abs(size.height - targetHeight) < minDiff) {
+                optimalSize = size;
+                minDiff = Math.abs(size.height - targetHeight);
+            }
+        }
+
+        // Cannot find the one match the aspect ratio, ignore the requirement
+        if (optimalSize == null) {
+            minDiff = Double.MAX_VALUE;
+            for (Size size : sizes) {
+                if (Math.abs(size.height - targetHeight) < minDiff) {
+                    optimalSize = size;
+                    minDiff = Math.abs(size.height - targetHeight);
+                }
+            }
+        }
+        return optimalSize;
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        // Now that the size is known, set up the camera parameters and begin
+        // the preview.
+        Camera.Parameters parameters = mCamera.getParameters();
+        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
+        requestLayout();
+
+        mCamera.setParameters(parameters);
+        mCamera.startPreview();
+    }
+
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/CameraSample.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/CameraSample.java
new file mode 100644
index 0000000..2243858
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/CameraSample.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class CameraSample extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        int themeId = this.getIntent().getExtras().getInt("theme");
+        this.setTheme(themeId);
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.camera_sample);
+    }
+
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/ContentFragment.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/ContentFragment.java
new file mode 100644
index 0000000..8c3323b
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/ContentFragment.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.ClipData;
+import android.content.ClipData.Item;
+import android.content.ClipDescription;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.view.ActionMode;
+import android.view.DragEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+public class ContentFragment extends Fragment {
+    private View mContentView;
+
+    // The bitmap currently used by ImageView
+    private Bitmap mBitmap = null;
+
+    // Current action mode (contextual action bar, a.k.a. CAB)
+    private ActionMode mCurrentActionMode;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        mContentView = inflater.inflate(R.layout.content_welcome, null);
+        final ImageView imageView = (ImageView) mContentView.findViewById(R.id.image);
+        mContentView.setDrawingCacheEnabled(false);
+
+        mContentView.setOnDragListener(new View.OnDragListener() {
+            public boolean onDrag(View v, DragEvent event) {
+                switch (event.getAction()) {
+                    case DragEvent.ACTION_DRAG_ENTERED:
+                        mContentView.setBackgroundColor(
+                                getResources().getColor(R.color.drag_active_color));
+                        break;
+
+                    case DragEvent.ACTION_DRAG_EXITED:
+                        mContentView.setBackgroundColor(Color.TRANSPARENT);
+                        break;
+
+                    case DragEvent.ACTION_DRAG_STARTED:
+                        return processDragStarted(event);
+
+                    case DragEvent.ACTION_DROP:
+                        mContentView.setBackgroundColor(Color.TRANSPARENT);
+                        return processDrop(event, imageView);
+                }
+                return false;
+            }
+        });
+
+        // Keep the action bar visibility in sync with the system status bar. That is, when entering
+        // 'lights out mode,' hide the action bar, and when exiting this mode, show the action bar.
+
+        final Activity activity = getActivity();
+        mContentView.setOnSystemUiVisibilityChangeListener(
+                new View.OnSystemUiVisibilityChangeListener() {
+                    public void onSystemUiVisibilityChange(int visibility) {
+                        ActionBar actionBar = activity.getActionBar();
+                        if (actionBar != null) {
+                            mContentView.setSystemUiVisibility(visibility);
+                            if (visibility == View.STATUS_BAR_VISIBLE) {
+                                actionBar.show();
+                            } else {
+                                actionBar.hide();
+                            }
+                        }
+                    }
+                });
+
+        // Show/hide the system status bar when single-clicking a photo. This is also called
+        // 'lights out mode.' Activating and deactivating this mode also invokes the listener
+        // defined above, which will show or hide the action bar accordingly.
+
+        mContentView.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                if (mContentView.getSystemUiVisibility() == View.STATUS_BAR_VISIBLE) {
+                    mContentView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
+                } else {
+                    mContentView.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
+                }
+            }
+        });
+
+        // When long-pressing a photo, activate the action mode for selection, showing the
+        // contextual action bar (CAB).
+
+        mContentView.setOnLongClickListener(new View.OnLongClickListener() {
+            public boolean onLongClick(View view) {
+                if (mCurrentActionMode != null) {
+                    return false;
+                }
+
+                mCurrentActionMode = getActivity().startActionMode(
+                        mContentSelectionActionModeCallback);
+                mContentView.setSelected(true);
+                return true;
+            }
+        });
+
+        return mContentView;
+    }
+
+    boolean processDragStarted(DragEvent event) {
+        // Determine whether to continue processing drag and drop based on the
+        // plain text mime type.
+        ClipDescription clipDesc = event.getClipDescription();
+        if (clipDesc != null) {
+            return clipDesc.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
+        }
+        return false;
+    }
+
+    boolean processDrop(DragEvent event, ImageView imageView) {
+        // Attempt to parse clip data with expected format: category||entry_id.
+        // Ignore event if data does not conform to this format.
+        ClipData data = event.getClipData();
+        if (data != null) {
+            if (data.getItemCount() > 0) {
+                Item item = data.getItemAt(0);
+                String textData = (String) item.getText();
+                if (textData != null) {
+                    StringTokenizer tokenizer = new StringTokenizer(textData, "||");
+                    if (tokenizer.countTokens() != 2) {
+                        return false;
+                    }
+                    int category = -1;
+                    int entryId = -1;
+                    try {
+                        category = Integer.parseInt(tokenizer.nextToken());
+                        entryId = Integer.parseInt(tokenizer.nextToken());
+                    } catch (NumberFormatException exception) {
+                        return false;
+                    }
+                    updateContentAndRecycleBitmap(category, entryId);
+                    // Update list fragment with selected entry.
+                    TitlesFragment titlesFrag = (TitlesFragment)
+                            getFragmentManager().findFragmentById(R.id.frag_title);
+                    titlesFrag.selectPosition(entryId);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    void updateContentAndRecycleBitmap(int category, int position) {
+        if (mCurrentActionMode != null) {
+            mCurrentActionMode.finish();
+        }
+
+        if (mBitmap != null) {
+            // This is an advanced call and should be used if you
+            // are working with a lot of bitmaps. The bitmap is dead
+            // after this call.
+            mBitmap.recycle();
+        }
+
+        // Get the bitmap that needs to be drawn and update the ImageView
+        mBitmap = Directory.getCategory(category).getEntry(position)
+                .getBitmap(getResources());
+        ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
+    }
+
+    void shareCurrentPhoto() {
+        File externalCacheDir = getActivity().getExternalCacheDir();
+        if (externalCacheDir == null) {
+            Toast.makeText(getActivity(), "Error writing to USB/external storage.",
+                    Toast.LENGTH_SHORT).show();
+            return;
+        }
+
+        // Prevent media scanning of the cache directory.
+        final File noMediaFile = new File(externalCacheDir, ".nomedia");
+        try {
+            noMediaFile.createNewFile();
+        } catch (IOException e) {
+        }
+
+        // Write the bitmap to temporary storage in the external storage directory (e.g. SD card).
+        // We perform the actual disk write operations on a separate thread using the
+        // {@link AsyncTask} class, thus avoiding the possibility of stalling the main (UI) thread.
+
+        final File tempFile = new File(externalCacheDir, "tempfile.jpg");
+
+        new AsyncTask<Void, Void, Boolean>() {
+            /**
+             * Compress and write the bitmap to disk on a separate thread.
+             * @return TRUE if the write was successful, FALSE otherwise.
+             */
+            protected Boolean doInBackground(Void... voids) {
+                try {
+                    FileOutputStream fo = new FileOutputStream(tempFile, false);
+                    if (!mBitmap.compress(Bitmap.CompressFormat.JPEG, 60, fo)) {
+                        Toast.makeText(getActivity(), "Error writing bitmap data.",
+                                Toast.LENGTH_SHORT).show();
+                        return Boolean.FALSE;
+                    }
+                    return Boolean.TRUE;
+
+                } catch (FileNotFoundException e) {
+                    Toast.makeText(getActivity(), "Error writing to USB/external storage.",
+                            Toast.LENGTH_SHORT).show();
+                    return Boolean.FALSE;
+                }
+            }
+
+            /**
+             * After doInBackground completes (either successfully or in failure), we invoke an
+             * intent to share the photo. This code is run on the main (UI) thread.
+             */
+            protected void onPostExecute(Boolean result) {
+                if (result != Boolean.TRUE) {
+                    return;
+                }
+
+                Intent shareIntent = new Intent(Intent.ACTION_SEND);
+                shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
+                shareIntent.setType("image/jpeg");
+                startActivity(Intent.createChooser(shareIntent, "Share photo"));
+            }
+        }.execute();
+    }
+
+    /**
+     * The callback for the 'photo selected' {@link ActionMode}. In this action mode, we can
+     * provide contextual actions for the selected photo. We currently only provide the 'share'
+     * action, but we could also add clipboard functions such as cut/copy/paste here as well.
+     */
+    private ActionMode.Callback mContentSelectionActionModeCallback = new ActionMode.Callback() {
+        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
+            actionMode.setTitle(R.string.photo_selection_cab_title);
+
+            MenuInflater inflater = getActivity().getMenuInflater();
+            inflater.inflate(R.menu.photo_context_menu, menu);
+            return true;
+        }
+
+        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
+            return false;
+        }
+
+        public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
+            switch (menuItem.getItemId()) {
+                case R.id.share:
+                    shareCurrentPhoto();
+                    actionMode.finish();
+                    return true;
+            }
+            return false;
+        }
+
+        public void onDestroyActionMode(ActionMode actionMode) {
+            mContentView.setSelected(false);
+            mCurrentActionMode = null;
+        }
+    };
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/Directory.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/Directory.java
new file mode 100644
index 0000000..4500fe3
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/Directory.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+public class Directory {
+    private static DirectoryCategory[] mCategories;
+
+    public static void initializeDirectory() {
+      mCategories = new DirectoryCategory[] {
+                new DirectoryCategory("Balloons", new DirectoryEntry[] {
+                        new DirectoryEntry("Red Balloon", R.drawable.red_balloon),
+                        new DirectoryEntry("Green Balloon", R.drawable.green_balloon),
+                        new DirectoryEntry("Blue Balloon", R.drawable.blue_balloon)}),
+                new DirectoryCategory("Bikes", new DirectoryEntry[] {
+                        new DirectoryEntry("Old school huffy", R.drawable.blue_bike),
+                        new DirectoryEntry("New Bikes", R.drawable.rainbow_bike),
+                        new DirectoryEntry("Chrome Fast", R.drawable.chrome_wheel)}),
+                new DirectoryCategory("Androids", new DirectoryEntry[] {
+                        new DirectoryEntry("Steampunk Android", R.drawable.punk_droid),
+                        new DirectoryEntry("Stargazing Android", R.drawable.stargazer_droid),
+                        new DirectoryEntry("Big Android", R.drawable.big_droid) }),
+                new DirectoryCategory("Pastries", new DirectoryEntry[] {
+                        new DirectoryEntry("Cupcake", R.drawable.cupcake),
+                        new DirectoryEntry("Donut", R.drawable.donut),
+                        new DirectoryEntry("Eclair", R.drawable.eclair),
+                        new DirectoryEntry("Froyo", R.drawable.froyo), }), };
+
+    }
+
+    public static int getCategoryCount() {
+        return mCategories.length;
+    }
+
+    public static DirectoryCategory getCategory(int i) {
+        return mCategories[i];
+    }
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/DirectoryCategory.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/DirectoryCategory.java
new file mode 100644
index 0000000..926f6e5
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/DirectoryCategory.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+public class DirectoryCategory {
+    private String name;
+    private DirectoryEntry[] entries;
+
+    public DirectoryCategory(String name, DirectoryEntry[] entries) {
+        this.name = name;
+        this.entries = entries;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getEntryCount() {
+        return entries.length;
+    }
+
+    public DirectoryEntry getEntry(int i) {
+        return entries[i];
+    }
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/DirectoryEntry.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/DirectoryEntry.java
new file mode 100644
index 0000000..ecfd4c3
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/DirectoryEntry.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Drawable;
+
+public class DirectoryEntry {
+    private String name;
+    private int resID;
+
+    public DirectoryEntry(String name, int resID) {
+        this.name = name;
+        this.resID = resID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Drawable getDrawable(Resources res) {
+        return res.getDrawable(resID);
+    }
+
+    public Bitmap getBitmap(Resources res) {
+        return BitmapFactory.decodeResource(res, resID);
+    }
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/FitCenterFrameLayout.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/FitCenterFrameLayout.java
new file mode 100644
index 0000000..c6247ba
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/FitCenterFrameLayout.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A simple layout that fits and centers each child view, maintaining aspect ratio.
+ */
+public class FitCenterFrameLayout extends ViewGroup {
+    public FitCenterFrameLayout(Context context) {
+        super(context);
+    }
+
+    public FitCenterFrameLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // We purposely disregard child measurements.
+        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
+        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
+        setMeasuredDimension(width, height);
+
+        int childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.UNSPECIFIED);
+        int childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED);
+
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            getChildAt(i).measure(childWidthSpec, childHeightSpec);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int childCount = getChildCount();
+
+        final int parentLeft = getPaddingLeft();
+        final int parentTop = getPaddingTop();
+        final int parentRight = r - l - getPaddingRight();
+        final int parentBottom = b - t - getPaddingBottom();
+
+        final int parentWidth = parentRight - parentLeft;
+        final int parentHeight = parentBottom - parentTop;
+
+        int unpaddedWidth, unpaddedHeight, parentUnpaddedWidth, parentUnpaddedHeight;
+        int childPaddingLeft, childPaddingTop, childPaddingRight, childPaddingBottom;
+
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+
+            // Fit and center the child within the parent. Make sure not to consider padding
+            // as part of the child's aspect ratio.
+
+            childPaddingLeft = child.getPaddingLeft();
+            childPaddingTop = child.getPaddingTop();
+            childPaddingRight = child.getPaddingRight();
+            childPaddingBottom = child.getPaddingBottom();
+
+            unpaddedWidth = child.getMeasuredWidth() - childPaddingLeft - childPaddingRight;
+            unpaddedHeight = child.getMeasuredHeight() - childPaddingTop - childPaddingBottom;
+
+            parentUnpaddedWidth = parentWidth - childPaddingLeft - childPaddingRight;
+            parentUnpaddedHeight = parentHeight - childPaddingTop - childPaddingBottom;
+
+            if (parentUnpaddedWidth * unpaddedHeight > parentUnpaddedHeight * unpaddedWidth) {
+                // The child view should be left/right letterboxed.
+                final int scaledChildWidth = unpaddedWidth * parentUnpaddedHeight
+                        / unpaddedHeight + childPaddingLeft + childPaddingRight;
+                child.layout(
+                        parentLeft + (parentWidth - scaledChildWidth) / 2,
+                        parentTop,
+                        parentRight - (parentWidth - scaledChildWidth) / 2,
+                        parentBottom);
+            } else {
+                // The child view should be top/bottom letterboxed.
+                final int scaledChildHeight = unpaddedHeight * parentUnpaddedWidth
+                        / unpaddedWidth + childPaddingTop + childPaddingBottom;
+                child.layout(
+                        parentLeft,
+                        parentTop + (parentHeight - scaledChildHeight) / 2,
+                        parentRight,
+                        parentTop + (parentHeight + scaledChildHeight) / 2);
+            }
+        }
+    }
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/MainActivity.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/MainActivity.java
new file mode 100644
index 0000000..3cfaf6d
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/MainActivity.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.RemoteViews;
+
+public class MainActivity extends Activity implements ActionBar.TabListener {
+
+    private static final int NOTIFICATION_DEFAULT = 1;
+    private static final String ACTION_DIALOG = "com.example.android.hcgallery.action.DIALOG";
+
+    private View mActionBarView;
+    private Animator mCurrentTitlesAnimator;
+    private String[] mToggleLabels = {"Show Titles", "Hide Titles"};
+    private int mLabelIndex = 1;
+    private int mThemeId = -1;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if(savedInstanceState != null && savedInstanceState.getInt("theme", -1) != -1) {
+            mThemeId = savedInstanceState.getInt("theme");
+            this.setTheme(mThemeId);
+        }
+
+        setContentView(R.layout.main);
+
+        Directory.initializeDirectory();
+
+        ActionBar bar = getActionBar();
+
+        int i;
+        for (i = 0; i < Directory.getCategoryCount(); i++) {
+            bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName())
+                    .setTabListener(this));
+        }
+
+        mActionBarView = getLayoutInflater().inflate(
+                R.layout.action_bar_custom, null);
+
+        bar.setCustomView(mActionBarView);
+        bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_USE_LOGO);
+        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+        bar.setDisplayShowHomeEnabled(true);
+
+        // If category is not saved to the savedInstanceState,
+        // 0 is returned by default.
+        if(savedInstanceState != null) {
+            int category = savedInstanceState.getInt("category");
+            bar.selectTab(bar.getTabAt(category));
+        }
+    }
+
+    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
+        TitlesFragment titleFrag = (TitlesFragment) getFragmentManager()
+                .findFragmentById(R.id.frag_title);
+        titleFrag.populateTitles(tab.getPosition());
+
+        titleFrag.selectPosition(0);
+    }
+
+    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
+    }
+
+    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.main_menu, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case R.id.camera:
+            Intent intent = new Intent(this, CameraSample.class);
+            intent.putExtra("theme", mThemeId);
+            startActivity(intent);
+            return true;
+
+        case R.id.toggleTitles:
+            toggleVisibleTitles();
+            return true;
+
+        case R.id.toggleTheme:
+            if (mThemeId == R.style.AppTheme_Dark) {
+                mThemeId = R.style.AppTheme_Light;
+            } else {
+                mThemeId = R.style.AppTheme_Dark;
+            }
+            this.recreate();
+            return true;
+
+        case R.id.showDialog:
+            showDialog("This is indeed an awesome dialog.");
+            return true;
+
+        case R.id.showStandardNotification:
+            showNotification(false);
+            return true;
+
+        case R.id.showCustomNotification:
+            showNotification(true);
+            return true;
+
+        default:
+            return super.onOptionsItemSelected(item);
+        }
+    }
+
+    public void toggleVisibleTitles() {
+        // Use these for custom animations.
+        final FragmentManager fm = getFragmentManager();
+        final TitlesFragment f = (TitlesFragment) fm
+                .findFragmentById(R.id.frag_title);
+        final View titlesView = f.getView();
+        mLabelIndex = 1 - mLabelIndex;
+
+        // Determine if we're in portrait, and whether we're showing or hiding the titles
+        // with this toggle.
+        final boolean isPortrait = getResources().getConfiguration().orientation ==
+                Configuration.ORIENTATION_PORTRAIT;
+
+        final boolean shouldShow = f.isHidden() || mCurrentTitlesAnimator != null;
+
+        // Cancel the current titles animation if there is one.
+        if (mCurrentTitlesAnimator != null)
+            mCurrentTitlesAnimator.cancel();
+
+        // Begin setting up the object animator. We'll animate the bottom or right edge of the
+        // titles view, as well as its alpha for a fade effect.
+        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(
+                titlesView,
+                PropertyValuesHolder.ofInt(
+                        isPortrait ? "bottom" : "right",
+                        shouldShow ? getResources().getDimensionPixelSize(R.dimen.titles_size)
+                                   : 0),
+                PropertyValuesHolder.ofFloat("alpha", shouldShow ? 1 : 0)
+        );
+
+        // At each step of the animation, we'll perform layout by calling setLayoutParams.
+        final ViewGroup.LayoutParams lp = titlesView.getLayoutParams();
+        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                // *** WARNING ***: triggering layout at each animation frame highly impacts
+                // performance so you should only do this for simple layouts. More complicated
+                // layouts can be better served with individual animations on child views to
+                // avoid the performance penalty of layout.
+                if (isPortrait) {
+                    lp.height = (Integer) valueAnimator.getAnimatedValue();
+                } else {
+                    lp.width = (Integer) valueAnimator.getAnimatedValue();
+                }
+                titlesView.setLayoutParams(lp);
+            }
+        });
+
+        if (shouldShow) {
+            fm.beginTransaction().show(f).commit();
+            objectAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animator) {
+                    mCurrentTitlesAnimator = null;
+                }
+            });
+
+        } else {
+            objectAnimator.addListener(new AnimatorListenerAdapter() {
+                boolean canceled;
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    canceled = true;
+                    super.onAnimationCancel(animation);
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animator) {
+                    if (canceled)
+                        return;
+                    mCurrentTitlesAnimator = null;
+                    fm.beginTransaction().hide(f).commit();
+                }
+            });
+        }
+
+        // Start the animation.
+        objectAnimator.start();
+        mCurrentTitlesAnimator = objectAnimator;
+
+        invalidateOptionsMenu();
+
+        // Manually trigger onNewIntent to check for ACTION_DIALOG.
+        onNewIntent(getIntent());
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        if (ACTION_DIALOG.equals(intent.getAction())) {
+            showDialog(intent.getStringExtra(Intent.EXTRA_TEXT));
+        }
+    }
+
+    void showDialog(String text) {
+        // DialogFragment.show() will take care of adding the fragment
+        // in a transaction.  We also want to remove any currently showing
+        // dialog, so make our own transaction and take care of that here.
+        FragmentTransaction ft = getFragmentManager().beginTransaction();
+
+        DialogFragment newFragment = MyDialogFragment.newInstance(text);
+
+        // Show the dialog.
+        newFragment.show(ft, "dialog");
+    }
+
+    void showNotification(boolean custom) {
+        final Resources res = getResources();
+        final NotificationManager notificationManager = (NotificationManager) getSystemService(
+                NOTIFICATION_SERVICE);
+
+        Notification.Builder builder = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.ic_stat_notify_example)
+                .setAutoCancel(true)
+                .setTicker(getString(R.string.notification_text))
+                .setContentIntent(getDialogPendingIntent("Tapped the notification entry."));
+
+        if (custom) {
+            // Sets a custom content view for the notification, including an image button.
+            RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification);
+            layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
+            layout.setOnClickPendingIntent(R.id.notification_button,
+                    getDialogPendingIntent("Tapped the 'dialog' button in the notification."));
+            builder.setContent(layout);
+
+            // Notifications in Android 3.0 now have a standard mechanism for displaying large
+            // bitmaps such as contact avatars. Here, we load an example image and resize it to the
+            // appropriate size for large bitmaps in notifications.
+            Bitmap largeIconTemp = BitmapFactory.decodeResource(res,
+                    R.drawable.notification_default_largeicon);
+            Bitmap largeIcon = Bitmap.createScaledBitmap(
+                    largeIconTemp,
+                    res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
+                    res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height),
+                    false);
+            largeIconTemp.recycle();
+
+            builder.setLargeIcon(largeIcon);
+
+        } else {
+            builder
+                    .setNumber(7) // An example number.
+                    .setContentTitle(getString(R.string.app_name))
+                    .setContentText(getString(R.string.notification_text));
+        }
+
+        notificationManager.notify(NOTIFICATION_DEFAULT, builder.getNotification());
+    }
+
+    PendingIntent getDialogPendingIntent(String dialogText) {
+        return PendingIntent.getActivity(
+                this,
+                dialogText.hashCode(), // Otherwise previous PendingIntents with the same
+                                       // requestCode may be overwritten.
+                new Intent(ACTION_DIALOG)
+                        .putExtra(Intent.EXTRA_TEXT, dialogText)
+                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
+                0);
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        menu.getItem(1).setTitle(mToggleLabels[mLabelIndex]);
+        return true;
+    }
+
+    @Override
+    public void onSaveInstanceState (Bundle outState) {
+        super.onSaveInstanceState(outState);
+        ActionBar bar = getActionBar();
+        int category = bar.getSelectedTab().getPosition();
+        outState.putInt("category", category);
+        outState.putInt("theme", mThemeId);
+    }
+
+
+    public static class MyDialogFragment extends DialogFragment {
+
+        public static MyDialogFragment newInstance(String title) {
+            MyDialogFragment frag = new MyDialogFragment();
+            Bundle args = new Bundle();
+            args.putString("text", title);
+            frag.setArguments(args);
+            return frag;
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            String text = getArguments().getString("text");
+
+            return new AlertDialog.Builder(getActivity())
+                    .setTitle("A Dialog of Awesome")
+                    .setMessage(text)
+                    .setPositiveButton(android.R.string.ok,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int whichButton) {
+                                }
+                            }
+                    )
+                    .create();
+        }
+    }
+}
diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/TitlesFragment.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/TitlesFragment.java
new file mode 100644
index 0000000..85a7b68
--- /dev/null
+++ b/samples/HoneycombGallery/src/com/example/android/hcgallery/TitlesFragment.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.ListFragment;
+import android.content.ClipData;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.TextPaint;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemLongClickListener;
+
+public class TitlesFragment extends ListFragment {
+    private int mCategory = 0;
+    private int mCurPosition = 0;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        //Current position should survive screen rotations.
+        if (savedInstanceState != null) {
+            mCategory = savedInstanceState.getInt("category");
+            mCurPosition = savedInstanceState.getInt("listPosition");
+        }
+
+        populateTitles(mCategory);
+        ListView lv = getListView();
+        lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        lv.setCacheColorHint(Color.TRANSPARENT);
+        lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+            public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
+                final String title = (String) ((TextView) v).getText();
+
+                // Set up clip data with the category||entry_id format.
+                final String textData = String.format("%d||%d", mCategory, pos);
+                ClipData data = ClipData.newPlainText(title, textData);
+                v.startDrag(data, new MyDragShadowBuilder(v), null, 0);
+                return true;
+            }
+        });
+
+        selectPosition(mCurPosition);
+    }
+
+    private class MyDragShadowBuilder extends View.DragShadowBuilder {
+        private Drawable mShadow;
+
+        public MyDragShadowBuilder(View v) {
+            super(v);
+
+            final TypedArray a = v.getContext().obtainStyledAttributes(R.styleable.AppTheme);
+            mShadow = a.getDrawable(R.styleable.AppTheme_listDragShadowBackground);
+            mShadow.setCallback(v);
+            mShadow.setBounds(0, 0, v.getWidth(), v.getHeight());
+            a.recycle();
+        }
+
+        @Override
+        public void onDrawShadow(Canvas canvas) {
+            super.onDrawShadow(canvas);
+            mShadow.draw(canvas);
+            getView().draw(canvas);
+        }
+    }
+
+    public void populateTitles(int category) {
+        DirectoryCategory cat = Directory.getCategory(category);
+        String[] items = new String[cat.getEntryCount()];
+        for (int i = 0; i < cat.getEntryCount(); i++)
+            items[i] = cat.getEntry(i).getName();
+        setListAdapter(new ArrayAdapter<String>(getActivity(),
+                R.layout.title_list_item, items));
+        mCategory = category;
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        updateImage(position);
+    }
+
+    private void updateImage(int position) {
+        ContentFragment frag = (ContentFragment) getFragmentManager()
+                .findFragmentById(R.id.frag_content);
+        frag.updateContentAndRecycleBitmap(mCategory, position);
+        mCurPosition = position;
+    }
+
+    public void selectPosition(int position) {
+        ListView lv = getListView();
+        lv.setItemChecked(position, true);
+        updateImage(position);
+    }
+
+    @Override
+    public void onSaveInstanceState (Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("listPosition", mCurPosition);
+        outState.putInt("category", mCategory);
+    }
+}
diff --git a/samples/JetBoy/AndroidManifest.xml b/samples/JetBoy/AndroidManifest.xml
index d0d4173..2176696 100755
--- a/samples/JetBoy/AndroidManifest.xml
+++ b/samples/JetBoy/AndroidManifest.xml
@@ -21,7 +21,8 @@
 	package="com.example.android.jetboy" android:versionCode="1"
 	android:versionName="1.0.0">
 
-	<uses-sdk android:minSdkVersion="3"></uses-sdk>
+	<uses-sdk android:minSdkVersion="3" 
+	  android:targetSdkVersion="11"/>
 
 	<application android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git a/samples/LunarLander/AndroidManifest.xml b/samples/LunarLander/AndroidManifest.xml
index 301291a..3ef4a2f 100644
--- a/samples/LunarLander/AndroidManifest.xml
+++ b/samples/LunarLander/AndroidManifest.xml
@@ -21,7 +21,10 @@
      to come from a domain that you own or have control over. -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.lunarlander">
-    <application android:icon="@drawable/app_lunar_lander" android:label="@string/app_name">
+
+    <uses-sdk android:targetSdkVersion="11"/>
+
+    <application android:icon="@drawable/app_lunar_lander" android:label="@string/app_name">   
         <activity android:name="LunarLander" android:theme="@android:style/Theme.NoTitleBar">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/samples/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
index 83e5732..ead7829 100644
--- a/samples/NotePad/AndroidManifest.xml
+++ b/samples/NotePad/AndroidManifest.xml
@@ -22,15 +22,18 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.notepad" >
 
-    <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
+    <uses-sdk android:minSdkVersion="11" />
 
     <application android:icon="@drawable/app_notes"
-        android:label="@string/app_name" >
+        android:label="@string/app_name"
+    >
         <provider android:name="NotePadProvider"
-            android:authorities="com.example.notepad.provider.NotePad" />
+            android:authorities="com.google.provider.NotePad"
+            android:exported="false">
+            <grant-uri-permission android:pathPattern=".*" />
+        </provider>
 
-        <activity android:name="NotesList"
-            android:label="@string/title_notes_list">
+        <activity android:name="NotesList" android:label="@string/title_notes_list">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -50,22 +53,27 @@
         </activity>
 
         <activity android:name="NoteEditor"
-            android:theme="@android:style/Theme.Light"
-            android:configChanges="keyboardHidden|orientation">
+            android:theme="@android:style/Theme.Holo.Light"
+            android:screenOrientation="sensor"
+            android:configChanges="keyboardHidden|orientation"
+        >
             <!-- This filter says that we can view or edit the data of
                  a single note -->
             <intent-filter android:label="@string/resolve_edit">
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.EDIT" />
-                <action android:name="com.android.notes.action.EDIT_NOTE" />
+                <action android:name="com.android.notepad.action.EDIT_NOTE" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
             </intent-filter>
 
             <!-- This filter says that we can create a new note inside
-                 of a directory of notes. -->
+                 of a directory of notes.  The INSERT action creates an
+                 empty note; the PASTE action initializes a new note from
+                 the current contents of the clipboard. -->
             <intent-filter>
                 <action android:name="android.intent.action.INSERT" />
+                <action android:name="android.intent.action.PASTE" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
             </intent-filter>
@@ -74,8 +82,8 @@
 
         <activity android:name="TitleEditor"
             android:label="@string/title_edit_title"
-            android:theme="@android:style/Theme.Dialog"
             android:icon="@drawable/ic_menu_edit"
+            android:theme="@android:style/Theme.Holo.Dialog"
             android:windowSoftInputMode="stateVisible">
             <!-- This activity implements an alternative action that can be
                  performed on notes: editing their title.  It can be used as
diff --git a/samples/NotePad/res/drawable-hdpi/ic_menu_discard.png b/samples/NotePad/res/drawable-hdpi/ic_menu_discard.png
deleted file mode 100644
index 4683f61..0000000
--- a/samples/NotePad/res/drawable-hdpi/ic_menu_discard.png
+++ /dev/null
Binary files differ
diff --git a/samples/NotePad/res/drawable/ic_menu_discard.png b/samples/NotePad/res/drawable/ic_menu_discard.png
deleted file mode 100644
index 04a76b5..0000000
--- a/samples/NotePad/res/drawable/ic_menu_discard.png
+++ /dev/null
Binary files differ
diff --git a/samples/NotePad/res/layout/note_editor.xml b/samples/NotePad/res/layout/note_editor.xml
index f142c71..552e105 100644
--- a/samples/NotePad/res/layout/note_editor.xml
+++ b/samples/NotePad/res/layout/note_editor.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -16,12 +16,13 @@
 <view xmlns:android="http://schemas.android.com/apk/res/android"
     class="com.example.android.notepad.NoteEditor$LinedEditText"
     android:id="@+id/note"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
     android:background="@android:color/transparent"
     android:padding="5dp"
     android:scrollbars="vertical"
     android:fadingEdge="vertical"
     android:gravity="top"
     android:textSize="22sp"
-    android:capitalize="sentences" />
+    android:capitalize="sentences"
+/>
diff --git a/samples/NotePad/res/layout/noteslist_item.xml b/samples/NotePad/res/layout/noteslist_item.xml
index b167734..cafa9b1 100644
--- a/samples/NotePad/res/layout/noteslist_item.xml
+++ b/samples/NotePad/res/layout/noteslist_item.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
 
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/text1"
-    android:layout_width="fill_parent"
+    android:layout_width="match_parent"
     android:layout_height="?android:attr/listPreferredItemHeight"
     android:textAppearance="?android:attr/textAppearanceLarge"
     android:gravity="center_vertical"
diff --git a/samples/NotePad/res/layout/title_editor.xml b/samples/NotePad/res/layout/title_editor.xml
index 3593ec6..bbf38fc 100644
--- a/samples/NotePad/res/layout/title_editor.xml
+++ b/samples/NotePad/res/layout/title_editor.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -24,7 +24,8 @@
    					  
     <EditText android:id="@+id/title" 
         android:maxLines="1" 
-        android:layout_marginTop="2dip"
+        android:layout_marginTop="2dp"
+        android:layout_marginBottom="15dp"
         android:layout_width="wrap_content"
       	android:ems="25"
         android:layout_height="wrap_content" 
@@ -36,6 +37,7 @@
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:layout_gravity="right"
-        android:text="@string/button_ok" />
+        android:text="@string/button_ok"
+        android:onClick="onClickOk" />
    		
 </LinearLayout>
diff --git a/samples/NotePad/res/menu/editor_options_menu.xml b/samples/NotePad/res/menu/editor_options_menu.xml
index b2d14ac..306139a 100644
--- a/samples/NotePad/res/menu/editor_options_menu.xml
+++ b/samples/NotePad/res/menu/editor_options_menu.xml
@@ -3,18 +3,13 @@
     <item android:id="@+id/menu_save"
           android:icon="@drawable/ic_menu_save"
           android:alphabeticShortcut='s'
-          android:title="@string/menu_save" />
-    <group android:id="@+id/menu_group_edit">
-        <item android:id="@+id/menu_revert"
-              android:icon="@drawable/ic_menu_revert"
-              android:title="@string/menu_revert" />
-        <item android:id="@+id/menu_delete"
-              android:icon="@drawable/ic_menu_delete"
-              android:title="@string/menu_delete" />
-    </group>
-    <group android:id="@+id/menu_group_insert">
-        <item android:id="@+id/menu_discard"
-              android:icon="@drawable/ic_menu_discard"
-              android:title="@string/menu_discard" />
-    </group>
+          android:title="@string/menu_save"
+          android:showAsAction="ifRoom|withText" />
+    <item android:id="@+id/menu_revert"
+          android:icon="@drawable/ic_menu_revert"
+          android:title="@string/menu_revert" />
+    <item android:id="@+id/menu_delete"
+          android:icon="@drawable/ic_menu_delete"
+          android:title="@string/menu_delete"
+          android:showAsAction="ifRoom|withText" />
 </menu>
\ No newline at end of file
diff --git a/samples/NotePad/res/menu/list_context_menu.xml b/samples/NotePad/res/menu/list_context_menu.xml
index acc8edd..71509c6 100644
--- a/samples/NotePad/res/menu/list_context_menu.xml
+++ b/samples/NotePad/res/menu/list_context_menu.xml
@@ -2,6 +2,8 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:id="@+id/context_open"
           android:title="@string/menu_open" />
+    <item android:id="@+id/context_copy"
+          android:title="@string/menu_copy" />
     <item android:id="@+id/context_delete"
           android:title="@string/menu_delete" />
 </menu>
\ No newline at end of file
diff --git a/samples/NotePad/res/menu/list_options_menu.xml b/samples/NotePad/res/menu/list_options_menu.xml
index 9754554..a60e6a4 100644
--- a/samples/NotePad/res/menu/list_options_menu.xml
+++ b/samples/NotePad/res/menu/list_options_menu.xml
@@ -3,6 +3,13 @@
     <!--  This is our one standard application action (creating a new note). -->
     <item android:id="@+id/menu_add"
           android:icon="@drawable/ic_menu_compose"
+          android:title="@string/menu_add"
           android:alphabeticShortcut='a'
-          android:title="@string/menu_add" />
+          android:showAsAction="always" />
+    <!--  If there is currently data in the clipboard, this adds a PASTE menu item to the menu
+          so that the user can paste in the data.. -->
+    <item android:id="@+id/menu_paste"
+          android:icon="@drawable/ic_menu_compose"
+          android:title="@string/menu_paste"
+          android:alphabeticShortcut='p' />
 </menu>
\ No newline at end of file
diff --git a/samples/NotePad/res/values/strings.xml b/samples/NotePad/res/values/strings.xml
index 4100652..26d23d0 100644
--- a/samples/NotePad/res/values/strings.xml
+++ b/samples/NotePad/res/values/strings.xml
@@ -17,25 +17,26 @@
 <resources>
     <string name="app_name">NotePad</string>
     <string name="live_folder_name">Notes</string>
-    
+
     <string name="title_edit_title">Note title:</string>
-    <string name="title_create">Create note</string>
-    <string name="title_edit">Edit: \"%1$s\"</string>
+    <string name="title_create">New note</string>
+    <string name="title_edit">Edit: %1$s</string>
     <string name="title_notes_list">Notes</string>
-    
-    <string name="menu_add">Add note</string>
+
+    <string name="menu_add">New note</string>
     <string name="menu_save">Save</string>
     <string name="menu_delete">Delete</string>
     <string name="menu_open">Open</string>
     <string name="menu_revert">Revert changes</string>
-    <string name="menu_discard">Discard</string>
-    
-    <string name="button_ok">OK</string>  
+    <string name="menu_copy">Copy</string>
+    <string name="menu_paste">Paste</string>
+
+    <string name="button_ok">OK</string>
     <string name="text_title">Title:</string>
-    
+
     <string name="resolve_edit">Edit note</string>
     <string name="resolve_title">Edit title</string>
-    
+
     <string name="error_title">Error</string>
     <string name="error_message">Error loading note</string>
     <string name="nothing_to_save">There is nothing to save</string>
diff --git a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
index 66f4ce6..59d6f12 100644
--- a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
+++ b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
@@ -17,7 +17,10 @@
 package com.example.android.notepad;
 
 import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipboardManager;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -34,38 +37,41 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.widget.EditText;
-import android.widget.Toast;
-
-import com.example.android.notepad.NotePad.NoteColumns;
 
 /**
- * A generic activity for editing a note in a database.  This can be used
- * either to simply view a note {@link Intent#ACTION_VIEW}, view and edit a note
- * {@link Intent#ACTION_EDIT}, or create a new note {@link Intent#ACTION_INSERT}.  
+ * This Activity handles "editing" a note, where editing is responding to
+ * {@link Intent#ACTION_VIEW} (request to view data), edit a note
+ * {@link Intent#ACTION_EDIT}, create a note {@link Intent#ACTION_INSERT}, or
+ * create a new note from the current contents of the clipboard {@link Intent#ACTION_PASTE}.
+ *
+ * NOTE: Notice that the provider operations in this Activity are taking place on the UI thread.
+ * This is not a good practice. It is only done here to make the code more readable. A real
+ * application should use the {@link android.content.AsyncQueryHandler}
+ * or {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread.
  */
 public class NoteEditor extends Activity {
+    // For logging and debugging purposes
     private static final String TAG = "NoteEditor";
 
-    /**
-     * Standard projection for the interesting columns of a normal note.
+    /*
+     * Creates a projection that returns the note ID and the note contents.
      */
-    private static final String[] PROJECTION = new String[] {
-        NoteColumns._ID, // 0
-        NoteColumns.NOTE, // 1
-        NoteColumns.TITLE, // 2
+    private static final String[] PROJECTION =
+        new String[] {
+            NotePad.Notes._ID,
+            NotePad.Notes.COLUMN_NAME_TITLE,
+            NotePad.Notes.COLUMN_NAME_NOTE
     };
-    /** The index of the note column */
-    private static final int COLUMN_INDEX_NOTE = 1;
-    /** The index of the title column */
-    private static final int COLUMN_INDEX_TITLE = 2;
-    
-    // This is our state data that is stored when freezing.
+
+    // A label for the saved state of the activity
     private static final String ORIGINAL_CONTENT = "origContent";
 
-    // The different distinct states the activity can be run in.
+    // This Activity can be started by more than one action. Each action is represented
+    // as a "state" constant
     private static final int STATE_EDIT = 0;
     private static final int STATE_INSERT = 1;
 
+    // Global mutable variables
     private int mState;
     private Uri mUri;
     private Cursor mCursor;
@@ -73,133 +79,240 @@
     private String mOriginalContent;
 
     /**
-     * A custom EditText that draws lines between each line of text that is displayed.
+     * Defines a custom EditText View that draws lines between each line of text that is displayed.
      */
     public static class LinedEditText extends EditText {
         private Rect mRect;
         private Paint mPaint;
 
-        // we need this constructor for LayoutInflater
+        // This constructor is used by LayoutInflater
         public LinedEditText(Context context, AttributeSet attrs) {
             super(context, attrs);
-            
+
+            // Creates a Rect and a Paint object, and sets the style and color of the Paint object.
             mRect = new Rect();
             mPaint = new Paint();
             mPaint.setStyle(Paint.Style.STROKE);
             mPaint.setColor(0x800000FF);
         }
-        
+
+        /**
+         * This is called to draw the LinedEditText object
+         * @param canvas The canvas on which the background is drawn.
+         */
         @Override
         protected void onDraw(Canvas canvas) {
+
+            // Gets the number of lines of text in the View.
             int count = getLineCount();
+
+            // Gets the global Rect and Paint objects
             Rect r = mRect;
             Paint paint = mPaint;
 
+            /*
+             * Draws one line in the rectangle for every line of text in the EditText
+             */
             for (int i = 0; i < count; i++) {
+
+                // Gets the baseline coordinates for the current line of text
                 int baseline = getLineBounds(i, r);
 
+                /*
+                 * Draws a line in the background from the left of the rectangle to the right,
+                 * at a vertical position one dip below the baseline, using the "paint" object
+                 * for details.
+                 */
                 canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
             }
 
+            // Finishes up by calling the parent method
             super.onDraw(canvas);
         }
     }
 
+    /**
+     * This method is called by Android when the Activity is first started. From the incoming
+     * Intent, it determines what kind of editing is desired, and then does it.
+     */
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        /*
+         * Creates an Intent to use when the Activity object's result is sent back to the
+         * caller.
+         */
         final Intent intent = getIntent();
 
-        // Do some setup based on the action being performed.
+        /*
+         *  Sets up for the edit, based on the action specified for the incoming Intent.
+         */
+
+        // Gets the action that triggered the intent filter for this Activity
         final String action = intent.getAction();
+
+        // For an edit action:
         if (Intent.ACTION_EDIT.equals(action)) {
-            // Requested to edit: set that state, and the data being edited.
+
+            // Sets the Activity state to EDIT, and gets the URI for the data to be edited.
             mState = STATE_EDIT;
             mUri = intent.getData();
-        } else if (Intent.ACTION_INSERT.equals(action)) {
-            // Requested to insert: set that state, and create a new entry
-            // in the container.
+
+            // For an insert or paste action:
+        } else if (Intent.ACTION_INSERT.equals(action)
+                || Intent.ACTION_PASTE.equals(action)) {
+
+            // Sets the Activity state to INSERT, gets the general note URI, and inserts an
+            // empty record in the provider
             mState = STATE_INSERT;
             mUri = getContentResolver().insert(intent.getData(), null);
 
-            // If we were unable to create a new note, then just finish
-            // this activity.  A RESULT_CANCELED will be sent back to the
-            // original activity if they requested a result.
+            /*
+             * If the attempt to insert the new note fails, shuts down this Activity. The
+             * originating Activity receives back RESULT_CANCELED if it requested a result.
+             * Logs that the insert failed.
+             */
             if (mUri == null) {
+
+                // Writes the log identifier, a message, and the URI that failed.
                 Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
+
+                // Closes the activity.
                 finish();
                 return;
             }
 
-            // The new entry was created, so assume all will end well and
+            // Since the new entry was created, this sets the result to be returned
             // set the result to be returned.
             setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
 
+        // If the action was other than EDIT or INSERT:
         } else {
-            // Whoops, unknown action!  Bail.
+
+            // Logs an error that the action was not understood, finishes the Activity, and
+            // returns RESULT_CANCELED to an originating Activity.
             Log.e(TAG, "Unknown action, exiting");
             finish();
             return;
         }
 
-        // Set the layout for this activity.  You can find it in res/layout/note_editor.xml
+        /*
+         * Using the URI passed in with the triggering Intent, gets the note or notes in
+         * the provider.
+         * Note: This is being done on the UI thread. It will block the thread until the query
+         * completes. In a sample app, going against a simple provider based on a local database,
+         * the block will be momentary, but in a real app you should use
+         * android.content.AsyncQueryHandler or android.os.AsyncTask.
+         */
+        mCursor = managedQuery(
+            mUri,         // The URI that gets multiple notes from the provider.
+            PROJECTION,   // A projection that returns the note ID and note content for each note.
+            null,         // No "where" clause selection criteria.
+            null,         // No "where" clause selection values.
+            null          // Use the default sort order (modification date, descending)
+        );
+
+        // For a paste, initializes the data from clipboard.
+        // (Must be done after mCursor is initialized.)
+        if (Intent.ACTION_PASTE.equals(action)) {
+            // Does the paste
+            performPaste();
+            // Switches the state to EDIT so the title can be modified.
+            mState = STATE_EDIT;
+        }
+
+        // Sets the layout for this Activity. See res/layout/note_editor.xml
         setContentView(R.layout.note_editor);
-        
-        // The text view for our note, identified by its ID in the XML file.
+
+        // Gets a handle to the EditText in the the layout.
         mText = (EditText) findViewById(R.id.note);
 
-        // Get the note!
-        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
-
-        // If an instance of this activity had previously stopped, we can
-        // get the original text it started with.
+        /*
+         * If this Activity had stopped previously, its state was written the ORIGINAL_CONTENT
+         * location in the saved Instance state. This gets the state.
+         */
         if (savedInstanceState != null) {
             mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
         }
     }
 
+    /**
+     * This method is called when the Activity is about to come to the foreground. This happens
+     * when the Activity comes to the top of the task stack, OR when it is first starting.
+     *
+     * Moves to the first note in the list, sets an appropriate title for the action chosen by
+     * the user, puts the note contents into the TextView, and saves the original text as a
+     * backup.
+     */
     @Override
     protected void onResume() {
         super.onResume();
-        // If we didn't have any trouble retrieving the data, it is now
-        // time to get at the stuff.
+
+        /*
+         * mCursor is initialized, since onCreate() always precedes onResume for any running
+         * process. This tests that it's not null, since it should always contain data.
+         */
         if (mCursor != null) {
             // Requery in case something changed while paused (such as the title)
             mCursor.requery();
-            // Make sure we are at the one and only row in the cursor.
+
+            /* Moves to the first record. Always call moveToFirst() before accessing data in
+             * a Cursor for the first time. The semantics of using a Cursor are that when it is
+             * created, its internal index is pointing to a "place" immediately before the first
+             * record.
+             */
             mCursor.moveToFirst();
 
-            // Modify our overall title depending on the mode we are running in.
+            // Modifies the window title for the Activity according to the current Activity state.
             if (mState == STATE_EDIT) {
                 // Set the title of the Activity to include the note title
-                String title = mCursor.getString(COLUMN_INDEX_TITLE);
+                int colTitleIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE);
+                String title = mCursor.getString(colTitleIndex);
                 Resources res = getResources();
                 String text = String.format(res.getString(R.string.title_edit), title);
                 setTitle(text);
+            // Sets the title to "create" for inserts
             } else if (mState == STATE_INSERT) {
                 setTitle(getText(R.string.title_create));
             }
 
-            // This is a little tricky: we may be resumed after previously being
-            // paused/stopped.  We want to put the new text in the text view,
-            // but leave the user where they were (retain the cursor position
-            // etc).  This version of setText does that for us.
-            String note = mCursor.getString(COLUMN_INDEX_NOTE);
+            /*
+             * onResume() may have been called after the Activity lost focus (was paused).
+             * The user was either editing or creating a note when the Activity paused.
+             * The Activity should re-display the text that had been retrieved previously, but
+             * it should not move the cursor. This helps the user to continue editing or entering.
+             */
+
+            // Gets the note text from the Cursor and puts it in the TextView, but doesn't change
+            // the text cursor's position.
+            int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);
+            String note = mCursor.getString(colNoteIndex);
             mText.setTextKeepState(note);
-            
-            // If we hadn't previously retrieved the original text, do so
-            // now.  This allows the user to revert their changes.
+
+            // Stores the original note text, to allow the user to revert changes.
             if (mOriginalContent == null) {
                 mOriginalContent = note;
             }
 
+        /*
+         * Something is wrong. The Cursor should always contain data. Report an error in the
+         * note.
+         */
         } else {
             setTitle(getText(R.string.error_title));
             mText.setText(getText(R.string.error_message));
         }
     }
 
+    /**
+     * This method is called when an Activity loses focus during its normal operation, and is then
+     * later on killed. The Activity has a chance to save its state so that the system can restore
+     * it.
+     *
+     * Notice that this method isn't a normal part of the Activity lifecycle. It won't be called
+     * if the user simply navigates away from the Activity.
+     */
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         // Save away the original text, so we still have it if the activity
@@ -207,74 +320,122 @@
         outState.putString(ORIGINAL_CONTENT, mOriginalContent);
     }
 
+    /**
+     * This method is called when the Activity loses focus.
+     *
+     * For Activity objects that edit information, onPause() may be the one place where changes are
+     * saved. The Android application model is predicated on the idea that "save" and "exit" aren't
+     * required actions. When users navigate away from an Activity, they shouldn't have to go back
+     * to it to complete their work. The act of going away should save everything and leave the
+     * Activity in a state where Android can destroy it if necessary.
+     *
+     * If the user hasn't done anything, then this deletes or clears out the note, otherwise it
+     * writes the user's work to the provider.
+     */
     @Override
     protected void onPause() {
         super.onPause();
-        // The user is going somewhere, so make sure changes are saved
 
-        String text = mText.getText().toString();
-        int length = text.length();
+        /*
+         * Tests to see that the query operation didn't fail (see onCreate()). The Cursor object
+         * will exist, even if no records were returned, unless the query failed because of some
+         * exception or error.
+         *
+         */
+        if (mCursor != null) {
 
-        // If this activity is finished, and there is no text, then we
-        // simply delete the note entry.
-        // Note that we do this both for editing and inserting...  it
-        // would be reasonable to only do it when inserting.
-        if (isFinishing() && (length == 0) && mCursor != null) {
-            setResult(RESULT_CANCELED);
-            deleteNote();
-        } else {
-            saveNote();
+            // Get the current note text.
+            String text = mText.getText().toString();
+            int length = text.length();
+
+            /*
+             * If the Activity is in the midst of finishing and there is no text in the current
+             * note, returns a result of CANCELED to the caller, and deletes the note. This is done
+             * even if the note was being edited, the assumption being that the user wanted to
+             * "clear out" (delete) the note.
+             */
+            if (isFinishing() && (length == 0)) {
+                setResult(RESULT_CANCELED);
+                deleteNote();
+
+                /*
+                 * Writes the edits to the provider. The note has been edited if an existing note was
+                 * retrieved into the editor *or* if a new note was inserted. In the latter case,
+                 * onCreate() inserted a new empty note into the provider, and it is this new note
+                 * that is being edited.
+                 */
+            } else if (mState == STATE_EDIT) {
+                // Creates a map to contain the new values for the columns
+                updateNote(text, null);
+            } else if (mState == STATE_INSERT) {
+                updateNote(text, text);
+                mState = STATE_EDIT;
+          }
         }
     }
 
+    /**
+     * This method is called when the user clicks the device's Menu button the first time for
+     * this Activity. Android passes in a Menu object that is populated with items.
+     *
+     * Builds the menus for editing and inserting, and adds in alternative actions that
+     * registered themselves to handle the MIME types for this application.
+     *
+     * @param menu A Menu object to which items should be added.
+     * @return True to display the menu.
+     */
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         // Inflate menu from XML resource
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.editor_options_menu, menu);
 
-        // Append to the
-        // menu items for any other activities that can do stuff with it
-        // as well.  This does a query on the system for any activities that
-        // implement the ALTERNATIVE_ACTION for our data, adding a menu item
-        // for each one that is found.
-        Intent intent = new Intent(null, getIntent().getData());
-        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
-        menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
-                new ComponentName(this, NoteEditor.class), null, intent, 0, null);
+        // Only add extra menu items for a saved note 
+        if (mState == STATE_EDIT) {
+            // Append to the
+            // menu items for any other activities that can do stuff with it
+            // as well.  This does a query on the system for any activities that
+            // implement the ALTERNATIVE_ACTION for our data, adding a menu item
+            // for each one that is found.
+            Intent intent = new Intent(null, mUri);
+            intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
+                    new ComponentName(this, NoteEditor.class), null, intent, 0, null);
+        }
 
         return super.onCreateOptionsMenu(menu);
     }
-    
-    
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        if (mState == STATE_EDIT) {
-            menu.setGroupVisible(R.id.menu_group_edit, true);
-            menu.setGroupVisible(R.id.menu_group_insert, false);
-            
-            // Check if note has changed and enable/disable the revert option
-            String savedNote = mCursor.getString(COLUMN_INDEX_NOTE);
-            String currentNote = mText.getText().toString();
-            if (savedNote.equals(currentNote)) {
-                menu.findItem(R.id.menu_revert).setEnabled(false);
-            } else {
-                menu.findItem(R.id.menu_revert).setEnabled(true);
-            }
+        // Check if note has changed and enable/disable the revert option
+        int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);
+        String savedNote = mCursor.getString(colNoteIndex);
+        String currentNote = mText.getText().toString();
+        if (savedNote.equals(currentNote)) {
+            menu.findItem(R.id.menu_revert).setVisible(false);
         } else {
-            menu.setGroupVisible(R.id.menu_group_edit, false);
-            menu.setGroupVisible(R.id.menu_group_insert, true);
+            menu.findItem(R.id.menu_revert).setVisible(true);
         }
         return super.onPrepareOptionsMenu(menu);
     }
 
+    /**
+     * This method is called when a menu item is selected. Android passes in the selected item.
+     * The switch statement in this method calls the appropriate method to perform the action the
+     * user chose.
+     *
+     * @param item The selected MenuItem
+     * @return True to indicate that the item was processed, and no further work is necessary. False
+     * to proceed to further processing as indicated in the MenuItem object.
+     */
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         // Handle all of the possible menu actions.
         switch (item.getItemId()) {
         case R.id.menu_save:
-            saveNote();
+            String text = mText.getText().toString();
+            updateNote(text, null);
             finish();
             break;
         case R.id.menu_delete:
@@ -282,62 +443,146 @@
             finish();
             break;
         case R.id.menu_revert:
-        case R.id.menu_discard:
             cancelNote();
             break;
         }
         return super.onOptionsItemSelected(item);
-        
     }
-    
-    private final void saveNote() {
-        // Make sure their current
-        // changes are safely saved away in the provider.  We don't need
-        // to do this if only editing.
-        if (mCursor != null) {
-            // Get out updates into the provider.
-            ContentValues values = new ContentValues();
 
-            // Bump the modification time to now.
-            values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
+//BEGIN_INCLUDE(paste)
+    /**
+     * A helper method that replaces the note's data with the contents of the clipboard.
+     */
+    private final void performPaste() {
 
-            String text = mText.getText().toString();
-            int length = text.length();
-            // If we are creating a new note, then we want to also create
-            // an initial title for it.
-            if (mState == STATE_INSERT) {
-                if (length == 0) {
-                    Toast.makeText(this, R.string.nothing_to_save, Toast.LENGTH_SHORT).show();
-                    return;
+        // Gets a handle to the Clipboard Manager
+        ClipboardManager clipboard = (ClipboardManager)
+                getSystemService(Context.CLIPBOARD_SERVICE);
+
+        // Gets a content resolver instance
+        ContentResolver cr = getContentResolver();
+
+        // Gets the clipboard data from the clipboard
+        ClipData clip = clipboard.getPrimaryClip();
+        if (clip != null) {
+
+            String text=null;
+            String title=null;
+
+            // Gets the first item from the clipboard data
+            ClipData.Item item = clip.getItemAt(0);
+
+            // Tries to get the item's contents as a URI pointing to a note
+            Uri uri = item.getUri();
+
+            // Tests to see that the item actually is an URI, and that the URI
+            // is a content URI pointing to a provider whose MIME type is the same
+            // as the MIME type supported by the Note pad provider.
+            if (uri != null && NotePad.Notes.CONTENT_ITEM_TYPE.equals(cr.getType(uri))) {
+
+                // The clipboard holds a reference to data with a note MIME type. This copies it.
+                Cursor orig = cr.query(
+                        uri,            // URI for the content provider
+                        PROJECTION,     // Get the columns referred to in the projection
+                        null,           // No selection variables
+                        null,           // No selection variables, so no criteria are needed
+                        null            // Use the default sort order
+                );
+
+                // If the Cursor is not null, and it contains at least one record
+                // (moveToFirst() returns true), then this gets the note data from it.
+                if (orig != null) {
+                    if (orig.moveToFirst()) {
+                        int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);
+                        int colTitleIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE);
+                        text = orig.getString(colNoteIndex);
+                        title = orig.getString(colTitleIndex);
+                    }
+
+                    // Closes the cursor.
+                    orig.close();
                 }
-                String title = text.substring(0, Math.min(30, length));
+            }
+
+            // If the contents of the clipboard wasn't a reference to a note, then
+            // this converts whatever it is to text.
+            if (text == null) {
+                text = item.coerceToText(this).toString();
+            }
+
+            // Updates the current note with the retrieved title and text.
+            updateNote(text, title);
+        }
+    }
+//END_INCLUDE(paste)
+
+    /**
+     * Replaces the current note contents with the text and title provided as arguments.
+     * @param text The new note contents to use.
+     * @param title The new note title to use
+     */
+    private final void updateNote(String text, String title) {
+
+        // Sets up a map to contain values to be updated in the provider.
+        ContentValues values = new ContentValues();
+        values.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, System.currentTimeMillis());
+
+        // If the action is to insert a new note, this creates an initial title for it.
+        if (mState == STATE_INSERT) {
+
+            // If no title was provided as an argument, create one from the note text.
+            if (title == null) {
+  
+                // Get the note's length
+                int length = text.length();
+
+                // Sets the title by getting a substring of the text that is 31 characters long
+                // or the number of characters in the note plus one, whichever is smaller.
+                title = text.substring(0, Math.min(30, length));
+  
+                // If the resulting length is more than 30 characters, chops off any
+                // trailing spaces
                 if (length > 30) {
                     int lastSpace = title.lastIndexOf(' ');
                     if (lastSpace > 0) {
                         title = title.substring(0, lastSpace);
                     }
                 }
-                values.put(NoteColumns.TITLE, title);
             }
-
-            // Write our text back into the provider.
-            values.put(NoteColumns.NOTE, text);
-
-            // Commit all of our changes to persistent storage. When the update completes
-            // the content provider will notify the cursor of the change, which will
-            // cause the UI to be updated.
-            try {
-                getContentResolver().update(mUri, values, null, null);
-            } catch (NullPointerException e) {
-                Log.e(TAG, e.getMessage());
-            }
-            
+            // In the values map, sets the value of the title
+            values.put(NotePad.Notes.COLUMN_NAME_TITLE, title);
+        } else if (title != null) {
+            // In the values map, sets the value of the title
+            values.put(NotePad.Notes.COLUMN_NAME_TITLE, title);
         }
+
+        // This puts the desired notes text into the map.
+        values.put(NotePad.Notes.COLUMN_NAME_NOTE, text);
+
+        /*
+         * Updates the provider with the new values in the map. The ListView is updated
+         * automatically. The provider sets this up by setting the notification URI for
+         * query Cursor objects to the incoming URI. The content resolver is thus
+         * automatically notified when the Cursor for the URI changes, and the UI is
+         * updated.
+         * Note: This is being done on the UI thread. It will block the thread until the
+         * update completes. In a sample app, going against a simple provider based on a
+         * local database, the block will be momentary, but in a real app you should use
+         * android.content.AsyncQueryHandler or android.os.AsyncTask.
+         */
+        getContentResolver().update(
+                mUri,    // The URI for the record to update.
+                values,  // The map of column names and new values to apply to them.
+                null,    // No selection criteria are used, so no where columns are necessary.
+                null     // No where columns are used, so no where arguments are necessary.
+            );
+
+
     }
 
     /**
-     * Take care of canceling work on a note.  Deletes the note if we
-     * had created it, otherwise reverts to the original text.
+     * This helper method cancels the work done on a note.  It deletes the note if it was
+     * newly created, or reverts to the original text of the note i
      */
     private final void cancelNote() {
         if (mCursor != null) {
@@ -346,7 +591,7 @@
                 mCursor.close();
                 mCursor = null;
                 ContentValues values = new ContentValues();
-                values.put(NoteColumns.NOTE, mOriginalContent);
+                values.put(NotePad.Notes.COLUMN_NAME_NOTE, mOriginalContent);
                 getContentResolver().update(mUri, values, null, null);
             } else if (mState == STATE_INSERT) {
                 // We inserted an empty note, make sure to delete it
diff --git a/samples/NotePad/src/com/example/android/notepad/NotePad.java b/samples/NotePad/src/com/example/android/notepad/NotePad.java
index 09087db..624be90 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotePad.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotePad.java
@@ -20,25 +20,92 @@
 import android.provider.BaseColumns;
 
 /**
- * Convenience definitions for NotePadProvider
+ * Defines a contract between the Note Pad content provider and its clients. A contract defines the
+ * information that a client needs to access the provider as one or more data tables. A contract
+ * is a public, non-extendable (final) class that contains constants defining column names and
+ * URIs. A well-written client depends only on the constants in the contract.
  */
 public final class NotePad {
-    public static final String AUTHORITY = "com.example.notepad.provider.NotePad";
+    public static final String AUTHORITY = "com.google.provider.NotePad";
 
     // This class cannot be instantiated
-    private NotePad() {}
-    
+    private NotePad() {
+    }
+
     /**
-     * Notes table
+     * Notes table contract
      */
-    public static final class NoteColumns implements BaseColumns {
+    public static final class Notes implements BaseColumns {
+
         // This class cannot be instantiated
-        private NoteColumns() {}
+        private Notes() {}
+
+        /**
+         * The table name offered by this provider
+         */
+        public static final String TABLE_NAME = "notes";
+
+        /*
+         * URI definitions
+         */
+
+        /**
+         * The scheme part for this provider's URI
+         */
+        private static final String SCHEME = "content://";
+
+        /**
+         * Path parts for the URIs
+         */
+
+        /**
+         * Path part for the Notes URI
+         */
+        private static final String PATH_NOTES = "/notes";
+
+        /**
+         * Path part for the Note ID URI
+         */
+        private static final String PATH_NOTE_ID = "/notes/";
+
+        /**
+         * 0-relative position of a note ID segment in the path part of a note ID URI
+         */
+        public static final int NOTE_ID_PATH_POSITION = 1;
+
+        /**
+         * Path part for the Live Folder URI
+         */
+        private static final String PATH_LIVE_FOLDER = "/live_folders/notes";
 
         /**
          * The content:// style URL for this table
          */
-        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
+        public static final Uri CONTENT_URI =  Uri.parse(SCHEME + AUTHORITY + PATH_NOTES);
+
+        /**
+         * The content URI base for a single note. Callers must
+         * append a numeric note id to this Uri to retrieve a note
+         */
+        public static final Uri CONTENT_ID_URI_BASE
+            = Uri.parse(SCHEME + AUTHORITY + PATH_NOTE_ID);
+
+        /**
+         * The content URI match pattern for a single note, specified by its ID. Use this to match
+         * incoming URIs or to construct an Intent.
+         */
+        public static final Uri CONTENT_ID_URI_PATTERN
+            = Uri.parse(SCHEME + AUTHORITY + PATH_NOTE_ID + "/#");
+
+        /**
+         * The content Uri pattern for a notes listing for live folders
+         */
+        public static final Uri LIVE_FOLDER_URI
+            = Uri.parse(SCHEME + AUTHORITY + PATH_LIVE_FOLDER);
+
+        /*
+         * MIME type definitions
+         */
 
         /**
          * The MIME type of {@link #CONTENT_URI} providing a directory of notes.
@@ -46,7 +113,8 @@
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";
 
         /**
-         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single note.
+         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
+         * note.
          */
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";
 
@@ -55,28 +123,32 @@
          */
         public static final String DEFAULT_SORT_ORDER = "modified DESC";
 
+        /*
+         * Column definitions
+         */
+
         /**
-         * The title of the note
+         * Column name for the title of the note
          * <P>Type: TEXT</P>
          */
-        public static final String TITLE = "title";
+        public static final String COLUMN_NAME_TITLE = "title";
 
         /**
-         * The note itself
+         * Column name of the note content
          * <P>Type: TEXT</P>
          */
-        public static final String NOTE = "note";
+        public static final String COLUMN_NAME_NOTE = "note";
 
         /**
-         * The timestamp for when the note was created
+         * Column name for the creation timestamp
          * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
          */
-        public static final String CREATED_DATE = "created";
+        public static final String COLUMN_NAME_CREATE_DATE = "created";
 
         /**
-         * The timestamp for when the note was last modified
+         * Column name for the modification timestamp
          * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
          */
-        public static final String MODIFIED_DATE = "modified";
+        public static final String COLUMN_NAME_MODIFICATION_DATE = "modified";
     }
 }
diff --git a/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java b/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
index 5c349c5..1839645 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
@@ -16,13 +16,16 @@
 
 package com.example.android.notepad;
 
-import com.example.android.notepad.NotePad.NoteColumns;
+import com.example.android.notepad.NotePad;
 
+import android.content.ClipDescription;
 import android.content.ContentProvider;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.UriMatcher;
+import android.content.ContentProvider.PipeDataWriter;
+import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.SQLException;
@@ -30,236 +33,720 @@
 import android.database.sqlite.SQLiteOpenHelper;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
 import android.provider.LiveFolders;
 import android.text.TextUtils;
 import android.util.Log;
 
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 
 /**
  * Provides access to a database of notes. Each note has a title, the note
  * itself, a creation date and a modified data.
  */
-public class NotePadProvider extends ContentProvider {
-
+public class NotePadProvider extends ContentProvider implements PipeDataWriter<Cursor> {
+    // Used for debugging and logging
     private static final String TAG = "NotePadProvider";
 
-    private static final String DATABASE_NAME = "notepad.db";
-    private static final int DATABASE_VERSION = 2;
-    private static final String NOTES_TABLE_NAME = "notes";
-
-    private static HashMap<String, String> sNotesProjectionMap;
-    private static HashMap<String, String> sLiveFolderProjectionMap;
-
-    private static final int NOTES = 1;
-    private static final int NOTE_ID = 2;
-    private static final int LIVE_FOLDER_NOTES = 3;
-
-    private static final UriMatcher sUriMatcher;
+    /**
+     * The database that the provider uses as its underlying data store
+     */
+    private static final String DATABASE_NAME = "note_pad.db";
 
     /**
-     * This class helps open, create, and upgrade the database file.
+     * The database version
      */
-    private static class DatabaseHelper extends SQLiteOpenHelper {
+    private static final int DATABASE_VERSION = 2;
 
-        DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-        }
+    /**
+     * A projection map used to select columns from the database
+     */
+    private static HashMap<String, String> sNotesProjectionMap;
 
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
-                    + NoteColumns._ID + " INTEGER PRIMARY KEY,"
-                    + NoteColumns.TITLE + " TEXT,"
-                    + NoteColumns.NOTE + " TEXT,"
-                    + NoteColumns.CREATED_DATE + " INTEGER,"
-                    + NoteColumns.MODIFIED_DATE + " INTEGER"
-                    + ");");
-        }
+    /**
+     * A projection map used to select columns from the database
+     */
+    private static HashMap<String, String> sLiveFolderProjectionMap;
 
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
-                    + newVersion + ", which will destroy all old data");
-            db.execSQL("DROP TABLE IF EXISTS notes");
-            onCreate(db);
-        }
-    }
+    /**
+     * Standard projection for the interesting columns of a normal note.
+     */
+    private static final String[] READ_NOTE_PROJECTION = new String[] {
+            NotePad.Notes._ID,               // Projection position 0, the note's id
+            NotePad.Notes.COLUMN_NAME_NOTE,  // Projection position 1, the note's content
+            NotePad.Notes.COLUMN_NAME_TITLE, // Projection position 2, the note's title
+    };
+    private static final int READ_NOTE_NOTE_INDEX = 1;
+    private static final int READ_NOTE_TITLE_INDEX = 2;
 
+    /*
+     * Constants used by the Uri matcher to choose an action based on the pattern
+     * of the incoming URI
+     */
+    // The incoming URI matches the Notes URI pattern
+    private static final int NOTES = 1;
+
+    // The incoming URI matches the Note ID URI pattern
+    private static final int NOTE_ID = 2;
+
+    // The incoming URI matches the Live Folder URI pattern
+    private static final int LIVE_FOLDER_NOTES = 3;
+
+    /**
+     * A UriMatcher instance
+     */
+    private static final UriMatcher sUriMatcher;
+
+    // Handle to a new DatabaseHelper.
     private DatabaseHelper mOpenHelper;
 
-    @Override
-    public boolean onCreate() {
-        mOpenHelper = new DatabaseHelper(getContext());
-        return true;
+
+    /**
+     * A block that instantiates and sets static objects
+     */
+    static {
+
+        /*
+         * Creates and initializes the URI matcher
+         */
+        // Create a new instance
+        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+        // Add a pattern that routes URIs terminated with "notes" to a NOTES operation
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
+
+        // Add a pattern that routes URIs terminated with "notes" plus an integer
+        // to a note ID operation
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
+
+        // Add a pattern that routes URIs terminated with live_folders/notes to a
+        // live folder operation
+        sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
+
+        /*
+         * Creates and initializes a projection map that returns all columns
+         */
+
+        // Creates a new projection map instance. The map returns a column name
+        // given a string. The two are usually equal.
+        sNotesProjectionMap = new HashMap<String, String>();
+
+        // Maps the string "_ID" to the column name "_ID"
+        sNotesProjectionMap.put(NotePad.Notes._ID, NotePad.Notes._ID);
+
+        // Maps "title" to "title"
+        sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_TITLE, NotePad.Notes.COLUMN_NAME_TITLE);
+
+        // Maps "note" to "note"
+        sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_NOTE, NotePad.Notes.COLUMN_NAME_NOTE);
+
+        // Maps "created" to "created"
+        sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE,
+                NotePad.Notes.COLUMN_NAME_CREATE_DATE);
+
+        // Maps "modified" to "modified"
+        sNotesProjectionMap.put(
+                NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE,
+                NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE);
+
+        /*
+         * Creates an initializes a projection map for handling Live Folders
+         */
+
+        // Creates a new projection map instance
+        sLiveFolderProjectionMap = new HashMap<String, String>();
+
+        // Maps "_ID" to "_ID AS _ID" for a live folder
+        sLiveFolderProjectionMap.put(LiveFolders._ID, NotePad.Notes._ID + " AS " + LiveFolders._ID);
+
+        // Maps "NAME" to "title AS NAME"
+        sLiveFolderProjectionMap.put(LiveFolders.NAME, NotePad.Notes.COLUMN_NAME_TITLE + " AS " +
+            LiveFolders.NAME);
     }
 
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-        qb.setTables(NOTES_TABLE_NAME);
+    /**
+    *
+    * This class helps open, create, and upgrade the database file. Set to package visibility
+    * for testing purposes.
+    */
+   static class DatabaseHelper extends SQLiteOpenHelper {
 
+       DatabaseHelper(Context context) {
+
+           // calls the super constructor, requesting the default cursor factory.
+           super(context, DATABASE_NAME, null, DATABASE_VERSION);
+       }
+
+       /**
+        *
+        * Creates the underlying database with table name and column names taken from the
+        * NotePad class.
+        */
+       @Override
+       public void onCreate(SQLiteDatabase db) {
+           db.execSQL("CREATE TABLE " + NotePad.Notes.TABLE_NAME + " ("
+                   + NotePad.Notes._ID + " INTEGER PRIMARY KEY,"
+                   + NotePad.Notes.COLUMN_NAME_TITLE + " TEXT,"
+                   + NotePad.Notes.COLUMN_NAME_NOTE + " TEXT,"
+                   + NotePad.Notes.COLUMN_NAME_CREATE_DATE + " INTEGER,"
+                   + NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE + " INTEGER"
+                   + ");");
+       }
+
+       /**
+        *
+        * Demonstrates that the provider must consider what happens when the
+        * underlying datastore is changed. In this sample, the database is upgraded the database
+        * by destroying the existing data.
+        * A real application should upgrade the database in place.
+        */
+       @Override
+       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+           // Logs that the database is being upgraded
+           Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                   + newVersion + ", which will destroy all old data");
+
+           // Kills the table and existing data
+           db.execSQL("DROP TABLE IF EXISTS notes");
+
+           // Recreates the database with a new version
+           onCreate(db);
+       }
+   }
+
+   /**
+    *
+    * Initializes the provider by creating a new DatabaseHelper. onCreate() is called
+    * automatically when Android creates the provider in response to a resolver request from a
+    * client.
+    */
+   @Override
+   public boolean onCreate() {
+
+       // Creates a new helper object. Note that the database itself isn't opened until
+       // something tries to access it, and it's only created if it doesn't already exist.
+       mOpenHelper = new DatabaseHelper(getContext());
+
+       // Assumes that any failures will be reported by a thrown exception.
+       return true;
+   }
+
+   /**
+    * This method is called when a client calls
+    * {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)}.
+    * Queries the database and returns a cursor containing the results.
+    *
+    * @return A cursor containing the results of the query. The cursor exists but is empty if
+    * the query returns no results or an exception occurs.
+    * @throws IllegalArgumentException if the incoming URI pattern is invalid.
+    */
+   @Override
+   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+           String sortOrder) {
+
+       // Constructs a new query builder and sets its table name
+       SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+       qb.setTables(NotePad.Notes.TABLE_NAME);
+
+       /**
+        * Choose the projection and adjust the "where" clause based on URI pattern-matching.
+        */
+       switch (sUriMatcher.match(uri)) {
+           // If the incoming URI is for notes, chooses the Notes projection
+           case NOTES:
+               qb.setProjectionMap(sNotesProjectionMap);
+               break;
+
+           /* If the incoming URI is for a single note identified by its ID, chooses the
+            * note ID projection, and appends "_ID = <noteID>" to the where clause, so that
+            * it selects that single note
+            */
+           case NOTE_ID:
+               qb.setProjectionMap(sNotesProjectionMap);
+               qb.appendWhere(
+                   NotePad.Notes._ID +    // the name of the ID column
+                   "=" +
+                   // the position of the note ID itself in the incoming URI
+                   uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION));
+               break;
+
+           case LIVE_FOLDER_NOTES:
+               // If the incoming URI is from a live folder, chooses the live folder projection.
+               qb.setProjectionMap(sLiveFolderProjectionMap);
+               break;
+
+           default:
+               // If the URI doesn't match any of the known patterns, throw an exception.
+               throw new IllegalArgumentException("Unknown URI " + uri);
+       }
+
+
+       String orderBy;
+       // If no sort order is specified, uses the default
+       if (TextUtils.isEmpty(sortOrder)) {
+           orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;
+       } else {
+           // otherwise, uses the incoming sort order
+           orderBy = sortOrder;
+       }
+
+       // Opens the database object in "read" mode, since no writes need to be done.
+       SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+       /*
+        * Performs the query. If no problems occur trying to read the database, then a Cursor
+        * object is returned; otherwise, the cursor variable contains null. If no records were
+        * selected, then the Cursor object is empty, and Cursor.getCount() returns 0.
+        */
+       Cursor c = qb.query(
+           db,            // The database to query
+           projection,    // The columns to return from the query
+           selection,     // The columns for the where clause
+           selectionArgs, // The values for the where clause
+           null,          // don't group the rows
+           null,          // don't filter by row groups
+           orderBy        // The sort order
+       );
+
+       // Tells the Cursor what URI to watch, so it knows when its source data changes
+       c.setNotificationUri(getContext().getContentResolver(), uri);
+       return c;
+   }
+
+   /**
+    * This is called when a client calls {@link android.content.ContentResolver#getType(Uri)}.
+    * Returns the MIME data type of the URI given as a parameter.
+    *
+    * @param uri The URI whose MIME type is desired.
+    * @return The MIME type of the URI.
+    * @throws IllegalArgumentException if the incoming URI pattern is invalid.
+    */
+   @Override
+   public String getType(Uri uri) {
+
+       /**
+        * Chooses the MIME type based on the incoming URI pattern
+        */
+       switch (sUriMatcher.match(uri)) {
+
+           // If the pattern is for notes or live folders, returns the general content type.
+           case NOTES:
+           case LIVE_FOLDER_NOTES:
+               return NotePad.Notes.CONTENT_TYPE;
+
+           // If the pattern is for note IDs, returns the note ID content type.
+           case NOTE_ID:
+               return NotePad.Notes.CONTENT_ITEM_TYPE;
+
+           // If the URI pattern doesn't match any permitted patterns, throws an exception.
+           default:
+               throw new IllegalArgumentException("Unknown URI " + uri);
+       }
+    }
+
+//BEGIN_INCLUDE(stream)
+    /**
+     * This describes the MIME types that are supported for opening a note
+     * URI as a stream.
+     */
+    static ClipDescription NOTE_STREAM_TYPES = new ClipDescription(null,
+            new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN });
+
+    /**
+     * Returns the types of available data streams.  URIs to specific notes are supported.
+     * The application can convert such a note to a plain text stream.
+     *
+     * @param uri the URI to analyze
+     * @param mimeTypeFilter The MIME type to check for. This method only returns a data stream
+     * type for MIME types that match the filter. Currently, only text/plain MIME types match.
+     * @return a data stream MIME type. Currently, only text/plan is returned.
+     * @throws IllegalArgumentException if the URI pattern doesn't match any supported patterns.
+     */
+    @Override
+    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
+        /**
+         *  Chooses the data stream type based on the incoming URI pattern.
+         */
         switch (sUriMatcher.match(uri)) {
-        case NOTES:
-            qb.setProjectionMap(sNotesProjectionMap);
-            break;
 
-        case NOTE_ID:
-            qb.setProjectionMap(sNotesProjectionMap);
-            qb.appendWhere(NoteColumns._ID + "=" + uri.getPathSegments().get(1));
-            break;
+            // If the pattern is for notes or live folders, return null. Data streams are not
+            // supported for this type of URI.
+            case NOTES:
+            case LIVE_FOLDER_NOTES:
+                return null;
 
-        case LIVE_FOLDER_NOTES:
-            qb.setProjectionMap(sLiveFolderProjectionMap);
-            break;
+            // If the pattern is for note IDs and the MIME filter is text/plain, then return
+            // text/plain
+            case NOTE_ID:
+                return NOTE_STREAM_TYPES.filterMimeTypes(mimeTypeFilter);
 
-        default:
-            throw new IllegalArgumentException("Unknown URI " + uri);
-        }
-
-        // If no sort order is specified use the default
-        String orderBy;
-        if (TextUtils.isEmpty(sortOrder)) {
-            orderBy = NoteColumns.DEFAULT_SORT_ORDER;
-        } else {
-            orderBy = sortOrder;
-        }
-
-        // Get the database and run the query
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
-
-        // Tell the cursor what uri to watch, so it knows when its source data changes
-        c.setNotificationUri(getContext().getContentResolver(), uri);
-        return c;
+                // If the URI pattern doesn't match any permitted patterns, throws an exception.
+            default:
+                throw new IllegalArgumentException("Unknown URI " + uri);
+            }
     }
 
+
+    /**
+     * Returns a stream of data for each supported stream type. This method does a query on the
+     * incoming URI, then uses
+     * {@link android.content.ContentProvider#openPipeHelper(Uri, String, Bundle, Object,
+     * PipeDataWriter)} to start another thread in which to convert the data into a stream.
+     *
+     * @param uri The URI pattern that points to the data stream
+     * @param mimeTypeFilter A String containing a MIME type. This method tries to get a stream of
+     * data with this MIME type.
+     * @param opts Additional options supplied by the caller.  Can be interpreted as
+     * desired by the content provider.
+     * @return AssetFileDescriptor A handle to the file.
+     * @throws FileNotFoundException if there is no file associated with the incoming URI.
+     */
     @Override
-    public String getType(Uri uri) {
-        switch (sUriMatcher.match(uri)) {
-        case NOTES:
-        case LIVE_FOLDER_NOTES:
-            return NoteColumns.CONTENT_TYPE;
+    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
+            throws FileNotFoundException {
 
-        case NOTE_ID:
-            return NoteColumns.CONTENT_ITEM_TYPE;
+        // Checks to see if the MIME type filter matches a supported MIME type.
+        String[] mimeTypes = getStreamTypes(uri, mimeTypeFilter);
 
-        default:
-            throw new IllegalArgumentException("Unknown URI " + uri);
+        // If the MIME type is supported
+        if (mimeTypes != null) {
+
+            // Retrieves the note for this URI. Uses the query method defined for this provider,
+            // rather than using the database query method.
+            Cursor c = query(
+                    uri,                    // The URI of a note
+                    READ_NOTE_PROJECTION,   // Gets a projection containing the note's ID, title,
+                                            // and contents
+                    null,                   // No WHERE clause, get all matching records
+                    null,                   // Since there is no WHERE clause, no selection criteria
+                    null                    // Use the default sort order (modification date,
+                                            // descending
+            );
+
+
+            // If the query fails or the cursor is empty, stop
+            if (c == null || !c.moveToFirst()) {
+
+                // If the cursor is empty, simply close the cursor and return
+                if (c != null) {
+                    c.close();
+                }
+
+                // If the cursor is null, throw an exception
+                throw new FileNotFoundException("Unable to query " + uri);
+            }
+
+            // Start a new thread that pipes the stream data back to the caller.
+            return new AssetFileDescriptor(
+                    openPipeHelper(uri, mimeTypes[0], opts, c, this), 0,
+                    AssetFileDescriptor.UNKNOWN_LENGTH);
         }
+
+        // If the MIME type is not supported, return a read-only handle to the file.
+        return super.openTypedAssetFile(uri, mimeTypeFilter, opts);
     }
 
+    /**
+     * Implementation of {@link android.content.ContentProvider.PipeDataWriter}
+     * to perform the actual work of converting the data in one of cursors to a
+     * stream of data for the client to read.
+     */
+    @Override
+    public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
+            Bundle opts, Cursor c) {
+        // We currently only support conversion-to-text from a single note entry,
+        // so no need for cursor data type checking here.
+        FileOutputStream fout = new FileOutputStream(output.getFileDescriptor());
+        PrintWriter pw = null;
+        try {
+            pw = new PrintWriter(new OutputStreamWriter(fout, "UTF-8"));
+            pw.println(c.getString(READ_NOTE_TITLE_INDEX));
+            pw.println("");
+            pw.println(c.getString(READ_NOTE_NOTE_INDEX));
+        } catch (UnsupportedEncodingException e) {
+            Log.w(TAG, "Ooops", e);
+        } finally {
+            c.close();
+            if (pw != null) {
+                pw.flush();
+            }
+            try {
+                fout.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+//END_INCLUDE(stream)
+
+    /**
+     * This is called when a client calls
+     * {@link android.content.ContentResolver#insert(Uri, ContentValues)}.
+     * Inserts a new row into the database. This method sets up default values for any
+     * columns that are not included in the incoming map.
+     * If rows were inserted, then listeners are notified of the change.
+     * @return The row ID of the inserted row.
+     * @throws SQLException if the insertion fails.
+     */
     @Override
     public Uri insert(Uri uri, ContentValues initialValues) {
-        // Validate the requested uri
+
+        // Validates the incoming URI. Only the full provider URI is allowed for inserts.
         if (sUriMatcher.match(uri) != NOTES) {
             throw new IllegalArgumentException("Unknown URI " + uri);
         }
 
+        // A map to hold the new record's values.
         ContentValues values;
+
+        // If the incoming values map is not null, uses it for the new values.
         if (initialValues != null) {
             values = new ContentValues(initialValues);
+
         } else {
+            // Otherwise, create a new value map
             values = new ContentValues();
         }
 
+        // Gets the current system time in milliseconds
         Long now = Long.valueOf(System.currentTimeMillis());
 
-        // Make sure that the fields are all set
-        if (values.containsKey(NoteColumns.CREATED_DATE) == false) {
-            values.put(NoteColumns.CREATED_DATE, now);
+        // If the values map doesn't contain the creation date, sets the value to the current time.
+        if (values.containsKey(NotePad.Notes.COLUMN_NAME_CREATE_DATE) == false) {
+            values.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, now);
         }
 
-        if (values.containsKey(NoteColumns.MODIFIED_DATE) == false) {
-            values.put(NoteColumns.MODIFIED_DATE, now);
+        // If the values map doesn't contain the modification date, sets the value to the current
+        // time.
+        if (values.containsKey(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE) == false) {
+            values.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, now);
         }
 
-        if (values.containsKey(NoteColumns.TITLE) == false) {
+        // If the values map doesn't contain a title, sets the value to the default title.
+        if (values.containsKey(NotePad.Notes.COLUMN_NAME_TITLE) == false) {
             Resources r = Resources.getSystem();
-            values.put(NoteColumns.TITLE, r.getString(android.R.string.untitled));
+            values.put(NotePad.Notes.COLUMN_NAME_TITLE, r.getString(android.R.string.untitled));
         }
 
-        if (values.containsKey(NoteColumns.NOTE) == false) {
-            values.put(NoteColumns.NOTE, "");
+        // If the values map doesn't contain note text, sets the value to an empty string.
+        if (values.containsKey(NotePad.Notes.COLUMN_NAME_NOTE) == false) {
+            values.put(NotePad.Notes.COLUMN_NAME_NOTE, "");
         }
 
+        // Opens the database object in "write" mode.
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        long rowId = db.insert(NOTES_TABLE_NAME, NoteColumns.NOTE, values);
+
+        // Performs the insert and returns the ID of the new note.
+        long rowId = db.insert(
+            NotePad.Notes.TABLE_NAME,        // The table to insert into.
+            NotePad.Notes.COLUMN_NAME_NOTE,  // A hack, SQLite sets this column value to null
+                                             // if values is empty.
+            values                           // A map of column names, and the values to insert
+                                             // into the columns.
+        );
+
+        // If the insert succeeded, the row ID exists.
         if (rowId > 0) {
-            Uri noteUri = ContentUris.withAppendedId(NoteColumns.CONTENT_URI, rowId);
+            // Creates a URI with the note ID pattern and the new row ID appended to it.
+            Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, rowId);
+
+            // Notifies observers registered against this provider that the data changed.
             getContext().getContentResolver().notifyChange(noteUri, null);
             return noteUri;
         }
 
+        // If the insert didn't succeed, then the rowID is <= 0. Throws an exception.
         throw new SQLException("Failed to insert row into " + uri);
     }
 
+    /**
+     * This is called when a client calls
+     * {@link android.content.ContentResolver#delete(Uri, String, String[])}.
+     * Deletes records from the database. If the incoming URI matches the note ID URI pattern,
+     * this method deletes the one record specified by the ID in the URI. Otherwise, it deletes a
+     * a set of records. The record or records must also match the input selection criteria
+     * specified by where and whereArgs.
+     *
+     * If rows were deleted, then listeners are notified of the change.
+     * @return If a "where" clause is used, the number of rows affected is returned, otherwise
+     * 0 is returned. To delete all rows and get a row count, use "1" as the where clause.
+     * @throws IllegalArgumentException if the incoming URI pattern is invalid.
+     */
     @Override
     public int delete(Uri uri, String where, String[] whereArgs) {
+
+        // Opens the database object in "write" mode.
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        String finalWhere;
+
         int count;
+
+        // Does the delete based on the incoming URI pattern.
         switch (sUriMatcher.match(uri)) {
-        case NOTES:
-            count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
-            break;
 
-        case NOTE_ID:
-            String noteId = uri.getPathSegments().get(1);
-            count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId
-                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
-            break;
+            // If the incoming pattern matches the general pattern for notes, does a delete
+            // based on the incoming "where" columns and arguments.
+            case NOTES:
+                count = db.delete(
+                    NotePad.Notes.TABLE_NAME,  // The database table name
+                    where,                     // The incoming where clause column names
+                    whereArgs                  // The incoming where clause values
+                );
+                break;
 
-        default:
-            throw new IllegalArgumentException("Unknown URI " + uri);
+                // If the incoming URI matches a single note ID, does the delete based on the
+                // incoming data, but modifies the where clause to restrict it to the
+                // particular note ID.
+            case NOTE_ID:
+                /*
+                 * Starts a final WHERE clause by restricting it to the
+                 * desired note ID.
+                 */
+                finalWhere =
+                        NotePad.Notes._ID +                              // The ID column name
+                        " = " +                                          // test for equality
+                        uri.getPathSegments().                           // the incoming note ID
+                            get(NotePad.Notes.NOTE_ID_PATH_POSITION)
+                ;
+
+                // If there were additional selection criteria, append them to the final
+                // WHERE clause
+                if (where != null) {
+                    finalWhere = finalWhere + " AND " + where;
+                }
+
+                // Performs the delete.
+                count = db.delete(
+                    NotePad.Notes.TABLE_NAME,  // The database table name.
+                    finalWhere,                // The final WHERE clause
+                    whereArgs                  // The incoming where clause values.
+                );
+                break;
+
+            // If the incoming pattern is invalid, throws an exception.
+            default:
+                throw new IllegalArgumentException("Unknown URI " + uri);
         }
 
+        /*Gets a handle to the content resolver object for the current context, and notifies it
+         * that the incoming URI changed. The object passes this along to the resolver framework,
+         * and observers that have registered themselves for the provider are notified.
+         */
         getContext().getContentResolver().notifyChange(uri, null);
+
+        // Returns the number of rows deleted.
         return count;
     }
 
+    /**
+     * This is called when a client calls
+     * {@link android.content.ContentResolver#update(Uri,ContentValues,String,String[])}
+     * Updates records in the database. The column names specified by the keys in the values map
+     * are updated with new data specified by the values in the map. If the incoming URI matches the
+     * note ID URI pattern, then the method updates the one record specified by the ID in the URI;
+     * otherwise, it updates a set of records. The record or records must match the input
+     * selection criteria specified by where and whereArgs.
+     * If rows were updated, then listeners are notified of the change.
+     *
+     * @param uri The URI pattern to match and update.
+     * @param values A map of column names (keys) and new values (values).
+     * @param where An SQL "WHERE" clause that selects records based on their column values. If this
+     * is null, then all records that match the URI pattern are selected.
+     * @param whereArgs An array of selection criteria. If the "where" param contains value
+     * placeholders ("?"), then each placeholder is replaced by the corresponding element in the
+     * array.
+     * @return The number of rows updated.
+     * @throws IllegalArgumentException if the incoming URI pattern is invalid.
+     */
     @Override
     public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
+
+        // Opens the database object in "write" mode.
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         int count;
+        String finalWhere;
+
+        // Does the update based on the incoming URI pattern
         switch (sUriMatcher.match(uri)) {
-        case NOTES:
-            count = db.update(NOTES_TABLE_NAME, values, where, whereArgs);
-            break;
 
-        case NOTE_ID:
-            String noteId = uri.getPathSegments().get(1);
-            count = db.update(NOTES_TABLE_NAME, values, NoteColumns._ID + "=" + noteId
-                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
-            break;
+            // If the incoming URI matches the general notes pattern, does the update based on
+            // the incoming data.
+            case NOTES:
 
-        default:
-            throw new IllegalArgumentException("Unknown URI " + uri);
+                // Does the update and returns the number of rows updated.
+                count = db.update(
+                    NotePad.Notes.TABLE_NAME, // The database table name.
+                    values,                   // A map of column names and new values to use.
+                    where,                    // The where clause column names.
+                    whereArgs                 // The where clause column values to select on.
+                );
+                break;
+
+            // If the incoming URI matches a single note ID, does the update based on the incoming
+            // data, but modifies the where clause to restrict it to the particular note ID.
+            case NOTE_ID:
+                // From the incoming URI, get the note ID
+                String noteId = uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION);
+
+                /*
+                 * Starts creating the final WHERE clause by restricting it to the incoming
+                 * note ID.
+                 */
+                finalWhere =
+                        NotePad.Notes._ID +                              // The ID column name
+                        " = " +                                          // test for equality
+                        uri.getPathSegments().                           // the incoming note ID
+                            get(NotePad.Notes.NOTE_ID_PATH_POSITION)
+                ;
+
+                // If there were additional selection criteria, append them to the final WHERE
+                // clause
+                if (where !=null) {
+                    finalWhere = finalWhere + " AND " + where;
+                }
+
+
+                // Does the update and returns the number of rows updated.
+                count = db.update(
+                    NotePad.Notes.TABLE_NAME, // The database table name.
+                    values,                   // A map of column names and new values to use.
+                    finalWhere,               // The final WHERE clause to use
+                                              // placeholders for whereArgs
+                    whereArgs                 // The where clause column values to select on, or
+                                              // null if the values are in the where argument.
+                );
+                break;
+            // If the incoming pattern is invalid, throws an exception.
+            default:
+                throw new IllegalArgumentException("Unknown URI " + uri);
         }
 
+        /*Gets a handle to the content resolver object for the current context, and notifies it
+         * that the incoming URI changed. The object passes this along to the resolver framework,
+         * and observers that have registered themselves for the provider are notified.
+         */
         getContext().getContentResolver().notifyChange(uri, null);
+
+        // Returns the number of rows updated.
         return count;
     }
 
-    static {
-        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
-        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
-        sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
-
-        sNotesProjectionMap = new HashMap<String, String>();
-        sNotesProjectionMap.put(NoteColumns._ID, NoteColumns._ID);
-        sNotesProjectionMap.put(NoteColumns.TITLE, NoteColumns.TITLE);
-        sNotesProjectionMap.put(NoteColumns.NOTE, NoteColumns.NOTE);
-        sNotesProjectionMap.put(NoteColumns.CREATED_DATE, NoteColumns.CREATED_DATE);
-        sNotesProjectionMap.put(NoteColumns.MODIFIED_DATE, NoteColumns.MODIFIED_DATE);
-
-        // Support for Live Folders.
-        sLiveFolderProjectionMap = new HashMap<String, String>();
-        sLiveFolderProjectionMap.put(LiveFolders._ID, NoteColumns._ID + " AS " +
-                LiveFolders._ID);
-        sLiveFolderProjectionMap.put(LiveFolders.NAME, NoteColumns.TITLE + " AS " +
-                LiveFolders.NAME);
-        // Add more columns here for more robust Live Folders.
+    /**
+     * A test package can call this to get a handle to the database underlying NotePadProvider,
+     * so it can insert test data into the database. The test case class is responsible for
+     * instantiating the provider in a test context; {@link android.test.ProviderTestCase2} does
+     * this during the call to setUp()
+     *
+     * @return a handle to the database helper object for the provider's data.
+     */
+    DatabaseHelper getOpenHelperForTest() {
+        return mOpenHelper;
     }
 }
diff --git a/samples/NotePad/src/com/example/android/notepad/NotesList.java b/samples/NotePad/src/com/example/android/notepad/NotesList.java
index ec80902..7e91f64 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotesList.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotesList.java
@@ -16,9 +16,14 @@
 
 package com.example.android.notepad;
 
+import com.example.android.notepad.NotePad;
+
 import android.app.ListActivity;
+import android.content.ClipboardManager;
+import android.content.ClipData;
 import android.content.ComponentName;
 import android.content.ContentUris;
+import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
@@ -34,60 +39,123 @@
 import android.widget.ListView;
 import android.widget.SimpleCursorAdapter;
 
-import com.example.android.notepad.NotePad.NoteColumns;
-
 /**
  * Displays a list of notes. Will display notes from the {@link Uri}
- * provided in the intent if there is one, otherwise defaults to displaying the
- * contents of the {@link NoteProvider}
+ * provided in the incoming Intent if there is one, otherwise it defaults to displaying the
+ * contents of the {@link NotePadProvider}.
+ *
+ * NOTE: Notice that the provider operations in this Activity are taking place on the UI thread.
+ * This is not a good practice. It is only done here to make the code more readable. A real
+ * application should use the {@link android.content.AsyncQueryHandler} or
+ * {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread.
  */
 public class NotesList extends ListActivity {
+
+    // For logging and debugging
     private static final String TAG = "NotesList";
 
     /**
-     * The columns we are interested in from the database
+     * The columns needed by the cursor adapter
      */
     private static final String[] PROJECTION = new String[] {
-        NoteColumns._ID, // 0
-        NoteColumns.TITLE, // 1
+            NotePad.Notes._ID, // 0
+            NotePad.Notes.COLUMN_NAME_TITLE, // 1
     };
 
     /** The index of the title column */
     private static final int COLUMN_INDEX_TITLE = 1;
-    
+
+    /**
+     * onCreate is called when Android starts this Activity from scratch.
+     */
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        // The user does not need to hold down the key to use menu shortcuts.
         setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
 
-        // If no data was given in the intent (because we were started
-        // as a MAIN activity), then use our default content provider.
+        /* If no data is given in the Intent that started this Activity, then this Activity
+         * was started when the intent filter matched a MAIN action. We should use the default
+         * provider URI.
+         */
+        // Gets the intent that started this Activity.
         Intent intent = getIntent();
+
+        // If there is no data associated with the Intent, sets the data to the default URI, which
+        // accesses a list of notes.
         if (intent.getData() == null) {
-            intent.setData(NoteColumns.CONTENT_URI);
+            intent.setData(NotePad.Notes.CONTENT_URI);
         }
 
-        // Inform the list we provide context menus for items
+        /*
+         * Sets the callback for context menu activation for the ListView. The listener is set
+         * to be this Activity. The effect is that context menus are enabled for items in the
+         * ListView, and the context menu is handled by a method in NotesList.
+         */
         getListView().setOnCreateContextMenuListener(this);
-        
-        // Perform a managed query. The Activity will handle closing and requerying the cursor
-        // when needed.
-        Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,
-                                        NoteColumns.DEFAULT_SORT_ORDER);
 
-        // Used to map notes entries from the database to views
-        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
-                new String[] { NoteColumns.TITLE }, new int[] { android.R.id.text1 });
+        /* Performs a managed query. The Activity handles closing and requerying the cursor
+         * when needed.
+         *
+         * Please see the introductory note about performing provider operations on the UI thread.
+         */
+        Cursor cursor = managedQuery(
+            getIntent().getData(),            // Use the default content URI for the provider.
+            PROJECTION,                       // Return the note ID and title for each note.
+            null,                             // No where clause, return all records.
+            null,                             // No where clause, therefore no where column values.
+            NotePad.Notes.DEFAULT_SORT_ORDER  // Use the default sort order.
+        );
+
+        /*
+         * The following two arrays create a "map" between columns in the cursor and view IDs
+         * for items in the ListView. Each element in the dataColumns array represents
+         * a column name; each element in the viewID array represents the ID of a View.
+         * The SimpleCursorAdapter maps them in ascending order to determine where each column
+         * value will appear in the ListView.
+         */
+
+        // The names of the cursor columns to display in the view, initialized to the title column
+        String[] dataColumns = { NotePad.Notes.COLUMN_NAME_TITLE } ;
+
+        // The view IDs that will display the cursor columns, initialized to the TextView in
+        // noteslist_item.xml
+        int[] viewIDs = { android.R.id.text1 };
+
+        // Creates the backing adapter for the ListView.
+        SimpleCursorAdapter adapter
+            = new SimpleCursorAdapter(
+                      this,                             // The Context for the ListView
+                      R.layout.noteslist_item,          // Points to the XML for a list item
+                      cursor,                           // The cursor to get items from
+                      dataColumns,
+                      viewIDs
+              );
+
+        // Sets the ListView's adapter to be the cursor adapter that was just created.
         setListAdapter(adapter);
     }
 
+    /**
+     * Called when the user clicks the device's Menu button the first time for
+     * this Activity. Android passes in a Menu object that is populated with items.
+     *
+     * Sets up a menu that provides the Insert option plus a list of alternative actions for
+     * this Activity. Other applications that want to handle notes can "register" themselves in
+     * Android by providing an intent filter that includes the category ALTERNATIVE and the
+     * mimeTYpe NotePad.Notes.CONTENT_TYPE. If they do this, the code in onCreateOptionsMenu()
+     * will add the Activity that contains the intent filter to its list of options. In effect,
+     * the menu will offer the user other applications that can handle notes.
+     * @param menu A Menu object, to which menu items should be added.
+     * @return True, always. The menu should be displayed.
+     */
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         // Inflate menu from XML resource
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.list_options_menu, menu);
-        
+
         // Generate any additional actions that can be performed on the
         // overall list.  In a normal install, there are no additional
         // actions found here, but this allows other applications to extend
@@ -101,28 +169,160 @@
     }
 
     @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+
+        // The paste menu item is enabled if there is data on the clipboard.
+        ClipboardManager clipboard = (ClipboardManager)
+                getSystemService(Context.CLIPBOARD_SERVICE);
+
+
+        MenuItem mPasteItem = menu.findItem(R.id.menu_paste);
+
+        // If the clipboard contains an item, enables the Paste option on the menu.
+        if (clipboard.hasPrimaryClip()) {
+            mPasteItem.setEnabled(true);
+        } else {
+            // If the clipboard is empty, disables the menu's Paste option.
+            mPasteItem.setEnabled(false);
+        }
+
+        // Gets the number of notes currently being displayed.
+        final boolean haveItems = getListAdapter().getCount() > 0;
+
+        // If there are any notes in the list (which implies that one of
+        // them is selected), then we need to generate the actions that
+        // can be performed on the current selection.  This will be a combination
+        // of our own specific actions along with any extensions that can be
+        // found.
+        if (haveItems) {
+
+            // This is the selected item.
+            Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
+
+            // Creates an array of Intents with one element. This will be used to send an Intent
+            // based on the selected menu item.
+            Intent[] specifics = new Intent[1];
+
+            // Sets the Intent in the array to be an EDIT action on the URI of the selected note.
+            specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
+
+            // Creates an array of menu items with one element. This will contain the EDIT option.
+            MenuItem[] items = new MenuItem[1];
+
+            // Creates an Intent with no specific action, using the URI of the selected note.
+            Intent intent = new Intent(null, uri);
+
+            /* Adds the category ALTERNATIVE to the Intent, with the note ID URI as its
+             * data. This prepares the Intent as a place to group alternative options in the
+             * menu.
+             */
+            intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+
+            /*
+             * Add alternatives to the menu
+             */
+            menu.addIntentOptions(
+                Menu.CATEGORY_ALTERNATIVE,  // Add the Intents as options in the alternatives group.
+                Menu.NONE,                  // A unique item ID is not required.
+                Menu.NONE,                  // The alternatives don't need to be in order.
+                null,                       // The caller's name is not excluded from the group.
+                specifics,                  // These specific options must appear first.
+                intent,                     // These Intent objects map to the options in specifics.
+                Menu.NONE,                  // No flags are required.
+                items                       // The menu items generated from the specifics-to-
+                                            // Intents mapping
+            );
+                // If the Edit menu item exists, adds shortcuts for it.
+                if (items[0] != null) {
+
+                    // Sets the Edit menu item shortcut to numeric "1", letter "e"
+                    items[0].setShortcut('1', 'e');
+                }
+            } else {
+                // If the list is empty, removes any existing alternative actions from the menu
+                menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
+            }
+
+        // Displays the menu
+        return true;
+    }
+
+    /**
+     * This method is called when the user selects an option from the menu, but no item
+     * in the list is selected. If the option was INSERT, then a new Intent is sent out with action
+     * ACTION_INSERT. The data from the incoming Intent is put into the new Intent. In effect,
+     * this triggers the NoteEditor activity in the NotePad application.
+     *
+     * If the item was not INSERT, then most likely it was an alternative option from another
+     * application. The parent method is called to process the item.
+     * @param item The menu item that was selected by the user
+     * @return True, if the INSERT menu item was selected; otherwise, the result of calling
+     * the parent method.
+     */
+    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
         case R.id.menu_add:
-            // Launch activity to insert a new item
-            startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
-            return true;
+          /*
+           * Launches a new Activity using an Intent. The intent filter for the Activity
+           * has to have action ACTION_INSERT. No category is set, so DEFAULT is assumed.
+           * In effect, this starts the NoteEditor Activity in NotePad.
+           */
+           startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
+           return true;
+        case R.id.menu_paste:
+          /*
+           * Launches a new Activity using an Intent. The intent filter for the Activity
+           * has to have action ACTION_PASTE. No category is set, so DEFAULT is assumed.
+           * In effect, this starts the NoteEditor Activity in NotePad.
+           */
+          startActivity(new Intent(Intent.ACTION_PASTE, getIntent().getData()));
+          return true;
         default:
             return super.onOptionsItemSelected(item);
         }
     }
 
+    /**
+     * This method is called when the user context-clicks a note in the list. NotesList registers
+     * itself as the handler for context menus in its ListView (this is done in onCreate()).
+     *
+     * The only available options are COPY and DELETE.
+     *
+     * Context-click is equivalent to long-press.
+     *
+     * @param menu A ContexMenu object to which items should be added.
+     * @param view The View for which the context menu is being constructed.
+     * @param menuInfo Data associated with view.
+     * @throws ClassCastException
+     */
     @Override
     public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+
+        // The data from the menu item.
         AdapterView.AdapterContextMenuInfo info;
+
+        // Tries to get the position of the item in the ListView that was long-pressed.
         try {
-             info = (AdapterView.AdapterContextMenuInfo) menuInfo;
+            // Casts the incoming data object into the type for AdapterView objects.
+            info = (AdapterView.AdapterContextMenuInfo) menuInfo;
         } catch (ClassCastException e) {
+            // If the menu object can't be cast, logs an error.
             Log.e(TAG, "bad menuInfo", e);
             return;
         }
 
+        /*
+         * Gets the data associated with the item at the selected position. getItem() returns
+         * whatever the backing adapter of the ListView has associated with the item. In NotesList,
+         * the adapter associated all of the data for a note with its list item. As a result,
+         * getItem() returns that data as a Cursor.
+         */
         Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
+
+        // If the cursor is empty, then for some reason the adapter can't get the data from the
+        // provider, so returns null to the caller.
         if (cursor == null) {
             // For some reason the requested item isn't available, do nothing
             return;
@@ -131,10 +331,10 @@
         // Inflate menu from XML resource
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.list_context_menu, menu);
-        
-        // Set the context menu header
+
+        // Sets the menu header to be the title of the selected note.
         menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
-        
+
         // Append to the
         // menu items for any other activities that can do stuff with it
         // as well.  This does a query on the system for any activities that
@@ -146,45 +346,122 @@
         menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
                 new ComponentName(this, NotesList.class), null, intent, 0, null);
     }
-        
+
+    /**
+     * This method is called when the user selects an item from the context menu
+     * (see onCreateContextMenu()). The only menu items that are actually handled are DELETE and
+     * COPY. Anything else is an alternative option, for which default handling should be done.
+     *
+     * @param item The selected menu item
+     * @return True if the menu item was DELETE, and no default processing is need, otherwise false,
+     * which triggers the default handling of the item.
+     * @throws ClassCastException
+     */
     @Override
     public boolean onContextItemSelected(MenuItem item) {
+        // The data from the menu item.
         AdapterView.AdapterContextMenuInfo info;
+
+        /*
+         * Gets the extra info from the menu item. When an note in the Notes list is long-pressed, a
+         * context menu appears. The menu items for the menu automatically get the data
+         * associated with the note that was long-pressed. The data comes from the provider that
+         * backs the list.
+         *
+         * The note's data is passed to the context menu creation routine in a ContextMenuInfo
+         * object.
+         *
+         * When one of the context menu items is clicked, the same data is passed, along with the
+         * note ID, to onContextItemSelected() via the item parameter.
+         */
         try {
-             info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+            // Casts the data object in the item into the type for AdapterView objects.
+            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
         } catch (ClassCastException e) {
+
+            // If the object can't be cast, logs an error
             Log.e(TAG, "bad menuInfo", e);
+
+            // Triggers default processing of the menu item.
             return false;
         }
-        
+        // Appends the selected note's ID to the URI sent with the incoming Intent.
         Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
 
+        /*
+         * Gets the menu item's ID and compares it to known actions.
+         */
         switch (item.getItemId()) {
         case R.id.context_open:
             // Launch activity to view/edit the currently selected item
             startActivity(new Intent(Intent.ACTION_EDIT, noteUri));
             return true;
+//BEGIN_INCLUDE(copy)
+        case R.id.context_copy:
+            // Gets a handle to the clipboard service.
+            ClipboardManager clipboard = (ClipboardManager)
+                    getSystemService(Context.CLIPBOARD_SERVICE);
+  
+            // Copies the notes URI to the clipboard. In effect, this copies the note itself
+            clipboard.setPrimaryClip(ClipData.newUri(   // new clipboard item holding a URI
+                    getContentResolver(),               // resolver to retrieve URI info
+                    "Note",                             // label for the clip
+                    noteUri)                            // the URI
+            );
+  
+            // Returns to the caller and skips further processing.
+            return true;
+//END_INCLUDE(copy)
         case R.id.context_delete:
-            // Delete the note that the context menu is for
-            getContentResolver().delete(noteUri, null, null);
+  
+            // Deletes the note from the provider by passing in a URI in note ID format.
+            // Please see the introductory note about performing provider operations on the
+            // UI thread.
+            getContentResolver().delete(
+                noteUri,  // The URI of the provider
+                null,     // No where clause is needed, since only a single note ID is being
+                          // passed in.
+                null      // No where clause is used, so no where arguments are needed.
+            );
+  
+            // Returns to the caller and skips further processing.
             return true;
         default:
             return super.onContextItemSelected(item);
         }
     }
 
+    /**
+     * This method is called when the user clicks a note in the displayed list.
+     *
+     * This method handles incoming actions of either PICK (get data from the provider) or
+     * GET_CONTENT (get or create data). If the incoming action is EDIT, this method sends a
+     * new Intent to start NoteEditor.
+     * @param l The ListView that contains the clicked item
+     * @param v The View of the individual item
+     * @param position The position of v in the displayed list
+     * @param id The row ID of the clicked item
+     */
     @Override
     protected void onListItemClick(ListView l, View v, int position, long id) {
-        Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), id);
-        
+
+        // Constructs a new URI from the incoming URI and the row ID
+        Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
+
+        // Gets the action from the incoming Intent
         String action = getIntent().getAction();
+
+        // Handles requests for note data
         if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
-            // The caller is waiting for us to return a note selected by
-            // the user.  The have clicked on one, so return it now.
-            setResult(RESULT_OK, new Intent().setData(noteUri));
+
+            // Sets the result to return to the component that called this Activity. The
+            // result contains the new URI
+            setResult(RESULT_OK, new Intent().setData(uri));
         } else {
-            // Launch activity to view/edit the currently selected item
-            startActivity(new Intent(Intent.ACTION_EDIT, noteUri));
+
+            // Sends out an Intent to start an Activity that can handle ACTION_EDIT. The
+            // Intent's data is the note ID URI. The effect is to call NoteEdit.
+            startActivity(new Intent(Intent.ACTION_EDIT, uri));
         }
     }
 }
diff --git a/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java b/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java
index 00eb314..24afaa0 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java
@@ -16,50 +16,98 @@
 
 package com.example.android.notepad;
 
+import com.example.android.notepad.NotePad;
+
 import android.app.Activity;
 import android.content.Intent;
-import android.net.Uri;
+import android.content.Intent.ShortcutIconResource;
 import android.os.Bundle;
 import android.provider.LiveFolders;
 
+/**
+ * This Activity creates a live folder Intent and
+ * sends it back to HOME. From the data in the Intent, HOME creates a live folder and displays
+ * its icon in the Home view.
+ * When the user clicks the icon, Home uses the data it got from the Intent to retrieve information
+ * from a content provider and display it in a View.
+ *
+ * The intent filter for this Activity is set to ACTION_CREATE_LIVE_FOLDER, which
+ * HOME sends in response to a long press and selection of Live Folder.
+ */
 public class NotesLiveFolder extends Activity {
+
     /**
-     * The URI for the Notes Live Folder content provider.
+     * All of the work is done in onCreate(). The Activity doesn't actually display a UI.
+     * Instead, it sets up an Intent and returns it to its caller (the HOME activity).
      */
-    public static final Uri CONTENT_URI = Uri.parse("content://"
-            + NotePad.AUTHORITY + "/live_folders/notes");
-
-    public static final Uri NOTE_URI = Uri.parse("content://"
-            + NotePad.AUTHORITY + "/notes/#");
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        /*
+         * Gets the incoming Intent and its action. If the incoming Intent was
+         * ACTION_CREATE_LIVE_FOLDER, then create an outgoing Intent with the
+         * necessary data and send back OK. Otherwise, send back CANCEL.
+         */
         final Intent intent = getIntent();
         final String action = intent.getAction();
 
         if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
-            // Build the live folder intent.
+
+            // Creates a new Intent.
             final Intent liveFolderIntent = new Intent();
 
-            liveFolderIntent.setData(CONTENT_URI);
-            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME,
-                    getString(R.string.live_folder_name));
-            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON,
-                    Intent.ShortcutIconResource.fromContext(this,
-                            R.drawable.live_folder_notes));
-            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
-                    LiveFolders.DISPLAY_MODE_LIST);
-            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT,
-                    new Intent(Intent.ACTION_EDIT, NOTE_URI));
+            /*
+             * The following statements put data into the outgoing Intent. Please see
+             * {@link android.provider.LiveFolders for a detailed description of these
+             * data values. From this data, HOME sets up a live folder.
+             */
+            // Sets the URI pattern for the content provider backing the folder.
+            liveFolderIntent.setData(NotePad.Notes.LIVE_FOLDER_URI);
 
-            // The result of this activity should be a live folder intent.
+            // Adds the display name of the live folder as an Extra string.
+            String foldername = getString(R.string.live_folder_name);
+            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, foldername);
+
+            // Adds the display icon of the live folder as an Extra resource.
+            ShortcutIconResource foldericon =
+                Intent.ShortcutIconResource.fromContext(this, R.drawable.live_folder_notes);
+            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON, foldericon);
+
+            // Add the display mode of the live folder as an integer. The specified
+            // mode causes the live folder to display as a list.
+            liveFolderIntent.putExtra(
+                    LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
+                    LiveFolders.DISPLAY_MODE_LIST);
+
+            /*
+             * Adds a base action for items in the live folder list, as an Intent. When the
+             * user clicks an individual note in the list, the live folder fires this Intent.
+             *
+             * Its action is ACTION_EDIT, so it triggers the Note Editor activity. Its
+             * data is the URI pattern for a single note identified by its ID. The live folder
+             * automatically adds the ID value of the selected item to the URI pattern.
+             *
+             * As a result, Note Editor is triggered and gets a single note to retrieve by ID.
+             */
+            Intent returnIntent
+                    = new Intent(Intent.ACTION_EDIT, NotePad.Notes.CONTENT_ID_URI_PATTERN);
+            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT, returnIntent);
+
+            /* Creates an ActivityResult object to propagate back to HOME. Set its result indicator
+             * to OK, and sets the returned Intent to the live folder Intent that was just
+             * constructed.
+             */
             setResult(RESULT_OK, liveFolderIntent);
+
         } else {
+
+            // If the original action was not ACTION_CREATE_LIVE_FOLDER, creates an
+            // ActivityResult with the indicator set to CANCELED, but do not return an Intent
             setResult(RESULT_CANCELED);
         }
 
+        // Closes the Activity. The ActivityObject is propagated back to the caller.
         finish();
     }
 }
diff --git a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
index fe232ed..5abe97b 100644
--- a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
+++ b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
@@ -22,94 +22,146 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.view.View;
-import android.widget.Button;
 import android.widget.EditText;
 
-import com.example.android.notepad.NotePad.NoteColumns;
-
 /**
- * An activity that will edit the title of a note. Displays a floating
- * window with a text field.
+ * This Activity allows the user to edit a note's title. It displays a floating window
+ * containing an EditText.
+ *
+ * NOTE: Notice that the provider operations in this Activity are taking place on the UI thread.
+ * This is not a good practice. It is only done here to make the code more readable. A real
+ * application should use the {@link android.content.AsyncQueryHandler}
+ * or {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread.
  */
-public class TitleEditor extends Activity implements View.OnClickListener {
+public class TitleEditor extends Activity {
 
     /**
      * This is a special intent action that means "edit the title of a note".
      */
     public static final String EDIT_TITLE_ACTION = "com.android.notepad.action.EDIT_TITLE";
 
-    /**
-     * An array of the columns we are interested in.
-     */
+    // Creates a projection that returns the note ID and the note contents.
     private static final String[] PROJECTION = new String[] {
-        NoteColumns._ID, // 0
-        NoteColumns.TITLE, // 1
+            NotePad.Notes._ID, // 0
+            NotePad.Notes.COLUMN_NAME_TITLE, // 1
     };
-    /** Index of the title column */
+
+    // The position of the title column in a Cursor returned by the provider.
     private static final int COLUMN_INDEX_TITLE = 1;
 
-    /**
-     * Cursor which will provide access to the note whose title we are editing.
-     */
+    // A Cursor object that will contain the results of querying the provider for a note.
     private Cursor mCursor;
 
-    /**
-     * The EditText field from our UI. Keep track of this so we can extract the
-     * text when we are finished.
-     */
+    // An EditText object for preserving the edited title.
     private EditText mText;
 
-    /**
-     * The content URI to the note that's being edited.
-     */
+    // A URI object for the note whose title is being edited.
     private Uri mUri;
 
+    /**
+     * This method is called by Android when the Activity is first started. From the incoming
+     * Intent, it determines what kind of editing is desired, and then does it.
+     */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        // Set the View for this Activity object's UI.
         setContentView(R.layout.title_editor);
 
-        // Get the uri of the note whose title we want to edit
+        // Get the Intent that activated this Activity, and from it get the URI of the note whose
+        // title we need to edit.
         mUri = getIntent().getData();
 
-        // Get a cursor to access the note
-        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
+        /*
+         * Using the URI passed in with the triggering Intent, gets the note.
+         *
+         * Note: This is being done on the UI thread. It will block the thread until the query
+         * completes. In a sample app, going against a simple provider based on a local database,
+         * the block will be momentary, but in a real app you should use
+         * android.content.AsyncQueryHandler or android.os.AsyncTask.
+         */
 
-        // Set up click handlers for the text field and button
+        mCursor = managedQuery(
+            mUri,        // The URI for the note that is to be retrieved.
+            PROJECTION,  // The columns to retrieve
+            null,        // No selection criteria are used, so no where columns are needed.
+            null,        // No where columns are used, so no where values are needed.
+            null         // No sort order is needed.
+        );
+
+        // Gets the View ID for the EditText box
         mText = (EditText) this.findViewById(R.id.title);
-        mText.setOnClickListener(this);
-        
-        Button b = (Button) findViewById(R.id.ok);
-        b.setOnClickListener(this);
     }
 
+    /**
+     * This method is called when the Activity is about to come to the foreground. This happens
+     * when the Activity comes to the top of the task stack, OR when it is first starting.
+     *
+     * Displays the current title for the selected note.
+     */
     @Override
     protected void onResume() {
         super.onResume();
 
-        // Initialize the text with the title column from the cursor
+        // Verifies that the query made in onCreate() actually worked. If it worked, then the
+        // Cursor object is not null. If it is *empty*, then mCursor.getCount() == 0.
         if (mCursor != null) {
+
+            // The Cursor was just retrieved, so its index is set to one record *before* the first
+            // record retrieved. This moves it to the first record.
             mCursor.moveToFirst();
+
+            // Displays the current title text in the EditText object.
             mText.setText(mCursor.getString(COLUMN_INDEX_TITLE));
         }
     }
 
+    /**
+     * This method is called when the Activity loses focus.
+     *
+     * For Activity objects that edit information, onPause() may be the one place where changes are
+     * saved. The Android application model is predicated on the idea that "save" and "exit" aren't
+     * required actions. When users navigate away from an Activity, they shouldn't have to go back
+     * to it to complete their work. The act of going away should save everything and leave the
+     * Activity in a state where Android can destroy it if necessary.
+     *
+     * Updates the note with the text currently in the text box.
+     */
     @Override
     protected void onPause() {
         super.onPause();
 
+        // Verifies that the query made in onCreate() actually worked. If it worked, then the
+        // Cursor object is not null. If it is *empty*, then mCursor.getCount() == 0.
+
         if (mCursor != null) {
-            // Write the title back to the note 
+
+            // Creates a values map for updating the provider.
             ContentValues values = new ContentValues();
-            values.put(NoteColumns.TITLE, mText.getText().toString());
-            getContentResolver().update(mUri, values, null, null);
+
+            // In the values map, sets the title to the current contents of the edit box.
+            values.put(NotePad.Notes.COLUMN_NAME_TITLE, mText.getText().toString());
+
+            /*
+             * Updates the provider with the note's new title.
+             *
+             * Note: This is being done on the UI thread. It will block the thread until the
+             * update completes. In a sample app, going against a simple provider based on a
+             * local database, the block will be momentary, but in a real app you should use
+             * android.content.AsyncQueryHandler or android.os.AsyncTask.
+             */
+            getContentResolver().update(
+                mUri,    // The URI for the note to update.
+                values,  // The values map containing the columns to update and the values to use.
+                null,    // No selection criteria is used, so no "where" columns are needed.
+                null     // No "where" columns are used, so no "where" values are needed.
+            );
+
         }
     }
 
-    public void onClick(View v) {
-        // When the user clicks, just finish this activity.
-        // onPause will be called, and we save our data there.
+    public void onClickOk(View v) {
         finish();
     }
 }
diff --git a/samples/NotePad/tests/Android.mk b/samples/NotePad/tests/Android.mk
deleted file mode 100644
index 43efafc..0000000
--- a/samples/NotePad/tests/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := NotePadTests
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_INSTRUMENTATION_FOR := NotePad
-
-include $(BUILD_PACKAGE)
diff --git a/samples/NotePad/tests/AndroidManifest.xml b/samples/NotePad/tests/AndroidManifest.xml
index afd502b..b6b6101 100644
--- a/samples/NotePad/tests/AndroidManifest.xml
+++ b/samples/NotePad/tests/AndroidManifest.xml
@@ -1,32 +1,49 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
+<!--
+    Copyright (C) 2007 The Android Open Source Project
 
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
+    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.
 -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
-      package="com.example.android.notepad.tests">
-    
-    <!-- We add an application tag here just so that we can indicate that
-         this package needs to link against the android.test library,
-         which is needed when building test cases. -->    
+<!--
+    To run this test package, install it and the NotesList application to a device or emulator and
+    then run
+    adb shell am instrument -w com.example.android.notepad.tests/android.test.InstrumentationTestRunner
+-->
+<!--
+    The Android package name differs from the package ID of the code. The code package ID
+    'com.example.android.notepad' allows the test code to use declarations from the application
+    under test, while the Android package name identifies this as a separate test package.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.notepad.tests"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <!--
+        The application element indicates that this package must be linked against the library
+        android.test.runner, which is not part of the normal link path. The library contains
+        code for test cases.
+    -->
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-
-  <instrumentation android:name="android.test.InstrumentationTestRunner"
-      android:targetPackage="com.example.android.notepad"
-      android:label="NotePad sample tests">
-  </instrumentation>  
-  
+    <!--
+        The instrumentation element tells Android to use instrumentation to run this package.
+        The target Android package 'com.example.android.notepad' is loaded along with the
+        test package 'com.example.android.notepad.tests'. Android then starts the class
+        'android.test.InstrumentationTestRunner', which loads the test case classes in the package.
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.example.android.notepad"
+                     android:label="Tests for com.example.android.notepad"/>
+    <uses-sdk android:minSdkVersion="10"></uses-sdk>
 </manifest>
diff --git a/samples/NotePad/tests/build.properties b/samples/NotePad/tests/build.properties
deleted file mode 100644
index e0c39de..0000000
--- a/samples/NotePad/tests/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-tested.project.dir=..
diff --git a/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
new file mode 100644
index 0000000..6a66ebb
--- /dev/null
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.example.android.notepad;
+
+import android.test.ActivityInstrumentationTestCase2;
+import com.example.android.notepad.NotesList;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link #testActivityTestCaseSetUpProperly}.
+ */
+public class NotePadActivityTest extends ActivityInstrumentationTestCase2<NotesList> {
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2} for the {@link NotesList} activity.
+     */
+    public NotePadActivityTest() {
+        super(NotesList.class);
+    }
+
+    /**
+     * Verifies that the activity under test can be launched.
+     */
+    public void testActivityTestCaseSetUpProperly() {
+        assertNotNull("activity should be launched successfully", getActivity());
+    }
+}
diff --git a/samples/NotePad/tests/src/com/example/android/notepad/NotePadProviderTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadProviderTest.java
new file mode 100644
index 0000000..cd48347
--- /dev/null
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadProviderTest.java
@@ -0,0 +1,839 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.notepad;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.test.ProviderTestCase2;
+import android.test.mock.MockContentResolver;
+
+import java.io.BufferedReader;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/*
+ */
+/**
+ * This class tests the content provider for the Note Pad sample application.
+ *
+ * To learn how to run an entire test package or one of its classes, please see
+ * "Testing in Eclipse, with ADT" or "Testing in Other IDEs" in the Developer Guide.
+ */
+public class NotePadProviderTest extends ProviderTestCase2<NotePadProvider> {
+
+    // A URI that the provider does not offer, for testing error handling.
+    private static final Uri INVALID_URI =
+        Uri.withAppendedPath(NotePad.Notes.CONTENT_URI, "invalid");
+
+    // Contains a reference to the mocked content resolver for the provider under test.
+    private MockContentResolver mMockResolver;
+
+    // Contains an SQLite database, used as test data
+    private SQLiteDatabase mDb;
+
+    // Contains the test data, as an array of NoteInfo instances.
+    private final NoteInfo[] TEST_NOTES = {
+        new NoteInfo("Note0", "This is note 0"),
+        new NoteInfo("Note1", "This is note 1"),
+        new NoteInfo("Note2", "This is note 2"),
+        new NoteInfo("Note3", "This is note 3"),
+        new NoteInfo("Note4", "This is note 4"),
+        new NoteInfo("Note5", "This is note 5"),
+        new NoteInfo("Note6", "This is note 6"),
+        new NoteInfo("Note7", "This is note 7"),
+        new NoteInfo("Note8", "This is note 8"),
+        new NoteInfo("Note9", "This is note 9") };
+
+    // Number of milliseconds in one day (milliseconds * seconds * minutes * hours)
+    private static final long ONE_DAY_MILLIS = 1000 * 60 * 60 * 24;
+
+    // Number of milliseconds in one week
+    private static final long ONE_WEEK_MILLIS = ONE_DAY_MILLIS * 7;
+
+    // Creates a calendar object equal to January 1, 2010 at 12 midnight
+    private static final GregorianCalendar TEST_CALENDAR =
+        new GregorianCalendar(2010, Calendar.JANUARY, 1, 0, 0, 0);
+
+    // Stores a timestamp value, set to an arbitrary starting point
+    private final static long START_DATE = TEST_CALENDAR.getTimeInMillis();
+
+    // Sets a MIME type filter, used to test provider methods that return more than one MIME type
+    // for a particular note. The filter will retrieve any MIME types supported for the content URI.
+    private final static String MIME_TYPES_ALL = "*/*";
+
+    // Sets a MIME type filter, used to test provider methods that return more than one MIME type
+    // for a particular note. The filter is nonsense, so it will not retrieve any MIME types.
+    private final static String MIME_TYPES_NONE = "qwer/qwer";
+
+    // Sets a MIME type filter for plain text, used to the provider's methods that only handle
+    // plain text
+    private final static String MIME_TYPE_TEXT = "text/plain";
+
+    /*
+     * Constructor for the test case class.
+     * Calls the super constructor with the class name of the provider under test and the
+     * authority name of the provider.
+     */
+    public NotePadProviderTest() {
+        super(NotePadProvider.class, NotePad.AUTHORITY);
+    }
+
+    /*
+     * Sets up the test environment before each test method. Creates a mock content resolver,
+     * gets the provider under test, and creates a new database for the provider.
+     */
+    @Override
+    protected void setUp() throws Exception {
+        // Calls the base class implementation of this method.
+        super.setUp();
+
+        // Gets the resolver for this test.
+        mMockResolver = getMockContentResolver();
+
+        /*
+         * Gets a handle to the database underlying the provider. Gets the provider instance
+         * created in super.setUp(), gets the DatabaseOpenHelper for the provider, and gets
+         * a database object from the helper.
+         */
+        mDb = getProvider().getOpenHelperForTest().getWritableDatabase();
+    }
+
+    /*
+     *  This method is called after each test method, to clean up the current fixture. Since
+     *  this sample test case runs in an isolated context, no cleanup is necessary.
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /*
+     * Sets up test data.
+     * The test data is in an SQL database. It is created in setUp() without any data,
+     * and populated in insertData if necessary.
+     */
+    private void insertData() {
+        // Creates an instance of the ContentValues map type expected by database insertions
+        ContentValues values = new ContentValues();
+
+        // Sets up test data
+        for (int index = 0; index < TEST_NOTES.length; index++) {
+
+            // Set the creation and modification date for the note
+            TEST_NOTES[index].setCreationDate(START_DATE + (index * ONE_DAY_MILLIS));
+            TEST_NOTES[index].setModificationDate(START_DATE + (index * ONE_WEEK_MILLIS));
+
+            // Adds a record to the database.
+            mDb.insertOrThrow(
+                NotePad.Notes.TABLE_NAME,             // the table name for the insert
+                NotePad.Notes.COLUMN_NAME_TITLE,      // column set to null if empty values map
+                TEST_NOTES[index].getContentValues()  // the values map to insert
+            );
+        }
+    }
+
+    /*
+     * Tests the provider's publicly available URIs. If the URI is not one that the provider
+     * understands, the provider should throw an exception. It also tests the provider's getType()
+     * method for each URI, which should return the MIME type associated with the URI.
+     */
+    public void testUriAndGetType() {
+        // Tests the MIME type for the notes table URI.
+        String mimeType = mMockResolver.getType(NotePad.Notes.CONTENT_URI);
+        assertEquals(NotePad.Notes.CONTENT_TYPE, mimeType);
+
+        // Tests the MIME type for the live folder URI.
+        mimeType = mMockResolver.getType(NotePad.Notes.LIVE_FOLDER_URI);
+        assertEquals(NotePad.Notes.CONTENT_TYPE, mimeType);
+
+        // Creates a URI with a pattern for note ids. The id doesn't have to exist.
+        Uri noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
+
+        // Gets the note ID URI MIME type.
+        mimeType = mMockResolver.getType(noteIdUri);
+        assertEquals(NotePad.Notes.CONTENT_ITEM_TYPE, mimeType);
+
+        // Tests an invalid URI. This should throw an IllegalArgumentException.
+        mimeType = mMockResolver.getType(INVALID_URI);
+    }
+
+    /*
+     * Tests the provider's stream MIME types returned by getStreamTypes(). If the provider supports
+     * stream data for the URI, the MIME type is returned. Otherwise, the provider returns null.
+     */
+    public void testGetStreamTypes() {
+
+        // Tests the notes table URI. This should return null, since the content provider does
+        // not provide a stream MIME type for multiple notes.
+        assertNull(mMockResolver.getStreamTypes(NotePad.Notes.CONTENT_URI, MIME_TYPES_ALL));
+
+        // Tests the live folders URI. This should return null, since the content provider does not
+        // provide a stream MIME type for multiple notes.
+        assertNull(mMockResolver.getStreamTypes(NotePad.Notes.LIVE_FOLDER_URI, MIME_TYPES_ALL));
+
+        /*
+         * Tests the note id URI for a single note, using _ID value "1" which is a valid ID. Uses a
+         * valid MIME type filter that will return all the supported MIME types for a content URI.
+         * The result should be "text/plain".
+         */
+
+        // Constructs the note id URI
+        Uri testUri = Uri.withAppendedPath(NotePad.Notes.CONTENT_ID_URI_BASE, "1");
+
+        // Gets the MIME types for the URI, with the filter that selects all MIME types.
+        String mimeType[] = mMockResolver.getStreamTypes(testUri, MIME_TYPES_ALL);
+
+        // Tests that the result is not null and is equal to the expected value. Also tests that
+        // only one MIME type is returned.
+        assertNotNull(mimeType);
+        assertEquals(mimeType[0],"text/plain");
+        assertEquals(mimeType.length,1);
+
+        /*
+         * Tests with the same URI but with a filter that should not return any URIs.
+         */
+        mimeType = mMockResolver.getStreamTypes(testUri, MIME_TYPES_NONE);
+        assertNull(mimeType);
+
+        /*
+         * Tests with a URI that should not have any associated stream MIME types, but with a
+         * filter that returns all types. The result should still be null.
+         */
+        mimeType = mMockResolver.getStreamTypes(NotePad.Notes.CONTENT_URI, MIME_TYPES_ALL);
+        assertNull(mimeType);
+
+    }
+
+    /*
+     * Tests the provider's public API for opening a read-only pipe of data for a note ID URI
+     * and MIME type filter matching "text/plain".
+     * This method throws a FileNotFoundException if the URI isn't for a note ID or the MIME type
+     * filter isn't "text/plain". It throws an IOException if it can't close a file descriptor.
+     */
+    public void testOpenTypedAssetFile() throws FileNotFoundException, IOException {
+
+        // A URI to contain a note ID content URI.
+        Uri testNoteIdUri;
+
+        // A handle for the file descriptor returned by openTypedAssetFile().
+        AssetFileDescriptor testAssetDescriptor;
+
+        // Inserts data into the provider, so that the note ID URI will be recognized.
+        insertData();
+
+        // Constructs a URI with a note ID of 1. This matches the note ID URI pattern that
+        // openTypedAssetFile can handle.
+        testNoteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
+
+        // Opens the pipe. The opts argument is for passing options from a caller to the provider,
+        // but the NotePadProvider does not use it.
+        testAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
+                testNoteIdUri,         // the URI for a single note. The pipe points to this
+                                       // note's data
+                MIME_TYPE_TEXT,        // a MIME type of "text/plain"
+                null                   // the "opts" argument
+        );
+
+        // Gets the parcel file handle from the asset file handle.
+        ParcelFileDescriptor testParcelDescriptor = testAssetDescriptor.getParcelFileDescriptor();
+
+        // Gets the file handle from the asset file handle.
+        FileDescriptor testDescriptor = testAssetDescriptor.getFileDescriptor();
+
+        // Tests that the asset file handle is not null.
+        assertNotNull(testAssetDescriptor);
+
+        // Tests that the parcel file handle is not null.
+        assertNotNull(testParcelDescriptor);
+
+        // Tests that the file handle is not null.
+        assertNotNull(testDescriptor);
+
+        // Tests that the file handle is valid.
+        assertTrue(testDescriptor.valid());
+
+        // Closes the file handles.
+        testParcelDescriptor.close();
+        testAssetDescriptor.close();
+
+        /*
+         * Changes the URI to a notes URI for multiple notes, and re-test. This should fail, since
+         * the provider does not support this type of URI. A FileNotFound exception is expected,
+         * so call fail() if it does *not* occur.
+         */
+        try {
+            testAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
+                    NotePad.Notes.CONTENT_URI,
+                    MIME_TYPE_TEXT,
+                    null
+            );
+            fail();
+        } catch (FileNotFoundException e) {
+            // continue
+        }
+
+        /*
+         * Changes back to the note ID URI, but changes the MIME type filter to one that is not
+         * supported by the provider. This should also fail, since the provider will only open a
+         * pipe for MIME type "text/plain". A FileNotFound exception is expected, so calls
+         * fail() if it does *not* occur.
+         */
+
+        try {
+            testAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
+                    testNoteIdUri,
+                    MIME_TYPES_NONE,
+                    null
+            );
+            fail();
+        } catch (FileNotFoundException e) {
+            // continue
+        }
+
+    }
+
+    /*
+     * Tests the provider's method for actually returning writing data into a pipe. The method is
+     * writeDataToPipe, but this method is not called directly. Instead, a caller invokes
+     * openTypedAssetFile(). That method uses ContentProvider.openPipeHelper(), which has as one of
+     * its arguments a ContentProvider.PipeDataWriter object that must actually put the data into
+     * the pipe. PipeDataWriter is an interface, not a class, so it must be implemented.
+     *
+     * The NotePadProvider class itself implements the "ContentProvider.PipeDataWriter, which means
+     * that it supplies the interface's only method, writeDataToPipe(). In effect, a call to
+     * openTypedAssetFile() calls writeDataToPipe().
+     *
+     *  The test of writeDataToPipe() is separate from other tests of openTypedAssetFile() for the
+     *  sake of clarity.
+     */
+    public void testWriteDataToPipe() throws FileNotFoundException {
+
+        // A string array to hold the incoming data
+        String[] inputData = {"","",""};
+
+        // A URI for a note ID.
+        Uri noteIdUri;
+
+        // A Cursor to contain the retrieved note.
+        Cursor noteIdCursor;
+
+        // An AssetFileDescriptor for the pipe.
+        AssetFileDescriptor noteIdAssetDescriptor;
+
+        // The ParcelFileDescriptor in the AssetFileDescriptor
+        ParcelFileDescriptor noteIdParcelDescriptor;
+
+        // Inserts test data into the provider.
+        insertData();
+
+        // Creates note ID URI for a note that should now be in the provider.
+        noteIdUri = ContentUris.withAppendedId(
+                NotePad.Notes.CONTENT_ID_URI_BASE,  // The base pattern for a note ID URI
+                1                                   // Sets the URI to point to record ID 1 in the
+                                                    // provider
+        );
+
+        // Gets a Cursor for the note.
+        noteIdCursor = mMockResolver.query(
+                noteIdUri,  // the URI for the note ID we want to retrieve
+                null,       // no projection, retrieve all the columns
+                null,       // no WHERE clause
+                null,       // no WHERE arguments
+                null        // default sort order
+        );
+
+        // Checks that the call worked.
+        // a) Checks that the cursor is not null
+        // b) Checks that it contains a single record
+        assertNotNull(noteIdCursor);
+        assertEquals(1,noteIdCursor.getCount());
+
+        // Opens the pipe that will contain the data.
+        noteIdAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
+                noteIdUri,        // the URI of the note that will provide the data
+                MIME_TYPE_TEXT,   // the "text/plain" MIME type
+                null              // no other options
+        );
+
+        // Checks that the call worked.
+        // a) checks that the AssetFileDescriptor is not null
+        // b) gets its ParcelFileDescriptor
+        // c) checks that the ParcelFileDescriptor is not null
+        assertNotNull(noteIdAssetDescriptor);
+        noteIdParcelDescriptor = noteIdAssetDescriptor.getParcelFileDescriptor();
+        assertNotNull(noteIdParcelDescriptor);
+
+        // Gets a File Reader that can read the pipe.
+        FileReader fIn = new FileReader(noteIdParcelDescriptor.getFileDescriptor());
+
+        // Gets a buffered reader wrapper for the File Reader. This allows reading line by line.
+        BufferedReader bIn = new BufferedReader(fIn);
+
+        /*
+         * The pipe should contain three lines: The note's title, an empty line, and the note's
+         * contents. The following code reads and stores these three lines.
+         */
+        for (int index = 0; index < inputData.length; index++) {
+            try {
+                inputData[index] = bIn.readLine();
+            } catch (IOException e) {
+
+                e.printStackTrace();
+                fail();
+            }
+        }
+
+        // Asserts that the first record in the provider (written from TEST_NOTES[0]) has the same
+        // note title as the first line retrieved from the pipe.
+        assertEquals(TEST_NOTES[0].title, inputData[0]);
+
+        // Asserts that the first record in the provider (written from TEST_NOTES[0]) has the same
+        // note contents as the third line retrieved from the pipe.
+        assertEquals(TEST_NOTES[0].note, inputData[2]);
+    }
+
+    /*
+     * Tests the provider's public API for querying data in the table, using the URI for
+     * a dataset of records.
+     */
+    public void testQueriesOnNotesUri() {
+        // Defines a projection of column names to return for a query
+        final String[] TEST_PROJECTION = {
+            NotePad.Notes.COLUMN_NAME_TITLE,
+            NotePad.Notes.COLUMN_NAME_NOTE,
+            NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE
+        };
+
+        // Defines a selection column for the query. When the selection columns are passed
+        // to the query, the selection arguments replace the placeholders.
+        final String TITLE_SELECTION = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
+
+        // Defines the selection columns for a query.
+        final String SELECTION_COLUMNS =
+            TITLE_SELECTION + " OR " + TITLE_SELECTION + " OR " + TITLE_SELECTION;
+
+         // Defines the arguments for the selection columns.
+        final String[] SELECTION_ARGS = { "Note0", "Note1", "Note5" };
+
+         // Defines a query sort order
+        final String SORT_ORDER = NotePad.Notes.COLUMN_NAME_TITLE + " ASC";
+
+        // Query subtest 1.
+        // If there are no records in the table, the returned cursor from a query should be empty.
+        Cursor cursor = mMockResolver.query(
+            NotePad.Notes.CONTENT_URI,  // the URI for the main data table
+            null,                       // no projection, get all columns
+            null,                       // no selection criteria, get all records
+            null,                       // no selection arguments
+            null                        // use default sort order
+        );
+
+         // Asserts that the returned cursor contains no records
+        assertEquals(0, cursor.getCount());
+
+         // Query subtest 2.
+         // If the table contains records, the returned cursor from a query should contain records.
+
+        // Inserts the test data into the provider's underlying data source
+        insertData();
+
+        // Gets all the columns for all the rows in the table
+        cursor = mMockResolver.query(
+            NotePad.Notes.CONTENT_URI,  // the URI for the main data table
+            null,                       // no projection, get all columns
+            null,                       // no selection criteria, get all records
+            null,                       // no selection arguments
+            null                        // use default sort order
+        );
+
+        // Asserts that the returned cursor contains the same number of rows as the size of the
+        // test data array.
+        assertEquals(TEST_NOTES.length, cursor.getCount());
+
+        // Query subtest 3.
+        // A query that uses a projection should return a cursor with the same number of columns
+        // as the projection, with the same names, in the same order.
+        Cursor projectionCursor = mMockResolver.query(
+              NotePad.Notes.CONTENT_URI,  // the URI for the main data table
+              TEST_PROJECTION,            // get the title, note, and mod date columns
+              null,                       // no selection columns, get all the records
+              null,                       // no selection criteria
+              null                        // use default the sort order
+        );
+
+        // Asserts that the number of columns in the cursor is the same as in the projection
+        assertEquals(TEST_PROJECTION.length, projectionCursor.getColumnCount());
+
+        // Asserts that the names of the columns in the cursor and in the projection are the same.
+        // This also verifies that the names are in the same order.
+        assertEquals(TEST_PROJECTION[0], projectionCursor.getColumnName(0));
+        assertEquals(TEST_PROJECTION[1], projectionCursor.getColumnName(1));
+        assertEquals(TEST_PROJECTION[2], projectionCursor.getColumnName(2));
+
+        // Query subtest 4
+        // A query that uses selection criteria should return only those rows that match the
+        // criteria. Use a projection so that it's easy to get the data in a particular column.
+        projectionCursor = mMockResolver.query(
+            NotePad.Notes.CONTENT_URI, // the URI for the main data table
+            TEST_PROJECTION,           // get the title, note, and mod date columns
+            SELECTION_COLUMNS,         // select on the title column
+            SELECTION_ARGS,            // select titles "Note0", "Note1", or "Note5"
+            SORT_ORDER                 // sort ascending on the title column
+        );
+
+        // Asserts that the cursor has the same number of rows as the number of selection arguments
+        assertEquals(SELECTION_ARGS.length, projectionCursor.getCount());
+
+        int index = 0;
+
+        while (projectionCursor.moveToNext()) {
+
+            // Asserts that the selection argument at the current index matches the value of
+            // the title column (column 0) in the current record of the cursor
+            assertEquals(SELECTION_ARGS[index], projectionCursor.getString(0));
+
+            index++;
+        }
+
+        // Asserts that the index pointer is now the same as the number of selection arguments, so
+        // that the number of arguments tested is exactly the same as the number of rows returned.
+        assertEquals(SELECTION_ARGS.length, index);
+
+    }
+
+    /*
+     * Tests queries against the provider, using the note id URI. This URI encodes a single
+     * record ID. The provider should only return 0 or 1 record.
+     */
+    public void testQueriesOnNoteIdUri() {
+      // Defines the selection column for a query. The "?" is replaced by entries in the
+      // selection argument array
+      final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
+
+      // Defines the argument for the selection column.
+      final String[] SELECTION_ARGS = { "Note1" };
+
+      // A sort order for the query.
+      final String SORT_ORDER = NotePad.Notes.COLUMN_NAME_TITLE + " ASC";
+
+      // Creates a projection includes the note id column, so that note id can be retrieved.
+      final String[] NOTE_ID_PROJECTION = {
+           NotePad.Notes._ID,                 // The Notes class extends BaseColumns,
+                                              // which includes _ID as the column name for the
+                                              // record's id in the data model
+           NotePad.Notes.COLUMN_NAME_TITLE};  // The note's title
+
+      // Query subtest 1.
+      // Tests that a query against an empty table returns null.
+
+      // Constructs a URI that matches the provider's notes id URI pattern, using an arbitrary
+      // value of 1 as the note ID.
+      Uri noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
+
+      // Queries the table with the notes ID URI. This should return an empty cursor.
+      Cursor cursor = mMockResolver.query(
+          noteIdUri, // URI pointing to a single record
+          null,      // no projection, get all the columns for each record
+          null,      // no selection criteria, get all the records in the table
+          null,      // no need for selection arguments
+          null       // default sort, by ascending title
+      );
+
+      // Asserts that the cursor is null.
+      assertEquals(0,cursor.getCount());
+
+      // Query subtest 2.
+      // Tests that a query against a table containing records returns a single record whose ID
+      // is the one requested in the URI provided.
+
+      // Inserts the test data into the provider's underlying data source.
+      insertData();
+
+      // Queries the table using the URI for the full table.
+      cursor = mMockResolver.query(
+          NotePad.Notes.CONTENT_URI, // the base URI for the table
+          NOTE_ID_PROJECTION,        // returns the ID and title columns of rows
+          SELECTION_COLUMNS,         // select based on the title column
+          SELECTION_ARGS,            // select title of "Note1"
+          SORT_ORDER                 // sort order returned is by title, ascending
+      );
+
+      // Asserts that the cursor contains only one row.
+      assertEquals(1, cursor.getCount());
+
+      // Moves to the cursor's first row, and asserts that this did not fail.
+      assertTrue(cursor.moveToFirst());
+
+      // Saves the record's note ID.
+      int inputNoteId = cursor.getInt(0);
+
+      // Builds a URI based on the provider's content ID URI base and the saved note ID.
+      noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, inputNoteId);
+
+      // Queries the table using the content ID URI, which returns a single record with the
+      // specified note ID, matching the selection criteria provided.
+      cursor = mMockResolver.query(noteIdUri, // the URI for a single note
+          NOTE_ID_PROJECTION,                 // same projection, get ID and title columns
+          SELECTION_COLUMNS,                  // same selection, based on title column
+          SELECTION_ARGS,                     // same selection arguments, title = "Note1"
+          SORT_ORDER                          // same sort order returned, by title, ascending
+      );
+
+      // Asserts that the cursor contains only one row.
+      assertEquals(1, cursor.getCount());
+
+      // Moves to the cursor's first row, and asserts that this did not fail.
+      assertTrue(cursor.moveToFirst());
+
+      // Asserts that the note ID passed to the provider is the same as the note ID returned.
+      assertEquals(inputNoteId, cursor.getInt(0));
+    }
+
+    /*
+     *  Tests inserts into the data model.
+     */
+    public void testInserts() {
+        // Creates a new note instance with ID of 30.
+        NoteInfo note = new NoteInfo(
+            "Note30", // the note's title
+            "Test inserting a note" // the note's content
+        );
+
+        // Sets the note's creation and modification times
+        note.setCreationDate(START_DATE + (10 * ONE_DAY_MILLIS));
+        note.setModificationDate(START_DATE + (2 * ONE_WEEK_MILLIS));
+
+        // Insert subtest 1.
+        // Inserts a row using the new note instance.
+        // No assertion will be done. The insert() method either works or throws an Exception
+        Uri rowUri = mMockResolver.insert(
+            NotePad.Notes.CONTENT_URI,  // the main table URI
+            note.getContentValues()     // the map of values to insert as a new record
+        );
+
+        // Parses the returned URI to get the note ID of the new note. The ID is used in subtest 2.
+        long noteId = ContentUris.parseId(rowUri);
+
+        // Does a full query on the table. Since insertData() hasn't yet been called, the
+        // table should only contain the record just inserted.
+        Cursor cursor = mMockResolver.query(
+            NotePad.Notes.CONTENT_URI, // the main table URI
+            null,                      // no projection, return all the columns
+            null,                      // no selection criteria, return all the rows in the model
+            null,                      // no selection arguments
+            null                       // default sort order
+        );
+
+        // Asserts that there should be only 1 record.
+        assertEquals(1, cursor.getCount());
+
+        // Moves to the first (and only) record in the cursor and asserts that this worked.
+        assertTrue(cursor.moveToFirst());
+
+        // Since no projection was used, get the column indexes of the returned columns
+        int titleIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE);
+        int noteIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);
+        int crdateIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_CREATE_DATE);
+        int moddateIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE);
+
+        // Tests each column in the returned cursor against the data that was inserted, comparing
+        // the field in the NoteInfo object to the data at the column index in the cursor.
+        assertEquals(note.title, cursor.getString(titleIndex));
+        assertEquals(note.note, cursor.getString(noteIndex));
+        assertEquals(note.createDate, cursor.getLong(crdateIndex));
+        assertEquals(note.modDate, cursor.getLong(moddateIndex));
+
+        // Insert subtest 2.
+        // Tests that we can't insert a record whose id value already exists.
+
+        // Defines a ContentValues object so that the test can add a note ID to it.
+        ContentValues values = note.getContentValues();
+
+        // Adds the note ID retrieved in subtest 1 to the ContentValues object.
+        values.put(NotePad.Notes._ID, (int) noteId);
+
+        // Tries to insert this record into the table. This should fail and drop into the
+        // catch block. If it succeeds, issue a failure message.
+        try {
+            rowUri = mMockResolver.insert(NotePad.Notes.CONTENT_URI, values);
+            fail("Expected insert failure for existing record but insert succeeded.");
+        } catch (Exception e) {
+          // succeeded, so do nothing.
+        }
+    }
+
+    /*
+     * Tests deletions from the data model.
+     */
+    public void testDeletes() {
+        // Subtest 1.
+        // Tries to delete a record from a data model that is empty.
+
+        // Sets the selection column to "title"
+        final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
+
+        // Sets the selection argument "Note0"
+        final String[] SELECTION_ARGS = { "Note0" };
+
+        // Tries to delete rows matching the selection criteria from the data model.
+        int rowsDeleted = mMockResolver.delete(
+            NotePad.Notes.CONTENT_URI, // the base URI of the table
+            SELECTION_COLUMNS,         // select based on the title column
+            SELECTION_ARGS             // select title = "Note0"
+        );
+
+        // Assert that the deletion did not work. The number of deleted rows should be zero.
+        assertEquals(0, rowsDeleted);
+
+        // Subtest 2.
+        // Tries to delete an existing record. Repeats the previous subtest, but inserts data first.
+
+        // Inserts data into the model.
+        insertData();
+
+        // Uses the same parameters to try to delete the row with title "Note0"
+        rowsDeleted = mMockResolver.delete(
+            NotePad.Notes.CONTENT_URI, // the base URI of the table
+            SELECTION_COLUMNS,         // same selection column, "title"
+            SELECTION_ARGS             // same selection arguments, title = "Note0"
+        );
+
+        // The number of deleted rows should be 1.
+        assertEquals(1, rowsDeleted);
+
+        // Tests that the record no longer exists. Tries to get it from the table, and
+        // asserts that nothing was returned.
+
+        // Queries the table with the same selection column and argument used to delete the row.
+        Cursor cursor = mMockResolver.query(
+            NotePad.Notes.CONTENT_URI, // the base URI of the table
+            null,                      // no projection, return all columns
+            SELECTION_COLUMNS,         // select based on the title column
+            SELECTION_ARGS,            // select title = "Note0"
+            null                       // use the default sort order
+        );
+
+        // Asserts that the cursor is empty since the record had already been deleted.
+        assertEquals(0, cursor.getCount());
+    }
+
+    /*
+     * Tests updates to the data model.
+     */
+    public void testUpdates() {
+        // Selection column for identifying a record in the data model.
+        final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
+
+        // Selection argument for the selection column.
+        final String[] selectionArgs = { "Note1" };
+
+        // Defines a map of column names and values
+        ContentValues values = new ContentValues();
+
+        // Subtest 1.
+        // Tries to update a record in an empty table.
+
+        // Sets up the update by putting the "note" column and a value into the values map.
+        values.put(NotePad.Notes.COLUMN_NAME_NOTE, "Testing an update with this string");
+
+        // Tries to update the table
+        int rowsUpdated = mMockResolver.update(
+            NotePad.Notes.CONTENT_URI,  // the URI of the data table
+            values,                     // a map of the updates to do (column title and value)
+            SELECTION_COLUMNS,           // select based on the title column
+            selectionArgs               // select "title = Note1"
+        );
+
+        // Asserts that no rows were updated.
+        assertEquals(0, rowsUpdated);
+
+        // Subtest 2.
+        // Builds the table, and then tries the update again using the same arguments.
+
+        // Inserts data into the model.
+        insertData();
+
+        //  Does the update again, using the same arguments as in subtest 1.
+        rowsUpdated = mMockResolver.update(
+            NotePad.Notes.CONTENT_URI,   // The URI of the data table
+            values,                      // the same map of updates
+            SELECTION_COLUMNS,            // same selection, based on the title column
+            selectionArgs                // same selection argument, to select "title = Note1"
+        );
+
+        // Asserts that only one row was updated. The selection criteria evaluated to
+        // "title = Note1", and the test data should only contain one row that matches that.
+        assertEquals(1, rowsUpdated);
+
+    }
+
+    // A utility for converting note data to a ContentValues map.
+    private static class NoteInfo {
+        String title;
+        String note;
+        long createDate;
+        long modDate;
+
+        /*
+         * Constructor for a NoteInfo instance. This class helps create a note and
+         * return its values in a ContentValues map expected by data model methods.
+         * The note's id is created automatically when it is inserted into the data model.
+         */
+        public NoteInfo(String t, String n) {
+            title = t;
+            note = n;
+            createDate = 0;
+            modDate = 0;
+        }
+
+        // Sets the creation date for a test note
+        public void setCreationDate(long c) {
+            createDate = c;
+        }
+
+        // Sets the modification date for a test note
+        public void setModificationDate(long m) {
+            modDate = m;
+        }
+
+        /*
+         * Returns a ContentValues instance (a map) for this NoteInfo instance. This is useful for
+         * inserting a NoteInfo into a database.
+         */
+        public ContentValues getContentValues() {
+            // Gets a new ContentValues object
+            ContentValues v = new ContentValues();
+
+            // Adds map entries for the user-controlled fields in the map
+            v.put(NotePad.Notes.COLUMN_NAME_TITLE, title);
+            v.put(NotePad.Notes.COLUMN_NAME_NOTE, note);
+            v.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, createDate);
+            v.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, modDate);
+            return v;
+
+        }
+    }
+}
diff --git a/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
deleted file mode 100644
index 80f71d2..0000000
--- a/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.example.android.notepad;
-
-import android.test.ActivityInstrumentationTestCase2;
-
-import com.example.android.notepad.NotesList;
-
-/**
- * Make sure that the main launcher activity opens up properly, which will be
- * verified by {@link #testActivityTestCaseSetUpProperly}.
- */
-public class NotePadTest extends ActivityInstrumentationTestCase2<NotesList> {
-
-    /**
-     * Creates an {@link ActivityInstrumentationTestCase2} for the {@link NotesList} activity.
-     */
-    public NotePadTest() {
-        super(NotesList.class);
-    }
-
-    /**
-     * Verifies that the activity under test can be launched.
-     */
-    public void testActivityTestCaseSetUpProperly() {
-        assertNotNull("activity should be launched successfully", getActivity());
-    }
-}
diff --git a/samples/RenderScript/Android.mk b/samples/RenderScript/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/samples/RenderScript/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/samples/RenderScript/Balls/Android.mk b/samples/RenderScript/Balls/Android.mk
new file mode 100644
index 0000000..3899752
--- /dev/null
+++ b/samples/RenderScript/Balls/Android.mk
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := RsBalls
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/samples/RenderScript/Balls/AndroidManifest.xml b/samples/RenderScript/Balls/AndroidManifest.xml
new file mode 100644
index 0000000..c0ae2ff
--- /dev/null
+++ b/samples/RenderScript/Balls/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.rs.balls">
+    <uses-sdk android:minSdkVersion="11" />
+    <application 
+        android:label="RsBalls"
+        android:icon="@drawable/test_pattern">
+        <activity android:name="Balls"
+                  android:screenOrientation="landscape">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/RenderScript/Balls/_index.html b/samples/RenderScript/Balls/_index.html
new file mode 100644
index 0000000..8760485
--- /dev/null
+++ b/samples/RenderScript/Balls/_index.html
@@ -0,0 +1 @@
+<p>A brute force physics simulation that renders many balls onto the screen and moves them according to user touch and gravity.</p>
\ No newline at end of file
diff --git a/samples/RenderScript/Balls/res/drawable/flares.png b/samples/RenderScript/Balls/res/drawable/flares.png
new file mode 100644
index 0000000..3a5c970
--- /dev/null
+++ b/samples/RenderScript/Balls/res/drawable/flares.png
Binary files differ
diff --git a/samples/RenderScript/Balls/res/drawable/test_pattern.png b/samples/RenderScript/Balls/res/drawable/test_pattern.png
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/samples/RenderScript/Balls/res/drawable/test_pattern.png
Binary files differ
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/Balls.java b/samples/RenderScript/Balls/src/com/example/android/rs/balls/Balls.java
new file mode 100644
index 0000000..d3b900a
--- /dev/null
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/Balls.java
@@ -0,0 +1,121 @@
+/*
+ * 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.example.android.rs.balls;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+
+public class Balls extends Activity implements SensorEventListener {
+    //EventListener mListener = new EventListener();
+
+    private static final String LOG_TAG = "libRS_jni";
+    private static final boolean DEBUG  = false;
+    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+    private BallsView mView;
+    private SensorManager mSensorManager;
+
+    // get the current looper (from your Activity UI thread for instance
+
+
+    public void onSensorChanged(SensorEvent event) {
+        //android.util.Log.d("rs", "sensor: " + event.sensor + ", x: " + event.values[0] + ", y: " + event.values[1] + ", z: " + event.values[2]);
+        synchronized (this) {
+            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+                if(mView != null) {
+                    mView.setAccel(event.values[0], event.values[1], event.values[2]);
+                }
+            }
+        }
+    }
+
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new BallsView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        mSensorManager.registerListener(this,
+                                        mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
+                                        SensorManager.SENSOR_DELAY_FASTEST);
+
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mView.pause();
+        Runtime.getRuntime().exit(0);
+    }
+
+    @Override
+    protected void onStop() {
+        mSensorManager.unregisterListener(this);
+        super.onStop();
+    }
+
+    static void log(String message) {
+        if (LOG_ENABLED) {
+            Log.v(LOG_TAG, message);
+        }
+    }
+
+
+}
+
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/BallsRS.java b/samples/RenderScript/Balls/src/com/example/android/rs/balls/BallsRS.java
new file mode 100644
index 0000000..8cab9b8
--- /dev/null
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/BallsRS.java
@@ -0,0 +1,143 @@
+/*
+ * 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.example.android.rs.balls;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+public class BallsRS {
+    public static final int PART_COUNT = 900;
+
+    public BallsRS() {
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+    private ScriptC_balls mScript;
+    private ScriptC_ball_physics mPhysicsScript;
+    private ProgramFragment mPFLines;
+    private ProgramFragment mPFPoints;
+    private ProgramVertex mPV;
+    private ScriptField_Point mPoints;
+    private ScriptField_VpConsts mVpConsts;
+
+    void updateProjectionMatrices() {
+        mVpConsts = new ScriptField_VpConsts(mRS, 1,
+                                             Allocation.USAGE_SCRIPT |
+                                             Allocation.USAGE_GRAPHICS_CONSTANTS);
+        ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
+        Matrix4f mvp = new Matrix4f();
+        mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1);
+        i.MVP = mvp;
+        mVpConsts.set(i, 0, true);
+    }
+
+    private void createProgramVertex() {
+        updateProjectionMatrices();
+
+        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
+        String t =  "varying vec4 varColor;\n" +
+                    "void main() {\n" +
+                    "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
+                    "  pos.xy = ATTRIB_position;\n" +
+                    "  gl_Position = UNI_MVP * pos;\n" +
+                    "  varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
+                    "  gl_PointSize = ATTRIB_size;\n" +
+                    "}\n";
+        sb.setShader(t);
+        sb.addConstant(mVpConsts.getType());
+        sb.addInput(mPoints.getElement());
+        ProgramVertex pvs = sb.create();
+        pvs.bindConstants(mVpConsts.getAllocation(), 0);
+        mRS.bindProgramVertex(pvs);
+    }
+
+    private Allocation loadTexture(int id) {
+        final Allocation allocation =
+            Allocation.createFromBitmapResource(mRS, mRes,
+                id, Allocation.MipmapControl.MIPMAP_NONE,
+                Allocation.USAGE_GRAPHICS_TEXTURE);
+        return allocation;
+    }
+
+    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
+        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+        builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
+        return builder.create();
+    }
+
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
+
+        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
+        pfb.setPointSpriteTexCoordinateReplacement(true);
+        pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
+                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+        pfb.setVaryingColor(true);
+        mPFPoints = pfb.create();
+
+        pfb = new ProgramFragmentFixedFunction.Builder(rs);
+        pfb.setVaryingColor(true);
+        mPFLines = pfb.create();
+
+        android.util.Log.e("rs", "Load texture");
+        mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
+
+        mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
+
+        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
+        smb.addVertexAllocation(mPoints.getAllocation());
+        smb.addIndexSetType(Mesh.Primitive.POINT);
+        Mesh smP = smb.create();
+
+        mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
+
+        mScript = new ScriptC_balls(mRS, mRes, R.raw.balls);
+        mScript.set_partMesh(smP);
+        mScript.set_physics_script(mPhysicsScript);
+        mScript.bind_point(mPoints);
+        mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
+        mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
+
+        mScript.set_gPFLines(mPFLines);
+        mScript.set_gPFPoints(mPFPoints);
+        createProgramVertex();
+
+        mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS));
+
+        mPhysicsScript.set_gMinPos(new Float2(5, 5));
+        mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
+
+        mScript.invoke_initParts(width, height);
+
+        mRS.bindRootScript(mScript);
+    }
+
+    public void newTouchPosition(float x, float y, float pressure, int id) {
+        mPhysicsScript.invoke_touch(x, y, pressure, id);
+    }
+
+    public void setAccel(float x, float y) {
+        mPhysicsScript.set_gGravityVector(new Float2(x, y));
+    }
+
+}
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/BallsView.java b/samples/RenderScript/Balls/src/com/example/android/rs/balls/BallsView.java
new file mode 100644
index 0000000..b3b3756
--- /dev/null
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/BallsView.java
@@ -0,0 +1,116 @@
+/*
+ * 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.example.android.rs.balls;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class BallsView extends RSSurfaceView {
+
+    public BallsView(Context context) {
+        super(context);
+        //setFocusable(true);
+    }
+
+    private RenderScriptGL mRS;
+    private BallsRS mRender;
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+        if (mRS == null) {
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            mRS = createRenderScriptGL(sc);
+            mRS.setSurface(holder, w, h);
+            mRender = new BallsRS();
+            mRender.init(mRS, getResources(), w, h);
+        }
+        mRender.updateProjectionMatrices();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        if(mRS != null) {
+            mRS = null;
+            destroyRenderScriptGL();
+        }
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev)
+    {
+        int act = ev.getActionMasked();
+        if (act == ev.ACTION_UP) {
+            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
+            return false;
+        } else if (act == MotionEvent.ACTION_POINTER_UP) {
+            // only one pointer going up, we can get the index like this
+            int pointerIndex = ev.getActionIndex();
+            int pointerId = ev.getPointerId(pointerIndex);
+            mRender.newTouchPosition(0, 0, 0, pointerId);
+            return false;
+        }
+        int count = ev.getHistorySize();
+        int pcount = ev.getPointerCount();
+
+        for (int p=0; p < pcount; p++) {
+            int id = ev.getPointerId(p);
+            mRender.newTouchPosition(ev.getX(p),
+                                     ev.getY(p),
+                                     ev.getPressure(p),
+                                     id);
+
+            for (int i=0; i < count; i++) {
+                mRender.newTouchPosition(ev.getHistoricalX(p, i),
+                                         ev.getHistoricalY(p, i),
+                                         ev.getHistoricalPressure(p, i),
+                                         id);
+            }
+        }
+        return true;
+    }
+
+    void setAccel(float x, float y, float z) {
+        if (mRender == null) {
+            return;
+        }
+        mRender.setAccel(x, -y);
+    }
+
+}
+
+
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/ball_physics.rs b/samples/RenderScript/Balls/src/com/example/android/rs/balls/ball_physics.rs
new file mode 100644
index 0000000..ee6ab1d
--- /dev/null
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/ball_physics.rs
@@ -0,0 +1,146 @@
+#pragma version(1)
+#pragma rs java_package_name(com.example.android.rs.balls)
+
+#include "balls.rsh"
+
+float2 gGravityVector = {0.f, 9.8f};
+
+float2 gMinPos = {0.f, 0.f};
+float2 gMaxPos = {1280.f, 700.f};
+
+static float2 touchPos[10];
+static float touchPressure[10];
+
+void touch(float x, float y, float pressure, int id) {
+    if (id >= 10) {
+        return;
+    }
+
+    touchPos[id].x = x;
+    touchPos[id].y = y;
+    touchPressure[id] = pressure;
+}
+
+void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) {
+    float2 fv = {0, 0};
+    float2 pos = ballIn->position;
+
+    int arcID = -1;
+    float arcInvStr = 100000;
+
+    const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0);
+    for (uint32_t xin = 0; xin < ctl->dimX; xin++) {
+        float2 vec = bPtr[xin].position - pos;
+        float2 vec2 = vec * vec;
+        float len2 = vec2.x + vec2.y;
+
+        if (len2 < 10000) {
+            //float minDist = ballIn->size + bPtr[xin].size;
+            float forceScale = ballIn->size * bPtr[xin].size;
+            forceScale *= forceScale;
+
+            if (len2 > 16 /* (minDist*minDist)*/)  {
+                // Repulsion
+                float len = sqrt(len2);
+                fv -= (vec / (len * len * len)) * 20000.f * forceScale;
+            } else {
+                if (len2 < 1) {
+                    if (xin == x) {
+                        continue;
+                    }
+                    ballOut->delta = 0.f;
+                    ballOut->position = ballIn->position;
+                    if (xin > x) {
+                        ballOut->position.x += 1.f;
+                    } else {
+                        ballOut->position.x -= 1.f;
+                    }
+                    //ballOut->color.rgb = 1.f;
+                    //ballOut->arcID = -1;
+                    //ballOut->arcStr = 0;
+                    return;
+                }
+                // Collision
+                float2 axis = normalize(vec);
+                float e1 = dot(axis, ballIn->delta);
+                float e2 = dot(axis, bPtr[xin].delta);
+                float e = (e1 - e2) * 0.45f;
+                if (e1 > 0) {
+                    fv -= axis * e;
+                } else {
+                    fv += axis * e;
+                }
+            }
+        }
+    }
+
+    fv /= ballIn->size * ballIn->size * ballIn->size;
+    fv -= gGravityVector * 4.f;
+    fv *= ctl->dt;
+
+    for (int i=0; i < 10; i++) {
+        if (touchPressure[i] > 0.1f) {
+            float2 vec = touchPos[i] - ballIn->position;
+            float2 vec2 = vec * vec;
+            float len2 = max(2.f, vec2.x + vec2.y);
+            fv -= (vec / len2) * touchPressure[i] * 300.f;
+        }
+    }
+
+    ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv;
+    ballOut->position = ballIn->position + (ballOut->delta * ctl->dt);
+
+    const float wallForce = 400.f;
+    if (ballOut->position.x > (gMaxPos.x - 20.f)) {
+        float d = gMaxPos.x - ballOut->position.x;
+        if (d < 0.f) {
+            if (ballOut->delta.x > 0) {
+                ballOut->delta.x *= -0.7;
+            }
+            ballOut->position.x = gMaxPos.x;
+        } else {
+            ballOut->delta.x -= min(wallForce / (d * d), 10.f);
+        }
+    }
+
+    if (ballOut->position.x < (gMinPos.x + 20.f)) {
+        float d = ballOut->position.x - gMinPos.x;
+        if (d < 0.f) {
+            if (ballOut->delta.x < 0) {
+                ballOut->delta.x *= -0.7;
+            }
+            ballOut->position.x = gMinPos.x + 1.f;
+        } else {
+            ballOut->delta.x += min(wallForce / (d * d), 10.f);
+        }
+    }
+
+    if (ballOut->position.y > (gMaxPos.y - 20.f)) {
+        float d = gMaxPos.y - ballOut->position.y;
+        if (d < 0.f) {
+            if (ballOut->delta.y > 0) {
+                ballOut->delta.y *= -0.7;
+            }
+            ballOut->position.y = gMaxPos.y;
+        } else {
+            ballOut->delta.y -= min(wallForce / (d * d), 10.f);
+        }
+    }
+
+    if (ballOut->position.y < (gMinPos.y + 20.f)) {
+        float d = ballOut->position.y - gMinPos.y;
+        if (d < 0.f) {
+            if (ballOut->delta.y < 0) {
+                ballOut->delta.y *= -0.7;
+            }
+            ballOut->position.y = gMinPos.y + 1.f;
+        } else {
+            ballOut->delta.y += min(wallForce / (d * d * d), 10.f);
+        }
+    }
+
+    ballOut->size = ballIn->size;
+
+    //rsDebug("physics pos out", ballOut->position);
+}
+
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
new file mode 100644
index 0000000..d86b804
--- /dev/null
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
@@ -0,0 +1,85 @@
+#pragma version(1)
+#pragma rs java_package_name(com.example.android.rs.balls)
+#include "rs_graphics.rsh"
+
+#include "balls.rsh"
+
+#pragma stateVertex(parent)
+#pragma stateStore(parent)
+
+rs_program_fragment gPFPoints;
+rs_program_fragment gPFLines;
+rs_mesh partMesh;
+
+typedef struct __attribute__((packed, aligned(4))) Point {
+    float2 position;
+    float size;
+} Point_t;
+Point_t *point;
+
+typedef struct VpConsts {
+    rs_matrix4x4 MVP;
+} VpConsts_t;
+VpConsts_t *vpConstants;
+
+rs_script physics_script;
+
+Ball_t *balls1;
+Ball_t *balls2;
+
+static int frame = 0;
+
+void initParts(int w, int h)
+{
+    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls1));
+
+    for (uint32_t ct=0; ct < dimX; ct++) {
+        balls1[ct].position.x = rsRand(0.f, (float)w);
+        balls1[ct].position.y = rsRand(0.f, (float)h);
+        balls1[ct].delta.x = 0.f;
+        balls1[ct].delta.y = 0.f;
+        balls1[ct].size = 1.f;
+
+        float r = rsRand(100.f);
+        if (r > 90.f) {
+            balls1[ct].size += pow(10.f, rsRand(0.f, 2.f)) * 0.07;
+        }
+    }
+}
+
+
+
+int root() {
+    rsgClearColor(0.f, 0.f, 0.f, 1.f);
+
+    BallControl_t bc;
+    Ball_t *bout;
+
+    if (frame & 1) {
+        rsSetObject(&bc.ain, rsGetAllocation(balls2));
+        rsSetObject(&bc.aout, rsGetAllocation(balls1));
+        bout = balls2;
+    } else {
+        rsSetObject(&bc.ain, rsGetAllocation(balls1));
+        rsSetObject(&bc.aout, rsGetAllocation(balls2));
+        bout = balls1;
+    }
+
+    bc.dimX = rsAllocationGetDimX(bc.ain);
+    bc.dt = 1.f / 30.f;
+
+    rsForEach(physics_script, bc.ain, bc.aout, &bc);
+
+    for (uint32_t ct=0; ct < bc.dimX; ct++) {
+        point[ct].position = bout[ct].position;
+        point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size;
+    }
+
+    frame++;
+    rsgBindProgramFragment(gPFPoints);
+    rsgDrawMesh(partMesh);
+    rsClearObject(&bc.ain);
+    rsClearObject(&bc.aout);
+    return 1;
+}
+
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rsh b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rsh
new file mode 100644
index 0000000..fc886f9
--- /dev/null
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rsh
@@ -0,0 +1,18 @@
+
+typedef struct __attribute__((packed, aligned(4))) Ball {
+    float2 delta;
+    float2 position;
+    //float3 color;
+    float size;
+    //int arcID;
+    //float arcStr;
+} Ball_t;
+Ball_t *balls;
+
+
+typedef struct BallControl {
+    uint32_t dimX;
+    rs_allocation ain;
+    rs_allocation aout;
+    float dt;
+} BallControl_t;
diff --git a/samples/RenderScript/Fountain/Android.mk b/samples/RenderScript/Fountain/Android.mk
new file mode 100644
index 0000000..27994ba
--- /dev/null
+++ b/samples/RenderScript/Fountain/Android.mk
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := RsFountain
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/samples/RenderScript/Fountain/AndroidManifest.xml b/samples/RenderScript/Fountain/AndroidManifest.xml
new file mode 100644
index 0000000..3d72552
--- /dev/null
+++ b/samples/RenderScript/Fountain/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.rs.fountain">
+    <uses-sdk android:minSdkVersion="11" />
+    <application
+        android:label="RsFountain"
+        android:icon="@drawable/test_pattern">
+        <activity android:name="Fountain">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/RenderScript/Fountain/_index.html b/samples/RenderScript/Fountain/_index.html
new file mode 100644
index 0000000..223242f
--- /dev/null
+++ b/samples/RenderScript/Fountain/_index.html
@@ -0,0 +1,5 @@
+<p>An example that renders many dots on the screen that follow a user's touch. The dots fall 
+to the bottom of the screen when the user releases the finger.</p>
+
+
+
diff --git a/samples/RenderScript/Fountain/res/drawable/test_pattern.png b/samples/RenderScript/Fountain/res/drawable/test_pattern.png
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/samples/RenderScript/Fountain/res/drawable/test_pattern.png
Binary files differ
diff --git a/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/Fountain.java b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/Fountain.java
new file mode 100644
index 0000000..53b4f26
--- /dev/null
+++ b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/Fountain.java
@@ -0,0 +1,96 @@
+/*
+ * 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.example.android.rs.fountain;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class Fountain extends Activity {
+    //EventListener mListener = new EventListener();
+
+    private static final String LOG_TAG = "libRS_jni";
+    private static final boolean DEBUG  = false;
+    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+    private FountainView mView;
+
+    // get the current looper (from your Activity UI thread for instance
+
+
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new FountainView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        Log.e("rs", "onResume");
+
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        Log.e("rs", "onPause");
+
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mView.pause();
+
+
+
+        //Runtime.getRuntime().exit(0);
+    }
+
+
+    static void log(String message) {
+        if (LOG_ENABLED) {
+            Log.v(LOG_TAG, message);
+        }
+    }
+
+
+}
+
diff --git a/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainRS.java b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainRS.java
new file mode 100644
index 0000000..eff6b89
--- /dev/null
+++ b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainRS.java
@@ -0,0 +1,72 @@
+/*
+ * 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.example.android.rs.fountain;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+
+public class FountainRS {
+    public static final int PART_COUNT = 50000;
+
+    public FountainRS() {
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+    private ScriptC_fountain mScript;
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
+
+        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
+        pfb.setVaryingColor(true);
+        rs.bindProgramFragment(pfb.create());
+
+        ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);//
+ //                                                        Allocation.USAGE_GRAPHICS_VERTEX);
+
+        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
+        smb.addVertexAllocation(points.getAllocation());
+        smb.addIndexSetType(Mesh.Primitive.POINT);
+        Mesh sm = smb.create();
+
+        mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
+        mScript.set_partMesh(sm);
+        mScript.bind_point(points);
+        mRS.bindRootScript(mScript);
+    }
+
+    boolean holdingColor[] = new boolean[10];
+    public void newTouchPosition(float x, float y, float pressure, int id) {
+        if (id >= holdingColor.length) {
+            return;
+        }
+        int rate = (int)(pressure * pressure * 500.f);
+        if (rate > 500) {
+            rate = 500;
+        }
+        if (rate > 0) {
+            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
+            holdingColor[id] = true;
+        } else {
+            holdingColor[id] = false;
+        }
+
+    }
+}
diff --git a/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainView.java b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainView.java
new file mode 100644
index 0000000..933b3e9
--- /dev/null
+++ b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainView.java
@@ -0,0 +1,106 @@
+/*
+ * 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.example.android.rs.fountain;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class FountainView extends RSSurfaceView {
+
+    public FountainView(Context context) {
+        super(context);
+        //setFocusable(true);
+    }
+
+    private RenderScriptGL mRS;
+    private FountainRS mRender;
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+        if (mRS == null) {
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            mRS = createRenderScriptGL(sc);
+            mRS.setSurface(holder, w, h);
+            mRender = new FountainRS();
+            mRender.init(mRS, getResources(), w, h);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        if (mRS != null) {
+            mRS = null;
+            destroyRenderScriptGL();
+        }
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev)
+    {
+        int act = ev.getActionMasked();
+        if (act == ev.ACTION_UP) {
+            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
+            return false;
+        } else if (act == MotionEvent.ACTION_POINTER_UP) {
+            // only one pointer going up, we can get the index like this
+            int pointerIndex = ev.getActionIndex();
+            int pointerId = ev.getPointerId(pointerIndex);
+            mRender.newTouchPosition(0, 0, 0, pointerId);
+        }
+        int count = ev.getHistorySize();
+        int pcount = ev.getPointerCount();
+
+        for (int p=0; p < pcount; p++) {
+            int id = ev.getPointerId(p);
+            mRender.newTouchPosition(ev.getX(p),
+                                     ev.getY(p),
+                                     ev.getPressure(p),
+                                     id);
+
+            for (int i=0; i < count; i++) {
+                mRender.newTouchPosition(ev.getHistoricalX(p, i),
+                                         ev.getHistoricalY(p, i),
+                                         ev.getHistoricalPressure(p, i),
+                                         id);
+            }
+        }
+        return true;
+    }
+}
+
+
diff --git a/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/fountain.rs b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/fountain.rs
new file mode 100644
index 0000000..b8b8421
--- /dev/null
+++ b/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/fountain.rs
@@ -0,0 +1,69 @@
+// Fountain test script
+#pragma version(1)
+
+#pragma rs java_package_name(com.example.android.rs.fountain)
+
+#pragma stateFragment(parent)
+
+#include "rs_graphics.rsh"
+
+static int newPart = 0;
+rs_mesh partMesh;
+
+typedef struct __attribute__((packed, aligned(4))) Point {
+    float2 delta;
+    float2 position;
+    uchar4 color;
+} Point_t;
+Point_t *point;
+
+int root() {
+    float dt = min(rsGetDt(), 0.1f);
+    rsgClearColor(0.f, 0.f, 0.f, 1.f);
+    const float height = rsgGetHeight();
+    const int size = rsAllocationGetDimX(rsGetAllocation(point));
+    float dy2 = dt * (10.f);
+    Point_t * p = point;
+    for (int ct=0; ct < size; ct++) {
+        p->delta.y += dy2;
+        p->position += p->delta;
+        if ((p->position.y > height) && (p->delta.y > 0)) {
+            p->delta.y *= -0.3f;
+        }
+        p++;
+    }
+
+    rsgDrawMesh(partMesh);
+    return 1;
+}
+
+static float4 partColor[10];
+void addParticles(int rate, float x, float y, int index, bool newColor)
+{
+    if (newColor) {
+        partColor[index].x = rsRand(0.5f, 1.0f);
+        partColor[index].y = rsRand(1.0f);
+        partColor[index].z = rsRand(1.0f);
+    }
+    float rMax = ((float)rate) * 0.02f;
+    int size = rsAllocationGetDimX(rsGetAllocation(point));
+    uchar4 c = rsPackColorTo8888(partColor[index]);
+
+    Point_t * np = &point[newPart];
+    float2 p = {x, y};
+    while (rate--) {
+        float angle = rsRand(3.14f * 2.f);
+        float len = rsRand(rMax);
+        np->delta.x = len * sin(angle);
+        np->delta.y = len * cos(angle);
+        np->position = p;
+        np->color = c;
+        newPart++;
+        np++;
+        if (newPart >= size) {
+            newPart = 0;
+            np = &point[newPart];
+        }
+    }
+}
+
diff --git a/samples/RenderScript/HelloCompute/Android.mk b/samples/RenderScript/HelloCompute/Android.mk
new file mode 100644
index 0000000..27bc92e
--- /dev/null
+++ b/samples/RenderScript/HelloCompute/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2011 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+                   $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := RsHelloCompute
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/samples/RenderScript/HelloCompute/AndroidManifest.xml b/samples/RenderScript/HelloCompute/AndroidManifest.xml
new file mode 100644
index 0000000..a7baf0d
--- /dev/null
+++ b/samples/RenderScript/HelloCompute/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.rs.hellocompute">
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    
+    <uses-sdk android:minSdkVersion="11" />
+    <application android:label="RsHelloCompute">
+        <activity android:name="HelloCompute">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/RenderScript/HelloCompute/_index.html b/samples/RenderScript/HelloCompute/_index.html
new file mode 100644
index 0000000..abfd978
--- /dev/null
+++ b/samples/RenderScript/HelloCompute/_index.html
@@ -0,0 +1,2 @@
+<p>A Renderscript compute sample that filters a bitmap. No Renderscript graphics APIs are used
+in this sample.</p>
\ No newline at end of file
diff --git a/samples/RenderScript/HelloCompute/res/drawable/data.jpg b/samples/RenderScript/HelloCompute/res/drawable/data.jpg
new file mode 100644
index 0000000..81a87b1
--- /dev/null
+++ b/samples/RenderScript/HelloCompute/res/drawable/data.jpg
Binary files differ
diff --git a/samples/RenderScript/HelloCompute/res/layout/main.xml b/samples/RenderScript/HelloCompute/res/layout/main.xml
new file mode 100644
index 0000000..3f7de43
--- /dev/null
+++ b/samples/RenderScript/HelloCompute/res/layout/main.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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">
+
+    <ImageView
+        android:id="@+id/displayin"
+        android:layout_width="320dip"
+        android:layout_height="266dip" />
+
+    <ImageView
+        android:id="@+id/displayout"
+        android:layout_width="320dip"
+        android:layout_height="266dip" />
+
+</LinearLayout>
diff --git a/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/HelloCompute.java b/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/HelloCompute.java
new file mode 100644
index 0000000..a017273
--- /dev/null
+++ b/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/HelloCompute.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 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.example.android.rs.hellocompute;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.renderscript.RenderScript;
+import android.renderscript.Allocation;
+import android.widget.ImageView;
+
+public class HelloCompute extends Activity {
+    private Bitmap mBitmapIn;
+    private Bitmap mBitmapOut;
+
+    private RenderScript mRS;
+    private Allocation mInAllocation;
+    private Allocation mOutAllocation;
+    private ScriptC_mono mScript;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        mBitmapIn = loadBitmap(R.drawable.data);
+        mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(),
+                                         mBitmapIn.getConfig());
+
+        ImageView in = (ImageView) findViewById(R.id.displayin);
+        in.setImageBitmap(mBitmapIn);
+
+        ImageView out = (ImageView) findViewById(R.id.displayout);
+        out.setImageBitmap(mBitmapOut);
+
+        createScript();
+    }
+
+
+    private void createScript() {
+        mRS = RenderScript.create(this);
+
+        mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
+                                                    Allocation.MipmapControl.MIPMAP_NONE,
+                                                    Allocation.USAGE_SCRIPT);
+        mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
+
+        mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono);
+
+        mScript.set_gIn(mInAllocation);
+        mScript.set_gOut(mOutAllocation);
+        mScript.set_gScript(mScript);
+        mScript.invoke_filter();
+        mOutAllocation.copyTo(mBitmapOut);
+    }
+
+    private Bitmap loadBitmap(int resource) {
+        final BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        return BitmapFactory.decodeResource(getResources(), resource, options);
+    }
+}
diff --git a/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/mono.rs b/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/mono.rs
new file mode 100644
index 0000000..a7c9b8b
--- /dev/null
+++ b/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/mono.rs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.example.android.rs.hellocompute)
+
+rs_allocation gIn;
+rs_allocation gOut;
+rs_script gScript;
+
+const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
+
+void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
+    float4 f4 = rsUnpackColor8888(*v_in);
+
+    float3 mono = dot(f4.rgb, gMonoMult);
+    *v_out = rsPackColorTo8888(mono);
+}
+
+void filter() {
+    rsForEach(gScript, gIn, gOut, 0);
+}
+
diff --git a/samples/RenderScript/HelloWorld/Android.mk b/samples/RenderScript/HelloWorld/Android.mk
new file mode 100644
index 0000000..2e194ef
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2011 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := RsHelloWorld
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/samples/RenderScript/HelloWorld/AndroidManifest.xml b/samples/RenderScript/HelloWorld/AndroidManifest.xml
new file mode 100644
index 0000000..1d37dc9
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.rs.helloworld">
+    <uses-sdk android:minSdkVersion="11" />
+    <application android:label="RsHelloWorld"
+    android:icon="@drawable/test_pattern">
+        <activity android:name="HelloWorld"
+                  android:label="RsHelloWorld"
+                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/RenderScript/HelloWorld/_index.html b/samples/RenderScript/HelloWorld/_index.html
new file mode 100644
index 0000000..4cab738
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/_index.html
@@ -0,0 +1 @@
+<p>A Renderscript graphics application that draws the text "Hello, World!" where the user touches.</p>
\ No newline at end of file
diff --git a/samples/RenderScript/HelloWorld/res/drawable/test_pattern.png b/samples/RenderScript/HelloWorld/res/drawable/test_pattern.png
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/res/drawable/test_pattern.png
Binary files differ
diff --git a/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorld.java b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorld.java
new file mode 100644
index 0000000..9b1697b
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorld.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 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.example.android.rs.helloworld;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+// Renderscript activity
+public class HelloWorld extends Activity {
+
+    // Custom view to use with RenderScript
+    private HelloWorldView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our view and set it as the content of our Activity
+        mView = new HelloWorldView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally an app should implement onResume() and onPause()
+        // to take appropriate action when the activity loses focus
+        super.onResume();
+        mView.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally an app should implement onResume() and onPause()
+        // to take appropriate action when the activity loses focus
+        super.onPause();
+        mView.pause();
+    }
+
+}
+
diff --git a/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorldRS.java b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorldRS.java
new file mode 100644
index 0000000..4316411
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorldRS.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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.example.android.rs.helloworld;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+
+// This is the renderer for the HelloWorldView
+public class HelloWorldRS {
+    private Resources mRes;
+    private RenderScriptGL mRS;
+
+    private ScriptC_helloworld mScript;
+
+    public HelloWorldRS() {
+    }
+
+    // This provides us with the renderscript context and resources that
+    // allow us to create the script that does rendering
+    public void init(RenderScriptGL rs, Resources res) {
+        mRS = rs;
+        mRes = res;
+        initRS();
+    }
+
+    public void onActionDown(int x, int y) {
+        mScript.set_gTouchX(x);
+        mScript.set_gTouchY(y);
+    }
+
+    private void initRS() {
+        mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld);
+        mRS.bindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorldView.java b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorldView.java
new file mode 100644
index 0000000..557ebc5
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/HelloWorldView.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 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.example.android.rs.helloworld;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.view.MotionEvent;
+
+public class HelloWorldView extends RSSurfaceView {
+    // Renderscipt context
+    private RenderScriptGL mRS;
+    // Script that does the rendering
+    private HelloWorldRS mRender;
+
+    public HelloWorldView(Context context) {
+        super(context);
+        ensureRenderScript();
+    }
+
+    private void ensureRenderScript() {
+        if (mRS == null) {
+            // Initialize renderscript with desired surface characteristics.
+            // In this case, just use the defaults
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            mRS = createRenderScriptGL(sc);
+            // Create an instance of the script that does the rendering
+            mRender = new HelloWorldRS();
+            mRender.init(mRS, getResources());
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        ensureRenderScript();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        // Handle the system event and clean up
+        mRender = null;
+        if (mRS != null) {
+            mRS = null;
+            destroyRenderScriptGL();
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        // Pass touch events from the system to the rendering script
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
+            return true;
+        }
+
+        return false;
+    }
+}
+
+
diff --git a/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/helloworld.rs b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/helloworld.rs
new file mode 100644
index 0000000..34e940a
--- /dev/null
+++ b/samples/RenderScript/HelloWorld/src/com/example/android/rs/helloworld/helloworld.rs
@@ -0,0 +1,47 @@
+// Copyright (C) 2011 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.
+
+#pragma version(1)
+
+// Tell which java package name the reflected files should belong to
+#pragma rs java_package_name(com.example.android.rs.helloworld)
+
+// Built-in header with graphics API's
+#include "rs_graphics.rsh"
+
+// gTouchX and gTouchY are variables that will be reflected for use
+// by the java API. We can use them to notify the script of touch events.
+int gTouchX;
+int gTouchY;
+
+// This is invoked automatically when the script is created
+void init() {
+    gTouchX = 50.0f;
+    gTouchY = 50.0f;
+}
+
+int root(int launchID) {
+
+    // Clear the background color
+    rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    // Tell the runtime what the font color should be
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    // Introuduce ourselves to the world by drawing a greeting
+    // at the position user touched on the screen
+    rsgDrawText("Hello World!", gTouchX, gTouchY);
+
+    // Return value tells RS roughly how often to redraw
+    // in this case 20 ms
+    return 20;
+}
diff --git a/samples/RenderScript/MiscSamples/Android.mk b/samples/RenderScript/MiscSamples/Android.mk
new file mode 100644
index 0000000..fcdefb7
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/Android.mk
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := RsMiscSamples
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/samples/RenderScript/MiscSamples/AndroidManifest.xml b/samples/RenderScript/MiscSamples/AndroidManifest.xml
new file mode 100644
index 0000000..08a3976
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.rs.miscsamples">
+    <uses-sdk android:minSdkVersion="11" />
+    <application android:label="RsMiscSamples"
+    android:icon="@drawable/test_pattern">
+        <activity android:name="RsList"
+                  android:label="RsList"
+                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name="RsRenderStates"
+                  android:label="RsStates"
+                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/RenderScript/MiscSamples/_index.html b/samples/RenderScript/MiscSamples/_index.html
new file mode 100644
index 0000000..5872431
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/_index.html
@@ -0,0 +1 @@
+<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p>
\ No newline at end of file
diff --git a/samples/RenderScript/MiscSamples/res/drawable/checker.png b/samples/RenderScript/MiscSamples/res/drawable/checker.png
new file mode 100644
index 0000000..b631e1e
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/drawable/checker.png
Binary files differ
diff --git a/samples/RenderScript/MiscSamples/res/drawable/cubemap_test.png b/samples/RenderScript/MiscSamples/res/drawable/cubemap_test.png
new file mode 100644
index 0000000..baf35d0
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/drawable/cubemap_test.png
Binary files differ
diff --git a/samples/RenderScript/MiscSamples/res/drawable/data.png b/samples/RenderScript/MiscSamples/res/drawable/data.png
new file mode 100644
index 0000000..8e34714
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/drawable/data.png
Binary files differ
diff --git a/samples/RenderScript/MiscSamples/res/drawable/leaf.png b/samples/RenderScript/MiscSamples/res/drawable/leaf.png
new file mode 100644
index 0000000..3cd3775
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/drawable/leaf.png
Binary files differ
diff --git a/samples/RenderScript/MiscSamples/res/drawable/test_pattern.png b/samples/RenderScript/MiscSamples/res/drawable/test_pattern.png
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/drawable/test_pattern.png
Binary files differ
diff --git a/samples/RenderScript/MiscSamples/res/drawable/torusmap.png b/samples/RenderScript/MiscSamples/res/drawable/torusmap.png
new file mode 100644
index 0000000..1e08f3b
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/drawable/torusmap.png
Binary files differ
diff --git a/samples/RenderScript/MiscSamples/res/raw/multitexf.glsl b/samples/RenderScript/MiscSamples/res/raw/multitexf.glsl
new file mode 100644
index 0000000..e492a47
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/multitexf.glsl
@@ -0,0 +1,13 @@
+varying vec2 varTex0;
+
+void main() {
+   vec2 t0 = varTex0.xy;
+   lowp vec4 col0 = texture2D(UNI_Tex0, t0).rgba;
+   lowp vec4 col1 = texture2D(UNI_Tex1, t0*4.0).rgba;
+   lowp vec4 col2 = texture2D(UNI_Tex2, t0).rgba;
+   col0.xyz = col0.xyz*col1.xyz*1.5;
+   col0.xyz = mix(col0.xyz, col2.xyz, col2.w);
+   col0.w = 0.5;
+   gl_FragColor = col0;
+}
+
diff --git a/samples/RenderScript/MiscSamples/res/raw/shader2f.glsl b/samples/RenderScript/MiscSamples/res/raw/shader2f.glsl
new file mode 100644
index 0000000..5fc05f1
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shader2f.glsl
@@ -0,0 +1,29 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+   vec3 V = normalize(-varWorldPos.xyz);
+   vec3 worldNorm = normalize(varWorldNormal);
+
+   vec3 light0Vec = normalize(UNI_light0_Posision.xyz - varWorldPos);
+   vec3 light0R = -reflect(light0Vec, worldNorm);
+   float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
+   float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
+   float light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
+
+   vec3 light1Vec = normalize(UNI_light1_Posision.xyz - varWorldPos);
+   vec3 light1R = reflect(light1Vec, worldNorm);
+   float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
+   float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
+   float light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
+
+   vec2 t0 = varTex0.xy;
+   lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+   col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
+   col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
+   col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
+   gl_FragColor = col;
+}
+
diff --git a/samples/RenderScript/MiscSamples/res/raw/shader2movev.glsl b/samples/RenderScript/MiscSamples/res/raw/shader2movev.glsl
new file mode 100644
index 0000000..a2c807e
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shader2movev.glsl
@@ -0,0 +1,21 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+   vec4 objPos = ATTRIB_position;
+   vec3 oldPos = objPos.xyz;
+   objPos.xyz += 0.1*sin(objPos.xyz*2.0 + UNI_time);
+   objPos.xyz += 0.05*sin(objPos.xyz*4.0 + UNI_time*0.5);
+   objPos.xyz += 0.02*sin(objPos.xyz*7.0 + UNI_time*0.75);
+   vec4 worldPos = UNI_model * objPos;
+   gl_Position = UNI_proj * worldPos;
+
+   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+   vec3 worldNorm = model3 * (ATTRIB_normal + oldPos - objPos.xyz);
+
+   varWorldPos = worldPos.xyz;
+   varWorldNormal = worldNorm;
+   varTex0 = ATTRIB_texture0;
+}
diff --git a/samples/RenderScript/MiscSamples/res/raw/shader2v.glsl b/samples/RenderScript/MiscSamples/res/raw/shader2v.glsl
new file mode 100644
index 0000000..e6885a3
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shader2v.glsl
@@ -0,0 +1,17 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+   vec4 objPos = ATTRIB_position;
+   vec4 worldPos = UNI_model * objPos;
+   gl_Position = UNI_proj * worldPos;
+
+   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+   vec3 worldNorm = model3 * ATTRIB_normal;
+
+   varWorldPos = worldPos.xyz;
+   varWorldNormal = worldNorm;
+   varTex0 = ATTRIB_texture0;
+}
diff --git a/samples/RenderScript/MiscSamples/res/raw/shaderarrayf.glsl b/samples/RenderScript/MiscSamples/res/raw/shaderarrayf.glsl
new file mode 100644
index 0000000..238ecad
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shaderarrayf.glsl
@@ -0,0 +1,16 @@
+
+varying lowp float light0_Diffuse;
+varying lowp float light0_Specular;
+varying lowp float light1_Diffuse;
+varying lowp float light1_Specular;
+varying vec2 varTex0;
+
+void main() {
+   vec2 t0 = varTex0.xy;
+   lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+   col.xyz = col.xyz * (light0_Diffuse * UNI_light_DiffuseColor[0].xyz + light1_Diffuse * UNI_light_DiffuseColor[1].xyz);
+   col.xyz += light0_Specular * UNI_light_SpecularColor[0].xyz;
+   col.xyz += light1_Specular * UNI_light_SpecularColor[1].xyz;
+   gl_FragColor = col;
+}
+
diff --git a/samples/RenderScript/MiscSamples/res/raw/shaderarrayv.glsl b/samples/RenderScript/MiscSamples/res/raw/shaderarrayv.glsl
new file mode 100644
index 0000000..7a1310a
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shaderarrayv.glsl
@@ -0,0 +1,32 @@
+varying float light0_Diffuse;
+varying float light0_Specular;
+varying float light1_Diffuse;
+varying float light1_Specular;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+   vec4 worldPos = UNI_model[0] * ATTRIB_position;
+   worldPos = UNI_model[1] * worldPos;
+   gl_Position = UNI_proj * worldPos;
+
+   mat4 model0 = UNI_model[0];
+   mat3 model3 = mat3(model0[0].xyz, model0[1].xyz, model0[2].xyz);
+   vec3 worldNorm = model3 * ATTRIB_normal;
+   vec3 V = normalize(-worldPos.xyz);
+
+   vec3 light0Vec = normalize(UNI_light_Posision[0].xyz - worldPos.xyz);
+   vec3 light0R = -reflect(light0Vec, worldNorm);
+   light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light_Diffuse[0];
+   float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
+   light0_Specular = pow(light0Spec, UNI_light_CosinePower[0]) * UNI_light_Specular[0];
+
+   vec3 light1Vec = normalize(UNI_light_Posision[1].xyz - worldPos.xyz);
+   vec3 light1R = reflect(light1Vec, worldNorm);
+   light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light_Diffuse[1];
+   float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
+   light1_Specular = pow(light1Spec, UNI_light_CosinePower[1]) * UNI_light_Specular[1];
+
+   gl_PointSize = 1.0;
+   varTex0 = ATTRIB_texture0;
+}
diff --git a/samples/RenderScript/MiscSamples/res/raw/shadercubef.glsl b/samples/RenderScript/MiscSamples/res/raw/shadercubef.glsl
new file mode 100644
index 0000000..15696a4
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shadercubef.glsl
@@ -0,0 +1,8 @@
+
+varying vec3 worldNormal;
+
+void main() {
+   lowp vec4 col = textureCube(UNI_Tex0, worldNormal);
+   gl_FragColor = col;
+}
+
diff --git a/samples/RenderScript/MiscSamples/res/raw/shadercubev.glsl b/samples/RenderScript/MiscSamples/res/raw/shadercubev.glsl
new file mode 100644
index 0000000..70f5cd6
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shadercubev.glsl
@@ -0,0 +1,10 @@
+varying vec3 worldNormal;
+
+// This is where actual shader code begins
+void main() {
+   vec4 worldPos = UNI_model * ATTRIB_position;
+   gl_Position = UNI_proj * worldPos;
+
+   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+   worldNormal = model3 * ATTRIB_normal;
+}
diff --git a/samples/RenderScript/MiscSamples/res/raw/shaderf.glsl b/samples/RenderScript/MiscSamples/res/raw/shaderf.glsl
new file mode 100644
index 0000000..d56e203
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shaderf.glsl
@@ -0,0 +1,16 @@
+
+varying lowp float light0_Diffuse;
+varying lowp float light0_Specular;
+varying lowp float light1_Diffuse;
+varying lowp float light1_Specular;
+varying vec2 varTex0;
+
+void main() {
+   vec2 t0 = varTex0.xy;
+   lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+   col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
+   col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
+   col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
+   gl_FragColor = col;
+}
+
diff --git a/samples/RenderScript/MiscSamples/res/raw/shaderv.glsl b/samples/RenderScript/MiscSamples/res/raw/shaderv.glsl
new file mode 100644
index 0000000..f7d01de
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/shaderv.glsl
@@ -0,0 +1,30 @@
+varying float light0_Diffuse;
+varying float light0_Specular;
+varying float light1_Diffuse;
+varying float light1_Specular;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+   vec4 worldPos = UNI_model * ATTRIB_position;
+   gl_Position = UNI_proj * worldPos;
+
+   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+   vec3 worldNorm = model3 * ATTRIB_normal;
+   vec3 V = normalize(-worldPos.xyz);
+
+   vec3 light0Vec = normalize(UNI_light0_Posision.xyz - worldPos.xyz);
+   vec3 light0R = -reflect(light0Vec, worldNorm);
+   light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
+   float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
+   light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
+
+   vec3 light1Vec = normalize(UNI_light1_Posision.xyz - worldPos.xyz);
+   vec3 light1R = reflect(light1Vec, worldNorm);
+   light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
+   float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
+   light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
+
+   gl_PointSize = 1.0;
+   varTex0 = ATTRIB_texture0;
+}
diff --git a/samples/RenderScript/MiscSamples/res/raw/torus.a3d b/samples/RenderScript/MiscSamples/res/raw/torus.a3d
new file mode 100644
index 0000000..0322b01
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/res/raw/torus.a3d
Binary files differ
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsList.java b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsList.java
new file mode 100644
index 0000000..dade3b3
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsList.java
@@ -0,0 +1,53 @@
+/*
+ * 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.example.android.rs.miscsamples;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class RsList extends Activity {
+
+    private RsListView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new RsListView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity loses focus
+        super.onResume();
+        mView.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity loses focus
+        super.onPause();
+        mView.pause();
+    }
+
+}
+
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsListRS.java b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsListRS.java
new file mode 100644
index 0000000..eeb2480
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsListRS.java
@@ -0,0 +1,140 @@
+/*
+ * 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.example.android.rs.miscsamples;
+
+import java.io.Writer;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+
+public class RsListRS {
+
+    private final int STATE_LAST_FOCUS = 1;
+
+    private static final String[] DATA_LIST = {
+    "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+    "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+    "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+    "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+    "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+    "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
+    "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
+    "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+    "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+    "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+    "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+    "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+    "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+    "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+    "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+    "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+    "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+    "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+    "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+    "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+    "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+    "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+    "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+    "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+    "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+    "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+    "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+    "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+    "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+    "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+    "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+    "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+    "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+    "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+    "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+    "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+    "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+    "Ukraine", "United Arab Emirates", "United Kingdom",
+    "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+    "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+    "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+    };
+
+    public RsListRS() {
+    }
+
+    public void init(RenderScriptGL rs, Resources res) {
+        mRS = rs;
+        mRes = res;
+        initRS();
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+    private Font mItalic;
+
+    ScriptField_ListAllocs_s mListAllocs;
+
+    private ScriptC_rslist mScript;
+
+    int mLastX;
+    int mLastY;
+
+    public void onActionDown(int x, int y) {
+        mScript.set_gDY(0.0f);
+
+        mLastX = x;
+        mLastY = y;
+    }
+
+    public void onActionMove(int x, int y) {
+        int dx = mLastX - x;
+        int dy = mLastY - y;
+
+        if (Math.abs(dy) <= 2) {
+            dy = 0;
+        }
+
+        mScript.set_gDY(dy);
+
+        mLastX = x;
+        mLastY = y;
+    }
+
+    private void initRS() {
+
+        mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist);
+
+        mListAllocs = new ScriptField_ListAllocs_s(mRS, DATA_LIST.length);
+        for (int i = 0; i < DATA_LIST.length; i ++) {
+            ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item();
+            listElem.text = Allocation.createFromString(mRS, DATA_LIST[i], Allocation.USAGE_SCRIPT);
+            mListAllocs.set(listElem, i, false);
+        }
+
+        mListAllocs.copyAll();
+
+        mScript.bind_gList(mListAllocs);
+
+        mItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+        mScript.set_gItalic(mItalic);
+
+        mRS.bindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsListView.java b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsListView.java
new file mode 100644
index 0000000..db6e6c5
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsListView.java
@@ -0,0 +1,75 @@
+/*
+ * 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.example.android.rs.miscsamples;
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.view.MotionEvent;
+
+public class RsListView extends RSSurfaceView {
+
+    public RsListView(Context context) {
+        super(context);
+        ensureRenderScript();
+    }
+
+    private RenderScriptGL mRS;
+    private RsListRS mRender;
+
+    private void ensureRenderScript() {
+        if (mRS == null) {
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            mRS = createRenderScriptGL(sc);
+            mRender = new RsListRS();
+            mRender.init(mRS, getResources());
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        ensureRenderScript();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        mRender = null;
+        if (mRS != null) {
+            mRS = null;
+            destroyRenderScriptGL();
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev)
+    {
+        boolean ret = false;
+        int act = ev.getAction();
+        if (act == MotionEvent.ACTION_DOWN) {
+            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
+            ret = true;
+        } else if (act == MotionEvent.ACTION_MOVE) {
+            mRender.onActionMove((int)ev.getX(), (int)ev.getY());
+            ret = true;
+        }
+
+        return ret;
+    }
+}
+
+
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStates.java b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStates.java
new file mode 100644
index 0000000..f4ea76e
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStates.java
@@ -0,0 +1,53 @@
+/*
+ * 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.example.android.rs.miscsamples;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class RsRenderStates extends Activity {
+
+    private RsRenderStatesView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new RsRenderStatesView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mView.pause();
+    }
+
+}
+
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.java b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.java
new file mode 100644
index 0000000..0e319fe
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.java
@@ -0,0 +1,422 @@
+/*
+ * 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.example.android.rs.miscsamples;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.*;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.renderscript.ProgramStore.BlendDstFunc;
+import android.renderscript.Sampler.Value;
+import android.util.Log;
+
+
+public class RsRenderStatesRS {
+
+    int mWidth;
+    int mHeight;
+
+    public RsRenderStatesRS() {
+    }
+
+    public void init(RenderScriptGL rs, Resources res) {
+        mRS = rs;
+        mWidth = mRS.getWidth();
+        mHeight = mRS.getHeight();
+        mRes = res;
+        mOptionsARGB.inScaled = false;
+        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        mMode = 0;
+        mMaxModes = 0;
+        initRS();
+    }
+
+    public void surfaceChanged() {
+        mWidth = mRS.getWidth();
+        mHeight = mRS.getHeight();
+
+        Matrix4f proj = new Matrix4f();
+        proj.loadOrthoWindow(mWidth, mHeight);
+        mPVA.setProjection(proj);
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+
+    private Sampler mLinearClamp;
+    private Sampler mLinearWrap;
+    private Sampler mMipLinearWrap;
+    private Sampler mNearestClamp;
+    private Sampler mMipLinearAniso8;
+    private Sampler mMipLinearAniso15;
+
+    private ProgramStore mProgStoreBlendNoneDepth;
+    private ProgramStore mProgStoreBlendNone;
+    private ProgramStore mProgStoreBlendAlpha;
+    private ProgramStore mProgStoreBlendAdd;
+
+    private ProgramFragment mProgFragmentTexture;
+    private ProgramFragment mProgFragmentColor;
+
+    private ProgramVertex mProgVertex;
+    private ProgramVertexFixedFunction.Constants mPVA;
+
+    // Custom shaders
+    private ProgramVertex mProgVertexCustom;
+    private ProgramFragment mProgFragmentCustom;
+    private ProgramFragment mProgFragmentMultitex;
+    private ScriptField_VertexShaderConstants_s mVSConst;
+    private ScriptField_VertexShaderConstants2_s mVSConst2;
+    private ScriptField_FragentShaderConstants_s mFSConst;
+    private ScriptField_FragentShaderConstants2_s mFSConst2;
+
+    private ProgramVertex mProgVertexCustom2;
+    private ProgramFragment mProgFragmentCustom2;
+
+    private ProgramVertex mProgVertexCube;
+    private ProgramFragment mProgFragmentCube;
+
+    private ProgramRaster mCullBack;
+    private ProgramRaster mCullFront;
+    private ProgramRaster mCullNone;
+
+    private Allocation mTexTorus;
+    private Allocation mTexOpaque;
+    private Allocation mTexTransparent;
+    private Allocation mTexChecker;
+    private Allocation mTexCube;
+
+    private Mesh mMbyNMesh;
+    private Mesh mTorus;
+
+    Font mFontSans;
+    Font mFontSerif;
+    Font mFontSerifBold;
+    Font mFontSerifItalic;
+    Font mFontSerifBoldItalic;
+    Font mFontMono;
+    private Allocation mTextAlloc;
+
+    private ScriptC_rsrenderstates mScript;
+
+    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
+
+    int mMode;
+    int mMaxModes;
+
+    public void onActionDown(int x, int y) {
+        mMode ++;
+        mMode = mMode % mMaxModes;
+        mScript.set_gDisplayMode(mMode);
+    }
+
+    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
+        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
+        return builder.create();
+    }
+
+    private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
+
+        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
+                                           2, Mesh.TriangleMeshBuilder.TEXTURE_0);
+
+        for (int y = 0; y <= hResolution; y++) {
+            final float normalizedY = (float)y / hResolution;
+            final float yOffset = (normalizedY - 0.5f) * height;
+            for (int x = 0; x <= wResolution; x++) {
+                float normalizedX = (float)x / wResolution;
+                float xOffset = (normalizedX - 0.5f) * width;
+                tmb.setTexture(normalizedX, normalizedY);
+                tmb.addVertex(xOffset, yOffset);
+             }
+        }
+
+        for (int y = 0; y < hResolution; y++) {
+            final int curY = y * (wResolution + 1);
+            final int belowY = (y + 1) * (wResolution + 1);
+            for (int x = 0; x < wResolution; x++) {
+                int curV = curY + x;
+                int belowV = belowY + x;
+                tmb.addTriangle(curV, belowV, curV + 1);
+                tmb.addTriangle(belowV, belowV + 1, curV + 1);
+            }
+        }
+
+        return tmb.create(true);
+    }
+
+    private void initProgramStore() {
+        // Use stock the stock program store object
+        mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
+        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
+
+        // Create a custom program store
+        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
+        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+        builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
+                             ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
+        mProgStoreBlendAlpha = builder.create();
+
+        mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
+
+        mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
+        mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
+        mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
+        mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
+    }
+
+    private void initProgramFragment() {
+
+        ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
+        texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                              ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+        mProgFragmentTexture = texBuilder.create();
+        mProgFragmentTexture.bindSampler(mLinearClamp, 0);
+
+        ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
+        colBuilder.setVaryingColor(false);
+        mProgFragmentColor = colBuilder.create();
+
+        mScript.set_gProgFragmentColor(mProgFragmentColor);
+        mScript.set_gProgFragmentTexture(mProgFragmentTexture);
+    }
+
+    private void initProgramVertex() {
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
+        mProgVertex = pvb.create();
+
+        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
+        Matrix4f proj = new Matrix4f();
+        proj.loadOrthoWindow(mWidth, mHeight);
+        mPVA.setProjection(proj);
+
+        mScript.set_gProgVertex(mProgVertex);
+    }
+
+    private void initCustomShaders() {
+        mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
+        mVSConst2 = new ScriptField_VertexShaderConstants2_s(mRS, 1);
+        mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
+        mFSConst2 = new ScriptField_FragentShaderConstants2_s(mRS, 1);
+
+        mScript.bind_gVSConstants(mVSConst);
+        mScript.bind_gVSConstants2(mVSConst2);
+        mScript.bind_gFSConstants(mFSConst);
+        mScript.bind_gFSConstants2(mFSConst2);
+
+        // Initialize the shader builder
+        ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
+        // Specify the resource that contains the shader string
+        pvbCustom.setShader(mRes, R.raw.shaderv);
+        // Use a script field to spcify the input layout
+        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+        // Define the constant input layout
+        pvbCustom.addConstant(mVSConst.getAllocation().getType());
+        mProgVertexCustom = pvbCustom.create();
+        // Bind the source of constant data
+        mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
+
+        ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
+        // Specify the resource that contains the shader string
+        pfbCustom.setShader(mRes, R.raw.shaderf);
+        //Tell the builder how many textures we have
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+        // Define the constant input layout
+        pfbCustom.addConstant(mFSConst.getAllocation().getType());
+        mProgFragmentCustom = pfbCustom.create();
+        // Bind the source of constant data
+        mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
+
+        pvbCustom = new ProgramVertex.Builder(mRS);
+        pvbCustom.setShader(mRes, R.raw.shaderarrayv);
+        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+        pvbCustom.addConstant(mVSConst2.getAllocation().getType());
+        mProgVertexCustom2 = pvbCustom.create();
+        mProgVertexCustom2.bindConstants(mVSConst2.getAllocation(), 0);
+
+        pfbCustom = new ProgramFragment.Builder(mRS);
+        pfbCustom.setShader(mRes, R.raw.shaderarrayf);
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+        pfbCustom.addConstant(mFSConst2.getAllocation().getType());
+        mProgFragmentCustom2 = pfbCustom.create();
+        mProgFragmentCustom2.bindConstants(mFSConst2.getAllocation(), 0);
+
+        // Cubemap test shaders
+        pvbCustom = new ProgramVertex.Builder(mRS);
+        pvbCustom.setShader(mRes, R.raw.shadercubev);
+        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+        pvbCustom.addConstant(mVSConst.getAllocation().getType());
+        mProgVertexCube = pvbCustom.create();
+        mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
+
+        pfbCustom = new ProgramFragment.Builder(mRS);
+        pfbCustom.setShader(mRes, R.raw.shadercubef);
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
+        mProgFragmentCube = pfbCustom.create();
+
+        pfbCustom = new ProgramFragment.Builder(mRS);
+        pfbCustom.setShader(mRes, R.raw.multitexf);
+        for (int texCount = 0; texCount < 3; texCount ++) {
+            pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+        }
+        mProgFragmentMultitex = pfbCustom.create();
+
+        mScript.set_gProgVertexCustom(mProgVertexCustom);
+        mScript.set_gProgFragmentCustom(mProgFragmentCustom);
+        mScript.set_gProgVertexCustom2(mProgVertexCustom2);
+        mScript.set_gProgFragmentCustom2(mProgFragmentCustom2);
+        mScript.set_gProgVertexCube(mProgVertexCube);
+        mScript.set_gProgFragmentCube(mProgFragmentCube);
+        mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
+    }
+
+    private Allocation loadTextureRGB(int id) {
+        return Allocation.createFromBitmapResource(mRS, mRes, id,
+                                                   Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                   Allocation.USAGE_GRAPHICS_TEXTURE);
+    }
+
+    private Allocation loadTextureARGB(int id) {
+        Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
+        return Allocation.createFromBitmap(mRS, b,
+                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+    }
+
+    private void loadImages() {
+        mTexTorus = loadTextureRGB(R.drawable.torusmap);
+        mTexOpaque = loadTextureRGB(R.drawable.data);
+        mTexTransparent = loadTextureARGB(R.drawable.leaf);
+        mTexChecker = loadTextureRGB(R.drawable.checker);
+        Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
+        mTexCube = Allocation.createCubemapFromBitmap(mRS, b);
+
+        mScript.set_gTexTorus(mTexTorus);
+        mScript.set_gTexOpaque(mTexOpaque);
+        mScript.set_gTexTransparent(mTexTransparent);
+        mScript.set_gTexChecker(mTexChecker);
+        mScript.set_gTexCube(mTexCube);
+    }
+
+    private void initFonts() {
+        // Sans font by family name
+        mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
+        mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
+        // Create fonts by family and style
+        mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
+        mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+        mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+        mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
+
+        mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
+
+        mScript.set_gFontSans(mFontSans);
+        mScript.set_gFontSerif(mFontSerif);
+        mScript.set_gFontSerifBold(mFontSerifBold);
+        mScript.set_gFontSerifItalic(mFontSerifItalic);
+        mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
+        mScript.set_gFontMono(mFontMono);
+        mScript.set_gTextAlloc(mTextAlloc);
+    }
+
+    private void initMesh() {
+        mMbyNMesh = getMbyNMesh(256, 256, 10, 10);
+        mScript.set_gMbyNMesh(mMbyNMesh);
+
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
+            Log.e("rs", "could not load model");
+        } else {
+            mTorus = (Mesh)entry.getObject();
+            mScript.set_gTorusMesh(mTorus);
+        }
+    }
+
+    private void initSamplers() {
+        Sampler.Builder bs = new Sampler.Builder(mRS);
+        bs.setMinification(Sampler.Value.LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.WRAP);
+        bs.setWrapT(Sampler.Value.WRAP);
+        mLinearWrap = bs.create();
+
+        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
+        mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
+        mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
+
+        bs = new Sampler.Builder(mRS);
+        bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.WRAP);
+        bs.setWrapT(Sampler.Value.WRAP);
+        bs.setAnisotropy(8.0f);
+        mMipLinearAniso8 = bs.create();
+        bs.setAnisotropy(15.0f);
+        mMipLinearAniso15 = bs.create();
+
+        mScript.set_gLinearClamp(mLinearClamp);
+        mScript.set_gLinearWrap(mLinearWrap);
+        mScript.set_gMipLinearWrap(mMipLinearWrap);
+        mScript.set_gMipLinearAniso8(mMipLinearAniso8);
+        mScript.set_gMipLinearAniso15(mMipLinearAniso15);
+        mScript.set_gNearestClamp(mNearestClamp);
+    }
+
+    private void initProgramRaster() {
+        mCullBack = ProgramRaster.CULL_BACK(mRS);
+        mCullFront = ProgramRaster.CULL_FRONT(mRS);
+        mCullNone = ProgramRaster.CULL_NONE(mRS);
+
+        mScript.set_gCullBack(mCullBack);
+        mScript.set_gCullFront(mCullFront);
+        mScript.set_gCullNone(mCullNone);
+    }
+
+    private void initRS() {
+
+        mScript = new ScriptC_rsrenderstates(mRS, mRes, R.raw.rsrenderstates);
+
+        mMaxModes = mScript.get_gMaxModes();
+
+        initSamplers();
+        initProgramStore();
+        initProgramFragment();
+        initProgramVertex();
+        initFonts();
+        loadImages();
+        initMesh();
+        initProgramRaster();
+        initCustomShaders();
+
+        mRS.bindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesView.java b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesView.java
new file mode 100644
index 0000000..a15e38f
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesView.java
@@ -0,0 +1,78 @@
+/*
+ * 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.example.android.rs.miscsamples;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+
+public class RsRenderStatesView extends RSSurfaceView {
+
+    public RsRenderStatesView(Context context) {
+        super(context);
+        ensureRenderScript();
+    }
+
+    private RenderScriptGL mRS;
+    private RsRenderStatesRS mRender;
+
+    private void ensureRenderScript() {
+        if (mRS == null) {
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            sc.setDepth(16, 24);
+            mRS = createRenderScriptGL(sc);
+            mRender = new RsRenderStatesRS();
+            mRender.init(mRS, getResources());
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        ensureRenderScript();
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+        mRender.surfaceChanged();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        mRender = null;
+        if (mRS != null) {
+            mRS = null;
+            destroyRenderScriptGL();
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
+            return true;
+        }
+
+        return false;
+    }
+}
+
+
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/rslist.rs b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/rslist.rs
new file mode 100644
index 0000000..7b2dae2
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/rslist.rs
@@ -0,0 +1,70 @@
+// 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.example.android.rs.miscsamples)
+
+#include "rs_graphics.rsh"
+
+float gDY;
+
+rs_font gItalic;
+
+typedef struct ListAllocs_s {
+    rs_allocation text;
+} ListAllocs;
+
+ListAllocs *gList;
+
+void init() {
+    gDY = 0.0f;
+}
+
+int textPos = 0;
+
+int root(int launchID) {
+
+    rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+    textPos -= (int)gDY*2;
+    gDY *= 0.95;
+
+    rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f);
+    rsgBindFont(gItalic);
+
+    rs_allocation listAlloc;
+    rsSetObject(&listAlloc, rsGetAllocation(gList));
+    int allocSize = rsAllocationGetDimX(listAlloc);
+
+    int width = rsgGetWidth();
+    int height = rsgGetHeight();
+
+    int itemHeight = 80;
+    int currentYPos = itemHeight + textPos;
+
+    for (int i = 0; i < allocSize; i ++) {
+        if (currentYPos - itemHeight > height) {
+            break;
+        }
+
+        if (currentYPos > 0) {
+            rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0);
+            rsgDrawText(gList[i].text, 30, currentYPos - 32);
+        }
+        currentYPos += itemHeight;
+    }
+
+    return 10;
+}
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/rsrenderstates.rs b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/rsrenderstates.rs
new file mode 100644
index 0000000..b8ec8aa
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/rsrenderstates.rs
@@ -0,0 +1,680 @@
+// 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.example.android.rs.miscsamples)
+
+#include "rs_graphics.rsh"
+#include "shader_def.rsh"
+
+const int gMaxModes = 11;
+
+rs_program_vertex gProgVertex;
+rs_program_fragment gProgFragmentColor;
+rs_program_fragment gProgFragmentTexture;
+
+rs_program_store gProgStoreBlendNoneDepth;
+rs_program_store gProgStoreBlendNone;
+rs_program_store gProgStoreBlendAlpha;
+rs_program_store gProgStoreBlendAdd;
+
+rs_allocation gTexOpaque;
+rs_allocation gTexTorus;
+rs_allocation gTexTransparent;
+rs_allocation gTexChecker;
+rs_allocation gTexCube;
+
+rs_mesh gMbyNMesh;
+rs_mesh gTorusMesh;
+
+rs_font gFontSans;
+rs_font gFontSerif;
+rs_font gFontSerifBold;
+rs_font gFontSerifItalic;
+rs_font gFontSerifBoldItalic;
+rs_font gFontMono;
+rs_allocation gTextAlloc;
+
+int gDisplayMode;
+
+rs_sampler gLinearClamp;
+rs_sampler gLinearWrap;
+rs_sampler gMipLinearWrap;
+rs_sampler gMipLinearAniso8;
+rs_sampler gMipLinearAniso15;
+rs_sampler gNearestClamp;
+
+rs_program_raster gCullBack;
+rs_program_raster gCullFront;
+rs_program_raster gCullNone;
+
+// Custom vertex shader compunents
+VertexShaderConstants *gVSConstants;
+VertexShaderConstants2 *gVSConstants2;
+FragentShaderConstants *gFSConstants;
+FragentShaderConstants2 *gFSConstants2;
+// Export these out to easily set the inputs to shader
+VertexShaderInputs *gVSInputs;
+// Custom shaders we use for lighting
+rs_program_vertex gProgVertexCustom;
+rs_program_fragment gProgFragmentCustom;
+rs_program_vertex gProgVertexCustom2;
+rs_program_fragment gProgFragmentCustom2;
+rs_program_vertex gProgVertexCube;
+rs_program_fragment gProgFragmentCube;
+rs_program_fragment gProgFragmentMultitex;
+
+float gDt = 0;
+
+void init() {
+}
+
+static void displayFontSamples() {
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    int yPos = 100;
+    rsgBindFont(gFontSans);
+    rsgDrawText("Sans font sample", 30, yPos);
+    yPos += 30;
+    rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f);
+    rsgBindFont(gFontSerif);
+    rsgDrawText("Serif font sample", 30, yPos);
+    yPos += 30;
+    rsgFontColor(0.7f, 0.7f, 0.7f, 1.0f);
+    rsgBindFont(gFontSerifBold);
+    rsgDrawText("Serif Bold font sample", 30, yPos);
+    yPos += 30;
+    rsgFontColor(0.5f, 0.5f, 0.9f, 1.0f);
+    rsgBindFont(gFontSerifItalic);
+    rsgDrawText("Serif Italic font sample", 30, yPos);
+    yPos += 30;
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontSerifBoldItalic);
+    rsgDrawText("Serif Bold Italic font sample", 30, yPos);
+    yPos += 30;
+    rsgBindFont(gFontMono);
+    rsgDrawText("Monospace font sample", 30, yPos);
+    yPos += 50;
+
+    // Now use text metrics to center the text
+    uint width = rsgGetWidth();
+    uint height = rsgGetHeight();
+    int left = 0, right = 0, top = 0, bottom = 0;
+
+    rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
+    rsgBindFont(gFontSerifBoldItalic);
+
+    rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
+    int centeredPos = width / 2 - (right - left) / 2;
+    rsgDrawText(gTextAlloc, centeredPos, yPos);
+    yPos += 30;
+
+    const char* text = "Centered Text Sample";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    centeredPos = width / 2 - (right - left) / 2;
+    rsgDrawText(text, centeredPos, yPos);
+    yPos += 30;
+
+    rsgBindFont(gFontSans);
+    text = "More Centered Text Samples";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    centeredPos = width / 2 - (right - left) / 2;
+    rsgDrawText(text, centeredPos, yPos);
+    yPos += 30;
+
+    // Now draw bottom and top right aligned text
+    text = "Top-right aligned text";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    rsgDrawText(text, width - right, top);
+
+    text = "Top-left";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    rsgDrawText(text, -left, top);
+
+    text = "Bottom-right aligned text";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    rsgDrawText(text, width - right, height + bottom);
+
+}
+
+static void bindProgramVertexOrtho() {
+    // Default vertex sahder
+    rsgBindProgramVertex(gProgVertex);
+    // Setup the projectioni matrix
+    rs_matrix4x4 proj;
+    rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+}
+
+static void displayShaderSamples() {
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    float startX = 0, startY = 0;
+    float width = 256, height = 256;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
+
+    startX = 200; startY = 0;
+    width = 128; height = 128;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
+
+    rsgBindProgramStore(gProgStoreBlendAlpha);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexTransparent);
+    startX = 0; startY = 200;
+    width = 128; height = 128;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
+
+    // Fragment program with simple color
+    rsgBindProgramFragment(gProgFragmentColor);
+    rsgProgramFragmentConstantColor(gProgFragmentColor, 0.9, 0.3, 0.3, 1);
+    rsgDrawRect(200, 300, 350, 450, 0);
+    rsgProgramFragmentConstantColor(gProgFragmentColor, 0.3, 0.9, 0.3, 1);
+    rsgDrawRect(50, 400, 400, 600, 0);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Texture shader", 10, 50);
+    rsgDrawText("Alpha-blended texture shader", 10, 280);
+    rsgDrawText("Flat color shader", 100, 450);
+}
+
+static void displayBlendingSamples() {
+    int i;
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    rsgBindProgramFragment(gProgFragmentColor);
+
+    rsgBindProgramStore(gProgStoreBlendNone);
+    for (i = 0; i < 3; i ++) {
+        float iPlusOne = (float)(i + 1);
+        rsgProgramFragmentConstantColor(gProgFragmentColor,
+                                        0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
+        float yPos = 150 * (float)i;
+        rsgDrawRect(0, yPos, 200, yPos + 200, 0);
+    }
+
+    rsgBindProgramStore(gProgStoreBlendAlpha);
+    for (i = 0; i < 3; i ++) {
+        float iPlusOne = (float)(i + 1);
+        rsgProgramFragmentConstantColor(gProgFragmentColor,
+                                        0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
+        float yPos = 150 * (float)i;
+        rsgDrawRect(150, yPos, 350, yPos + 200, 0);
+    }
+
+    rsgBindProgramStore(gProgStoreBlendAdd);
+    for (i = 0; i < 3; i ++) {
+        float iPlusOne = (float)(i + 1);
+        rsgProgramFragmentConstantColor(gProgFragmentColor,
+                                        0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
+        float yPos = 150 * (float)i;
+        rsgDrawRect(300, yPos, 500, yPos + 200, 0);
+    }
+
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("No Blending", 10, 50);
+    rsgDrawText("Alpha Blending", 160, 150);
+    rsgDrawText("Additive Blending", 320, 250);
+
+}
+
+static void displayMeshSamples() {
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadTranslate(&matrix, 128, 128, 0);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    rsgDrawMesh(gMbyNMesh);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("User gen 10 by 10 grid mesh", 10, 250);
+}
+
+static void displayTextureSamplers() {
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    // Linear clamp
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    float startX = 0, startY = 0;
+    float width = 300, height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    // Linear Wrap
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
+    startX = 0; startY = 300;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    // Nearest
+    rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
+    startX = 300; startY = 0;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
+    startX = 300; startY = 300;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.5,
+                         startX + width, startY + height, 0, 1.5, 1.5,
+                         startX + width, startY, 0, 1.5, 0);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Filtering: linear clamp", 10, 290);
+    rsgDrawText("Filtering: linear wrap", 10, 590);
+    rsgDrawText("Filtering: nearest clamp", 310, 290);
+    rsgDrawText("Filtering: miplinear wrap", 310, 590);
+}
+
+static float gTorusRotation = 0;
+
+static void displayCullingSamples() {
+    rsgBindProgramVertex(gProgVertex);
+    // Setup the projectioni matrix with 60 degree field of view
+    rs_matrix4x4 proj;
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
+
+    // Aplly a rotation to our mesh
+    gTorusRotation += 50.0f * gDt;
+    if (gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    rs_matrix4x4 matrix;
+    // Position our model on the screen
+    rsMatrixLoadTranslate(&matrix, -2.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+    // Use front face culling
+    rsgBindProgramRaster(gCullFront);
+    rsgDrawMesh(gTorusMesh);
+
+    rsMatrixLoadTranslate(&matrix, 2.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+    // Use back face culling
+    rsgBindProgramRaster(gCullBack);
+    rsgDrawMesh(gTorusMesh);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Displaying mesh front/back face culling", 10, rsgGetHeight() - 10);
+}
+
+static float gLight0Rotation = 0;
+static float gLight1Rotation = 0;
+
+static void setupCustomShaderLights() {
+    float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
+    float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
+    float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f};
+    float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f};
+    float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f};
+    float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f};
+
+    gLight0Rotation += 50.0f * gDt;
+    if (gLight0Rotation > 360.0f) {
+        gLight0Rotation -= 360.0f;
+    }
+    gLight1Rotation -= 50.0f * gDt;
+    if (gLight1Rotation > 360.0f) {
+        gLight1Rotation -= 360.0f;
+    }
+
+    rs_matrix4x4 l0Mat;
+    rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f);
+    light0Pos = rsMatrixMultiply(&l0Mat, light0Pos);
+    rs_matrix4x4 l1Mat;
+    rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f);
+    light1Pos = rsMatrixMultiply(&l1Mat, light1Pos);
+
+    // Set light 0 properties
+    gVSConstants->light0_Posision = light0Pos;
+    gVSConstants->light0_Diffuse = 1.0f;
+    gVSConstants->light0_Specular = 0.5f;
+    gVSConstants->light0_CosinePower = 10.0f;
+    // Set light 1 properties
+    gVSConstants->light1_Posision = light1Pos;
+    gVSConstants->light1_Diffuse = 1.0f;
+    gVSConstants->light1_Specular = 0.7f;
+    gVSConstants->light1_CosinePower = 25.0f;
+    rsgAllocationSyncAll(rsGetAllocation(gVSConstants));
+
+    gVSConstants2->light_Posision[0] = light0Pos;
+    gVSConstants2->light_Diffuse[0] = 1.0f;
+    gVSConstants2->light_Specular[0] = 0.5f;
+    gVSConstants2->light_CosinePower[0] = 10.0f;
+    gVSConstants2->light_Posision[1] = light1Pos;
+    gVSConstants2->light_Diffuse[1] = 1.0f;
+    gVSConstants2->light_Specular[1] = 0.7f;
+    gVSConstants2->light_CosinePower[1] = 25.0f;
+    rsgAllocationSyncAll(rsGetAllocation(gVSConstants2));
+
+    // Update fragmetn shader constants
+    // Set light 0 colors
+    gFSConstants->light0_DiffuseColor = light0DiffCol;
+    gFSConstants->light0_SpecularColor = light0SpecCol;
+    // Set light 1 colors
+    gFSConstants->light1_DiffuseColor = light1DiffCol;
+    gFSConstants->light1_SpecularColor = light1SpecCol;
+    rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
+
+    gFSConstants2->light_DiffuseColor[0] = light0DiffCol;
+    gFSConstants2->light_SpecularColor[0] = light0SpecCol;
+    // Set light 1 colors
+    gFSConstants2->light_DiffuseColor[1] = light1DiffCol;
+    gFSConstants2->light_SpecularColor[1] = light1SpecCol;
+    rsgAllocationSyncAll(rsGetAllocation(gFSConstants2));
+}
+
+static void displayCustomShaderSamples() {
+
+    // Update vertex shader constants
+    // Load model matrix
+    // Aplly a rotation to our mesh
+    gTorusRotation += 50.0f * gDt;
+    if (gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    // Position our model on the screen
+    rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+    // Setup the projectioni matrix
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
+    setupCustomShaderLights();
+
+    rsgBindProgramVertex(gProgVertexCustom);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    rsgBindProgramFragment(gProgFragmentCustom);
+    rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentCustom, 0, gTexTorus);
+
+    // Use back face culling
+    rsgBindProgramRaster(gCullBack);
+    rsgDrawMesh(gTorusMesh);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Custom shader sample", 10, rsgGetHeight() - 10);
+}
+
+static void displayCustomShaderSamples2() {
+
+    // Update vertex shader constants
+    // Load model matrix
+    // Aplly a rotation to our mesh
+    gTorusRotation += 50.0f * gDt;
+    if (gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    // Position our model on the screen
+    rsMatrixLoadTranslate(&gVSConstants2->model[1], 0.0f, 0.0f, -10.0f);
+    rsMatrixLoadIdentity(&gVSConstants2->model[0]);
+    rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 0.0f, 0.0f, 1.0f);
+    // Setup the projectioni matrix
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&gVSConstants2->proj, 30.0f, aspect, 0.1f, 100.0f);
+    setupCustomShaderLights();
+
+    rsgBindProgramVertex(gProgVertexCustom2);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    rsgBindProgramFragment(gProgFragmentCustom2);
+    rsgBindSampler(gProgFragmentCustom2, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentCustom2, 0, gTexTorus);
+
+    // Use back face culling
+    rsgBindProgramRaster(gCullBack);
+    rsgDrawMesh(gTorusMesh);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Custom shader sample with array uniforms", 10, rsgGetHeight() - 10);
+}
+
+static void displayCubemapShaderSample() {
+    // Update vertex shader constants
+    // Load model matrix
+    // Aplly a rotation to our mesh
+    gTorusRotation += 50.0f * gDt;
+    if (gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    // Position our model on the screen
+    // Position our model on the screen
+    rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+    // Setup the projectioni matrix
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
+    rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
+
+    rsgBindProgramVertex(gProgVertexCube);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    rsgBindProgramFragment(gProgFragmentCube);
+    rsgBindSampler(gProgFragmentCube, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentCube, 0, gTexCube);
+
+    // Use back face culling
+    rsgBindProgramRaster(gCullBack);
+    rsgDrawMesh(gTorusMesh);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Cubemap shader sample", 10, rsgGetHeight() - 10);
+}
+
+static void displayMultitextureSample() {
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentMultitex);
+    rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp);
+    rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap);
+    rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp);
+    rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker);
+    rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus);
+    rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent);
+
+    float startX = 0, startY = 0;
+    float width = 256, height = 256;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Custom shader with multitexturing", 10, 280);
+}
+
+static float gAnisoTime = 0.0f;
+static uint anisoMode = 0;
+static void displayAnisoSample() {
+
+    gAnisoTime += gDt;
+
+    rsgBindProgramVertex(gProgVertex);
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rs_matrix4x4 proj;
+    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+
+    rs_matrix4x4 matrix;
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    rsgBindProgramRaster(gCullNone);
+
+    rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
+
+    if (gAnisoTime >= 5.0f) {
+        gAnisoTime = 0.0f;
+        anisoMode ++;
+        anisoMode = anisoMode % 3;
+    }
+
+    if (anisoMode == 0) {
+        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
+    } else if (anisoMode == 1) {
+        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
+    } else {
+        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
+    }
+
+    float startX = -15;
+    float startY = -15;
+    float width = 30;
+    float height = 30;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 10,
+                         startX + width, startY + height, 0, 10, 10,
+                         startX + width, startY, 0, 10, 0);
+
+    rsgBindProgramRaster(gCullBack);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    if (anisoMode == 0) {
+        rsgDrawText("Anisotropic filtering 8", 10, 40);
+    } else if (anisoMode == 1) {
+        rsgDrawText("Anisotropic filtering 15", 10, 40);
+    } else {
+        rsgDrawText("Miplinear filtering", 10, 40);
+    }
+}
+
+int root(int launchID) {
+
+    gDt = rsGetDt();
+
+    rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+    rsgClearDepth(1.0f);
+
+    switch (gDisplayMode) {
+    case 0:
+        displayFontSamples();
+        break;
+    case 1:
+        displayShaderSamples();
+        break;
+    case 2:
+        displayBlendingSamples();
+        break;
+    case 3:
+        displayMeshSamples();
+        break;
+    case 4:
+        displayTextureSamplers();
+        break;
+    case 5:
+        displayCullingSamples();
+        break;
+    case 6:
+        displayCustomShaderSamples();
+        break;
+    case 7:
+        displayMultitextureSample();
+        break;
+    case 8:
+        displayAnisoSample();
+        break;
+    case 9:
+        displayCustomShaderSamples2();
+        break;
+    case 10:
+        displayCubemapShaderSample();
+        break;
+    }
+
+    return 10;
+}
diff --git a/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/shader_def.rsh b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/shader_def.rsh
new file mode 100644
index 0000000..08cf361
--- /dev/null
+++ b/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/shader_def.rsh
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.example.android.rs.miscsamples)
+
+typedef struct VertexShaderConstants_s {
+    rs_matrix4x4 model;
+    rs_matrix4x4 proj;
+    float4 light0_Posision;
+    float light0_Diffuse;
+    float light0_Specular;
+    float light0_CosinePower;
+
+    float4 light1_Posision;
+    float light1_Diffuse;
+    float light1_Specular;
+    float light1_CosinePower;
+} VertexShaderConstants;
+
+typedef struct VertexShaderConstants2_s {
+    rs_matrix4x4 model[2];
+    rs_matrix4x4 proj;
+    float4 light_Posision[2];
+    float light_Diffuse[2];
+    float light_Specular[2];
+    float light_CosinePower[2];
+} VertexShaderConstants2;
+
+typedef struct VertexShaderConstants3_s {
+    rs_matrix4x4 model;
+    rs_matrix4x4 proj;
+    float time;
+} VertexShaderConstants3;
+
+
+typedef struct FragentShaderConstants_s {
+    float4 light0_DiffuseColor;
+    float4 light0_SpecularColor;
+
+    float4 light1_DiffuseColor;
+    float4 light1_SpecularColor;
+} FragentShaderConstants;
+
+typedef struct FragentShaderConstants2_s {
+    float4 light_DiffuseColor[2];
+    float4 light_SpecularColor[2];
+} FragentShaderConstants2;
+
+typedef struct FragentShaderConstants3_s {
+    float4 light0_DiffuseColor;
+    float4 light0_SpecularColor;
+    float4 light0_Posision;
+    float light0_Diffuse;
+    float light0_Specular;
+    float light0_CosinePower;
+
+    float4 light1_DiffuseColor;
+    float4 light1_SpecularColor;
+    float4 light1_Posision;
+    float light1_Diffuse;
+    float light1_Specular;
+    float light1_CosinePower;
+} FragentShaderConstants3;
+
+typedef struct VertexShaderInputs_s {
+    float4 position;
+    float3 normal;
+    float2 texture0;
+} VertexShaderInputs;
+
diff --git a/samples/RenderScript/_index.html b/samples/RenderScript/_index.html
new file mode 100644
index 0000000..5872431
--- /dev/null
+++ b/samples/RenderScript/_index.html
@@ -0,0 +1 @@
+<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p>
\ No newline at end of file
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/Constants.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/Constants.java
index f233a5d..49f92bf 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/Constants.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/Constants.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync;
 
 public class Constants {
@@ -26,7 +25,5 @@
     /**
      * Authtoken type string.
      */
-    public static final String AUTHTOKEN_TYPE =
-        "com.example.android.samplesync";
-
+    public static final String AUTHTOKEN_TYPE = "com.example.android.samplesync";
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticationService.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticationService.java
index b8a903d..2c163be 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticationService.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticationService.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.authenticator;
 
 import android.app.Service;
@@ -26,7 +25,9 @@
  * and returns its IBinder.
  */
 public class AuthenticationService extends Service {
+
     private static final String TAG = "AuthenticationService";
+
     private Authenticator mAuthenticator;
 
     @Override
@@ -47,9 +48,8 @@
     @Override
     public IBinder onBind(Intent intent) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
-            Log.v(TAG,
-                "getBinder()...  returning the AccountAuthenticator binder for intent "
-                    + intent);
+            Log.v(TAG, "getBinder()...  returning the AccountAuthenticator binder for intent "
+                + intent);
         }
         return mAuthenticator.getIBinder();
     }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/Authenticator.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/Authenticator.java
index 29613a9..0c79c5e 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/Authenticator.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/Authenticator.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.authenticator;
 
 import android.accounts.AbstractAccountAuthenticator;
@@ -33,6 +32,7 @@
  * authenticating accounts in the com.example.android.samplesync domain.
  */
 class Authenticator extends AbstractAccountAuthenticator {
+
     // Authentication Service context
     private final Context mContext;
 
@@ -41,34 +41,25 @@
         mContext = context;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Bundle addAccount(AccountAuthenticatorResponse response,
-        String accountType, String authTokenType, String[] requiredFeatures,
-        Bundle options) {
+    public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
+        String authTokenType, String[] requiredFeatures, Bundle options) {
+
         final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
-        intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE,
-            authTokenType);
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
-            response);
+        intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
         final Bundle bundle = new Bundle();
         bundle.putParcelable(AccountManager.KEY_INTENT, intent);
         return bundle;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Bundle confirmCredentials(AccountAuthenticatorResponse response,
-        Account account, Bundle options) {
+    public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
+        Bundle options) {
+
         if (options != null && options.containsKey(AccountManager.KEY_PASSWORD)) {
-            final String password =
-                options.getString(AccountManager.KEY_PASSWORD);
-            final boolean verified =
-                onlineConfirmPassword(account.name, password);
+            final String password = options.getString(AccountManager.KEY_PASSWORD);
+            final boolean verified = onlineConfirmPassword(account.name, password);
             final Bundle result = new Bundle();
             result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, verified);
             return result;
@@ -76,45 +67,35 @@
         // Launch AuthenticatorActivity to confirm credentials
         final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
         intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
-        intent.putExtra(AuthenticatorActivity.PARAM_CONFIRMCREDENTIALS, true);
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
-            response);
+        intent.putExtra(AuthenticatorActivity.PARAM_CONFIRM_CREDENTIALS, true);
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
         final Bundle bundle = new Bundle();
         bundle.putParcelable(AccountManager.KEY_INTENT, intent);
         return bundle;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Bundle editProperties(AccountAuthenticatorResponse response,
-        String accountType) {
+    public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
         throw new UnsupportedOperationException();
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Bundle getAuthToken(AccountAuthenticatorResponse response,
-        Account account, String authTokenType, Bundle loginOptions) {
+    public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
+        String authTokenType, Bundle loginOptions) {
+
         if (!authTokenType.equals(Constants.AUTHTOKEN_TYPE)) {
             final Bundle result = new Bundle();
-            result.putString(AccountManager.KEY_ERROR_MESSAGE,
-                "invalid authTokenType");
+            result.putString(AccountManager.KEY_ERROR_MESSAGE, "invalid authTokenType");
             return result;
         }
         final AccountManager am = AccountManager.get(mContext);
         final String password = am.getPassword(account);
         if (password != null) {
-            final boolean verified =
-                onlineConfirmPassword(account.name, password);
+            final boolean verified = onlineConfirmPassword(account.name, password);
             if (verified) {
                 final Bundle result = new Bundle();
                 result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-                result.putString(AccountManager.KEY_ACCOUNT_TYPE,
-                    Constants.ACCOUNT_TYPE);
+                result.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
                 result.putString(AccountManager.KEY_AUTHTOKEN, password);
                 return result;
             }
@@ -123,33 +104,25 @@
         // Activity that will prompt the user for the password.
         final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
         intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
-        intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE,
-            authTokenType);
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
-            response);
+        intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
         final Bundle bundle = new Bundle();
         bundle.putParcelable(AccountManager.KEY_INTENT, intent);
         return bundle;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public String getAuthTokenLabel(String authTokenType) {
-        if (authTokenType.equals(Constants.AUTHTOKEN_TYPE)) {
+        if (Constants.AUTHTOKEN_TYPE.equals(authTokenType)) {
             return mContext.getString(R.string.label);
         }
         return null;
-
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Bundle hasFeatures(AccountAuthenticatorResponse response,
-        Account account, String[] features) {
+    public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
+        String[] features) {
+
         final Bundle result = new Bundle();
         result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
         return result;
@@ -159,24 +132,20 @@
      * Validates user's password on the server
      */
     private boolean onlineConfirmPassword(String username, String password) {
-        return NetworkUtilities.authenticate(username, password,
-            null/* Handler */, null/* Context */);
+        return NetworkUtilities
+            .authenticate(username, password, null/* Handler */, null/* Context */);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Bundle updateCredentials(AccountAuthenticatorResponse response,
-        Account account, String authTokenType, Bundle loginOptions) {
+    public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
+        String authTokenType, Bundle loginOptions) {
+
         final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
         intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
-        intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE,
-            authTokenType);
-        intent.putExtra(AuthenticatorActivity.PARAM_CONFIRMCREDENTIALS, false);
+        intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
+        intent.putExtra(AuthenticatorActivity.PARAM_CONFIRM_CREDENTIALS, false);
         final Bundle bundle = new Bundle();
         bundle.putParcelable(AccountManager.KEY_INTENT, intent);
         return bundle;
     }
-
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java
index 779e894..4e1ee2a 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.authenticator;
 
 import android.accounts.Account;
@@ -42,16 +41,28 @@
  * Activity which displays login screen to the user.
  */
 public class AuthenticatorActivity extends AccountAuthenticatorActivity {
-    public static final String PARAM_CONFIRMCREDENTIALS = "confirmCredentials";
+
+    /** The Intent flag to confirm credentials. **/
+    public static final String PARAM_CONFIRM_CREDENTIALS = "confirmCredentials";
+
+    /** The Intent extra to store password. **/
     public static final String PARAM_PASSWORD = "password";
+
+    /** The Intent extra to store username. **/
     public static final String PARAM_USERNAME = "username";
+
+    /** The Intent extra to store authtoken type. **/
     public static final String PARAM_AUTHTOKEN_TYPE = "authtokenType";
 
+    /** The tag used to log to adb console. **/
     private static final String TAG = "AuthenticatorActivity";
 
     private AccountManager mAccountManager;
+
     private Thread mAuthThread;
+
     private String mAuthtoken;
+
     private String mAuthtokenType;
 
     /**
@@ -62,14 +73,18 @@
 
     /** for posting authentication attempts back to UI thread */
     private final Handler mHandler = new Handler();
+
     private TextView mMessage;
+
     private String mPassword;
+
     private EditText mPasswordEdit;
 
     /** Was the original caller asking for an entirely new account? */
     protected boolean mRequestNewAccount = false;
 
     private String mUsername;
+
     private EditText mUsernameEdit;
 
     /**
@@ -77,6 +92,7 @@
      */
     @Override
     public void onCreate(Bundle icicle) {
+
         Log.i(TAG, "onCreate(" + icicle + ")");
         super.onCreate(icicle);
         mAccountManager = AccountManager.get(this);
@@ -85,19 +101,15 @@
         mUsername = intent.getStringExtra(PARAM_USERNAME);
         mAuthtokenType = intent.getStringExtra(PARAM_AUTHTOKEN_TYPE);
         mRequestNewAccount = mUsername == null;
-        mConfirmCredentials =
-            intent.getBooleanExtra(PARAM_CONFIRMCREDENTIALS, false);
-
+        mConfirmCredentials = intent.getBooleanExtra(PARAM_CONFIRM_CREDENTIALS, false);
         Log.i(TAG, "    request new: " + mRequestNewAccount);
         requestWindowFeature(Window.FEATURE_LEFT_ICON);
         setContentView(R.layout.login_activity);
         getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
             android.R.drawable.ic_dialog_alert);
-
         mMessage = (TextView) findViewById(R.id.message);
         mUsernameEdit = (EditText) findViewById(R.id.username_edit);
         mPasswordEdit = (EditText) findViewById(R.id.password_edit);
-
         mUsernameEdit.setText(mUsername);
         mMessage.setText(getMessage());
     }
@@ -152,7 +164,7 @@
      * 
      * @param the confirmCredentials result.
      */
-    protected void finishConfirmCredentials(boolean result) {
+    private void finishConfirmCredentials(boolean result) {
         Log.i(TAG, "finishConfirmCredentials()");
         final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE);
         mAccountManager.setPassword(account, mPassword);
@@ -164,7 +176,6 @@
     }
 
     /**
-     * 
      * Called when response is received from the server for authentication
      * request. See onAuthenticationResult(). Sets the
      * AccountAuthenticatorResult which is sent back to the caller. Also sets
@@ -172,26 +183,22 @@
      * 
      * @param the confirmCredentials result.
      */
+    private void finishLogin() {
 
-    protected void finishLogin() {
         Log.i(TAG, "finishLogin()");
         final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE);
-
         if (mRequestNewAccount) {
             mAccountManager.addAccountExplicitly(account, mPassword, null);
             // Set contacts sync for this account.
-            ContentResolver.setSyncAutomatically(account,
-                ContactsContract.AUTHORITY, true);
+            ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true);
         } else {
             mAccountManager.setPassword(account, mPassword);
         }
         final Intent intent = new Intent();
         mAuthtoken = mPassword;
         intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mUsername);
-        intent
-            .putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
-        if (mAuthtokenType != null
-            && mAuthtokenType.equals(Constants.AUTHTOKEN_TYPE)) {
+        intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
+        if (mAuthtokenType != null && mAuthtokenType.equals(Constants.AUTHTOKEN_TYPE)) {
             intent.putExtra(AccountManager.KEY_AUTHTOKEN, mAuthtoken);
         }
         setAccountAuthenticatorResult(intent.getExtras());
@@ -202,7 +209,7 @@
     /**
      * Hides the progress UI for a lengthy operation.
      */
-    protected void hideProgress() {
+    private void hideProgress() {
         dismissDialog(0);
     }
 
@@ -210,6 +217,7 @@
      * Called when the authentication process completes (see attemptLogin()).
      */
     public void onAuthenticationResult(boolean result) {
+
         Log.i(TAG, "onAuthenticationResult(" + result + ")");
         // Hide the progress dialog
         hideProgress();
@@ -223,14 +231,12 @@
             Log.e(TAG, "onAuthenticationResult: failed to authenticate");
             if (mRequestNewAccount) {
                 // "Please enter a valid username/password.
-                mMessage
-                    .setText(getText(R.string.login_activity_loginfail_text_both));
+                mMessage.setText(getText(R.string.login_activity_loginfail_text_both));
             } else {
                 // "Please enter a valid password." (Used when the
                 // account is already in the database but the password
                 // doesn't work.)
-                mMessage
-                    .setText(getText(R.string.login_activity_loginfail_text_pwonly));
+                mMessage.setText(getText(R.string.login_activity_loginfail_text_pwonly));
             }
         }
     }
@@ -243,8 +249,7 @@
         if (TextUtils.isEmpty(mUsername)) {
             // If no username, then we ask the user to log in using an
             // appropriate service.
-            final CharSequence msg =
-                getText(R.string.login_activity_newaccount_text);
+            final CharSequence msg = getText(R.string.login_activity_newaccount_text);
             return msg;
         }
         if (TextUtils.isEmpty(mPassword)) {
@@ -257,7 +262,7 @@
     /**
      * Shows the progress UI for a lengthy operation.
      */
-    protected void showProgress() {
+    private void showProgress() {
         showDialog(0);
     }
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java
index 9d2b666..7824a4d 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.client;
 
 import android.accounts.Account;
@@ -52,21 +51,36 @@
 /**
  * Provides utility methods for communicating with the server.
  */
-public class NetworkUtilities {
+final public class NetworkUtilities {
+
+    /** The tag used to log to adb console. **/
     private static final String TAG = "NetworkUtilities";
-    public static final String PARAM_USERNAME = "username";
+
+    /** The Intent extra to store password. **/
     public static final String PARAM_PASSWORD = "password";
+
+    /** The Intent extra to store username. **/
+    public static final String PARAM_USERNAME = "username";
+
     public static final String PARAM_UPDATED = "timestamp";
+
     public static final String USER_AGENT = "AuthenticationService/1.0";
-    public static final int REGISTRATION_TIMEOUT = 30 * 1000; // ms
-    public static final String BASE_URL =
-        "https://samplesyncadapter.appspot.com";
+
+    public static final int REGISTRATION_TIMEOUT_MS = 30 * 1000; // ms
+
+    public static final String BASE_URL = "https://samplesyncadapter.appspot.com";
+
     public static final String AUTH_URI = BASE_URL + "/auth";
-    public static final String FETCH_FRIEND_UPDATES_URI =
-        BASE_URL + "/fetch_friend_updates";
+
+    public static final String FETCH_FRIEND_UPDATES_URI = BASE_URL + "/fetch_friend_updates";
+
     public static final String FETCH_STATUS_URI = BASE_URL + "/fetch_status";
+
     private static HttpClient mHttpClient;
 
+    private NetworkUtilities() {
+    }
+
     /**
      * Configures the httpClient to connect to the URL provided.
      */
@@ -74,10 +88,9 @@
         if (mHttpClient == null) {
             mHttpClient = new DefaultHttpClient();
             final HttpParams params = mHttpClient.getParams();
-            HttpConnectionParams.setConnectionTimeout(params,
-                REGISTRATION_TIMEOUT);
-            HttpConnectionParams.setSoTimeout(params, REGISTRATION_TIMEOUT);
-            ConnManagerParams.setTimeout(params, REGISTRATION_TIMEOUT);
+            HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT_MS);
+            HttpConnectionParams.setSoTimeout(params, REGISTRATION_TIMEOUT_MS);
+            ConnManagerParams.setTimeout(params, REGISTRATION_TIMEOUT_MS);
         }
     }
 
@@ -94,7 +107,6 @@
                 try {
                     runnable.run();
                 } finally {
-
                 }
             }
         };
@@ -113,10 +125,10 @@
      * @return boolean The boolean result indicating whether the user was
      *         successfully authenticated.
      */
-    public static boolean authenticate(String username, String password,
-        Handler handler, final Context context) {
-        final HttpResponse resp;
+    public static boolean authenticate(String username, String password, Handler handler,
+        final Context context) {
 
+        final HttpResponse resp;
         final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
         params.add(new BasicNameValuePair(PARAM_USERNAME, username));
         params.add(new BasicNameValuePair(PARAM_PASSWORD, password));
@@ -131,7 +143,6 @@
         post.addHeader(entity.getContentType());
         post.setEntity(entity);
         maybeCreateHttpClient();
-
         try {
             resp = mHttpClient.execute(post);
             if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
@@ -189,8 +200,9 @@
      * @param context The caller Activity's context
      * @return Thread The thread on which the network mOperations are executed.
      */
-    public static Thread attemptAuth(final String username,
-        final String password, final Handler handler, final Context context) {
+    public static Thread attemptAuth(final String username, final String password,
+        final Handler handler, final Context context) {
+
         final Runnable runnable = new Runnable() {
             public void run() {
                 authenticate(username, password, handler, context);
@@ -208,32 +220,27 @@
      * @param lastUpdated The last time that sync was performed
      * @return list The list of updates received from the server.
      */
-    public static List<User> fetchFriendUpdates(Account account,
-        String authtoken, Date lastUpdated) throws JSONException,
-        ParseException, IOException, AuthenticationException {
+    public static List<User> fetchFriendUpdates(Account account, String authtoken, Date lastUpdated)
+        throws JSONException, ParseException, IOException, AuthenticationException {
+
         final ArrayList<User> friendList = new ArrayList<User>();
         final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
         params.add(new BasicNameValuePair(PARAM_USERNAME, account.name));
         params.add(new BasicNameValuePair(PARAM_PASSWORD, authtoken));
         if (lastUpdated != null) {
-            final SimpleDateFormat formatter =
-                new SimpleDateFormat("yyyy/MM/dd HH:mm");
+            final SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm");
             formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
-            params.add(new BasicNameValuePair(PARAM_UPDATED, formatter
-                .format(lastUpdated)));
+            params.add(new BasicNameValuePair(PARAM_UPDATED, formatter.format(lastUpdated)));
         }
         Log.i(TAG, params.toString());
-
         HttpEntity entity = null;
         entity = new UrlEncodedFormEntity(params);
         final HttpPost post = new HttpPost(FETCH_FRIEND_UPDATES_URI);
         post.addHeader(entity.getContentType());
         post.setEntity(entity);
         maybeCreateHttpClient();
-
         final HttpResponse resp = mHttpClient.execute(post);
         final String response = EntityUtils.toString(resp.getEntity());
-
         if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
             // Succesfully connected to the samplesyncadapter server and
             // authenticated.
@@ -245,12 +252,10 @@
             }
         } else {
             if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
-                Log.e(TAG,
-                    "Authentication exception in fetching remote contacts");
+                Log.e(TAG, "Authentication exception in fetching remote contacts");
                 throw new AuthenticationException();
             } else {
-                Log.e(TAG, "Server error in fetching remote contacts: "
-                    + resp.getStatusLine());
+                Log.e(TAG, "Server error in fetching remote contacts: " + resp.getStatusLine());
                 throw new IOException();
             }
         }
@@ -265,24 +270,21 @@
      *        account
      * @return list The list of status messages received from the server.
      */
-    public static List<User.Status> fetchFriendStatuses(Account account,
-        String authtoken) throws JSONException, ParseException, IOException,
-        AuthenticationException {
+    public static List<User.Status> fetchFriendStatuses(Account account, String authtoken)
+        throws JSONException, ParseException, IOException, AuthenticationException {
+
         final ArrayList<User.Status> statusList = new ArrayList<User.Status>();
         final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
         params.add(new BasicNameValuePair(PARAM_USERNAME, account.name));
         params.add(new BasicNameValuePair(PARAM_PASSWORD, authtoken));
-
         HttpEntity entity = null;
         entity = new UrlEncodedFormEntity(params);
         final HttpPost post = new HttpPost(FETCH_STATUS_URI);
         post.addHeader(entity.getContentType());
         post.setEntity(entity);
         maybeCreateHttpClient();
-
         final HttpResponse resp = mHttpClient.execute(post);
         final String response = EntityUtils.toString(resp.getEntity());
-
         if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
             // Succesfully connected to the samplesyncadapter server and
             // authenticated.
@@ -293,8 +295,7 @@
             }
         } else {
             if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
-                Log.e(TAG,
-                    "Authentication exception in fetching friend status list");
+                Log.e(TAG, "Authentication exception in fetching friend status list");
                 throw new AuthenticationException();
             } else {
                 Log.e(TAG, "Server error in fetching friend status list");
@@ -303,5 +304,4 @@
         }
         return statusList;
     }
-
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/User.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/User.java
index 6ce9b3f..217a383 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/User.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/User.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.client;
 
 import android.util.Log;
@@ -23,16 +22,24 @@
 /**
  * Represents a sample SyncAdapter user
  */
-public class User {
+final public class User {
 
     private final String mUserName;
+
     private final String mFirstName;
+
     private final String mLastName;
+
     private final String mCellPhone;
+
     private final String mOfficePhone;
+
     private final String mHomePhone;
+
     private final String mEmail;
+
     private final boolean mDeleted;
+
     private final int mUserId;
 
     public int getUserId() {
@@ -71,9 +78,9 @@
         return mDeleted;
     }
 
-    public User(String name, String firstName, String lastName,
-        String cellPhone, String officePhone, String homePhone, String email,
-        Boolean deleted, Integer userId) {
+    private User(String name, String firstName, String lastName, String cellPhone,
+        String officePhone, String homePhone, String email, Boolean deleted, Integer userId) {
+
         mUserName = name;
         mFirstName = firstName;
         mLastName = lastName;
@@ -92,34 +99,33 @@
      * @return user The new instance of Voiper user created from the JSON data.
      */
     public static User valueOf(JSONObject user) {
+
         try {
             final String userName = user.getString("u");
             final String firstName = user.has("f") ? user.getString("f") : null;
             final String lastName = user.has("l") ? user.getString("l") : null;
             final String cellPhone = user.has("m") ? user.getString("m") : null;
-            final String officePhone =
-                user.has("o") ? user.getString("o") : null;
+            final String officePhone = user.has("o") ? user.getString("o") : null;
             final String homePhone = user.has("h") ? user.getString("h") : null;
             final String email = user.has("e") ? user.getString("e") : null;
-            final boolean deleted =
-                user.has("d") ? user.getBoolean("d") : false;
+            final boolean deleted = user.has("d") ? user.getBoolean("d") : false;
             final int userId = user.getInt("i");
-            return new User(userName, firstName, lastName, cellPhone,
-                officePhone, homePhone, email, deleted, userId);
+            return new User(userName, firstName, lastName, cellPhone, officePhone, homePhone,
+                email, deleted, userId);
         } catch (final Exception ex) {
             Log.i("User", "Error parsing JSON user object" + ex.toString());
-
         }
         return null;
-
     }
 
     /**
      * Represents the User's status messages
      * 
      */
-    public static class Status {
+    final public static class Status {
+
         private final Integer mUserId;
+
         private final String mStatus;
 
         public int getUserId() {
@@ -146,5 +152,4 @@
             return null;
         }
     }
-
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/BatchOperation.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/BatchOperation.java
index 509d151..0be3daa 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/BatchOperation.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/BatchOperation.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.platform;
 
 import android.content.ContentProviderOperation;
@@ -29,12 +28,14 @@
 /**
  * This class handles execution of batch mOperations on Contacts provider.
  */
-public class BatchOperation {
+final public class BatchOperation {
+
     private final String TAG = "BatchOperation";
 
     private final ContentResolver mResolver;
+
     // List for storing the batch mOperations
-    ArrayList<ContentProviderOperation> mOperations;
+    private final ArrayList<ContentProviderOperation> mOperations;
 
     public BatchOperation(Context context, ContentResolver resolver) {
         mResolver = resolver;
@@ -50,6 +51,7 @@
     }
 
     public void execute() {
+
         if (mOperations.size() == 0) {
             return;
         }
@@ -63,5 +65,4 @@
         }
         mOperations.clear();
     }
-
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
index 4f71be0..218b165 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.platform;
 
 import android.content.ContentResolver;
@@ -41,10 +40,12 @@
  * Class for managing contacts sync related mOperations
  */
 public class ContactManager {
+
     /**
      * Custom IM protocol used when storing status messages.
      */
     public static final String CUSTOM_IM_PROTOCOL = "SampleSyncAdapter";
+
     private static final String TAG = "ContactManager";
 
     /**
@@ -54,13 +55,12 @@
      * @param account The username for the account
      * @param users The list of users
      */
-    public static synchronized void syncContacts(Context context,
-        String account, List<User> users) {
+    public static synchronized void syncContacts(Context context, String account, List<User> users) {
+
         long userId;
         long rawContactId = 0;
         final ContentResolver resolver = context.getContentResolver();
-        final BatchOperation batchOperation =
-            new BatchOperation(context, resolver);
+        final BatchOperation batchOperation = new BatchOperation(context, resolver);
         Log.d(TAG, "In SyncContacts");
         for (final User user : users) {
             userId = user.getUserId();
@@ -69,8 +69,7 @@
             if (rawContactId != 0) {
                 if (!user.isDeleted()) {
                     // update contact
-                    updateContact(context, resolver, account, user,
-                        rawContactId, batchOperation);
+                    updateContact(context, resolver, account, user, rawContactId, batchOperation);
                 } else {
                     // delete contact
                     deleteContact(context, rawContactId, batchOperation);
@@ -98,17 +97,15 @@
      * @param accountName the username of the logged in user
      * @param statuses the list of statuses to store
      */
-    public static void insertStatuses(Context context, String username,
-        List<User.Status> list) {
+    public static void insertStatuses(Context context, String username, List<User.Status> list) {
+
         final ContentValues values = new ContentValues();
         final ContentResolver resolver = context.getContentResolver();
-        final BatchOperation batchOperation =
-            new BatchOperation(context, resolver);
+        final BatchOperation batchOperation = new BatchOperation(context, resolver);
         for (final User.Status status : list) {
             // Look up the user's sample SyncAdapter data row
             final long userId = status.getUserId();
             final long profileId = lookupProfile(resolver, userId);
-
             // Insert the activity into the stream
             if (profileId > 0) {
                 values.put(StatusUpdates.DATA_ID, profileId);
@@ -117,15 +114,11 @@
                 values.put(StatusUpdates.CUSTOM_PROTOCOL, CUSTOM_IM_PROTOCOL);
                 values.put(StatusUpdates.IM_ACCOUNT, username);
                 values.put(StatusUpdates.IM_HANDLE, status.getUserId());
-                values.put(StatusUpdates.STATUS_RES_PACKAGE, context
-                    .getPackageName());
+                values.put(StatusUpdates.STATUS_RES_PACKAGE, context.getPackageName());
                 values.put(StatusUpdates.STATUS_ICON, R.drawable.icon);
                 values.put(StatusUpdates.STATUS_LABEL, R.string.label);
-
-                batchOperation
-                    .add(ContactOperations.newInsertCpo(
-                        StatusUpdates.CONTENT_URI, true).withValues(values)
-                        .build());
+                batchOperation.add(ContactOperations.newInsertCpo(StatusUpdates.CONTENT_URI, true)
+                    .withValues(values).build());
                 // A sync adapter should batch operations on multiple contacts,
                 // because it will make a dramatic performance difference.
                 if (batchOperation.size() >= 50) {
@@ -143,16 +136,16 @@
      * @param accountName the account the contact belongs to
      * @param user the sample SyncAdapter User object
      */
-    private static void addContact(Context context, String accountName,
-        User user, BatchOperation batchOperation) {
+    private static void addContact(Context context, String accountName, User user,
+        BatchOperation batchOperation) {
+
         // Put the data in the contacts provider
         final ContactOperations contactOp =
-            ContactOperations.createNewContact(context, user.getUserId(),
-                accountName, batchOperation);
-        contactOp.addName(user.getFirstName(), user.getLastName()).addEmail(
-            user.getEmail()).addPhone(user.getCellPhone(), Phone.TYPE_MOBILE)
-            .addPhone(user.getHomePhone(), Phone.TYPE_OTHER).addProfileAction(
-                user.getUserId());
+            ContactOperations.createNewContact(context, user.getUserId(), accountName,
+                batchOperation);
+        contactOp.addName(user.getFirstName(), user.getLastName()).addEmail(user.getEmail())
+            .addPhone(user.getCellPhone(), Phone.TYPE_MOBILE).addPhone(user.getHomePhone(),
+                Phone.TYPE_OTHER).addProfileAction(user.getUserId());
     }
 
     /**
@@ -165,76 +158,57 @@
      * @param rawContactId the unique Id for this rawContact in contacts
      *        provider
      */
-    private static void updateContact(Context context,
-        ContentResolver resolver, String accountName, User user,
-        long rawContactId, BatchOperation batchOperation) {
+    private static void updateContact(Context context, ContentResolver resolver,
+        String accountName, User user, long rawContactId, BatchOperation batchOperation) {
+
         Uri uri;
         String cellPhone = null;
         String otherPhone = null;
         String email = null;
-
         final Cursor c =
-            resolver.query(Data.CONTENT_URI, DataQuery.PROJECTION,
-                DataQuery.SELECTION,
+            resolver.query(Data.CONTENT_URI, DataQuery.PROJECTION, DataQuery.SELECTION,
                 new String[] {String.valueOf(rawContactId)}, null);
         final ContactOperations contactOp =
-            ContactOperations.updateExistingContact(context, rawContactId,
-                batchOperation);
-
+            ContactOperations.updateExistingContact(context, rawContactId, batchOperation);
         try {
             while (c.moveToNext()) {
                 final long id = c.getLong(DataQuery.COLUMN_ID);
                 final String mimeType = c.getString(DataQuery.COLUMN_MIMETYPE);
                 uri = ContentUris.withAppendedId(Data.CONTENT_URI, id);
-
                 if (mimeType.equals(StructuredName.CONTENT_ITEM_TYPE)) {
-                    final String lastName =
-                        c.getString(DataQuery.COLUMN_FAMILY_NAME);
-                    final String firstName =
-                        c.getString(DataQuery.COLUMN_GIVEN_NAME);
-                    contactOp.updateName(uri, firstName, lastName, user
-                        .getFirstName(), user.getLastName());
-                }
-
-                else if (mimeType.equals(Phone.CONTENT_ITEM_TYPE)) {
+                    final String lastName = c.getString(DataQuery.COLUMN_FAMILY_NAME);
+                    final String firstName = c.getString(DataQuery.COLUMN_GIVEN_NAME);
+                    contactOp.updateName(uri, firstName, lastName, user.getFirstName(), user
+                        .getLastName());
+                } else if (mimeType.equals(Phone.CONTENT_ITEM_TYPE)) {
                     final int type = c.getInt(DataQuery.COLUMN_PHONE_TYPE);
-
                     if (type == Phone.TYPE_MOBILE) {
                         cellPhone = c.getString(DataQuery.COLUMN_PHONE_NUMBER);
-                        contactOp.updatePhone(cellPhone, user.getCellPhone(),
-                            uri);
+                        contactOp.updatePhone(cellPhone, user.getCellPhone(), uri);
                     } else if (type == Phone.TYPE_OTHER) {
                         otherPhone = c.getString(DataQuery.COLUMN_PHONE_NUMBER);
-                        contactOp.updatePhone(otherPhone, user.getHomePhone(),
-                            uri);
+                        contactOp.updatePhone(otherPhone, user.getHomePhone(), uri);
                     }
-                }
-
-                else if (Data.MIMETYPE.equals(Email.CONTENT_ITEM_TYPE)) {
+                } else if (Data.MIMETYPE.equals(Email.CONTENT_ITEM_TYPE)) {
                     email = c.getString(DataQuery.COLUMN_EMAIL_ADDRESS);
                     contactOp.updateEmail(user.getEmail(), email, uri);
-
                 }
             } // while
         } finally {
             c.close();
         }
-
         // Add the cell phone, if present and not updated above
         if (cellPhone == null) {
             contactOp.addPhone(user.getCellPhone(), Phone.TYPE_MOBILE);
         }
-
         // Add the other phone, if present and not updated above
         if (otherPhone == null) {
             contactOp.addPhone(user.getHomePhone(), Phone.TYPE_OTHER);
         }
-
         // Add the email address, if present and not updated above
         if (email == null) {
             contactOp.addEmail(user.getEmail());
         }
-
     }
 
     /**
@@ -246,9 +220,9 @@
      */
     private static void deleteContact(Context context, long rawContactId,
         BatchOperation batchOperation) {
+
         batchOperation.add(ContactOperations.newDeleteCpo(
-            ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
-            true).build());
+            ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), true).build());
     }
 
     /**
@@ -260,11 +234,11 @@
      * @return the RawContact id, or 0 if not found
      */
     private static long lookupRawContact(ContentResolver resolver, long userId) {
+
         long authorId = 0;
         final Cursor c =
-            resolver.query(RawContacts.CONTENT_URI, UserIdQuery.PROJECTION,
-                UserIdQuery.SELECTION, new String[] {String.valueOf(userId)},
-                null);
+            resolver.query(RawContacts.CONTENT_URI, UserIdQuery.PROJECTION, UserIdQuery.SELECTION,
+                new String[] {String.valueOf(userId)}, null);
         try {
             if (c.moveToFirst()) {
                 authorId = c.getLong(UserIdQuery.COLUMN_ID);
@@ -286,11 +260,11 @@
      * @return the profile Data row id, or 0 if not found
      */
     private static long lookupProfile(ContentResolver resolver, long userId) {
+
         long profileId = 0;
         final Cursor c =
-            resolver.query(Data.CONTENT_URI, ProfileQuery.PROJECTION,
-                ProfileQuery.SELECTION, new String[] {String.valueOf(userId)},
-                null);
+            resolver.query(Data.CONTENT_URI, ProfileQuery.PROJECTION, ProfileQuery.SELECTION,
+                new String[] {String.valueOf(userId)}, null);
         try {
             if (c != null && c.moveToFirst()) {
                 profileId = c.getLong(ProfileQuery.COLUMN_ID);
@@ -307,22 +281,30 @@
      * Constants for a query to find a contact given a sample SyncAdapter user
      * ID.
      */
-    private interface ProfileQuery {
+    final private static class ProfileQuery {
+
+        private ProfileQuery() {
+        }
+
         public final static String[] PROJECTION = new String[] {Data._ID};
 
         public final static int COLUMN_ID = 0;
 
         public static final String SELECTION =
-            Data.MIMETYPE + "='" + SampleSyncAdapterColumns.MIME_PROFILE
-                + "' AND " + SampleSyncAdapterColumns.DATA_PID + "=?";
+            Data.MIMETYPE + "='" + SampleSyncAdapterColumns.MIME_PROFILE + "' AND "
+                + SampleSyncAdapterColumns.DATA_PID + "=?";
     }
+
     /**
      * Constants for a query to find a contact given a sample SyncAdapter user
      * ID.
      */
-    private interface UserIdQuery {
-        public final static String[] PROJECTION =
-            new String[] {RawContacts._ID};
+    final private static class UserIdQuery {
+
+        private UserIdQuery() {
+        }
+
+        public final static String[] PROJECTION = new String[] {RawContacts._ID};
 
         public final static int COLUMN_ID = 0;
 
@@ -334,21 +316,34 @@
     /**
      * Constants for a query to get contact data for a given rawContactId
      */
-    private interface DataQuery {
+    final private static class DataQuery {
+
+        private DataQuery() {
+        }
+
         public static final String[] PROJECTION =
-            new String[] {Data._ID, Data.MIMETYPE, Data.DATA1, Data.DATA2,
-                Data.DATA3,};
+            new String[] {Data._ID, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3,};
 
         public static final int COLUMN_ID = 0;
+
         public static final int COLUMN_MIMETYPE = 1;
+
         public static final int COLUMN_DATA1 = 2;
+
         public static final int COLUMN_DATA2 = 3;
+
         public static final int COLUMN_DATA3 = 4;
+
         public static final int COLUMN_PHONE_NUMBER = COLUMN_DATA1;
+
         public static final int COLUMN_PHONE_TYPE = COLUMN_DATA2;
+
         public static final int COLUMN_EMAIL_ADDRESS = COLUMN_DATA1;
+
         public static final int COLUMN_EMAIL_TYPE = COLUMN_DATA2;
+
         public static final int COLUMN_GIVEN_NAME = COLUMN_DATA2;
+
         public static final int COLUMN_FAMILY_NAME = COLUMN_DATA3;
 
         public static final String SELECTION = Data.RAW_CONTACT_ID + "=?";
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java
index 9e47f70..db01f48 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.platform;
 
 import android.content.ContentProviderOperation;
@@ -38,12 +37,19 @@
 public class ContactOperations {
 
     private final ContentValues mValues;
+
     private ContentProviderOperation.Builder mBuilder;
+
     private final BatchOperation mBatchOperation;
+
     private final Context mContext;
+
     private boolean mYield;
+
     private long mRawContactId;
+
     private int mBackReference;
+
     private boolean mIsNewContact;
 
     /**
@@ -55,10 +61,10 @@
      * @param accountName the username of the current login
      * @return instance of ContactOperations
      */
-    public static ContactOperations createNewContact(Context context,
-        int userId, String accountName, BatchOperation batchOperation) {
-        return new ContactOperations(context, userId, accountName,
-            batchOperation);
+    public static ContactOperations createNewContact(Context context, int userId,
+        String accountName, BatchOperation batchOperation) {
+
+        return new ContactOperations(context, userId, accountName, batchOperation);
     }
 
     /**
@@ -69,8 +75,9 @@
      * @param rawContactId the unique Id of the existing rawContact
      * @return instance of ContactOperations
      */
-    public static ContactOperations updateExistingContact(Context context,
-        long rawContactId, BatchOperation batchOperation) {
+    public static ContactOperations updateExistingContact(Context context, long rawContactId,
+        BatchOperation batchOperation) {
+
         return new ContactOperations(context, rawContactId, batchOperation);
     }
 
@@ -83,19 +90,18 @@
 
     public ContactOperations(Context context, int userId, String accountName,
         BatchOperation batchOperation) {
+
         this(context, batchOperation);
         mBackReference = mBatchOperation.size();
         mIsNewContact = true;
         mValues.put(RawContacts.SOURCE_ID, userId);
         mValues.put(RawContacts.ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
         mValues.put(RawContacts.ACCOUNT_NAME, accountName);
-        mBuilder =
-            newInsertCpo(RawContacts.CONTENT_URI, true).withValues(mValues);
+        mBuilder = newInsertCpo(RawContacts.CONTENT_URI, true).withValues(mValues);
         mBatchOperation.add(mBuilder.build());
     }
 
-    public ContactOperations(Context context, long rawContactId,
-        BatchOperation batchOperation) {
+    public ContactOperations(Context context, long rawContactId, BatchOperation batchOperation) {
         this(context, batchOperation);
         mIsNewContact = false;
         mRawContactId = rawContactId;
@@ -109,16 +115,15 @@
      * @return instance of ContactOperations
      */
     public ContactOperations addName(String firstName, String lastName) {
+
         mValues.clear();
         if (!TextUtils.isEmpty(firstName)) {
             mValues.put(StructuredName.GIVEN_NAME, firstName);
-            mValues.put(StructuredName.MIMETYPE,
-                StructuredName.CONTENT_ITEM_TYPE);
+            mValues.put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
         }
         if (!TextUtils.isEmpty(lastName)) {
             mValues.put(StructuredName.FAMILY_NAME, lastName);
-            mValues.put(StructuredName.MIMETYPE,
-                StructuredName.CONTENT_ITEM_TYPE);
+            mValues.put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
         }
         if (mValues.size() > 0) {
             addInsertOp();
@@ -188,8 +193,7 @@
      * @param uri Uri for the existing raw contact to be updated
      * @return instance of ContactOperations
      */
-    public ContactOperations updateEmail(String email, String existingEmail,
-        Uri uri) {
+    public ContactOperations updateEmail(String email, String existingEmail, Uri uri) {
         if (!TextUtils.equals(existingEmail, email)) {
             mValues.clear();
             mValues.put(Email.DATA, email);
@@ -207,10 +211,11 @@
      * @param uri Uri for the existing raw contact to be updated
      * @return instance of ContactOperations
      */
-    public ContactOperations updateName(Uri uri, String existingFirstName,
-        String existingLastName, String firstName, String lastName) {
-        Log.i("ContactOperations", "ef=" + existingFirstName + "el="
-            + existingLastName + "f=" + firstName + "l=" + lastName);
+    public ContactOperations updateName(Uri uri, String existingFirstName, String existingLastName,
+        String firstName, String lastName) {
+
+        Log.i("ContactOperations", "ef=" + existingFirstName + "el=" + existingLastName + "f="
+            + firstName + "l=" + lastName);
         mValues.clear();
         if (!TextUtils.equals(existingFirstName, firstName)) {
             mValues.put(StructuredName.GIVEN_NAME, firstName);
@@ -232,8 +237,7 @@
      * @param uri Uri for the existing raw contact to be updated
      * @return instance of ContactOperations
      */
-    public ContactOperations updatePhone(String existingNumber, String phone,
-        Uri uri) {
+    public ContactOperations updatePhone(String existingNumber, String phone, Uri uri) {
         if (!TextUtils.equals(phone, existingNumber)) {
             mValues.clear();
             mValues.put(Phone.NUMBER, phone);
@@ -260,16 +264,14 @@
      * Adds an insert operation into the batch
      */
     private void addInsertOp() {
+
         if (!mIsNewContact) {
             mValues.put(Phone.RAW_CONTACT_ID, mRawContactId);
         }
-        mBuilder =
-            newInsertCpo(addCallerIsSyncAdapterParameter(Data.CONTENT_URI),
-                mYield);
+        mBuilder = newInsertCpo(addCallerIsSyncAdapterParameter(Data.CONTENT_URI), mYield);
         mBuilder.withValues(mValues);
         if (mIsNewContact) {
-            mBuilder
-                .withValueBackReference(Data.RAW_CONTACT_ID, mBackReference);
+            mBuilder.withValueBackReference(Data.RAW_CONTACT_ID, mBackReference);
         }
         mYield = false;
         mBatchOperation.add(mBuilder.build());
@@ -284,28 +286,23 @@
         mBatchOperation.add(mBuilder.build());
     }
 
-    public static ContentProviderOperation.Builder newInsertCpo(Uri uri,
-        boolean yield) {
-        return ContentProviderOperation.newInsert(
-            addCallerIsSyncAdapterParameter(uri)).withYieldAllowed(yield);
+    public static ContentProviderOperation.Builder newInsertCpo(Uri uri, boolean yield) {
+        return ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(uri))
+            .withYieldAllowed(yield);
     }
 
-    public static ContentProviderOperation.Builder newUpdateCpo(Uri uri,
-        boolean yield) {
-        return ContentProviderOperation.newUpdate(
-            addCallerIsSyncAdapterParameter(uri)).withYieldAllowed(yield);
+    public static ContentProviderOperation.Builder newUpdateCpo(Uri uri, boolean yield) {
+        return ContentProviderOperation.newUpdate(addCallerIsSyncAdapterParameter(uri))
+            .withYieldAllowed(yield);
     }
 
-    public static ContentProviderOperation.Builder newDeleteCpo(Uri uri,
-        boolean yield) {
-        return ContentProviderOperation.newDelete(
-            addCallerIsSyncAdapterParameter(uri)).withYieldAllowed(yield);
-
+    public static ContentProviderOperation.Builder newDeleteCpo(Uri uri, boolean yield) {
+        return ContentProviderOperation.newDelete(addCallerIsSyncAdapterParameter(uri))
+            .withYieldAllowed(yield);
     }
 
     private static Uri addCallerIsSyncAdapterParameter(Uri uri) {
-        return uri.buildUpon().appendQueryParameter(
-            ContactsContract.CALLER_IS_SYNCADAPTER, "true").build();
+        return uri.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+            .build();
     }
-
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/SampleSyncAdapterColumns.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/SampleSyncAdapterColumns.java
index bc02325..7b60d5b 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/SampleSyncAdapterColumns.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/SampleSyncAdapterColumns.java
@@ -20,7 +20,11 @@
 /*
  * The standard columns representing contact's info from social apps.
  */
-public interface SampleSyncAdapterColumns {
+public final class SampleSyncAdapterColumns {
+
+    private SampleSyncAdapterColumns() {
+    }
+
     /**
      * MIME-type used when storing a profile {@link Data} entry.
      */
@@ -28,7 +32,8 @@
         "vnd.android.cursor.item/vnd.samplesyncadapter.profile";
 
     public static final String DATA_PID = Data.DATA1;
-    public static final String DATA_SUMMARY = Data.DATA2;
-    public static final String DATA_DETAIL = Data.DATA3;
 
+    public static final String DATA_SUMMARY = Data.DATA2;
+
+    public static final String DATA_DETAIL = Data.DATA3;
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java
index 07525aa..206189a 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.syncadapter;
 
 import android.accounts.Account;
@@ -46,9 +45,11 @@
  * platform ContactOperations provider.
  */
 public class SyncAdapter extends AbstractThreadedSyncAdapter {
+
     private static final String TAG = "SyncAdapter";
 
     private final AccountManager mAccountManager;
+
     private final Context mContext;
 
     private Date mLastUpdated;
@@ -62,18 +63,17 @@
     @Override
     public void onPerformSync(Account account, Bundle extras, String authority,
         ContentProviderClient provider, SyncResult syncResult) {
+
         List<User> users;
         List<Status> statuses;
         String authtoken = null;
-         try {
-             // use the account manager to request the credentials
-             authtoken =
-                mAccountManager.blockingGetAuthToken(account,
-                    Constants.AUTHTOKEN_TYPE, true /* notifyAuthFailure */);
-             // fetch updates from the sample service over the cloud
-             users =
-                NetworkUtilities.fetchFriendUpdates(account, authtoken,
-                    mLastUpdated);
+        try {
+            // use the account manager to request the credentials
+            authtoken =
+                mAccountManager
+                    .blockingGetAuthToken(account, Constants.AUTHTOKEN_TYPE, true /* notifyAuthFailure */);
+            // fetch updates from the sample service over the cloud
+            users = NetworkUtilities.fetchFriendUpdates(account, authtoken, mLastUpdated);
             // update the last synced date.
             mLastUpdated = new Date();
             // update platform contacts.
@@ -91,8 +91,7 @@
             Log.e(TAG, "IOException", e);
             syncResult.stats.numIoExceptions++;
         } catch (final AuthenticationException e) {
-            mAccountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE,
-                authtoken);
+            mAccountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, authtoken);
             syncResult.stats.numAuthExceptions++;
             Log.e(TAG, "AuthenticationException", e);
         } catch (final ParseException e) {
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncService.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncService.java
index 256f91d..57b7747 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncService.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncService.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.example.android.samplesync.syncadapter;
 
 import android.app.Service;
@@ -26,12 +25,11 @@
  * IBinder.
  */
 public class SyncService extends Service {
+
     private static final Object sSyncAdapterLock = new Object();
+
     private static SyncAdapter sSyncAdapter = null;
 
-    /*
-     * {@inheritDoc}
-     */
     @Override
     public void onCreate() {
         synchronized (sSyncAdapterLock) {
@@ -41,9 +39,6 @@
         }
     }
 
-    /*
-     * {@inheritDoc}
-     */
     @Override
     public IBinder onBind(Intent intent) {
         return sSyncAdapter.getSyncAdapterBinder();
diff --git a/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/AllTests.java b/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/AllTests.java
new file mode 100644
index 0000000..6f4f006
--- /dev/null
+++ b/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/AllTests.java
@@ -0,0 +1,32 @@
+/*
+ * 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.example.android.apis;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import android.test.suitebuilder.TestSuiteBuilder;
+
+/**
+ * A test suite containing all tests for SampleSyncAdapter.
+ *
+ */
+public class AllTests extends TestSuite {
+
+    public static Test suite() {
+        return new TestSuiteBuilder(AllTests.class).includeAllPackagesUnderHere().build();
+    }
+}
diff --git a/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/authenticator/AuthenticatorActivityTest.java b/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/authenticator/AuthenticatorActivityTest.java
new file mode 100644
index 0000000..67d6fda
--- /dev/null
+++ b/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/authenticator/AuthenticatorActivityTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+package com.example.android.samplesync.authenticator;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.View;
+
+/**
+ * This is a series of unit tests for the {@link AuthenticatorActivity} class.
+ */
+@SmallTest
+public class AuthenticatorActivityTests extends
+    ActivityInstrumentationTestCase2<AuthenticatorActivity> {
+
+    private static final int ACTIVITY_WAIT = 10000;
+
+    private Instrumentation mInstrumentation;
+
+    private Context mContext;
+
+    public AuthenticatorActivityTests() {
+
+        super(AuthenticatorActivity.class);
+    }
+
+    /**
+     * Common setup code for all tests. Sets up a default launch intent, which
+     * some tests will use (others will override).
+     */
+    @Override
+    protected void setUp() throws Exception {
+
+        super.setUp();
+        mInstrumentation = this.getInstrumentation();
+        mContext = mInstrumentation.getTargetContext();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+
+        super.tearDown();
+    }
+
+    /**
+     * Confirm that Login is presented.
+     */
+    @SmallTest
+    public void testLoginOffered() {
+
+        Instrumentation.ActivityMonitor monitor =
+            mInstrumentation.addMonitor(AuthenticatorActivity.class.getName(), null, false);
+        Intent intent = new Intent(mContext, AuthenticatorActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mInstrumentation.startActivitySync(intent);
+        Activity activity = mInstrumentation.waitForMonitorWithTimeout(monitor, ACTIVITY_WAIT);
+        View loginbutton = activity.findViewById(R.id.ok_button);
+        int expected = View.VISIBLE;
+        assertEquals(expected, loginbutton.getVisibility());
+    }
+}
diff --git a/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/client/UserTest.java b/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/client/UserTest.java
new file mode 100644
index 0000000..4162340
--- /dev/null
+++ b/samples/SampleSyncAdapter/tests/src/com/example/android/samplesync/client/UserTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.example.android.samplesync.client;
+
+import com.example.android.samplesync.client.User;
+
+import junit.framework.TestCase;
+
+import org.json.JSONObject;
+
+public class UserTest extends TestCase {
+
+    @SmallTest
+    public void testConstructor() throws Exception {
+        User user =
+            new User("mjoshi", "Megha", "Joshi", "1-650-335-5681", "1-650-111-5681",
+                "1-650-222-5681", "test@google.com", false, 1);
+        assertEquals("Megha", user.getFirstName());
+        assertEquals("Joshi", user.getLastName());
+        assertEquals("mjoshi", user.getUserName());
+        assertEquals(1, user.getUserId());
+        assertEquals("1-650-335-5681", user.getCellPhone());
+        assertEquals(false, user.isDeleted());
+    }
+
+    @SmallTest
+    public void testValueOf() throws Exception {
+        JSONObject jsonObj = new JSONObject();
+        jsonObj.put("u", "mjoshi");
+        jsonObj.put("f", "Megha");
+        jsonObj.put("l", "Joshi");
+        jsonObj.put("i", 1);
+        User user = User.valueOf(jsonObj);
+        assertEquals("Megha", user.getFirstName());
+        assertEquals("Joshi", user.getLastName());
+        assertEquals("mjoshi", user.getUserName());
+        assertEquals(1, user.getUserId());
+    }
+}
diff --git a/samples/SearchableDictionary/AndroidManifest.xml b/samples/SearchableDictionary/AndroidManifest.xml
index 7ef031d..5d835ee 100644
--- a/samples/SearchableDictionary/AndroidManifest.xml
+++ b/samples/SearchableDictionary/AndroidManifest.xml
@@ -21,14 +21,14 @@
         android:versionCode="2"
         android:versionName="2.0">
 
-    <uses-sdk android:minSdkVersion="4" />
+    <uses-sdk android:minSdkVersion="11" />
 
     <application android:label="@string/app_name"
                  android:icon="@drawable/ic_dictionary">
 
         <!-- The default activity of the app; displays search results. -->
         <activity android:name=".SearchableDictionary"
-                  android:theme="@android:style/Theme.NoTitleBar">
+                  android:launchMode="singleTop">
 
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -48,8 +48,7 @@
         </activity>
 
         <!-- Displays the definition of a word. -->
-        <activity android:name=".WordActivity"
-                  android:theme="@android:style/Theme.NoTitleBar" />
+        <activity android:name=".WordActivity" />
 
         <!-- Provides search suggestions for words and their definitions. -->
         <provider android:name=".DictionaryProvider"
diff --git a/samples/SearchableDictionary/_index.html b/samples/SearchableDictionary/_index.html
index ce3ec54..1e929be 100644
--- a/samples/SearchableDictionary/_index.html
+++ b/samples/SearchableDictionary/_index.html
@@ -19,6 +19,14 @@
 bind data from a Cursor to a ListView.</li>
 </ul>
 
+<p><b>Revisions:</b></p>
+<ul>
+  <li>Updated for Android 3.0 to use the <a href="../../../guide/topics/ui/actionbar.html">Action
+Bar</a> and the <code><a
+href="../../../reference/android/widget/SearchView.html">SearchView</a></code> widget as an action item.
+(Available in the <em>Samples for SDK API 11</em>.)</li>
+</ul>
+
 <p>See also:</p>
 <ul>
   <li><a href="../../../guide/topics/search/index.html">Search Developer Guide</a></li>
diff --git a/samples/SearchableDictionary/res/menu/options_menu.xml b/samples/SearchableDictionary/res/menu/options_menu.xml
index 2aa7cf2..c35c7d4 100644
--- a/samples/SearchableDictionary/res/menu/options_menu.xml
+++ b/samples/SearchableDictionary/res/menu/options_menu.xml
@@ -20,5 +20,7 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:id="@+id/search"
           android:title="@string/menu_search"
-          android:icon="@drawable/ic_menu_search" />
+          android:icon="@drawable/ic_menu_search"
+          android:showAsAction="ifRoom"
+          android:actionViewClass="android.widget.SearchView" />
 </menu>
diff --git a/samples/SearchableDictionary/res/values/strings.xml b/samples/SearchableDictionary/res/values/strings.xml
index ee628ce..e7aa7c1 100644
--- a/samples/SearchableDictionary/res/values/strings.xml
+++ b/samples/SearchableDictionary/res/values/strings.xml
@@ -34,7 +34,7 @@
     <string name="settings_description">Definitions of words</string>
 
     <!-- General instructions in the main activity. -->
-    <string name="search_instructions">Press the search key to look up a word</string>
+    <string name="search_instructions">Use the search box in the Action Bar to look up a word</string>
 
     <!-- Shown above search results when we receive a search request. -->
     <plurals name="search_results">
diff --git a/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.java b/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.java
index ef938f8..a83ebce 100644
--- a/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.java
+++ b/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.java
@@ -17,7 +17,9 @@
 package com.example.android.searchabledict;
 
 import android.app.Activity;
+import android.app.ActionBar;
 import android.app.SearchManager;
+import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
@@ -28,6 +30,7 @@
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ListView;
+import android.widget.SearchView;
 import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
@@ -50,8 +53,19 @@
         mTextView = (TextView) findViewById(R.id.text);
         mListView = (ListView) findViewById(R.id.list);
 
-        Intent intent = getIntent();
+        handleIntent(getIntent());
+    }
 
+    @Override
+    protected void onNewIntent(Intent intent) {
+        // Because this activity has set launchMode="singleTop", the system calls this method
+        // to deliver the intent if this actvity is currently the foreground activity when
+        // invoked again (when the user executes a search from this activity, we don't create
+        // a new instance of this activity, so the system delivers the search intent here)
+        handleIntent(intent);
+    }
+
+    private void handleIntent(Intent intent) {
         if (Intent.ACTION_VIEW.equals(intent.getAction())) {
             // handles a click on a search suggestion; launches activity to show word
             Intent wordIntent = new Intent(this, WordActivity.class);
@@ -115,6 +129,12 @@
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.options_menu, menu);
+
+        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+        SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
+        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
+        searchView.setIconifiedByDefault(false);
+
         return true;
     }
 
diff --git a/samples/SearchableDictionary/src/com/example/android/searchabledict/WordActivity.java b/samples/SearchableDictionary/src/com/example/android/searchabledict/WordActivity.java
index 00dc270..d56a145 100644
--- a/samples/SearchableDictionary/src/com/example/android/searchabledict/WordActivity.java
+++ b/samples/SearchableDictionary/src/com/example/android/searchabledict/WordActivity.java
@@ -17,12 +17,17 @@
 package com.example.android.searchabledict;
 
 import android.app.Activity;
+import android.app.ActionBar;
+import android.app.SearchManager;
+import android.content.Context;
+import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
+import android.widget.SearchView;
 import android.widget.TextView;
 
 /**
@@ -35,6 +40,9 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.word);
 
+        ActionBar actionBar = getActionBar();
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
         Uri uri = getIntent().getData();
         Cursor cursor = managedQuery(uri, null, null, null, null);
 
@@ -58,6 +66,12 @@
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.options_menu, menu);
+
+        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+        SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
+        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
+        searchView.setIconifiedByDefault(false);
+        
         return true;
     }
 
@@ -67,6 +81,11 @@
             case R.id.search:
                 onSearchRequested();
                 return true;
+            case android.R.id.home:
+                Intent intent = new Intent(this, SearchableDictionary.class);
+                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                startActivity(intent);
+                return true;
             default:
                 return false;
         }
diff --git a/samples/SkeletonApp/AndroidManifest.xml b/samples/SkeletonApp/AndroidManifest.xml
index b0b4ef2..af5a694 100644
--- a/samples/SkeletonApp/AndroidManifest.xml
+++ b/samples/SkeletonApp/AndroidManifest.xml
@@ -25,7 +25,8 @@
      to come from a domain that you own or have control over. -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.skeletonapp">
-
+    
+    <uses-sdk android:targetSdkVersion="11"/>
     <!-- This package contains an application...  The 'label' is the name
          to display to the user for the overall application, and provides
          a default label for all following components.  The syntax here is a
diff --git a/samples/Spinner/AndroidManifest.xml b/samples/Spinner/AndroidManifest.xml
index 719a022..500c864 100644
--- a/samples/Spinner/AndroidManifest.xml
+++ b/samples/Spinner/AndroidManifest.xml
@@ -30,7 +30,8 @@
     <!--
         Requires a minimum platform version of Android-3 (SDK 1.5) to run
     -->
-    <uses-sdk android:minSdkVersion="3"/>
+    <uses-sdk android:minSdkVersion="3"
+      android:targetSdkVersion="11"/>
 
     <!--
         Sets the application's user-readable label
diff --git a/samples/StackWidget/Android.mk b/samples/StackWidget/Android.mk
new file mode 100644
index 0000000..016a454
--- /dev/null
+++ b/samples/StackWidget/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := StackWidget
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/StackWidget/AndroidManifest.xml b/samples/StackWidget/AndroidManifest.xml
new file mode 100644
index 0000000..1fec157
--- /dev/null
+++ b/samples/StackWidget/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     to come from a domain that you own or have control over. -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.stackwidget">
+    <uses-sdk android:targetSdkVersion="11" android:minSdkVersion="11"/>
+    <application android:label="StackWidget">
+        <receiver android:name="StackWidgetProvider">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+            <meta-data android:name="android.appwidget.provider"
+                android:resource="@xml/stackwidgetinfo" />
+        </receiver>
+
+        <service android:name="StackWidgetService"
+            android:permission="android.permission.BIND_REMOTEVIEWS"
+            android:exported="false" />
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/samples/StackWidget/_index.html b/samples/StackWidget/_index.html
new file mode 100644
index 0000000..e1af317
--- /dev/null
+++ b/samples/StackWidget/_index.html
@@ -0,0 +1,31 @@
+<p>
+    This sample shows how to construct a simple collection widget. This particular example shows how
+    to create a widget containing a <a href="../../../reference/android/widget/StackView.html"><code>StackView</code></a>
+    ; however, only minimal changes are required to include
+    a <a href="../../../reference/android/widget/ListView.html"><code>ListView</code></a>,
+    <a href="../../../reference/android/widget/GridView.html"><code>GridView</code></a> or
+    <a href="../../../reference/android/widget/AdapterViewFlipper.html"><code>AdapterViewFlipper</code></a> instead.
+</p>
+<p>
+    The sample demonstrates the following:
+</p>
+    <ul>
+        <li>
+            The pattern for creating and wiring a <a href="../../../reference/android/widget/RemoteViewsService.html"><code>RemoteViewsService</code></a>
+            and <a href="../../../reference/android/widget/RemoteViewsService.RemoteViewsFactory.html"><code>RemoteViewsFactory</code></a> which
+            serve the function of an adapter for the widget collection.
+        </li>
+        <li>
+            The pattern for setting an intent template and fill-in intents in order to
+            provide children of the collection with click behaviour.
+        </li>
+        <li>
+            How to make a widget with a <a href="../../../reference/android/widget/StackView.html"><code>StackView</code></a>
+            (or <a href="../../../reference/android/widget/AdapterViewFlipper.html"><code>AdapterViewFlipper</code></a>) auto-advance.
+        </li>
+        <li>
+            How to set a widget preview image.
+        </li>
+    </ul>
+<img alt="The widget."
+     src="../images/StackWidget.png"/>
\ No newline at end of file
diff --git a/samples/StackWidget/res/drawable-hdpi/icon.png b/samples/StackWidget/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/samples/StackWidget/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/samples/StackWidget/res/drawable-ldpi/icon.png b/samples/StackWidget/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/samples/StackWidget/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/samples/StackWidget/res/drawable-mdpi/icon.png b/samples/StackWidget/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/samples/StackWidget/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/samples/StackWidget/res/drawable-nodpi/preview.png b/samples/StackWidget/res/drawable-nodpi/preview.png
new file mode 100644
index 0000000..f2f83a0
--- /dev/null
+++ b/samples/StackWidget/res/drawable-nodpi/preview.png
Binary files differ
diff --git a/samples/StackWidget/res/drawable-nodpi/widget_item_background.xml b/samples/StackWidget/res/drawable-nodpi/widget_item_background.xml
new file mode 100644
index 0000000..c0b3843
--- /dev/null
+++ b/samples/StackWidget/res/drawable-nodpi/widget_item_background.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <gradient android:startColor="#ff666666" android:endColor="#ff333333" android:angle="270" />
+</shape>
diff --git a/samples/StackWidget/res/layout/widget_item.xml b/samples/StackWidget/res/layout/widget_item.xml
new file mode 100644
index 0000000..75e31ab
--- /dev/null
+++ b/samples/StackWidget/res/layout/widget_item.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/widget_item"
+    android:layout_width="120dp"
+    android:layout_height="120dp"
+    android:gravity="center"
+    android:background="@drawable/widget_item_background"
+    android:textColor="#ffffff"
+    android:textStyle="bold"
+    android:textSize="44sp" />
diff --git a/samples/StackWidget/res/layout/widget_layout.xml b/samples/StackWidget/res/layout/widget_layout.xml
new file mode 100644
index 0000000..11f9d36
--- /dev/null
+++ b/samples/StackWidget/res/layout/widget_layout.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <StackView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/stack_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:loopViews="true" />
+    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/empty_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:background="@drawable/widget_item_background"
+        android:textColor="#ffffff"
+        android:textStyle="bold"
+        android:text="@string/empty_view_text"
+        android:textSize="20sp" />
+</FrameLayout>
diff --git a/samples/StackWidget/res/values/strings.xml b/samples/StackWidget/res/values/strings.xml
new file mode 100644
index 0000000..acb2f7f
--- /dev/null
+++ b/samples/StackWidget/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<resources>
+    <string name="empty_view_text">This is the empty view</string>
+</resources>
diff --git a/samples/StackWidget/res/xml/stackwidgetinfo.xml b/samples/StackWidget/res/xml/stackwidgetinfo.xml
new file mode 100644
index 0000000..8c2630f
--- /dev/null
+++ b/samples/StackWidget/res/xml/stackwidgetinfo.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<appwidget-provider
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:minWidth="150dip"
+  android:minHeight="150dip"
+  android:updatePeriodMillis="3600000"
+  android:previewImage="@drawable/preview"
+  android:initialLayout="@layout/widget_layout"
+  android:autoAdvanceViewId="@id/stack_view">
+</appwidget-provider>
\ No newline at end of file
diff --git a/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetProvider.java b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetProvider.java
new file mode 100644
index 0000000..e053c21
--- /dev/null
+++ b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetProvider.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 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.example.android.stackwidget;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.widget.RemoteViews;
+import android.widget.Toast;
+
+public class StackWidgetProvider extends AppWidgetProvider {
+    public static final String TOAST_ACTION = "com.example.android.stackwidget.TOAST_ACTION";
+    public static final String EXTRA_ITEM = "com.example.android.stackwidget.EXTRA_ITEM";
+
+    @Override
+    public void onDeleted(Context context, int[] appWidgetIds) {
+        super.onDeleted(context, appWidgetIds);
+    }
+
+    @Override
+    public void onDisabled(Context context) {
+        super.onDisabled(context);
+    }
+
+    @Override
+    public void onEnabled(Context context) {
+        super.onEnabled(context);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        AppWidgetManager mgr = AppWidgetManager.getInstance(context);
+        if (intent.getAction().equals(TOAST_ACTION)) {
+            int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                    AppWidgetManager.INVALID_APPWIDGET_ID);
+            int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0);
+            Toast.makeText(context, "Touched view " + viewIndex, Toast.LENGTH_SHORT).show();
+        }
+        super.onReceive(context, intent);
+    }
+
+    @Override
+    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+        // update each of the widgets with the remote adapter
+        for (int i = 0; i < appWidgetIds.length; ++i) {
+
+            // Here we setup the intent which points to the StackViewService which will
+            // provide the views for this collection.
+            Intent intent = new Intent(context, StackWidgetService.class);
+            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
+            // When intents are compared, the extras are ignored, so we need to embed the extras
+            // into the data so that the extras will not be ignored.
+            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
+            RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
+            rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent);
+
+            // The empty view is displayed when the collection has no items. It should be a sibling
+            // of the collection view.
+            rv.setEmptyView(R.id.stack_view, R.id.empty_view);
+
+            // Here we setup the a pending intent template. Individuals items of a collection
+            // cannot setup their own pending intents, instead, the collection as a whole can
+            // setup a pending intent template, and the individual items can set a fillInIntent
+            // to create unique before on an item to item basis.
+            Intent toastIntent = new Intent(context, StackWidgetProvider.class);
+            toastIntent.setAction(StackWidgetProvider.TOAST_ACTION);
+            toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
+            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
+            PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
+                    PendingIntent.FLAG_UPDATE_CURRENT);
+            rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent);
+
+            appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
+        }
+        super.onUpdate(context, appWidgetManager, appWidgetIds);
+    }
+}
\ No newline at end of file
diff --git a/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetService.java b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetService.java
new file mode 100644
index 0000000..d53b0ea
--- /dev/null
+++ b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetService.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2011 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.example.android.stackwidget;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.RemoteViews;
+import android.widget.RemoteViewsService;
+
+public class StackWidgetService extends RemoteViewsService {
+    @Override
+    public RemoteViewsFactory onGetViewFactory(Intent intent) {
+        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
+    }
+}
+
+class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
+    private static final int mCount = 10;
+    private List<WidgetItem> mWidgetItems = new ArrayList<WidgetItem>();
+    private Context mContext;
+    private int mAppWidgetId;
+
+    public StackRemoteViewsFactory(Context context, Intent intent) {
+        mContext = context;
+        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                AppWidgetManager.INVALID_APPWIDGET_ID);
+    }
+
+    public void onCreate() {
+        // In onCreate() you setup any connections / cursors to your data source. Heavy lifting,
+        // for example downloading or creating content etc, should be deferred to onDataSetChanged()
+        // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR.
+        for (int i = 0; i < mCount; i++) {
+            mWidgetItems.add(new WidgetItem(i + "!"));
+        }
+
+        // We sleep for 3 seconds here to show how the empty view appears in the interim.
+        // The empty view is set in the StackWidgetProvider and should be a sibling of the
+        // collection view.
+        try {
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void onDestroy() {
+        // In onDestroy() you should tear down anything that was setup for your data source,
+        // eg. cursors, connections, etc.
+        mWidgetItems.clear();
+    }
+
+    public int getCount() {
+        return mCount;
+    }
+
+    public RemoteViews getViewAt(int position) {
+        // position will always range from 0 to getCount() - 1.
+
+        // We construct a remote views item based on our widget item xml file, and set the
+        // text based on the position.
+        RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
+        rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);
+
+        // Next, we set a fill-intent which will be used to fill-in the pending intent template
+        // which is set on the collection view in StackWidgetProvider.
+        Bundle extras = new Bundle();
+        extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
+        Intent fillInIntent = new Intent();
+        fillInIntent.putExtras(extras);
+        rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
+
+        // You can do heaving lifting in here, synchronously. For example, if you need to
+        // process an image, fetch something from the network, etc., it is ok to do it here,
+        // synchronously. A loading view will show up in lieu of the actual contents in the
+        // interim.
+        try {
+            System.out.println("Loading view " + position);
+            Thread.sleep(500);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        // Return the remote views object.
+        return rv;
+    }
+
+    public RemoteViews getLoadingView() {
+        // You can create a custom loading view (for instance when getViewAt() is slow.) If you
+        // return null here, you will get the default loading view.
+        return null;
+    }
+
+    public int getViewTypeCount() {
+        return 1;
+    }
+
+    public long getItemId(int position) {
+        return position;
+    }
+
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    public void onDataSetChanged() {
+        // This is triggered when you call AppWidgetManager notifyAppWidgetViewDataChanged
+        // on the collection view corresponding to this factory. You can do heaving lifting in
+        // here, synchronously. For example, if you need to process an image, fetch something
+        // from the network, etc., it is ok to do it here, synchronously. The widget will remain
+        // in its current state while work is being done here, so you don't need to worry about
+        // locking up the widget.
+    }
+}
\ No newline at end of file
diff --git a/samples/StackWidget/src/com/example/android/stackwidget/WidgetItem.java b/samples/StackWidget/src/com/example/android/stackwidget/WidgetItem.java
new file mode 100644
index 0000000..aa822ca
--- /dev/null
+++ b/samples/StackWidget/src/com/example/android/stackwidget/WidgetItem.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 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.example.android.stackwidget;
+
+public class WidgetItem {
+    public String text;
+
+    public WidgetItem(String text) {
+        this.text = text;
+    }
+}
diff --git a/samples/USB/AdbTest/Android.mk b/samples/USB/AdbTest/Android.mk
new file mode 100644
index 0000000..bfb9fa8
--- /dev/null
+++ b/samples/USB/AdbTest/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := AdbTest
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/samples/USB/AdbTest/AndroidManifest.xml b/samples/USB/AdbTest/AndroidManifest.xml
new file mode 100644
index 0000000..9690ccf
--- /dev/null
+++ b/samples/USB/AdbTest/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.adb">
+
+    <uses-feature android:name="android.hardware.usb.host" />
+    <uses-sdk android:minSdkVersion="12" />
+
+    <application>
+        <activity android:name="AdbTestActivity" android:label="ADB Test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
+            </intent-filter>
+
+            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
+                android:resource="@xml/device_filter" />
+        </activity>
+    </application>
+
+</manifest>
diff --git a/samples/USB/AdbTest/README.txt b/samples/USB/AdbTest/README.txt
new file mode 100644
index 0000000..3fd9cbb
--- /dev/null
+++ b/samples/USB/AdbTest/README.txt
@@ -0,0 +1,11 @@
+AdbTest is a sample program that implements a subset of the adb USB protocol.
+Currently it only implements the "adb logcat" command and displays the log
+output in a text view and only allows connecting to one device at a time.
+However the support classes are structured in a way that would allow
+connecting to multiple devices and running multiple adb commands simultaneously.
+
+This program serves as an example of the following USB host features:
+
+- Matching devices based on interface class, subclass and protocol (see device_filter.xml)
+
+- Asynchronous IO on bulk endpoints
\ No newline at end of file
diff --git a/samples/USB/AdbTest/_index.html b/samples/USB/AdbTest/_index.html
new file mode 100644
index 0000000..424ee5b
--- /dev/null
+++ b/samples/USB/AdbTest/_index.html
@@ -0,0 +1,13 @@
+<p>AdbTest is a sample program that implements a subset of the <code>adb</code> USB protocol.
+Currently it only implements the <code>adb logcat</code> command and displays the log
+output in a text view and only allows connecting to one device at a time.
+However, the support classes are structured in a way that would allow
+connecting to multiple devices and running multiple <code>adb</code> commands simultaneously.</p>
+
+<p>This program serves as an example of the following USB host features:</p>
+
+<ul> 
+<li>Matching devices based on interface class, subclass and protocol (see <code>device_filter.xml</code>)</li>
+
+<li>Asynchronous IO on bulk endpoints</li>
+</ul>
\ No newline at end of file
diff --git a/samples/USB/AdbTest/default.properties b/samples/USB/AdbTest/default.properties
new file mode 100644
index 0000000..3ac2523
--- /dev/null
+++ b/samples/USB/AdbTest/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-12
diff --git a/samples/USB/AdbTest/res/layout/adb.xml b/samples/USB/AdbTest/res/layout/adb.xml
new file mode 100644
index 0000000..10994d5
--- /dev/null
+++ b/samples/USB/AdbTest/res/layout/adb.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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"
+    >
+
+    <TextView android:id="@+id/log"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="25dp"
+        android:textSize="18sp"
+        android:textColor="#ffffffff"
+        />
+
+</LinearLayout>
+
+
diff --git a/samples/USB/AdbTest/res/xml/device_filter.xml b/samples/USB/AdbTest/res/xml/device_filter.xml
new file mode 100644
index 0000000..bc6fa04
--- /dev/null
+++ b/samples/USB/AdbTest/res/xml/device_filter.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<resources>
+    <usb-device class="255" subclass="66" protocol="1" />
+</resources>
diff --git a/samples/USB/AdbTest/src/com/android/adb/AdbDevice.java b/samples/USB/AdbTest/src/com/android/adb/AdbDevice.java
new file mode 100644
index 0000000..f793ce4
--- /dev/null
+++ b/samples/USB/AdbTest/src/com/android/adb/AdbDevice.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2011 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.adb;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbRequest;
+import android.util.SparseArray;
+
+import java.util.LinkedList;
+
+/* This class represents a USB device that supports the adb protocol. */
+public class AdbDevice {
+
+    private final AdbTestActivity mActivity;
+    private final UsbDeviceConnection mDeviceConnection;
+    private final UsbEndpoint mEndpointOut;
+    private final UsbEndpoint mEndpointIn;
+
+    private String mSerial;
+
+    // pool of requests for the OUT endpoint
+    private final LinkedList<UsbRequest> mOutRequestPool = new LinkedList<UsbRequest>();
+    // pool of requests for the IN endpoint
+    private final LinkedList<UsbRequest> mInRequestPool = new LinkedList<UsbRequest>();
+    // list of currently opened sockets
+    private final SparseArray<AdbSocket> mSockets = new SparseArray<AdbSocket>();
+    private int mNextSocketId = 1;
+
+    private final WaiterThread mWaiterThread = new WaiterThread();
+
+    public AdbDevice(AdbTestActivity activity, UsbDeviceConnection connection,
+            UsbInterface intf) {
+        mActivity = activity;
+        mDeviceConnection = connection;
+        mSerial = connection.getSerial();
+
+        UsbEndpoint epOut = null;
+        UsbEndpoint epIn = null;
+        // look for our bulk endpoints
+        for (int i = 0; i < intf.getEndpointCount(); i++) {
+            UsbEndpoint ep = intf.getEndpoint(i);
+            if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
+                if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
+                    epOut = ep;
+                } else {
+                    epIn = ep;
+                }
+            }
+        }
+        if (epOut == null || epIn == null) {
+            throw new IllegalArgumentException("not all endpoints found");
+        }
+        mEndpointOut = epOut;
+        mEndpointIn = epIn;
+    }
+
+    // return device serial number
+    public String getSerial() {
+        return mSerial;
+    }
+
+    // get an OUT request from our pool
+    public UsbRequest getOutRequest() {
+        synchronized(mOutRequestPool) {
+            if (mOutRequestPool.isEmpty()) {
+                UsbRequest request = new UsbRequest();
+                request.initialize(mDeviceConnection, mEndpointOut);
+                return request;
+            } else {
+                return mOutRequestPool.removeFirst();
+            }
+        }
+    }
+
+    // return an OUT request to the pool
+    public void releaseOutRequest(UsbRequest request) {
+        synchronized (mOutRequestPool) {
+            mOutRequestPool.add(request);
+        }
+    }
+
+    // get an IN request from the pool
+    public UsbRequest getInRequest() {
+        synchronized(mInRequestPool) {
+            if (mInRequestPool.isEmpty()) {
+                UsbRequest request = new UsbRequest();
+                request.initialize(mDeviceConnection, mEndpointIn);
+                return request;
+            } else {
+                return mInRequestPool.removeFirst();
+            }
+        }
+    }
+
+    public void start() {
+        mWaiterThread.start();
+        connect();
+    }
+
+    public AdbSocket openSocket(String destination) {
+        AdbSocket socket;
+        synchronized (mSockets) {
+            int id = mNextSocketId++;
+            socket = new AdbSocket(this, id);
+            mSockets.put(id, socket);
+        }
+        if (socket.open(destination)) {
+            return socket;
+        } else {
+            return null;
+        }
+    }
+
+    private AdbSocket getSocket(int id) {
+        synchronized (mSockets) {
+            return mSockets.get(id);
+        }
+    }
+
+    public void socketClosed(AdbSocket socket) {
+        synchronized (mSockets) {
+            mSockets.remove(socket.getId());
+        }
+    }
+
+    // send a connect command
+    private void connect() {
+        AdbMessage message = new AdbMessage();
+        message.set(AdbMessage.A_CNXN, AdbMessage.A_VERSION, AdbMessage.MAX_PAYLOAD, "host::\0");
+        message.write(this);
+    }
+
+    // handle connect response
+    private void handleConnect(AdbMessage message) {
+        if (message.getDataString().startsWith("device:")) {
+            log("connected");
+            mActivity.deviceOnline(this);
+        }
+    }
+
+    public void stop() {
+        synchronized (mWaiterThread) {
+            mWaiterThread.mStop = true;
+        }
+    }
+
+    // dispatch a message from the device
+    void dispatchMessage(AdbMessage message) {
+        int command = message.getCommand();
+        switch (command) {
+            case AdbMessage.A_SYNC:
+                log("got A_SYNC");
+                break;
+            case AdbMessage.A_CNXN:
+                handleConnect(message);
+                break;
+            case AdbMessage.A_OPEN:
+            case AdbMessage.A_OKAY:
+            case AdbMessage.A_CLSE:
+            case AdbMessage.A_WRTE:
+                AdbSocket socket = getSocket(message.getArg1());
+                if (socket == null) {
+                    log("ERROR socket not found");
+                } else {
+                    socket.handleMessage(message);
+                }
+                break;
+        }
+    }
+
+    void log(String s) {
+        mActivity.log(s);
+    }
+
+
+    private class WaiterThread extends Thread {
+        public boolean mStop;
+
+        public void run() {
+            // start out with a command read
+            AdbMessage currentCommand = new AdbMessage();
+            AdbMessage currentData = null;
+            // FIXME error checking
+            currentCommand.readCommand(getInRequest());
+
+            while (true) {
+                synchronized (this) {
+                    if (mStop) {
+                        return;
+                    }
+                }
+                UsbRequest request = mDeviceConnection.requestWait();
+                if (request == null) {
+                    break;
+                }
+
+                AdbMessage message = (AdbMessage)request.getClientData();
+                request.setClientData(null);
+                AdbMessage messageToDispatch = null;
+
+                if (message == currentCommand) {
+                    int dataLength = message.getDataLength();
+                    // read data if length > 0
+                    if (dataLength > 0) {
+                        message.readData(getInRequest(), dataLength);
+                        currentData = message;
+                    } else {
+                        messageToDispatch = message;
+                    }
+                    currentCommand = null;
+                } else if (message == currentData) {
+                    messageToDispatch = message;
+                    currentData = null;
+                }
+
+                if (messageToDispatch != null) {
+                    // queue another read first
+                    currentCommand = new AdbMessage();
+                    currentCommand.readCommand(getInRequest());
+
+                    // then dispatch the current message
+                    dispatchMessage(messageToDispatch);
+                }
+
+                // put request back into the appropriate pool
+                if (request.getEndpoint() == mEndpointOut) {
+                    releaseOutRequest(request);
+                } else {
+                    synchronized (mInRequestPool) {
+                        mInRequestPool.add(request);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/samples/USB/AdbTest/src/com/android/adb/AdbMessage.java b/samples/USB/AdbTest/src/com/android/adb/AdbMessage.java
new file mode 100644
index 0000000..1dbb136
--- /dev/null
+++ b/samples/USB/AdbTest/src/com/android/adb/AdbMessage.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 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.adb;
+
+import android.hardware.usb.UsbRequest;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/* This class encapsulates and adb command packet */
+public class AdbMessage {
+
+    // command names
+    public static final int A_SYNC = 0x434e5953;
+    public static final int A_CNXN = 0x4e584e43;
+    public static final int A_OPEN = 0x4e45504f;
+    public static final int A_OKAY = 0x59414b4f;
+    public static final int A_CLSE = 0x45534c43;
+    public static final int A_WRTE = 0x45545257;
+
+    // ADB protocol version
+    public static final int A_VERSION = 0x01000000;
+
+    public static final int MAX_PAYLOAD = 4096;
+
+    private final ByteBuffer mMessageBuffer;
+    private final ByteBuffer mDataBuffer;
+
+    public AdbMessage() {
+        mMessageBuffer = ByteBuffer.allocate(24);
+        mDataBuffer = ByteBuffer.allocate(MAX_PAYLOAD);
+        mMessageBuffer.order(ByteOrder.LITTLE_ENDIAN);
+        mDataBuffer.order(ByteOrder.LITTLE_ENDIAN);
+    }
+
+    // sets the fields in the command header
+    public void set(int command, int arg0, int arg1, byte[] data) {
+        mMessageBuffer.putInt(0, command);
+        mMessageBuffer.putInt(4, arg0);
+        mMessageBuffer.putInt(8, arg1);
+        mMessageBuffer.putInt(12, (data == null ? 0 : data.length));
+        mMessageBuffer.putInt(16, (data == null ? 0 : checksum(data)));
+        mMessageBuffer.putInt(20, command ^ 0xFFFFFFFF);
+        if (data != null) {
+            mDataBuffer.put(data, 0, data.length);
+        }
+    }
+
+    public void set(int command, int arg0, int arg1) {
+        set(command, arg0, arg1, (byte[])null);
+    }
+    public void set(int command, int arg0, int arg1, String data) {
+        // add trailing zero
+        data += "\0";
+        set(command, arg0, arg1, data.getBytes());
+    }
+
+    // returns the command's message ID
+    public int getCommand() {
+        return mMessageBuffer.getInt(0);
+    }
+
+    // returns command's first argument
+    public int getArg0() {
+        return mMessageBuffer.getInt(4);
+    }
+
+    // returns command's second argument
+    public int getArg1() {
+        return mMessageBuffer.getInt(8);
+    }
+
+    // returns command's data buffer
+    public ByteBuffer getData() {
+        return mDataBuffer;
+    }
+
+    // returns command's data length
+    public int getDataLength() {
+        return mMessageBuffer.getInt(12);
+    }
+
+    // returns command's data as a string
+    public String getDataString() {
+        int length = getDataLength();
+        if (length == 0) return null;
+        // trim trailing zero
+        return new String(mDataBuffer.array(), 0, length - 1);
+    }
+
+
+    public boolean write(AdbDevice device) {
+        synchronized (device) {
+            UsbRequest request = device.getOutRequest();
+            request.setClientData(this);
+            if (request.queue(mMessageBuffer, 24)) {
+                int length = getDataLength();
+                if (length > 0) {
+                    request = device.getOutRequest();
+                    request.setClientData(this);
+                    if (request.queue(mDataBuffer, length)) {
+                        return true;
+                    } else {
+                        device.releaseOutRequest(request);
+                        return false;
+                    }
+                }
+                return true;
+            } else {
+                device.releaseOutRequest(request);
+                return false;
+            }
+        }
+    }
+
+    public boolean readCommand(UsbRequest request) {
+        request.setClientData(this);
+        return request.queue(mMessageBuffer, 24);
+    }
+
+    public boolean readData(UsbRequest request, int length) {
+        request.setClientData(this);
+        return request.queue(mDataBuffer, length);
+    }
+
+    private static String extractString(ByteBuffer buffer, int offset, int length) {
+        byte[] bytes = new byte[length];
+        for (int i = 0; i < length; i++) {
+            bytes[i] = buffer.get(offset++);
+        }
+        return new String(bytes);
+    }
+
+    @Override
+    public String toString() {
+        String commandName = extractString(mMessageBuffer, 0, 4);
+        int dataLength = getDataLength();
+        String result = "Adb Message: " + commandName + " arg0: " + getArg0() +
+             " arg1: " + getArg1() + " dataLength: " + dataLength;
+        if (dataLength > 0) {
+            result += (" data: \"" + getDataString() + "\"");
+        }
+        return result;
+    }
+
+    private static int checksum(byte[] data) {
+        int result = 0;
+        for (int i = 0; i < data.length; i++) {
+            int x = data[i];
+            // dang, no unsigned ints in java
+            if (x < 0) x += 256;
+            result += x;
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/samples/USB/AdbTest/src/com/android/adb/AdbSocket.java b/samples/USB/AdbTest/src/com/android/adb/AdbSocket.java
new file mode 100644
index 0000000..deb5980
--- /dev/null
+++ b/samples/USB/AdbTest/src/com/android/adb/AdbSocket.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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.adb;
+
+/* This class represents an adb socket.  adb supports multiple independent
+ * socket connections to a single device.  Typically a socket is created
+ * for each adb command that is executed.
+ */
+public class AdbSocket {
+
+    private final AdbDevice mDevice;
+    private final int mId;
+    private int mPeerId;
+
+    public AdbSocket(AdbDevice device, int id) {
+        mDevice = device;
+        mId = id;
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    public boolean open(String destination) {
+        AdbMessage message = new AdbMessage();
+        message.set(AdbMessage.A_OPEN, mId, 0, destination);
+        if (! message.write(mDevice)) {
+            return false;
+        }
+
+        synchronized (this) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public void handleMessage(AdbMessage message) {
+        switch (message.getCommand()) {
+            case AdbMessage.A_OKAY:
+                mPeerId = message.getArg0();
+                synchronized (this) {
+                    notify();
+                }
+                break;
+            case AdbMessage.A_WRTE:
+                mDevice.log(message.getDataString());
+                sendReady();
+                break;
+        }
+    }
+
+    private void sendReady() {
+        AdbMessage message = new AdbMessage();
+        message.set(AdbMessage.A_OKAY, mId, mPeerId);
+        message.write(mDevice);
+    }
+}
diff --git a/samples/USB/AdbTest/src/com/android/adb/AdbTestActivity.java b/samples/USB/AdbTest/src/com/android/adb/AdbTestActivity.java
new file mode 100644
index 0000000..bd11977
--- /dev/null
+++ b/samples/USB/AdbTest/src/com/android/adb/AdbTestActivity.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2011 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.adb;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Rect;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.widget.TextView;
+
+/* Main activity for the adb test program */
+public class AdbTestActivity extends Activity {
+
+    private static final String TAG = "AdbTestActivity";
+
+    private TextView mLog;
+    private UsbManager mManager;
+    private UsbDevice mDevice;
+    private UsbDeviceConnection mDeviceConnection;
+    private UsbInterface mInterface;
+    private AdbDevice mAdbDevice;
+
+    private static final int MESSAGE_LOG = 1;
+    private static final int MESSAGE_DEVICE_ONLINE = 2;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.adb);
+        mLog = (TextView)findViewById(R.id.log);
+
+        mManager = (UsbManager)getSystemService(Context.USB_SERVICE);
+
+        // check for existing devices
+        for (UsbDevice device :  mManager.getDeviceList().values()) {
+            UsbInterface intf = findAdbInterface(device);
+            if (setAdbInterface(device, intf)) {
+                break;
+            }
+        }
+
+        // listen for new devices
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+        registerReceiver(mUsbReceiver, filter);
+    }
+
+    @Override
+    public void onDestroy() {
+        unregisterReceiver(mUsbReceiver);
+        setAdbInterface(null, null);
+        super.onDestroy();
+    }
+
+    public void log(String s) {
+        Message m = Message.obtain(mHandler, MESSAGE_LOG);
+        m.obj = s;
+        mHandler.sendMessage(m);
+    }
+
+    private void appendLog(String text) {
+        Rect r = new Rect();
+        mLog.getDrawingRect(r);
+        int maxLines = r.height() / mLog.getLineHeight() - 1;
+        text = mLog.getText() + "\n" + text;
+
+        // see how many lines we have
+        int index = text.lastIndexOf('\n');
+        int count = 0;
+        while (index > 0 && count <= maxLines) {
+            count++;
+            index = text.lastIndexOf('\n', index - 1);
+        }
+
+        // truncate to maxLines
+        if (index > 0) {
+            text = text.substring(index + 1);
+        }
+        mLog.setText(text);
+    }
+
+    public void deviceOnline(AdbDevice device) {
+        Message m = Message.obtain(mHandler, MESSAGE_DEVICE_ONLINE);
+        m.obj = device;
+        mHandler.sendMessage(m);
+    }
+
+    private void handleDeviceOnline(AdbDevice device) {
+        log("device online: " + device.getSerial());
+        device.openSocket("shell:exec logcat");
+    }
+
+    // Sets the current USB device and interface
+    private boolean setAdbInterface(UsbDevice device, UsbInterface intf) {
+        if (mDeviceConnection != null) {
+            if (mInterface != null) {
+                mDeviceConnection.releaseInterface(mInterface);
+                mInterface = null;
+            }
+            mDeviceConnection.close();
+            mDevice = null;
+            mDeviceConnection = null;
+        }
+
+        if (device != null && intf != null) {
+            UsbDeviceConnection connection = mManager.openDevice(device);
+            if (connection != null) {
+                log("open succeeded");
+                if (connection.claimInterface(intf, false)) {
+                    log("claim interface succeeded");
+                    mDevice = device;
+                    mDeviceConnection = connection;
+                    mInterface = intf;
+                    mAdbDevice = new AdbDevice(this, mDeviceConnection, intf);
+                    log("call start");
+                    mAdbDevice.start();
+                    return true;
+                } else {
+                    log("claim interface failed");
+                    connection.close();
+                }
+            } else {
+                log("open failed");
+            }
+        }
+
+        if (mDeviceConnection == null && mAdbDevice != null) {
+            mAdbDevice.stop();
+            mAdbDevice = null;
+        }
+        return false;
+    }
+
+    // searches for an adb interface on the given USB device
+    static private UsbInterface findAdbInterface(UsbDevice device) {
+        Log.d(TAG, "findAdbInterface " + device);
+        int count = device.getInterfaceCount();
+        for (int i = 0; i < count; i++) {
+            UsbInterface intf = device.getInterface(i);
+            if (intf.getInterfaceClass() == 255 && intf.getInterfaceSubclass() == 66 &&
+                    intf.getInterfaceProtocol() == 1) {
+                return intf;
+            }
+        }
+        return null;
+    }
+
+    BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+
+            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
+                UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+                UsbInterface intf = findAdbInterface(device);
+                if (intf != null) {
+                    log("Found adb interface " + intf);
+                    setAdbInterface(device, intf);
+                }
+            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
+                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+                String deviceName = device.getDeviceName();
+                if (mDevice != null && mDevice.equals(deviceName)) {
+                    log("adb interface removed");
+                    setAdbInterface(null, null);
+                }
+            }
+        }
+    };
+
+    Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_LOG:
+                    appendLog((String)msg.obj);
+                    break;
+                case MESSAGE_DEVICE_ONLINE:
+                    handleDeviceOnline((AdbDevice)msg.obj);
+                    break;
+            }
+        }
+    };
+}
+
+
diff --git a/samples/USB/Android.mk b/samples/USB/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/samples/USB/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/samples/USB/MissileLauncher/Android.mk b/samples/USB/MissileLauncher/Android.mk
new file mode 100644
index 0000000..daabb0c
--- /dev/null
+++ b/samples/USB/MissileLauncher/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := MissileLauncher
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/samples/USB/MissileLauncher/AndroidManifest.xml b/samples/USB/MissileLauncher/AndroidManifest.xml
new file mode 100644
index 0000000..b1c2c2b
--- /dev/null
+++ b/samples/USB/MissileLauncher/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.missilelauncher">
+
+    <uses-feature android:name="android.hardware.usb.host" />
+    <uses-sdk android:minSdkVersion="12" />
+
+    <application>
+        <activity android:name="MissileLauncherActivity"
+            android:label="Missile Launcher"
+            android:screenOrientation="nosensor">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
+            </intent-filter>
+
+            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
+                android:resource="@xml/device_filter" />
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/USB/MissileLauncher/README.txt b/samples/USB/MissileLauncher/README.txt
new file mode 100644
index 0000000..863baad
--- /dev/null
+++ b/samples/USB/MissileLauncher/README.txt
@@ -0,0 +1,13 @@
+MissileLauncher is a simple program that controls Dream Cheeky USB missile launchers.
+You control the left/right/up/down orientation of the launcher using the accelerometer.
+Tilt the tablet to change the direction of the launcher.
+Pressing the "Fire" button will fire one missile.
+
+This program serves as an example of the following USB host features:
+
+- filtering for multiple devices based on vendor and product IDs (see device_filter.xml)
+
+- Sending control requests on endpoint zero that contain data
+
+- Receiving packets on an interrupt endpoint using a thread that calls
+  UsbRequest.queue and UsbDeviceConnection.requestWait()
diff --git a/samples/USB/MissileLauncher/_index.html b/samples/USB/MissileLauncher/_index.html
new file mode 100644
index 0000000..99a5cf4
--- /dev/null
+++ b/samples/USB/MissileLauncher/_index.html
@@ -0,0 +1,11 @@
+<p>MissileLauncher is a simple program that controls Dream Cheeky USB missile launchers.
+You control the left/right/up/down orientation of the launcher using the accelerometer.
+Tilt the tablet to change the direction of the launcher. Pressing the <strong>Fire</strong> button will fire one missile.</p>
+
+<p>This program serves as an example of the following USB host features:</p>
+<ul>
+<li>filtering for multiple devices based on vendor and product IDs (see <code>device_filter.xml</code>)</li>
+<li>Sending control requests on endpoint zero that contain data</li>
+<li>Receiving packets on an interrupt endpoint using a thread that calls
+  {@link android.hardware.usb.UsbRequest#queue queue()} and {@link android.hardware.usb.UsbDeviceConnection#requestWait requestWait()}.</li>
+</p>
\ No newline at end of file
diff --git a/samples/USB/MissileLauncher/default.properties b/samples/USB/MissileLauncher/default.properties
new file mode 100644
index 0000000..3ac2523
--- /dev/null
+++ b/samples/USB/MissileLauncher/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-12
diff --git a/samples/USB/MissileLauncher/res/layout/launcher.xml b/samples/USB/MissileLauncher/res/layout/launcher.xml
new file mode 100644
index 0000000..1e488f7
--- /dev/null
+++ b/samples/USB/MissileLauncher/res/layout/launcher.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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"
+    >
+
+        <Button android:id="@+id/fire"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="25dp"
+            android:layout_marginBottom="25dp"
+            android:layout_marginLeft="25dp"
+            android:layout_marginRight="25dp"
+            android:textSize="36sp"
+            android:text="@string/fire">
+        </Button>
+
+
+</LinearLayout>
+
+
diff --git a/samples/USB/MissileLauncher/res/values/strings.xml b/samples/USB/MissileLauncher/res/values/strings.xml
new file mode 100644
index 0000000..3f7f85d
--- /dev/null
+++ b/samples/USB/MissileLauncher/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+
+    <string name="fire">Fire!</string>
+
+</resources>
+
diff --git a/samples/USB/MissileLauncher/res/xml/device_filter.xml b/samples/USB/MissileLauncher/res/xml/device_filter.xml
new file mode 100644
index 0000000..391a7f1
--- /dev/null
+++ b/samples/USB/MissileLauncher/res/xml/device_filter.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<resources>
+    <!-- vendor and product ID for Dream Cheeky USB Missle Launcher -->
+    <usb-device vendor-id="2689" product-id="1793" />
+    <!-- vendor and product ID for Dream Cheeky Wireless USB Missle Launcher -->
+    <usb-device vendor-id="2689" product-id="65281" />
+</resources>
diff --git a/samples/USB/MissileLauncher/src/com/android/missilelauncher/MissileLauncherActivity.java b/samples/USB/MissileLauncher/src/com/android/missilelauncher/MissileLauncherActivity.java
new file mode 100644
index 0000000..75e191c
--- /dev/null
+++ b/samples/USB/MissileLauncher/src/com/android/missilelauncher/MissileLauncherActivity.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2011 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.missilelauncher;
+
+import java.nio.ByteBuffer;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbRequest;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+
+public class MissileLauncherActivity extends Activity
+        implements View.OnClickListener, Runnable {
+
+    private static final String TAG = "MissileLauncherActivity";
+
+    private Button mFire;
+    private UsbManager mUsbManager;
+    private UsbDevice mDevice;
+    private UsbDeviceConnection mConnection;
+    private UsbEndpoint mEndpointIntr;
+    private SensorManager mSensorManager;
+    private Sensor mGravitySensor;
+
+    // USB control commands
+    private static final int COMMAND_UP = 1;
+    private static final int COMMAND_DOWN = 2;
+    private static final int COMMAND_RIGHT = 4;
+    private static final int COMMAND_LEFT = 8;
+    private static final int COMMAND_FIRE = 16;
+    private static final int COMMAND_STOP = 32;
+    private static final int COMMAND_STATUS = 64;
+
+    // constants for accelerometer orientation
+    private static final int TILT_LEFT = 1;
+    private static final int TILT_RIGHT = 2;
+    private static final int TILT_UP = 4;
+    private static final int TILT_DOWN = 8;
+    private static final double THRESHOLD = 5.0;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.launcher);
+        mFire = (Button)findViewById(R.id.fire);
+        mFire.setOnClickListener(this);
+
+        mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
+
+        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
+        mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mSensorManager.unregisterListener(mGravityListener);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mSensorManager.registerListener(mGravityListener, mGravitySensor,
+                SensorManager.SENSOR_DELAY_NORMAL);
+
+        Intent intent = getIntent();
+        Log.d(TAG, "intent: " + intent);
+        String action = intent.getAction();
+
+        UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
+            setDevice(device);
+        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
+            if (mDevice != null && mDevice.equals(device)) {
+                setDevice(null);
+            }
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    private void setDevice(UsbDevice device) {
+        Log.d(TAG, "setDevice " + device);
+        if (device.getInterfaceCount() != 1) {
+            Log.e(TAG, "could not find interface");
+            return;
+        }
+        UsbInterface intf = device.getInterface(0);
+        // device should have one endpoint
+        if (intf.getEndpointCount() != 1) {
+            Log.e(TAG, "could not find endpoint");
+            return;
+        }
+        // endpoint should be of type interrupt
+        UsbEndpoint ep = intf.getEndpoint(0);
+        if (ep.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
+            Log.e(TAG, "endpoint is not interrupt type");
+            return;
+        }
+        mDevice = device;
+        mEndpointIntr = ep;
+        if (device != null) {
+            UsbDeviceConnection connection = mUsbManager.openDevice(device);
+            if (connection != null && connection.claimInterface(intf, true)) {
+                Log.d(TAG, "open SUCCESS");
+                mConnection = connection;
+                Thread thread = new Thread(this);
+                thread.start();
+
+            } else {
+                Log.d(TAG, "open FAIL");
+                mConnection = null;
+            }
+         }
+    }
+
+    private void sendCommand(int control) {
+        synchronized (this) {
+            if (control != COMMAND_STATUS) {
+                Log.d(TAG, "sendMove " + control);
+            }
+            if (mConnection != null) {
+                byte[] message = new byte[1];
+                message[0] = (byte)control;
+                // Send command via a control request on endpoint zero
+                mConnection.controlTransfer(0x21, 0x9, 0x200, 0, message, message.length, 0);
+            }
+        }
+    }
+
+    public void onClick(View v) {
+        if (v == mFire) {
+            sendCommand(COMMAND_FIRE);
+        }
+    }
+
+    private int mLastValue = 0;
+
+    SensorEventListener mGravityListener = new SensorEventListener() {
+        public void onSensorChanged(SensorEvent event) {
+
+            // compute current tilt
+            int value = 0;
+            if (event.values[0] < -THRESHOLD) {
+                value += TILT_LEFT;
+            } else if (event.values[0] > THRESHOLD) {
+                value += TILT_RIGHT;
+            }
+            if (event.values[1] < -THRESHOLD) {
+                value += TILT_UP;
+            } else if (event.values[1] > THRESHOLD) {
+                value += TILT_DOWN;
+            }
+
+            if (value != mLastValue) {
+                mLastValue = value;
+                // send motion command if the tilt changed
+                switch (value) {
+                    case TILT_LEFT:
+                        sendCommand(COMMAND_LEFT);
+                        break;
+                    case TILT_RIGHT:
+                       sendCommand(COMMAND_RIGHT);
+                        break;
+                    case TILT_UP:
+                        sendCommand(COMMAND_UP);
+                        break;
+                    case TILT_DOWN:
+                        sendCommand(COMMAND_DOWN);
+                        break;
+                    default:
+                        sendCommand(COMMAND_STOP);
+                        break;
+                }
+            }
+        }
+
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // ignore
+        }
+    };
+
+    @Override
+    public void run() {
+        ByteBuffer buffer = ByteBuffer.allocate(1);
+        UsbRequest request = new UsbRequest();
+        request.initialize(mConnection, mEndpointIntr);
+        byte status = -1;
+        while (true) {
+            // queue a request on the interrupt endpoint
+            request.queue(buffer, 1);
+            // send poll status command
+            sendCommand(COMMAND_STATUS);
+            // wait for status event
+            if (mConnection.requestWait() == request) {
+                byte newStatus = buffer.get(0);
+                if (newStatus != status) {
+                    Log.d(TAG, "got status " + newStatus);
+                    status = newStatus;
+                    if ((status & COMMAND_FIRE) != 0) {
+                        // stop firing
+                        sendCommand(COMMAND_STOP);
+                    }
+                }
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                }
+            } else {
+                Log.e(TAG, "requestWait failed, exiting");
+                break;
+            }
+        }
+    }
+}
+
+
diff --git a/samples/USB/_index.html b/samples/USB/_index.html
new file mode 100644
index 0000000..f82011d
--- /dev/null
+++ b/samples/USB/_index.html
@@ -0,0 +1 @@
+<p>A set of samples that demonstrate how to use various features of the USB APIs.</p>
\ No newline at end of file
diff --git a/samples/WeatherListWidget/Android.mk b/samples/WeatherListWidget/Android.mk
new file mode 100644
index 0000000..95d233f
--- /dev/null
+++ b/samples/WeatherListWidget/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := WeatherListWidget
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/WeatherListWidget/AndroidManifest.xml b/samples/WeatherListWidget/AndroidManifest.xml
new file mode 100644
index 0000000..cfb2372
--- /dev/null
+++ b/samples/WeatherListWidget/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     to come from a domain that you own or have control over. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.weatherlistwidget">
+    <uses-sdk android:minSdkVersion="11" />
+    <application android:label="Weather Widget Sample">
+        <!-- The widget provider -->
+        <receiver android:name="WeatherWidgetProvider">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+            <!-- This specifies the widget provider info -->
+            <meta-data android:name="android.appwidget.provider"
+                    android:resource="@xml/widgetinfo" />
+        </receiver>
+
+        <!-- The service serving the RemoteViews to the collection widget -->
+        <service android:name="WeatherWidgetService"
+            android:permission="android.permission.BIND_REMOTEVIEWS"
+            android:exported="false" />
+
+        <!-- The content provider serving the (fake) weather data -->
+        <provider android:name="WeatherDataProvider"
+              android:authorities="com.example.android.weatherlistwidget.provider" />
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/samples/WeatherListWidget/_index.html b/samples/WeatherListWidget/_index.html
new file mode 100644
index 0000000..730f27c
--- /dev/null
+++ b/samples/WeatherListWidget/_index.html
@@ -0,0 +1,43 @@
+<p>This sample demonstrates how to create a list-based widget specifically backed by a content provider.<br/>
+<em>Please make sure that you understand the earlier stack widget sample code before delving into this example
+ (see <a href="../StackWidget/index.html">StackWidget</a>).</em></p>
+
+<p>As in the StackWidget example, we will be using a collection view (the ListView in this case) to
+present some mock weather data in a widget.  In particular, we will be using a content provider to
+demonstrate how the widget can retrieve data and update itself when you are using more complex data
+sources.  When working with external data, or data which must be fetched over high latency, it is
+important to keep the data cached in a persistent location so that the widget feels responsive.</p>
+
+<p>This sample uses the following classes:
+	<ul>
+		<li><a href="src/com/example/android/weatherlistwidget/WeatherDataProvider.html"><code>WeatherDataProvider</code></a> &mdash;
+			Our ContentProvider which stores the weather data for this sample.  Note that for simplicity,
+			it currently stores the data in memory as opposed to an external and persistent storage such
+			as a file, network location, database, or shared preference.
+		</li>
+		<li><a href="src/com/example/android/weatherlistwidget/WeatherWidgetProvider.html"><code>WeatherWidgetProvider</code></a> &mdash;
+			Our AppWidgetProvider which handles specific intent actions (such as when an item is clicked,
+			or the refresh button is pressed).  It also sets up the RemoteViews for the widget and binds
+			the service to the collection view in the widget.
+		</li>
+		<li><a href="src/com/example/android/weatherlistwidget/WeatherWidgetService.html"><code>WeatherWidgetService</code></a> &mdash;
+			Our RemoteViewsService which manages the creation of new factories, which return the RemoteViews
+			for each item in the ListView.
+		</li>
+	</ul>
+</p>
+
+<p>If you are writing collection-based widgets, remember that the feature is
+supported only on Android 3.0 (API level 11) and higher versions of the platform.
+Remember to add the following to the application's manifest publishing to Android Market:</p>
+
+<ul>
+<li><code>&lt;uses-sdk android:minSdkVersion="11" /&gt;</code>, which indicates
+to Android Market and the platform that your application requires Android 3.0 or
+higher. For more information, see the <a href="../../../guide/appendix/api-levels.html">API Levels</a>
+and the documentation for the
+<a href="../../../guide/topics/manifest/uses-sdk-element.html"><code>&lt;uses-sdk&gt;</code></a>
+element.</li>
+</ul>
+
+<img alt="Screenshot" src="../images/WeatherListWidget.png" />
\ No newline at end of file
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/body.png b/samples/WeatherListWidget/res/drawable-hdpi/body.png
new file mode 100644
index 0000000..0a2c1d1
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/body.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/footer.png b/samples/WeatherListWidget/res/drawable-hdpi/footer.png
new file mode 100644
index 0000000..73cc95c
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/footer.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/header.png b/samples/WeatherListWidget/res/drawable-hdpi/header.png
new file mode 100644
index 0000000..e659aee
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/header.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/icon.png b/samples/WeatherListWidget/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/item_bg_dark.png b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_dark.png
new file mode 100644
index 0000000..5097ab7
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_dark.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/item_bg_light.png b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_light.png
new file mode 100644
index 0000000..019f36c
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_light.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/refresh.png b/samples/WeatherListWidget/res/drawable-hdpi/refresh.png
new file mode 100644
index 0000000..2847773
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/refresh.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/refresh_pressed.png b/samples/WeatherListWidget/res/drawable-hdpi/refresh_pressed.png
new file mode 100644
index 0000000..820cc36
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/refresh_pressed.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/body.png b/samples/WeatherListWidget/res/drawable-ldpi/body.png
new file mode 100644
index 0000000..3ce4276
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/body.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/footer.png b/samples/WeatherListWidget/res/drawable-ldpi/footer.png
new file mode 100644
index 0000000..ab89bf3
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/footer.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/header.png b/samples/WeatherListWidget/res/drawable-ldpi/header.png
new file mode 100644
index 0000000..ff29577
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/header.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/icon.png b/samples/WeatherListWidget/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/item_bg_dark.png b/samples/WeatherListWidget/res/drawable-ldpi/item_bg_dark.png
new file mode 100644
index 0000000..c945b5f
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/item_bg_dark.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/item_bg_light.png b/samples/WeatherListWidget/res/drawable-ldpi/item_bg_light.png
new file mode 100644
index 0000000..a14b9a6
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/item_bg_light.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/refresh.png b/samples/WeatherListWidget/res/drawable-ldpi/refresh.png
new file mode 100644
index 0000000..d08343c
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/refresh.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/refresh_pressed.png b/samples/WeatherListWidget/res/drawable-ldpi/refresh_pressed.png
new file mode 100644
index 0000000..3da3ae6
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-ldpi/refresh_pressed.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/body.png b/samples/WeatherListWidget/res/drawable-mdpi/body.png
new file mode 100644
index 0000000..5331a9a
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/body.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/footer.png b/samples/WeatherListWidget/res/drawable-mdpi/footer.png
new file mode 100644
index 0000000..ca8b7ec
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/footer.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/header.png b/samples/WeatherListWidget/res/drawable-mdpi/header.png
new file mode 100644
index 0000000..5452abf
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/header.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/icon.png b/samples/WeatherListWidget/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/item_bg_dark.png b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_dark.png
new file mode 100644
index 0000000..5ae5480
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_dark.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/item_bg_light.png b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_light.png
new file mode 100644
index 0000000..5696944
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_light.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/refresh.png b/samples/WeatherListWidget/res/drawable-mdpi/refresh.png
new file mode 100644
index 0000000..569b360
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/refresh.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/refresh_pressed.png b/samples/WeatherListWidget/res/drawable-mdpi/refresh_pressed.png
new file mode 100644
index 0000000..5f10662
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/refresh_pressed.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-nodpi/preview.png b/samples/WeatherListWidget/res/drawable-nodpi/preview.png
new file mode 100644
index 0000000..f0cbdaf
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-nodpi/preview.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable/refresh_button.xml b/samples/WeatherListWidget/res/drawable/refresh_button.xml
new file mode 100644
index 0000000..1c0017e
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable/refresh_button.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/refresh_pressed" /> <!-- pressed -->
+    <item android:drawable="@drawable/refresh" /> <!-- default -->
+</selector>
\ No newline at end of file
diff --git a/samples/WeatherListWidget/res/layout/dark_widget_item.xml b/samples/WeatherListWidget/res/layout/dark_widget_item.xml
new file mode 100644
index 0000000..1f920a2
--- /dev/null
+++ b/samples/WeatherListWidget/res/layout/dark_widget_item.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/widget_item"
+    android:layout_width="match_parent"
+    android:layout_height="46dp"
+    android:paddingLeft="25dp"
+    android:gravity="center_vertical"
+    android:background="@drawable/item_bg_dark"
+    android:textColor="#e5e5e1"
+    android:textSize="24sp" />
diff --git a/samples/WeatherListWidget/res/layout/light_widget_item.xml b/samples/WeatherListWidget/res/layout/light_widget_item.xml
new file mode 100644
index 0000000..bb2946f
--- /dev/null
+++ b/samples/WeatherListWidget/res/layout/light_widget_item.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/widget_item"
+    android:layout_width="match_parent"
+    android:layout_height="46dp"
+    android:paddingLeft="25dp"
+    android:gravity="center_vertical"
+    android:background="@drawable/item_bg_light"
+    android:textColor="#e5e5e1"
+    android:textSize="24sp" />
diff --git a/samples/WeatherListWidget/res/layout/widget_layout.xml b/samples/WeatherListWidget/res/layout/widget_layout.xml
new file mode 100644
index 0000000..4b09efc
--- /dev/null
+++ b/samples/WeatherListWidget/res/layout/widget_layout.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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="294dp"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <ImageView
+            android:id="@+id/header"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/header" />
+        <ImageButton
+            android:id="@+id/refresh"
+            android:layout_width="56dp"
+            android:layout_height="39dp"
+            android:layout_marginLeft="222dp"
+            android:layout_marginTop="20dp"
+            android:background="@drawable/refresh_button" />
+    </FrameLayout>
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:layout_gravity="center"
+        android:background="@drawable/body">
+        <ListView
+            android:id="@+id/weather_list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+        <TextView
+            android:id="@+id/empty_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center"
+            android:visibility="gone"
+            android:textColor="#ffffff"
+            android:text="@string/empty_view_text"
+            android:textSize="20sp" />
+    </FrameLayout>
+    <ImageView
+        android:id="@+id/footer"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:src="@drawable/footer" />
+</LinearLayout>
diff --git a/samples/WeatherListWidget/res/values/strings.xml b/samples/WeatherListWidget/res/values/strings.xml
new file mode 100644
index 0000000..6542545
--- /dev/null
+++ b/samples/WeatherListWidget/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<resources>
+    <string name="empty_view_text">No cities found...</string>
+    <string name="toast_format_string">%1$s says Hi!</string>
+    <string name="item_format_string">%1$d\u00B0 in %2$s</string>
+</resources>
diff --git a/samples/WeatherListWidget/res/xml/widgetinfo.xml b/samples/WeatherListWidget/res/xml/widgetinfo.xml
new file mode 100644
index 0000000..af64106
--- /dev/null
+++ b/samples/WeatherListWidget/res/xml/widgetinfo.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<appwidget-provider
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:minWidth="222dip"
+  android:minHeight="222dip"
+  android:updatePeriodMillis="1800000"
+  android:initialLayout="@layout/widget_layout"
+  android:resizeMode="vertical"
+  android:previewImage="@drawable/preview">
+</appwidget-provider>
diff --git a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherDataProvider.java b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherDataProvider.java
new file mode 100644
index 0000000..92a1cb3
--- /dev/null
+++ b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherDataProvider.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2011 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.example.android.weatherlistwidget;
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+
+import java.util.ArrayList;
+
+/**
+ * A dummy class that we are going to use internally to store weather data.  Generally, this data
+ * will be stored in an external and persistent location (ie. File, Database, SharedPreferences) so
+ * that the data can persist if the process is ever killed.  For simplicity, in this sample the
+ * data will only be stored in memory.
+ */
+class WeatherDataPoint {
+    String city;
+    int degrees;
+
+    WeatherDataPoint(String c, int d) {
+        city = c;
+        degrees = d;
+    }
+}
+
+/**
+ * The AppWidgetProvider for our sample weather widget.
+ */
+public class WeatherDataProvider extends ContentProvider {
+    public static final Uri CONTENT_URI =
+        Uri.parse("content://com.example.android.weatherlistwidget.provider");
+    public static class Columns {
+        public static final String ID = "_id";
+        public static final String CITY = "city";
+        public static final String TEMPERATURE = "temperature";
+    }
+
+    /**
+     * Generally, this data will be stored in an external and persistent location (ie. File,
+     * Database, SharedPreferences) so that the data can persist if the process is ever killed.
+     * For simplicity, in this sample the data will only be stored in memory.
+     */
+    private static final ArrayList<WeatherDataPoint> sData = new ArrayList<WeatherDataPoint>();
+
+    @Override
+    public boolean onCreate() {
+        // We are going to initialize the data provider with some default values
+        sData.add(new WeatherDataPoint("San Francisco", 13));
+        sData.add(new WeatherDataPoint("New York", 1));
+        sData.add(new WeatherDataPoint("Seattle", 7));
+        sData.add(new WeatherDataPoint("Boston", 4));
+        sData.add(new WeatherDataPoint("Miami", 22));
+        sData.add(new WeatherDataPoint("Toronto", -10));
+        sData.add(new WeatherDataPoint("Calgary", -13));
+        sData.add(new WeatherDataPoint("Tokyo", 8));
+        sData.add(new WeatherDataPoint("Kyoto", 11));
+        sData.add(new WeatherDataPoint("London", -1));
+        sData.add(new WeatherDataPoint("Nomanisan", 27));
+        return true;
+    }
+
+    @Override
+    public synchronized Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String sortOrder) {
+        assert(uri.getPathSegments().isEmpty());
+
+        // In this sample, we only query without any parameters, so we can just return a cursor to
+        // all the weather data.
+        final MatrixCursor c = new MatrixCursor(
+                new String[]{ Columns.ID, Columns.CITY, Columns.TEMPERATURE });
+        for (int i = 0; i < sData.size(); ++i) {
+            final WeatherDataPoint data = sData.get(i);
+            c.addRow(new Object[]{ new Integer(i), data.city, new Integer(data.degrees) });
+        }
+        return c;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return "vnd.android.cursor.dir/vnd.weatherlistwidget.citytemperature";
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        // This example code does not support inserting
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        // This example code does not support deleting
+        return 0;
+    }
+
+    @Override
+    public synchronized int update(Uri uri, ContentValues values, String selection,
+            String[] selectionArgs) {
+        assert(uri.getPathSegments().size() == 1);
+
+        // In this sample, we only update the content provider individually for each row with new
+        // temperature values.
+        final int index = Integer.parseInt(uri.getPathSegments().get(0));
+        final MatrixCursor c = new MatrixCursor(
+                new String[]{ Columns.ID, Columns.CITY, Columns.TEMPERATURE });
+        assert(0 <= index && index < sData.size());
+        final WeatherDataPoint data = sData.get(index);
+        data.degrees = values.getAsInteger(Columns.TEMPERATURE);
+
+        // Notify any listeners that the data backing the content provider has changed, and return
+        // the number of rows affected.
+        getContext().getContentResolver().notifyChange(uri, null);
+        return 1;
+    }
+
+}
\ No newline at end of file
diff --git a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetProvider.java b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetProvider.java
new file mode 100644
index 0000000..2f2b347
--- /dev/null
+++ b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetProvider.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 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.example.android.weatherlistwidget;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.widget.RemoteViews;
+import android.widget.Toast;
+
+import java.util.Random;
+
+/**
+ * Our data observer just notifies an update for all weather widgets when it detects a change.
+ */
+class WeatherDataProviderObserver extends ContentObserver {
+    private AppWidgetManager mAppWidgetManager;
+    private ComponentName mComponentName;
+
+    WeatherDataProviderObserver(AppWidgetManager mgr, ComponentName cn, Handler h) {
+        super(h);
+        mAppWidgetManager = mgr;
+        mComponentName = cn;
+    }
+
+    @Override
+    public void onChange(boolean selfChange) {
+        // The data has changed, so notify the widget that the collection view needs to be updated.
+        // In response, the factory's onDataSetChanged() will be called which will requery the
+        // cursor for the new data.
+        mAppWidgetManager.notifyAppWidgetViewDataChanged(
+                mAppWidgetManager.getAppWidgetIds(mComponentName), R.id.weather_list);
+    }
+}
+
+/**
+ * The weather widget's AppWidgetProvider.
+ */
+public class WeatherWidgetProvider extends AppWidgetProvider {
+    public static String CLICK_ACTION = "com.example.android.weatherlistwidget.CLICK";
+    public static String REFRESH_ACTION = "com.example.android.weatherlistwidget.REFRESH";
+    public static String EXTRA_CITY_ID = "com.example.android.weatherlistwidget.city";
+
+    private static HandlerThread sWorkerThread;
+    private static Handler sWorkerQueue;
+    private static WeatherDataProviderObserver sDataObserver;
+
+    public WeatherWidgetProvider() {
+        // Start the worker thread
+        sWorkerThread = new HandlerThread("WeatherWidgetProvider-worker");
+        sWorkerThread.start();
+        sWorkerQueue = new Handler(sWorkerThread.getLooper());
+    }
+
+    @Override
+    public void onEnabled(Context context) {
+        // Register for external updates to the data to trigger an update of the widget.  When using
+        // content providers, the data is often updated via a background service, or in response to
+        // user interaction in the main app.  To ensure that the widget always reflects the current
+        // state of the data, we must listen for changes and update ourselves accordingly.
+        final ContentResolver r = context.getContentResolver();
+        if (sDataObserver == null) {
+            final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
+            final ComponentName cn = new ComponentName(context, WeatherWidgetProvider.class);
+            sDataObserver = new WeatherDataProviderObserver(mgr, cn, sWorkerQueue);
+            r.registerContentObserver(WeatherDataProvider.CONTENT_URI, true, sDataObserver);
+        }
+    }
+
+    @Override
+    public void onReceive(Context ctx, Intent intent) {
+        final String action = intent.getAction();
+        if (action.equals(REFRESH_ACTION)) {
+            // BroadcastReceivers have a limited amount of time to do work, so for this sample, we
+            // are triggering an update of the data on another thread.  In practice, this update
+            // can be triggered from a background service, or perhaps as a result of user actions
+            // inside the main application.
+            final Context context = ctx;
+            sWorkerQueue.removeMessages(0);
+            sWorkerQueue.post(new Runnable() {
+                @Override
+                public void run() {
+                    final ContentResolver r = context.getContentResolver();
+                    final Cursor c = r.query(WeatherDataProvider.CONTENT_URI, null, null, null, 
+                            null);
+                    final int count = c.getCount();
+                    final int maxDegrees = 96;
+
+                    // We disable the data changed observer temporarily since each of the updates
+                    // will trigger an onChange() in our data observer.
+                    r.unregisterContentObserver(sDataObserver);
+                    for (int i = 0; i < count; ++i) {
+                        final Uri uri = ContentUris.withAppendedId(WeatherDataProvider.CONTENT_URI, i);
+                        final ContentValues values = new ContentValues();
+                        values.put(WeatherDataProvider.Columns.TEMPERATURE,
+                                new Random().nextInt(maxDegrees));
+                        r.update(uri, values, null, null);
+                    }
+                    r.registerContentObserver(WeatherDataProvider.CONTENT_URI, true, sDataObserver);
+
+                    final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
+                    final ComponentName cn = new ComponentName(context, WeatherWidgetProvider.class);
+                    mgr.notifyAppWidgetViewDataChanged(mgr.getAppWidgetIds(cn), R.id.weather_list);
+                }
+            });
+        } else if (action.equals(CLICK_ACTION)) {
+            // Show a toast
+            final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                    AppWidgetManager.INVALID_APPWIDGET_ID);
+            final String city = intent.getStringExtra(EXTRA_CITY_ID);
+            final String formatStr = ctx.getResources().getString(R.string.toast_format_string);
+            Toast.makeText(ctx, String.format(formatStr, city), Toast.LENGTH_SHORT).show();
+        }
+
+        super.onReceive(ctx, intent);
+    }
+
+    @Override
+    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+        // Update each of the widgets with the remote adapter
+        for (int i = 0; i < appWidgetIds.length; ++i) {
+            // Specify the service to provide data for the collection widget.  Note that we need to
+            // embed the appWidgetId via the data otherwise it will be ignored.
+            final Intent intent = new Intent(context, WeatherWidgetService.class);
+            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
+            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
+            final RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
+            rv.setRemoteAdapter(appWidgetIds[i], R.id.weather_list, intent);
+
+            // Set the empty view to be displayed if the collection is empty.  It must be a sibling
+            // view of the collection view.
+            rv.setEmptyView(R.id.weather_list, R.id.empty_view);
+
+            // Bind a click listener template for the contents of the weather list.  Note that we
+            // need to update the intent's data if we set an extra, since the extras will be
+            // ignored otherwise.
+            final Intent onClickIntent = new Intent(context, WeatherWidgetProvider.class);
+            onClickIntent.setAction(WeatherWidgetProvider.CLICK_ACTION);
+            onClickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
+            onClickIntent.setData(Uri.parse(onClickIntent.toUri(Intent.URI_INTENT_SCHEME)));
+            final PendingIntent onClickPendingIntent = PendingIntent.getBroadcast(context, 0,
+                    onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+            rv.setPendingIntentTemplate(R.id.weather_list, onClickPendingIntent);
+
+            // Bind the click intent for the refresh button on the widget
+            final Intent refreshIntent = new Intent(context, WeatherWidgetProvider.class);
+            refreshIntent.setAction(WeatherWidgetProvider.REFRESH_ACTION);
+            final PendingIntent refreshPendingIntent = PendingIntent.getBroadcast(context, 0,
+                    refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+            rv.setOnClickPendingIntent(R.id.refresh, refreshPendingIntent);
+
+            appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
+        }
+        super.onUpdate(context, appWidgetManager, appWidgetIds);
+    }
+}
\ No newline at end of file
diff --git a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java
new file mode 100644
index 0000000..e0bc682
--- /dev/null
+++ b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2011 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.example.android.weatherlistwidget;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.widget.RemoteViews;
+import android.widget.RemoteViewsService;
+
+/**
+ * This is the service that provides the factory to be bound to the collection service.
+ */
+public class WeatherWidgetService extends RemoteViewsService {
+    @Override
+    public RemoteViewsFactory onGetViewFactory(Intent intent) {
+        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
+    }
+}
+
+/**
+ * This is the factory that will provide data to the collection widget.
+ */
+class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
+    private Context mContext;
+    private Cursor mCursor;
+    private int mAppWidgetId;
+
+    public StackRemoteViewsFactory(Context context, Intent intent) {
+        mContext = context;
+        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                AppWidgetManager.INVALID_APPWIDGET_ID);
+    }
+
+    public void onCreate() {
+        // Since we reload the cursor in onDataSetChanged() which gets called immediately after
+        // onCreate(), we do nothing here.
+    }
+
+    public void onDestroy() {
+        if (mCursor != null) {
+            mCursor.close();
+        }
+    }
+
+    public int getCount() {
+        return mCursor.getCount();
+    }
+
+    public RemoteViews getViewAt(int position) {
+        // Get the data for this position from the content provider
+        String city = "Unknown City";
+        int temp = 0;
+        if (mCursor.moveToPosition(position)) {
+            final int cityColIndex = mCursor.getColumnIndex(WeatherDataProvider.Columns.CITY);
+            final int tempColIndex = mCursor.getColumnIndex(
+                    WeatherDataProvider.Columns.TEMPERATURE);
+            city = mCursor.getString(cityColIndex);
+            temp = mCursor.getInt(tempColIndex);
+        }
+
+        // Return a proper item with the proper city and temperature.  Just for fun, we alternate
+        // the items to make the list easier to read.
+        final String formatStr = mContext.getResources().getString(R.string.item_format_string);
+        final int itemId = (position % 2 == 0 ? R.layout.light_widget_item
+                : R.layout.dark_widget_item);
+        RemoteViews rv = new RemoteViews(mContext.getPackageName(), itemId);
+        rv.setTextViewText(R.id.widget_item, String.format(formatStr, temp, city));
+
+        // Set the click intent so that we can handle it and show a toast message
+        final Intent fillInIntent = new Intent();
+        final Bundle extras = new Bundle();
+        extras.putString(WeatherWidgetProvider.EXTRA_CITY_ID, city);
+        fillInIntent.putExtras(extras);
+        rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
+
+        return rv;
+    }
+    public RemoteViews getLoadingView() {
+        // We aren't going to return a default loading view in this sample
+        return null;
+    }
+
+    public int getViewTypeCount() {
+        // Technically, we have two types of views (the dark and light background views)
+        return 2;
+    }
+
+    public long getItemId(int position) {
+        return position;
+    }
+
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    public void onDataSetChanged() {
+        // Refresh the cursor
+        if (mCursor != null) {
+            mCursor.close();
+        }
+        mCursor = mContext.getContentResolver().query(WeatherDataProvider.CONTENT_URI, null, null,
+                null, null);
+    }
+}
\ No newline at end of file
diff --git a/samples/XmlAdapters/Android.mk b/samples/XmlAdapters/Android.mk
new file mode 100644
index 0000000..a2cad3a
--- /dev/null
+++ b/samples/XmlAdapters/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := xmladapters
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+#include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/XmlAdapters/AndroidManifest.xml b/samples/XmlAdapters/AndroidManifest.xml
new file mode 100644
index 0000000..e4ac4d8
--- /dev/null
+++ b/samples/XmlAdapters/AndroidManifest.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.xmladapters">
+    
+    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+
+    <application android:label="@string/app_name">
+        <activity android:name="ContactsListActivity"
+                  android:label="@string/contacts_list_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="PhotosListActivity"
+                  android:label="@string/photos_list_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="RssReaderActivity"
+                  android:label="@string/rss_reader_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <provider android:name="android.content.XmlDocumentProvider"
+           android:authorities="xmldocument" />
+
+    </application>
+
+</manifest>
+
diff --git a/samples/XmlAdapters/_index.html b/samples/XmlAdapters/_index.html
new file mode 100644
index 0000000..2ca3608
--- /dev/null
+++ b/samples/XmlAdapters/_index.html
@@ -0,0 +1,31 @@
+<p>This sample demonstrates the use of XML adapters.</p>
+
+<p>An XML Adapter is an XML file which defines the bindings between the data
+retrieved from a
+<a href="../../../reference/android/content/ContentProvider.html"><code>ContentProvider</code></a>
+and the different views of a layout. They are provided by the
+<a href="../../../reference/android/widget/Adapters.html"><code>Adapters</code></a>
+class.</p>
+
+Three list activities are provided which illustrate this:
+<ul>
+  <li><a href="src/com/example/android/xmladapters/ContactsListActivity.html"><strong>
+  ContactsListActivity</strong></a> uses the device's Contacts provider as its input source.
+  Contacts with a phone number are displayed, their photo being retrieved by a dedicated
+  <a href="src/com/example/android/xmladapters/ContactPhotoBinder.html"><code>ContactPhotoBinder
+  </code></a>.</li>
+
+  <li><a href="src/com/example/android/xmladapters/PhotosListActivity.html"><strong>
+  PhotosListActivity</strong></a> retrieves an RSS photo feed and displays the images and their
+  titles. The images are downloaded from the URL found in the feed using the
+  <a href="src/com/example/android/xmladapters/ImageDownloader.html"><code>ImageDownloader</code>
+  </a> helper class.</li>
+
+  <li><a href="src/com/example/android/xmladapters/RssReaderActivity.html"><strong>
+  RssReaderActivity</strong></a> also displays items extracted from an RSS feed. An additional
+  <a href="src/com/example/android/xmladapters/UrlIntentListener.html"><code>UrlIntentListener
+  </code></a> is used to open a browser when one of the news item is tapped.</li>
+</ul>
+
+<img alt="XmlPhotosAdapter" src="../images/XmlPhotosAdapter.png" />
+<img alt="XmlRssReader" src="../images/XmlRssReader.png" />
diff --git a/samples/XmlAdapters/res/drawable-hdpi/ic_contact_picture.png b/samples/XmlAdapters/res/drawable-hdpi/ic_contact_picture.png
new file mode 100644
index 0000000..a60565a
--- /dev/null
+++ b/samples/XmlAdapters/res/drawable-hdpi/ic_contact_picture.png
Binary files differ
diff --git a/samples/XmlAdapters/res/drawable-mdpi/ic_contact_picture.png b/samples/XmlAdapters/res/drawable-mdpi/ic_contact_picture.png
new file mode 100644
index 0000000..f6032f1
--- /dev/null
+++ b/samples/XmlAdapters/res/drawable-mdpi/ic_contact_picture.png
Binary files differ
diff --git a/samples/XmlAdapters/res/layout/contact_item.xml b/samples/XmlAdapters/res/layout/contact_item.xml
new file mode 100644
index 0000000..6fcb109
--- /dev/null
+++ b/samples/XmlAdapters/res/layout/contact_item.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeight">
+
+    <TextView
+        android:id="@+id/name"
+        android:layout_width="0px"
+        android:layout_weight="1.0"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:gravity="center_vertical"
+        android:drawablePadding="6dip"
+        android:paddingLeft="6dip"
+        android:paddingRight="6dip" />
+
+    <ImageView
+        android:id="@+id/star"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />    
+
+</LinearLayout>
diff --git a/samples/XmlAdapters/res/layout/contacts_list.xml b/samples/XmlAdapters/res/layout/contacts_list.xml
new file mode 100644
index 0000000..0dcc019
--- /dev/null
+++ b/samples/XmlAdapters/res/layout/contacts_list.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+ 
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <ListView
+        android:id="@android:id/list"
+        android:layout_width="match_parent" 
+        android:layout_height="match_parent" />
+
+    <TextView android:id="@android:id/empty"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:text="@string/no_contacts"
+        android:visibility="gone" />
+
+</merge>    
diff --git a/samples/XmlAdapters/res/layout/photo_item.xml b/samples/XmlAdapters/res/layout/photo_item.xml
new file mode 100644
index 0000000..f24b143
--- /dev/null
+++ b/samples/XmlAdapters/res/layout/photo_item.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeight">
+
+    <ImageView
+        android:id="@+id/photo"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingLeft="6dip"
+        android:paddingTop="4dip"
+        android:paddingBottom="4dip" />
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="0px"
+        android:layout_weight="1.0"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:gravity="center_vertical"
+        android:paddingLeft="6dip"
+        android:paddingRight="6dip" />
+
+</LinearLayout>
diff --git a/samples/XmlAdapters/res/layout/photos_list.xml b/samples/XmlAdapters/res/layout/photos_list.xml
new file mode 100644
index 0000000..5756f37
--- /dev/null
+++ b/samples/XmlAdapters/res/layout/photos_list.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <ListView
+        android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <TextView android:id="@android:id/empty"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:text="@string/no_photos"
+        android:visibility="gone" />
+
+</merge>
diff --git a/samples/XmlAdapters/res/layout/rss_feed_item.xml b/samples/XmlAdapters/res/layout/rss_feed_item.xml
new file mode 100644
index 0000000..3975aec
--- /dev/null
+++ b/samples/XmlAdapters/res/layout/rss_feed_item.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/item_layout"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:minHeight="?android:attr/listPreferredItemHeight">
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="fill_parent"
+        android:layout_weight="1.0"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:gravity="left"
+        android:paddingLeft="6dip"
+        android:paddingRight="6dip" />
+
+    <TextView
+        android:id="@+id/date"
+        android:layout_width="fill_parent"
+        android:layout_weight="1.0"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:gravity="left"
+        android:paddingLeft="6dip"
+        android:paddingRight="6dip" />
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:minHeight="?android:attr/listPreferredItemHeight">
+
+       <ImageView
+           android:id="@+id/image"
+           android:layout_width="wrap_content"
+           android:layout_height="match_parent"
+           android:gravity="center_vertical"
+           android:paddingLeft="6dip" />
+
+       <TextView
+           android:id="@+id/description"
+           android:layout_width="fill_parent"
+           android:layout_weight="1.0"
+           android:layout_height="wrap_content"
+           android:textAppearance="?android:attr/textAppearanceSmall"
+           android:gravity="left"
+           android:paddingLeft="6dip"
+           android:paddingRight="6dip" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/XmlAdapters/res/layout/rss_feeds_list.xml b/samples/XmlAdapters/res/layout/rss_feeds_list.xml
new file mode 100644
index 0000000..b761dcf
--- /dev/null
+++ b/samples/XmlAdapters/res/layout/rss_feeds_list.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <ListView
+        android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <TextView android:id="@android:id/empty"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:text="@string/no_rss_feed"
+        android:visibility="gone" />
+
+</merge>
diff --git a/samples/XmlAdapters/res/values/attrs.xml b/samples/XmlAdapters/res/values/attrs.xml
new file mode 100644
index 0000000..8b8ab71
--- /dev/null
+++ b/samples/XmlAdapters/res/values/attrs.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+
+    <!-- Adapter used to bind cursors. -->
+    <declare-styleable name="CursorAdapter">
+        <!-- URI to get the cursor from. Optional. -->
+        <attr name="uri" format="string" />
+        <!-- Selection statement for the query. Optional. -->
+        <attr name="selection" format="string" />
+        <!-- Sort order statement for the query. Optional. -->
+        <attr name="sortOrder" format="string" />
+        <!-- Layout resource used to display each row from the cursor. Mandatory. -->
+        <attr name="layout" format="reference" />
+    </declare-styleable>
+
+    <!-- Attributes used in bind items for XML cursor adapters. -->
+    <declare-styleable name="CursorAdapter_BindItem">
+        <!-- The name of the column to bind from. Mandatory. -->
+        <attr name="from" format="string" />
+        <!-- The resource id of the view to bind to. Mandatory. -->
+        <attr name="to" format="reference" />
+        <!-- The type of binding. If this value is not specified, the type will be
+             inferred from the type of the "to" target view. Mandatory.
+
+             The type can be one of:
+             <ul>
+             <li>string, The content of the column is interpreted as a string.</li>
+             <li>image, The content of the column is interpreted as a blob describing an image.</li>
+             <li>image-uri, The content of the column is interpreted as a URI to an image.</li>
+             <li>drawable, The content of the column is interpreted as a resource id to a drawable.</li>
+             <li>A fully qualified class name, corresponding to an implementation of
+                 android.widget.Adapters.CursorBinder.</li>
+             </ul>
+         -->
+        <attr name="as" format="string" />
+    </declare-styleable>
+
+    <!-- Attributes used in select items for XML cursor adapters.-->
+    <declare-styleable name="CursorAdapter_SelectItem">
+        <!-- The name of the column to select. Mandatory. -->
+        <attr name="column" format="string" />
+    </declare-styleable>
+
+    <!-- Attributes used to map values to new values in XML cursor adapters' bind items. -->
+    <declare-styleable name="CursorAdapter_MapItem">
+        <!-- The original value from the column. Mandatory. -->
+        <attr name="fromValue" format="string" />
+        <!-- The new value from the column. Mandatory. -->
+        <attr name="toValue" format="string" />
+    </declare-styleable>
+
+    <!-- Attributes used to map values to new values in XML cursor adapters' bind items. -->
+    <declare-styleable name="CursorAdapter_TransformItem">
+        <!-- The transformation expression. Mandatory if "withClass" is not specified. -->
+        <attr name="withExpression" format="string" />
+        <!-- The transformation class, an implementation of
+             android.widget.Adapters.CursorTransformation. Mandatory if "withExpression"
+             is not specified. -->
+        <attr name="withClass" format="string" />
+    </declare-styleable>
+
+</resources>
diff --git a/samples/XmlAdapters/res/values/strings.xml b/samples/XmlAdapters/res/values/strings.xml
new file mode 100644
index 0000000..1ae158e
--- /dev/null
+++ b/samples/XmlAdapters/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASI
+     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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">Xml Adapters</string>
+    <string name="contacts_list_activity">Xml Contacts Adapter</string>
+    <string name="photos_list_activity">Xml Photos Adapter</string>
+    <string name="rss_reader_activity">Xml RSS Reader</string>
+    <string name="no_contacts">No contacts available</string>
+    <string name="no_photos">Loading photos...</string>
+    <string name="no_rss_feed">Loading RSS feed...</string>
+
+</resources>
diff --git a/samples/XmlAdapters/res/xml/contacts.xml b/samples/XmlAdapters/res/xml/contacts.xml
new file mode 100644
index 0000000..f958522
--- /dev/null
+++ b/samples/XmlAdapters/res/xml/contacts.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<cursor-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:app="http://schemas.android.com/apk/res/com.example.android.xmladapters"
+  app:uri="content://com.android.contacts/contacts"
+  app:selection="has_phone_number=1"
+  app:layout="@layout/contact_item">
+
+  <bind app:from="display_name" app:to="@id/name" app:as="string" />
+  <bind app:from="starred" app:to="@id/star" app:as="drawable">
+        <map app:fromValue="0" app:toValue="@android:drawable/star_big_off" />
+        <map app:fromValue="1" app:toValue="@android:drawable/star_big_on" />
+  </bind>
+  <bind app:from="_id" app:to="@id/name" app:as="com.example.android.xmladapters.ContactPhotoBinder" />
+
+</cursor-adapter>
diff --git a/samples/XmlAdapters/res/xml/photos.xml b/samples/XmlAdapters/res/xml/photos.xml
new file mode 100644
index 0000000..7698895
--- /dev/null
+++ b/samples/XmlAdapters/res/xml/photos.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<cursor-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res/com.example.android.xmladapters"
+    app:selection="/feed/entry"
+    app:layout="@layout/photo_item">
+
+    <bind app:from="/summary" app:to="@id/title" app:as="string" />
+    <bind app:from="/media:group/media:thumbnail\@url" app:to="@id/photo"
+      app:as="com.example.android.xmladapters.UrlImageBinder" />
+
+</cursor-adapter>
diff --git a/samples/XmlAdapters/res/xml/rss_feed.xml b/samples/XmlAdapters/res/xml/rss_feed.xml
new file mode 100644
index 0000000..a488644
--- /dev/null
+++ b/samples/XmlAdapters/res/xml/rss_feed.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<cursor-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res/com.example.android.xmladapters"
+    app:selection="/rss/channel/item"
+    app:layout="@layout/rss_feed_item">
+
+    <bind app:from="/title" app:to="@id/title" app:as="string" />
+    <bind app:from="/media:content@url" app:to="@id/image" app:as="com.example.android.xmladapters.UrlImageBinder"/>
+    <bind app:from="/media:description" app:to="@id/description" app:as="string" />
+    <bind app:from="/guid" app:to="@id/item_layout" app:as="tag" />
+    <bind app:from="/pubDate" app:to="@id/date" app:as="string">
+       <transform app:withExpression="Published on {/pubDate}." />
+    </bind>
+
+</cursor-adapter>
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/Adapters.java b/samples/XmlAdapters/src/com/example/android/xmladapters/Adapters.java
new file mode 100644
index 0000000..9d4794c
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/Adapters.java
@@ -0,0 +1,1238 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.xmladapters;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.database.Cursor;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.util.AttributeSet;
+import android.util.Xml;
+import android.view.View;
+import android.widget.BaseAdapter;
+import android.widget.CursorAdapter;
+import android.widget.ImageView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * <p>This class can be used to load {@link android.widget.Adapter adapters} defined in
+ * XML resources. XML-defined adapters can be used to easily create adapters in your
+ * own application or to pass adapters to other processes.</p>
+ * 
+ * <h2>Types of adapters</h2>
+ * <p>Adapters defined using XML resources can only be one of the following supported
+ * types. Arbitrary adapters are not supported to guarantee the safety of the loaded
+ * code when adapters are loaded across packages.</p>
+ * <ul>
+ *  <li><a href="#xml-cursor-adapter">Cursor adapter</a>: a cursor adapter can be used
+ *  to display the content of a cursor, most often coming from a content provider</li>
+ * </ul>
+ * <p>The complete XML format definition of each adapter type is available below.</p>
+ * 
+ * <a name="xml-cursor-adapter"></a>
+ * <h2>Cursor adapter</h2>
+ * <p>A cursor adapter XML definition starts with the
+ * <a href="#xml-cursor-adapter-tag"><code>&lt;cursor-adapter /&gt;</code></a>
+ * tag and may contain one or more instances of the following tags:</p>
+ * <ul>
+ *  <li><a href="#xml-cursor-adapter-select-tag"><code>&lt;select /&gt;</code></a></li>
+ *  <li><a href="#xml-cursor-adapter-bind-tag"><code>&lt;bind /&gt;</code></a></li>
+ * </ul>
+ * 
+ * <a name="xml-cursor-adapter-tag"></a>
+ * <h3>&lt;cursor-adapter /&gt;</h3>
+ * <p>The <code>&lt;cursor-adapter /&gt;</code> element defines the beginning of the
+ * document and supports the following attributes:</p>
+ * <ul>
+ *  <li><code>android:layout</code>: Reference to the XML layout to be inflated for
+ *  each item of the adapter. This attribute is mandatory.</li>
+ *  <li><code>android:selection</code>: Selection expression, used when the
+ *  <code>android:uri</code> attribute is defined or when the adapter is loaded with
+ *  {@link Adapters#loadCursorAdapter(android.content.Context, int, String, Object[])}.
+ *  This attribute is optional.</li>
+ *  <li><code>android:sortOrder</code>: Sort expression, used when the
+ *  <code>android:uri</code> attribute is defined or when the adapter is loaded with
+ *  {@link Adapters#loadCursorAdapter(android.content.Context, int, String, Object[])}.
+ *  This attribute is optional.</li>
+ *  <li><code>android:uri</code>: URI of the content provider to query to retrieve a cursor.
+ *  Specifying this attribute is equivalent to calling
+ *  {@link Adapters#loadCursorAdapter(android.content.Context, int, String, Object[])}.
+ *  If you call this method, the value of the XML attribute is ignored. This attribute is
+ *  optional.</li>
+ * </ul>
+ * <p>In addition, you can specify one or more instances of
+ * <a href="#xml-cursor-adapter-select-tag"><code>&lt;select /&gt;</code></a> and
+ * <a href="#xml-cursor-adapter-bind-tag"><code>&lt;bind /&gt;</code></a> tags as children
+ * of <code>&lt;cursor-adapter /&gt;</code>.</p>
+ * 
+ * <a name="xml-cursor-adapter-select-tag"></a>
+ * <h3>&lt;select /&gt;</h3>
+ * <p>The <code>&lt;select /&gt;</code> tag is used to select columns from the cursor
+ * when doing the query. This can be very useful when using transformations in the
+ * <code>&lt;bind /&gt;</code> elements. It can also be very useful if you are providing
+ * your own <a href="#xml-cursor-adapter-bind-data-types">binder</a> or
+ * <a href="#xml-cursor-adapter-bind-data-types">transformation</a> classes.
+ * <code>&lt;select /&gt;</code> elements are ignored if you supply the cursor yourself.</p>
+ * <p>The <code>&lt;select /&gt;</code> supports the following attributes:</p>
+ * <ul>
+ *  <li><code>android:column</code>: Name of the column to select in the cursor during the
+ *  query operation</li>
+ * </ul>
+ * <p><strong>Note:</strong> The column named <code>_id</code> is always implicitly
+ * selected.</p>
+ * 
+ * <a name="xml-cursor-adapter-bind-tag"></a>
+ * <h3>&lt;bind /&gt;</h3>
+ * <p>The <code>&lt;bind /&gt;</code> tag is used to bind a column from the cursor to
+ * a {@link android.view.View}. A column bound using this tag is automatically selected
+ * during the query and a matching
+ * <a href="#xml-cursor-adapter-select-tag"><code>&lt;select /&gt;</code> tag is therefore
+ * not required.</p>
+ * 
+ * <p>Each binding is declared as a one to one matching but
+ * custom binder classes or special
+ * <a href="#xml-cursor-adapter-bind-data-transformation">data transformations</a> can
+ * allow you to bind several columns to a single view. In this case you must use the
+ * <a href="#xml-cursor-adapter-select-tag"><code>&lt;select /&gt;</code> tag to make
+ * sure any required column is part of the query.</p>
+ * 
+ * <p>The <code>&lt;bind /&gt;</code> tag supports the following attributes:</p>
+ * <ul>
+ *  <li><code>android:from</code>: The name of the column to bind from.
+ *  This attribute is mandatory. Note that <code>@</code> which are not used to reference resources
+ *  should be backslash protected as in <code>\@</code>.</li>
+ *  <li><code>android:to</code>: The id of the view to bind to. This attribute is mandatory.</li>
+ *  <li><code>android:as</code>: The <a href="#xml-cursor-adapter-bind-data-types">data type</a>
+ *  of the binding. This attribute is mandatory.</li>
+ * </ul>
+ * 
+ * <p>In addition, a <code>&lt;bind /&gt;</code> can contain zero or more instances of
+ * <a href="#xml-cursor-adapter-bind-data-transformation">data transformations</a> children
+ * tags.</p>
+ *
+ * <a name="xml-cursor-adapter-bind-data-types"></a>
+ * <h4>Binding data types</h4>
+ * <p>For a binding to occur the data type of the bound column/view pair must be specified.
+ * The following data types are currently supported:</p>
+ * <ul>
+ *  <li><code>string</code>: The content of the column is interpreted as a string and must be
+ *  bound to a {@link android.widget.TextView}</li>
+ *  <li><code>image</code>: The content of the column is interpreted as a blob describing an
+ *  image and must be bound to an {@link android.widget.ImageView}</li>
+ *  <li><code>image-uri</code>: The content of the column is interpreted as a URI to an image
+ *  and must be bound to an {@link android.widget.ImageView}</li>
+ *  <li><code>drawable</code>: The content of the column is interpreted as a resource id to a
+ *  drawable and must be bound to an {@link android.widget.ImageView}</li>
+ *  <li><code>tag</code>: The content of the column is interpreted as a string and will be set as
+ *  the tag (using {@link View#setTag(Object)} of the associated View. This can be used to
+ *  associate meta-data to your view, that can be used for instance by a listener.</li>
+ *  <li>A fully qualified class name: The name of a class corresponding to an implementation of
+ *  {@link Adapters.CursorBinder}. Cursor binders can be used to provide
+ *  bindings not supported by default. Custom binders cannot be used with
+ *  {@link android.content.Context#isRestricted() restricted contexts}, for instance in an
+ *  application widget</li>
+ * </ul>
+ * 
+ * <a name="xml-cursor-adapter-bind-transformation"></a>
+ * <h4>Binding transformations</h4>
+ * <p>When defining a data binding you can specify an optional transformation by using one
+ * of the following tags as a child of a <code>&lt;bind /&gt;</code> elements:</p>
+ * <ul>
+ *  <li><code>&lt;map /&gt;</code>: Maps a constant string to a string or a resource. Use
+ *  one instance of this tag per value you want to map</li>
+ *  <li><code>&lt;transform /&gt;</code>: Transforms a column's value using an expression
+ *  or an instance of {@link Adapters.CursorTransformation}</li>
+ * </ul>
+ * <p>While several <code>&lt;map /&gt;</code> tags can be used at the same time, you cannot
+ * mix <code>&lt;map /&gt;</code> and <code>&lt;transform /&gt;</code> tags. If several
+ * <code>&lt;transform /&gt;</code> tags are specified, only the last one is retained.</p>
+ * 
+ * <a name="xml-cursor-adapter-bind-transformation-map" />
+ * <p><strong>&lt;map /&gt;</strong></p>
+ * <p>A map element simply specifies a value to match from and a value to match to. When
+ * a column's value equals the value to match from, it is replaced with the value to match
+ * to. The following attributes are supported:</p>
+ * <ul>
+ *  <li><code>android:fromValue</code>: The value to match from. This attribute is mandatory</li>
+ *  <li><code>android:toValue</code>: The value to match to. This value can be either a string
+ *  or a resource identifier. This value is interpreted as a resource identifier when the
+ *  data binding is of type <code>drawable</code>. This attribute is mandatory</li>
+ * </ul>
+ * 
+ * <a name="xml-cursor-adapter-bind-transformation-transform"></a>
+ * <p><strong>&lt;transform /&gt;</strong></p>
+ * <p>A simple transform that occurs either by calling a specified class or by performing
+ * simple text substitution. The following attributes are supported:</p>
+ * <ul>
+ *  <li><code>android:withExpression</code>: The transformation expression. The expression is
+ *  a string containing column names surrounded with curly braces { and }. During the
+ *  transformation each column name is replaced by its value. All columns must have been
+ *  selected in the query. An example of expression is <code>"First name: {first_name},
+ *  last name: {last_name}"</code>. This attribute is mandatory
+ *  if <code>android:withClass</code> is not specified and ignored if <code>android:withClass</code>
+ *  is specified</li>
+ *  <li><code>android:withClass</code>: A fully qualified class name corresponding to an
+ *  implementation of {@link Adapters.CursorTransformation}. Custom
+ *  transformations cannot be used with
+ *  {@link android.content.Context#isRestricted() restricted contexts}, for instance in
+ *  an app widget This attribute is mandatory if <code>android:withExpression</code> is
+ *  not specified</li>
+ * </ul>
+ * 
+ * <h3>Example</h3>
+ * <p>The following example defines a cursor adapter that queries all the contacts with
+ * a phone number using the contacts content provider. Each contact is displayed with
+ * its display name, its favorite status and its photo. To display photos, a custom data
+ * binder is declared:</p>
+ * 
+ * <pre class="prettyprint">
+ * &lt;cursor-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+ *     android:uri="content://com.android.contacts/contacts"
+ *     android:selection="has_phone_number=1"
+ *     android:layout="@layout/contact_item"&gt;
+ *
+ *     &lt;bind android:from="display_name" android:to="@id/name" android:as="string" /&gt;
+ *     &lt;bind android:from="starred" android:to="@id/star" android:as="drawable"&gt;
+ *         &lt;map android:fromValue="0" android:toValue="@android:drawable/star_big_off" /&gt;
+ *         &lt;map android:fromValue="1" android:toValue="@android:drawable/star_big_on" /&gt;
+ *     &lt;/bind&gt;
+ *     &lt;bind android:from="_id" android:to="@id/name"
+ *              android:as="com.google.android.test.adapters.ContactPhotoBinder" /&gt;
+ *
+ * &lt;/cursor-adapter&gt;
+ * </pre>
+ * 
+ * <h3>Related APIs</h3>
+ * <ul>
+ *  <li>{@link Adapters#loadAdapter(android.content.Context, int, Object[])}</li>
+ *  <li>{@link Adapters#loadCursorAdapter(android.content.Context, int, android.database.Cursor, Object[])}</li>
+ *  <li>{@link Adapters#loadCursorAdapter(android.content.Context, int, String, Object[])}</li>
+ *  <li>{@link Adapters.CursorBinder}</li>
+ *  <li>{@link Adapters.CursorTransformation}</li>
+ *  <li>{@link android.widget.CursorAdapter}</li>
+ * </ul>
+ * 
+ * @see android.widget.Adapter
+ * @see android.content.ContentProvider
+ * 
+ * attr ref android.R.styleable#CursorAdapter_layout
+ * attr ref android.R.styleable#CursorAdapter_selection
+ * attr ref android.R.styleable#CursorAdapter_sortOrder
+ * attr ref android.R.styleable#CursorAdapter_uri
+ * attr ref android.R.styleable#CursorAdapter_BindItem_as
+ * attr ref android.R.styleable#CursorAdapter_BindItem_from
+ * attr ref android.R.styleable#CursorAdapter_BindItem_to
+ * attr ref android.R.styleable#CursorAdapter_MapItem_fromValue
+ * attr ref android.R.styleable#CursorAdapter_MapItem_toValue
+ * attr ref android.R.styleable#CursorAdapter_SelectItem_column
+ * attr ref android.R.styleable#CursorAdapter_TransformItem_withClass
+ * attr ref android.R.styleable#CursorAdapter_TransformItem_withExpression
+ */
+@SuppressWarnings({"JavadocReference"})
+public class Adapters {
+    private static final String ADAPTER_CURSOR = "cursor-adapter";
+
+    /**
+     * <p>Interface used to bind a {@link android.database.Cursor} column to a View. This
+     * interface can be used to provide bindings for data types not supported by the
+     * standard implementation of {@link Adapters}.</p>
+     * 
+     * <p>A binder is provided with a cursor transformation which may or may not be used
+     * to transform the value retrieved from the cursor. The transformation is guaranteed
+     * to never be null so it's always safe to apply the transformation.</p>
+     * 
+     * <p>The binder is associated with a Context but can be re-used with multiple cursors.
+     * As such, the implementation should make no assumption about the Cursor in use.</p>
+     *
+     * @see android.view.View 
+     * @see android.database.Cursor
+     * @see Adapters.CursorTransformation
+     */
+    public static abstract class CursorBinder {
+        /**
+         * <p>The context associated with this binder.</p>
+         */
+        protected final Context mContext;
+
+        /**
+         * <p>The transformation associated with this binder. This transformation is never
+         * null and may or may not be applied to the Cursor data during the
+         * {@link #bind(android.view.View, android.database.Cursor, int)} operation.</p>
+         * 
+         * @see #bind(android.view.View, android.database.Cursor, int) 
+         */
+        protected final CursorTransformation mTransformation;
+
+        /**
+         * <p>Creates a new Cursor binder.</p> 
+         * 
+         * @param context The context associated with this binder.
+         * @param transformation The transformation associated with this binder. This
+         *        transformation may or may not be applied by the binder and is guaranteed
+         *        to not be null.
+         */
+        public CursorBinder(Context context, CursorTransformation transformation) {
+            mContext = context;
+            mTransformation = transformation;
+        }
+
+        /**
+         * <p>Binds the specified Cursor column to the supplied View. The binding operation
+         * can query other Cursor columns as needed. During the binding operation, values
+         * retrieved from the Cursor may or may not be transformed using this binder's
+         * cursor transformation.</p>
+         * 
+         * @param view The view to bind data to.
+         * @param cursor The cursor to bind data from.
+         * @param columnIndex The column index in the cursor where the data to bind resides.
+         * 
+         * @see #mTransformation
+         * 
+         * @return True if the column was successfully bound to the View, false otherwise.
+         */
+        public abstract boolean bind(View view, Cursor cursor, int columnIndex);
+    }
+
+    /**
+     * <p>Interface used to transform data coming out of a {@link android.database.Cursor}
+     * before it is bound to a {@link android.view.View}.</p>
+     * 
+     * <p>Transformations are used to transform text-based data (in the form of a String),
+     * or to transform data into a resource identifier. A default implementation is provided
+     * to generate resource identifiers.</p>
+     * 
+     * @see android.database.Cursor
+     * @see Adapters.CursorBinder
+     */
+    public static abstract class CursorTransformation {
+        /**
+         * <p>The context associated with this transformation.</p>
+         */
+        protected final Context mContext;
+
+        /**
+         * <p>Creates a new Cursor transformation.</p>
+         * 
+         * @param context The context associated with this transformation.
+         */
+        public CursorTransformation(Context context) {
+            mContext = context;
+        }
+
+        /**
+         * <p>Transforms the specified Cursor column into a String. The transformation
+         * can simply return the content of the column as a String (this is known
+         * as the identity transformation) or manipulate the content. For instance,
+         * a transformation can perform text substitutions or concatenate other
+         * columns with the specified column.</p>
+         * 
+         * @param cursor The cursor that contains the data to transform. 
+         * @param columnIndex The index of the column to transform.
+         * 
+         * @return A String containing the transformed value of the column.
+         */
+        public abstract String transform(Cursor cursor, int columnIndex);
+
+        /**
+         * <p>Transforms the specified Cursor column into a resource identifier.
+         * The default implementation simply interprets the content of the column
+         * as an integer.</p>
+         * 
+         * @param cursor The cursor that contains the data to transform. 
+         * @param columnIndex The index of the column to transform.
+         * 
+         * @return A resource identifier.
+         */
+        public int transformToResource(Cursor cursor, int columnIndex) {
+            return cursor.getInt(columnIndex);
+        }
+    }
+
+    /**
+     * <p>Loads the {@link android.widget.CursorAdapter} defined in the specified
+     * XML resource. The content of the adapter is loaded from the content provider
+     * identified by the supplied URI.</p>
+     * 
+     * <p><strong>Note:</strong> If the supplied {@link android.content.Context} is
+     * an {@link android.app.Activity}, the cursor returned by the content provider
+     * will be automatically managed. Otherwise, you are responsible for managing the
+     * cursor yourself.</p>
+     * 
+     * <p>The format of the XML definition of the cursor adapter is documented at
+     * the top of this page.</p>
+     * 
+     * @param context The context to load the XML resource from.
+     * @param id The identifier of the XML resource declaring the adapter.
+     * @param uri The URI of the content provider.
+     * @param parameters Optional parameters to pass to the CursorAdapter, used
+     *        to substitute values in the selection expression.
+     * 
+     * @return A {@link android.widget.CursorAdapter}
+     * 
+     * @throws IllegalArgumentException If the XML resource does not contain
+     *         a valid &lt;cursor-adapter /&gt; definition.
+     * 
+     * @see android.content.ContentProvider
+     * @see android.widget.CursorAdapter
+     * @see #loadAdapter(android.content.Context, int, Object[])
+     */
+    public static CursorAdapter loadCursorAdapter(Context context, int id, String uri,
+            Object... parameters) {
+
+        XmlCursorAdapter adapter = (XmlCursorAdapter) loadAdapter(context, id, ADAPTER_CURSOR,
+                parameters);
+
+        if (uri != null) {
+            adapter.setUri(uri);
+        }
+        adapter.load();
+
+        return adapter;
+    }
+
+    /**
+     * <p>Loads the {@link android.widget.CursorAdapter} defined in the specified
+     * XML resource. The content of the adapter is loaded from the specified cursor.
+     * You are responsible for managing the supplied cursor.</p>
+     * 
+     * <p>The format of the XML definition of the cursor adapter is documented at
+     * the top of this page.</p>
+     * 
+     * @param context The context to load the XML resource from.
+     * @param id The identifier of the XML resource declaring the adapter.
+     * @param cursor The cursor containing the data for the adapter.
+     * @param parameters Optional parameters to pass to the CursorAdapter, used
+     *        to substitute values in the selection expression.
+     * 
+     * @return A {@link android.widget.CursorAdapter}
+     * 
+     * @throws IllegalArgumentException If the XML resource does not contain
+     *         a valid &lt;cursor-adapter /&gt; definition.
+     * 
+     * @see android.content.ContentProvider
+     * @see android.widget.CursorAdapter
+     * @see android.database.Cursor
+     * @see #loadAdapter(android.content.Context, int, Object[])
+     */
+    public static CursorAdapter loadCursorAdapter(Context context, int id, Cursor cursor,
+            Object... parameters) {
+
+        XmlCursorAdapter adapter = (XmlCursorAdapter) loadAdapter(context, id, ADAPTER_CURSOR,
+                parameters);
+
+        if (cursor != null) {
+            adapter.changeCursor(cursor);
+        }
+
+        return adapter;
+    }
+
+    /**
+     * <p>Loads the adapter defined in the specified XML resource. The XML definition of
+     * the adapter must follow the format definition of one of the supported adapter
+     * types described at the top of this page.</p>
+     * 
+     * <p><strong>Note:</strong> If the loaded adapter is a {@link android.widget.CursorAdapter}
+     * and the supplied {@link android.content.Context} is an {@link android.app.Activity},
+     * the cursor returned by the content provider will be automatically managed. Otherwise,
+     * you are responsible for managing the cursor yourself.</p>
+     * 
+     * @param context The context to load the XML resource from.
+     * @param id The identifier of the XML resource declaring the adapter.
+     * @param parameters Optional parameters to pass to the adapter.
+     *  
+     * @return An adapter instance.
+     * 
+     * @see #loadCursorAdapter(android.content.Context, int, android.database.Cursor, Object[])
+     * @see #loadCursorAdapter(android.content.Context, int, String, Object[])
+     */
+    public static BaseAdapter loadAdapter(Context context, int id, Object... parameters) {
+        final BaseAdapter adapter = loadAdapter(context, id, null, parameters);
+        if (adapter instanceof ManagedAdapter) {
+            ((ManagedAdapter) adapter).load();
+        }
+        return adapter;
+    }
+
+    /**
+     * Loads an adapter from the specified XML resource. The optional assertName can
+     * be used to exit early if the adapter defined in the XML resource is not of the
+     * expected type.
+     * 
+     * @param context The context to associate with the adapter.
+     * @param id The resource id of the XML document defining the adapter.
+     * @param assertName The mandatory name of the adapter in the XML document.
+     *        Ignored if null.
+     * @param parameters Optional parameters passed to the adapter.
+     * 
+     * @return An instance of {@link android.widget.BaseAdapter}.
+     */
+    private static BaseAdapter loadAdapter(Context context, int id, String assertName,
+            Object... parameters) {
+
+        XmlResourceParser parser = null;
+        try {
+            parser = context.getResources().getXml(id);
+            return createAdapterFromXml(context, parser, Xml.asAttributeSet(parser),
+                    id, parameters, assertName);
+        } catch (XmlPullParserException ex) {
+            Resources.NotFoundException rnf = new Resources.NotFoundException(
+                    "Can't load adapter resource ID " +
+                    context.getResources().getResourceEntryName(id));
+            rnf.initCause(ex);
+            throw rnf;
+        } catch (IOException ex) {
+            Resources.NotFoundException rnf = new Resources.NotFoundException(
+                    "Can't load adapter resource ID " +
+                    context.getResources().getResourceEntryName(id));
+            rnf.initCause(ex);
+            throw rnf;
+        } finally {
+            if (parser != null) parser.close();
+        }
+    }
+
+    /**
+     * Generates an adapter using the specified XML parser. This method is responsible
+     * for choosing the type of the adapter to create based on the content of the
+     * XML parser.
+     * 
+     * This method will generate an {@link IllegalArgumentException} if
+     * <code>assertName</code> is not null and does not match the root tag of the XML
+     * document.
+     */
+    private static BaseAdapter createAdapterFromXml(Context c,
+            XmlPullParser parser, AttributeSet attrs, int id, Object[] parameters,
+            String assertName) throws XmlPullParserException, IOException {
+
+        BaseAdapter adapter = null;
+
+        // Make sure we are on a start tag.
+        int type;
+        int depth = parser.getDepth();
+
+        while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) &&
+                type != XmlPullParser.END_DOCUMENT) {
+
+            if (type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            String name = parser.getName();
+            if (assertName != null && !assertName.equals(name)) {
+                throw new IllegalArgumentException("The adapter defined in " +
+                        c.getResources().getResourceEntryName(id) + " must be a <" +
+                        assertName + " />");
+            }
+
+            if (ADAPTER_CURSOR.equals(name)) {
+                adapter = createCursorAdapter(c, parser, attrs, id, parameters);
+            } else {
+                throw new IllegalArgumentException("Unknown adapter name " + parser.getName() +
+                        " in " + c.getResources().getResourceEntryName(id));
+            }
+        }
+
+        return adapter;
+
+    }
+
+    /**
+     * Creates an XmlCursorAdapter using an XmlCursorAdapterParser.
+     */
+    private static XmlCursorAdapter createCursorAdapter(Context c, XmlPullParser parser,
+            AttributeSet attrs, int id, Object[] parameters)
+            throws IOException, XmlPullParserException {
+
+        return new XmlCursorAdapterParser(c, parser, attrs, id).parse(parameters);
+    }
+
+    /**
+     * Parser that can generate XmlCursorAdapter instances. This parser is responsible for
+     * handling all the attributes and child nodes for a &lt;cursor-adapter /&gt;.
+     */
+    private static class XmlCursorAdapterParser {
+        private static final String ADAPTER_CURSOR_BIND = "bind";
+        private static final String ADAPTER_CURSOR_SELECT = "select";
+        private static final String ADAPTER_CURSOR_AS_STRING = "string";
+        private static final String ADAPTER_CURSOR_AS_IMAGE = "image";
+        private static final String ADAPTER_CURSOR_AS_TAG = "tag";
+        private static final String ADAPTER_CURSOR_AS_IMAGE_URI = "image-uri";
+        private static final String ADAPTER_CURSOR_AS_DRAWABLE = "drawable";
+        private static final String ADAPTER_CURSOR_MAP = "map";
+        private static final String ADAPTER_CURSOR_TRANSFORM = "transform";
+
+        private final Context mContext;
+        private final XmlPullParser mParser;
+        private final AttributeSet mAttrs;
+        private final int mId;
+
+        private final HashMap<String, CursorBinder> mBinders;
+        private final ArrayList<String> mFrom;
+        private final ArrayList<Integer> mTo;
+        private final CursorTransformation mIdentity;
+        private final Resources mResources;
+
+        public XmlCursorAdapterParser(Context c, XmlPullParser parser, AttributeSet attrs, int id) {
+            mContext = c;
+            mParser = parser;
+            mAttrs = attrs;
+            mId = id;
+
+            mResources = mContext.getResources();
+            mBinders = new HashMap<String, CursorBinder>();
+            mFrom = new ArrayList<String>();
+            mTo = new ArrayList<Integer>();
+            mIdentity = new IdentityTransformation(mContext);
+        }
+
+        public XmlCursorAdapter parse(Object[] parameters)
+               throws IOException, XmlPullParserException {
+
+            Resources resources = mResources;
+            TypedArray a = resources.obtainAttributes(mAttrs, R.styleable.CursorAdapter);
+
+            String uri = a.getString(R.styleable.CursorAdapter_uri);
+            String selection = a.getString(R.styleable.CursorAdapter_selection);
+            String sortOrder = a.getString(R.styleable.CursorAdapter_sortOrder);
+            int layout = a.getResourceId(R.styleable.CursorAdapter_layout, 0);
+            if (layout == 0) {
+                throw new IllegalArgumentException("The layout specified in " +
+                        resources.getResourceEntryName(mId) + " does not exist");
+            }
+
+            a.recycle();
+
+            XmlPullParser parser = mParser;
+            int type;
+            int depth = parser.getDepth();
+
+            while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) &&
+                    type != XmlPullParser.END_DOCUMENT) {
+
+                if (type != XmlPullParser.START_TAG) {
+                    continue;
+                }
+
+                String name = parser.getName();
+
+                if (ADAPTER_CURSOR_BIND.equals(name)) {
+                    parseBindTag();
+                } else if (ADAPTER_CURSOR_SELECT.equals(name)) {
+                    parseSelectTag();
+                } else {
+                    throw new RuntimeException("Unknown tag name " + parser.getName() + " in " +
+                            resources.getResourceEntryName(mId));
+                }
+            }
+
+            String[] fromArray = mFrom.toArray(new String[mFrom.size()]);
+            int[] toArray = new int[mTo.size()];
+            for (int i = 0; i < toArray.length; i++) {
+                toArray[i] = mTo.get(i);
+            }
+
+            String[] selectionArgs = null;
+            if (parameters != null) {
+                selectionArgs = new String[parameters.length];
+                for (int i = 0; i < selectionArgs.length; i++) {
+                    selectionArgs[i] = (String) parameters[i];
+                }
+            }
+
+            return new XmlCursorAdapter(mContext, layout, uri, fromArray, toArray, selection,
+                    selectionArgs, sortOrder, mBinders);
+        }
+
+        private void parseSelectTag() {
+            TypedArray a = mResources.obtainAttributes(mAttrs,
+                    R.styleable.CursorAdapter_SelectItem);
+
+            String fromName = a.getString(R.styleable.CursorAdapter_SelectItem_column);
+            if (fromName == null) {
+                throw new IllegalArgumentException("A select item in " +
+                        mResources.getResourceEntryName(mId) +
+                        " does not have a 'column' attribute");
+            }
+
+            a.recycle();
+
+            mFrom.add(fromName);
+            mTo.add(View.NO_ID);
+        }
+
+        private void parseBindTag() throws IOException, XmlPullParserException {
+            Resources resources = mResources;
+            TypedArray a = resources.obtainAttributes(mAttrs,
+                    R.styleable.CursorAdapter_BindItem);
+
+            String fromName = a.getString(R.styleable.CursorAdapter_BindItem_from);
+            if (fromName == null) {
+                throw new IllegalArgumentException("A bind item in " +
+                        resources.getResourceEntryName(mId) + " does not have a 'from' attribute");
+            }
+
+            int toName = a.getResourceId(R.styleable.CursorAdapter_BindItem_to, 0);
+            if (toName == 0) {
+                throw new IllegalArgumentException("A bind item in " +
+                        resources.getResourceEntryName(mId) + " does not have a 'to' attribute");
+            }
+
+            String asType = a.getString(R.styleable.CursorAdapter_BindItem_as);
+            if (asType == null) {
+                throw new IllegalArgumentException("A bind item in " +
+                        resources.getResourceEntryName(mId) + " does not have an 'as' attribute");
+            }
+
+            mFrom.add(fromName);
+            mTo.add(toName);
+            mBinders.put(fromName, findBinder(asType));
+
+            a.recycle();
+        }
+
+        private CursorBinder findBinder(String type) throws IOException, XmlPullParserException {
+            final XmlPullParser parser = mParser;
+            final Context context = mContext;
+            CursorTransformation transformation = mIdentity;
+
+            int tagType;
+            int depth = parser.getDepth();
+
+            final boolean isDrawable = ADAPTER_CURSOR_AS_DRAWABLE.equals(type);
+
+            while (((tagType = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                    && tagType != XmlPullParser.END_DOCUMENT) {
+
+                if (tagType != XmlPullParser.START_TAG) {
+                    continue;
+                }
+
+                String name = parser.getName();
+
+                if (ADAPTER_CURSOR_TRANSFORM.equals(name)) {
+                    transformation = findTransformation();
+                } else if (ADAPTER_CURSOR_MAP.equals(name)) {
+                    if (!(transformation instanceof MapTransformation)) {
+                        transformation = new MapTransformation(context);
+                    }
+                    findMap(((MapTransformation) transformation), isDrawable);
+                } else {
+                    throw new RuntimeException("Unknown tag name " + parser.getName() + " in " +
+                            context.getResources().getResourceEntryName(mId));
+                }
+            }
+
+            if (ADAPTER_CURSOR_AS_STRING.equals(type)) {
+                return new StringBinder(context, transformation);
+            } else if (ADAPTER_CURSOR_AS_TAG.equals(type)) {
+                return new TagBinder(context, transformation);
+            } else if (ADAPTER_CURSOR_AS_IMAGE.equals(type)) {
+                return new ImageBinder(context, transformation);
+            } else if (ADAPTER_CURSOR_AS_IMAGE_URI.equals(type)) {
+                return new ImageUriBinder(context, transformation);
+            } else if (isDrawable) {
+                return new DrawableBinder(context, transformation);
+            } else {
+                return createBinder(type, transformation);
+            }
+        }
+
+        private CursorBinder createBinder(String type, CursorTransformation transformation) {
+            if (mContext.isRestricted()) return null;
+
+            try {
+                final Class<?> klass = Class.forName(type, true, mContext.getClassLoader());
+                if (CursorBinder.class.isAssignableFrom(klass)) {
+                    final Constructor<?> c = klass.getDeclaredConstructor(
+                            Context.class, CursorTransformation.class);
+                    return (CursorBinder) c.newInstance(mContext, transformation);
+                }
+            } catch (ClassNotFoundException e) {
+                throw new IllegalArgumentException("Cannot instanciate binder type in " +
+                        mContext.getResources().getResourceEntryName(mId) + ": " + type, e);
+            } catch (NoSuchMethodException e) {
+                throw new IllegalArgumentException("Cannot instanciate binder type in " +
+                        mContext.getResources().getResourceEntryName(mId) + ": " + type, e);
+            } catch (InvocationTargetException e) {
+                throw new IllegalArgumentException("Cannot instanciate binder type in " +
+                        mContext.getResources().getResourceEntryName(mId) + ": " + type, e);
+            } catch (InstantiationException e) {
+                throw new IllegalArgumentException("Cannot instanciate binder type in " +
+                        mContext.getResources().getResourceEntryName(mId) + ": " + type, e);
+            } catch (IllegalAccessException e) {
+                throw new IllegalArgumentException("Cannot instanciate binder type in " +
+                        mContext.getResources().getResourceEntryName(mId) + ": " + type, e);
+            }
+
+            return null;
+        }
+
+        private void findMap(MapTransformation transformation, boolean drawable) {
+            Resources resources = mResources;
+
+            TypedArray a = resources.obtainAttributes(mAttrs,
+                    R.styleable.CursorAdapter_MapItem);
+
+            String from = a.getString(R.styleable.CursorAdapter_MapItem_fromValue);
+            if (from == null) {
+                throw new IllegalArgumentException("A map item in " +
+                        resources.getResourceEntryName(mId) +
+                        " does not have a 'fromValue' attribute");
+            }
+
+            if (!drawable) {
+                String to = a.getString(R.styleable.CursorAdapter_MapItem_toValue);
+                if (to == null) {
+                    throw new IllegalArgumentException("A map item in " +
+                            resources.getResourceEntryName(mId) +
+                            " does not have a 'toValue' attribute");
+                }
+                transformation.addStringMapping(from, to);
+            } else {
+                int to = a.getResourceId(R.styleable.CursorAdapter_MapItem_toValue, 0);
+                if (to == 0) {
+                    throw new IllegalArgumentException("A map item in " +
+                            resources.getResourceEntryName(mId) +
+                            " does not have a 'toValue' attribute");
+                }
+                transformation.addResourceMapping(from, to);
+            }
+
+            a.recycle();
+        }
+
+        private CursorTransformation findTransformation() {
+            Resources resources = mResources;
+            CursorTransformation transformation = null;
+            TypedArray a = resources.obtainAttributes(mAttrs,
+                    R.styleable.CursorAdapter_TransformItem);
+
+            String className = a.getString(R.styleable.CursorAdapter_TransformItem_withClass);
+            if (className == null) {
+                String expression = a.getString(
+                        R.styleable.CursorAdapter_TransformItem_withExpression);
+                transformation = createExpressionTransformation(expression);
+            } else if (!mContext.isRestricted()) {
+                try {
+                    final Class<?> klas = Class.forName(className, true, mContext.getClassLoader());
+                    if (CursorTransformation.class.isAssignableFrom(klas)) {
+                        final Constructor<?> c = klas.getDeclaredConstructor(Context.class);
+                        transformation = (CursorTransformation) c.newInstance(mContext);
+                    }
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalArgumentException("Cannot instanciate transform type in " +
+                           mContext.getResources().getResourceEntryName(mId) + ": " + className, e);
+                } catch (NoSuchMethodException e) {
+                    throw new IllegalArgumentException("Cannot instanciate transform type in " +
+                           mContext.getResources().getResourceEntryName(mId) + ": " + className, e);
+                } catch (InvocationTargetException e) {
+                    throw new IllegalArgumentException("Cannot instanciate transform type in " +
+                           mContext.getResources().getResourceEntryName(mId) + ": " + className, e);
+                } catch (InstantiationException e) {
+                    throw new IllegalArgumentException("Cannot instanciate transform type in " +
+                           mContext.getResources().getResourceEntryName(mId) + ": " + className, e);
+                } catch (IllegalAccessException e) {
+                    throw new IllegalArgumentException("Cannot instanciate transform type in " +
+                           mContext.getResources().getResourceEntryName(mId) + ": " + className, e);
+                }
+            }
+
+            a.recycle();
+
+            if (transformation == null) {
+                throw new IllegalArgumentException("A transform item in " +
+                    resources.getResourceEntryName(mId) + " must have a 'withClass' or " +
+                    "'withExpression' attribute");
+            }
+
+            return transformation;
+        }
+
+        private CursorTransformation createExpressionTransformation(String expression) {
+            return new ExpressionTransformation(mContext, expression);
+        }
+    }
+
+    /**
+     * Interface used by adapters that require to be loaded after creation.
+     */
+    private static interface ManagedAdapter {
+        /**
+         * Loads the content of the adapter, asynchronously.
+         */
+        void load();
+    }
+
+    /**
+     * Implementation of a Cursor adapter defined in XML. This class is a thin wrapper
+     * of a SimpleCursorAdapter. The main difference is the ability to handle CursorBinders.
+     */
+    private static class XmlCursorAdapter extends SimpleCursorAdapter implements ManagedAdapter {
+        private String mUri;
+        private final String mSelection;
+        private final String[] mSelectionArgs;
+        private final String mSortOrder;
+        private final String[] mColumns;
+        private final CursorBinder[] mBinders;
+        private AsyncTask<Void,Void,Cursor> mLoadTask;
+
+        XmlCursorAdapter(Context context, int layout, String uri, String[] from, int[] to,
+                String selection, String[] selectionArgs, String sortOrder,
+                HashMap<String, CursorBinder> binders) {
+
+            super(context, layout, null, from, to);
+            mContext = context;
+            mUri = uri;
+            mSelection = selection;
+            mSelectionArgs = selectionArgs;
+            mSortOrder = sortOrder;
+            mColumns = new String[from.length + 1];
+            // This is mandatory in CursorAdapter
+            mColumns[0] = "_id";
+            System.arraycopy(from, 0, mColumns, 1, from.length);
+
+            CursorBinder basic = new StringBinder(context, new IdentityTransformation(context));
+            final int count = from.length;
+            mBinders = new CursorBinder[count];
+
+            for (int i = 0; i < count; i++) {
+                CursorBinder binder = binders.get(from[i]);
+                if (binder == null) binder = basic;
+                mBinders[i] = binder;
+            }
+        }
+
+        @Override
+        public void bindView(View view, Context context, Cursor cursor) {
+            final int count = mTo.length;
+            final int[] from = mFrom;
+            final int[] to = mTo;
+            final CursorBinder[] binders = mBinders;
+
+            for (int i = 0; i < count; i++) {
+                final View v = view.findViewById(to[i]);
+                if (v != null) {
+                    binders[i].bind(v, cursor, from[i]);
+                }
+            }
+        }
+
+        public void load() {
+            if (mUri != null) {
+                mLoadTask = new QueryTask().execute();
+            }
+        }
+
+        void setUri(String uri) {
+            mUri = uri;
+        }
+
+        @Override
+        public void changeCursor(Cursor c) {
+            if (mLoadTask != null && mLoadTask.getStatus() != QueryTask.Status.FINISHED) {
+                mLoadTask.cancel(true);
+                mLoadTask = null;
+            }
+            super.changeCursor(c);
+        }
+
+        class QueryTask extends AsyncTask<Void, Void, Cursor> {
+            @Override
+            protected Cursor doInBackground(Void... params) {
+                if (mContext instanceof Activity) {
+                    return ((Activity) mContext).managedQuery(
+                            Uri.parse(mUri), mColumns, mSelection, mSelectionArgs, mSortOrder);
+                } else {
+                    return mContext.getContentResolver().query(
+                            Uri.parse(mUri), mColumns, mSelection, mSelectionArgs, mSortOrder);
+                }
+            }
+
+            @Override
+            protected void onPostExecute(Cursor cursor) {
+                if (!isCancelled()) {
+                    XmlCursorAdapter.super.changeCursor(cursor);
+                }
+            }
+        }
+    }
+
+    /**
+     * Identity transformation, returns the content of the specified column as a String,
+     * without performing any manipulation. This is used when no transformation is specified.
+     */
+    private static class IdentityTransformation extends CursorTransformation {
+        public IdentityTransformation(Context context) {
+            super(context);
+        }
+
+        @Override
+        public String transform(Cursor cursor, int columnIndex) {
+            return cursor.getString(columnIndex);
+        }
+    }
+
+    /**
+     * An expression transformation is a simple template based replacement utility.
+     * In an expression, each segment of the form <code>{([^}]+)}</code> is replaced
+     * with the value of the column of name $1.
+     */
+    private static class ExpressionTransformation extends CursorTransformation {
+        private final ExpressionNode mFirstNode = new ConstantExpressionNode("");
+        private final StringBuilder mBuilder = new StringBuilder();
+
+        public ExpressionTransformation(Context context, String expression) {
+            super(context);
+
+            parse(expression);
+        }
+
+        private void parse(String expression) {
+            ExpressionNode node = mFirstNode;
+            int segmentStart;
+            int count = expression.length();
+
+            for (int i = 0; i < count; i++) {
+                char c = expression.charAt(i);
+                // Start a column name segment
+                segmentStart = i;
+                if (c == '{') {
+                    while (i < count && (c = expression.charAt(i)) != '}') {
+                        i++;
+                    }
+                    // We've reached the end, but the expression didn't close
+                    if (c != '}') {
+                        throw new IllegalStateException("The transform expression contains a " +
+                                "non-closed column name: " +
+                                expression.substring(segmentStart + 1, i));
+                    }
+                    node.next = new ColumnExpressionNode(expression.substring(segmentStart + 1, i));
+                } else {
+                    while (i < count && (c = expression.charAt(i)) != '{') {
+                        i++;
+                    }
+                    node.next = new ConstantExpressionNode(expression.substring(segmentStart, i));
+                    // Rewind if we've reached a column expression
+                    if (c == '{') i--;
+                }
+                node = node.next;
+            }
+        }
+
+        @Override
+        public String transform(Cursor cursor, int columnIndex) {
+            final StringBuilder builder = mBuilder;
+            builder.delete(0, builder.length());
+
+            ExpressionNode node = mFirstNode;
+            // Skip the first node
+            while ((node = node.next) != null) {
+                builder.append(node.asString(cursor));
+            }
+
+            return builder.toString();
+        }
+
+        static abstract class ExpressionNode {
+            public ExpressionNode next;
+
+            public abstract String asString(Cursor cursor);
+        }
+
+        static class ConstantExpressionNode extends ExpressionNode {
+            private final String mConstant;
+
+            ConstantExpressionNode(String constant) {
+                mConstant = constant;
+            }
+
+            @Override
+            public String asString(Cursor cursor) {
+                return mConstant;
+            }
+        }
+
+        static class ColumnExpressionNode extends ExpressionNode {
+            private final String mColumnName;
+            private Cursor mSignature;
+            private int mColumnIndex = -1;
+
+            ColumnExpressionNode(String columnName) {
+                mColumnName = columnName;
+            }
+
+            @Override
+            public String asString(Cursor cursor) {
+                if (cursor != mSignature || mColumnIndex == -1) {
+                    mColumnIndex = cursor.getColumnIndex(mColumnName);
+                    mSignature = cursor;
+                }
+
+                return cursor.getString(mColumnIndex);
+            }
+        }
+    }
+
+    /**
+     * A map transformation offers a simple mapping between specified String values
+     * to Strings or integers.
+     */
+    private static class MapTransformation extends CursorTransformation {
+        private final HashMap<String, String> mStringMappings;
+        private final HashMap<String, Integer> mResourceMappings;
+
+        public MapTransformation(Context context) {
+            super(context);
+            mStringMappings = new HashMap<String, String>();
+            mResourceMappings = new HashMap<String, Integer>();
+        }
+
+        void addStringMapping(String from, String to) {
+            mStringMappings.put(from, to);
+        }
+
+        void addResourceMapping(String from, int to) {
+            mResourceMappings.put(from, to);
+        }
+
+        @Override
+        public String transform(Cursor cursor, int columnIndex) {
+            final String value = cursor.getString(columnIndex);
+            final String transformed = mStringMappings.get(value);
+            return transformed == null ? value : transformed;
+        }
+
+        @Override
+        public int transformToResource(Cursor cursor, int columnIndex) {
+            final String value = cursor.getString(columnIndex);
+            final Integer transformed = mResourceMappings.get(value);
+            try {
+                return transformed == null ? Integer.parseInt(value) : transformed;
+            } catch (NumberFormatException e) {
+                return 0;
+            }
+        }
+    }
+
+    /**
+     * Binds a String to a TextView.
+     */
+    private static class StringBinder extends CursorBinder {
+        public StringBinder(Context context, CursorTransformation transformation) {
+            super(context, transformation);
+        }
+
+        @Override
+        public boolean bind(View view, Cursor cursor, int columnIndex) {
+            if (view instanceof TextView) {
+                final String text = mTransformation.transform(cursor, columnIndex);
+                ((TextView) view).setText(text);
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Binds an image blob to an ImageView.
+     */
+    private static class ImageBinder extends CursorBinder {
+        public ImageBinder(Context context, CursorTransformation transformation) {
+            super(context, transformation);
+        }
+
+        @Override
+        public boolean bind(View view, Cursor cursor, int columnIndex) {
+            if (view instanceof ImageView) {
+                final byte[] data = cursor.getBlob(columnIndex);
+                ((ImageView) view).setImageBitmap(BitmapFactory.decodeByteArray(data, 0,
+                        data.length));
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private static class TagBinder extends CursorBinder {
+        public TagBinder(Context context, CursorTransformation transformation) {
+            super(context, transformation);
+        }
+
+        @Override
+        public boolean bind(View view, Cursor cursor, int columnIndex) {
+            final String text = mTransformation.transform(cursor, columnIndex);
+            view.setTag(text);
+            return true;
+        }
+    }
+
+    /**
+     * Binds an image URI to an ImageView.
+     */
+    private static class ImageUriBinder extends CursorBinder {
+        public ImageUriBinder(Context context, CursorTransformation transformation) {
+            super(context, transformation);
+        }
+
+        @Override
+        public boolean bind(View view, Cursor cursor, int columnIndex) {
+            if (view instanceof ImageView) {
+                ((ImageView) view).setImageURI(Uri.parse(
+                        mTransformation.transform(cursor, columnIndex)));
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Binds a drawable resource identifier to an ImageView.
+     */
+    private static class DrawableBinder extends CursorBinder {
+        public DrawableBinder(Context context, CursorTransformation transformation) {
+            super(context, transformation);
+        }
+
+        @Override
+        public boolean bind(View view, Cursor cursor, int columnIndex) {
+            if (view instanceof ImageView) {
+                final int resource = mTransformation.transformToResource(cursor, columnIndex);
+                if (resource == 0) return false;
+
+                ((ImageView) view).setImageResource(resource);
+                return true;
+            }
+            return false;
+        }
+    }
+}
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/ContactPhotoBinder.java b/samples/XmlAdapters/src/com/example/android/xmladapters/ContactPhotoBinder.java
new file mode 100644
index 0000000..a0df013
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/ContactPhotoBinder.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.xmladapters;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.view.View;
+import android.widget.TextView;
+
+import java.io.InputStream;
+import java.util.HashMap;
+
+/**
+ * This custom cursor binder is used by the adapter defined in res/xml to
+ * bind contacts photos to their respective list item. This binder simply
+ * queries a contact's photo based on the contact's id and sets the
+ * photo as a compound drawable on the TextView used to display the contact's
+ * name.
+ */
+public class ContactPhotoBinder extends Adapters.CursorBinder {
+    private static final int PHOTO_SIZE_DIP = 54;
+    
+    private final Drawable mDefault;
+    private final HashMap<Long, Drawable> mCache;
+    private final Resources mResources;
+    private final int mPhotoSize;
+
+    public ContactPhotoBinder(Context context, Adapters.CursorTransformation transformation) {
+        super(context, transformation);
+
+        mResources = mContext.getResources();
+        // Default picture used when a contact does not provide one
+        mDefault = mResources.getDrawable(R.drawable.ic_contact_picture);
+        // Cache used to avoid re-querying contacts photos every time
+        mCache = new HashMap<Long, Drawable>();
+        // Compute the size of the photo based on the display's density
+        mPhotoSize = (int) (PHOTO_SIZE_DIP * mResources.getDisplayMetrics().density + 0.5f);
+    }
+
+    @Override
+    public boolean bind(View view, Cursor cursor, int columnIndex) {
+        final long id = cursor.getLong(columnIndex);
+        
+        // First check whether we have already cached the contact's photo
+        Drawable d = mCache.get(id);
+        
+        if (d == null) {
+            // If the photo wasn't in the cache, ask the contacts provider for
+            // an input stream we can use to load the photo
+            Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
+            InputStream stream = ContactsContract.Contacts.openContactPhotoInputStream(
+                    mContext.getContentResolver(), uri);
+    
+            // Creates the drawable for the contact's photo or use our fallback drawable
+            if (stream != null) {
+                // decoding the bitmap could be done in a worker thread too.
+                Bitmap bitmap = BitmapFactory.decodeStream(stream);
+                d = new BitmapDrawable(mResources, bitmap);
+            } else {
+                d = mDefault;
+            }
+
+            d.setBounds(0, 0, mPhotoSize, mPhotoSize);
+            ((TextView) view).setCompoundDrawables(d, null, null, null);
+
+            // Remember the photo associated with this contact
+            mCache.put(id, d);
+        } else {
+            ((TextView) view).setCompoundDrawables(d, null, null, null);
+        }
+
+        return true;
+    }
+}
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/ContactsListActivity.java b/samples/XmlAdapters/src/com/example/android/xmladapters/ContactsListActivity.java
new file mode 100644
index 0000000..25ecd9e
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/ContactsListActivity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.xmladapters;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+
+/**
+ * This activity demonstrates how to create a complex UI using a ListView
+ * and an adapter defined in XML.
+ * 
+ * The following activity shows a list of contacts, their starred status
+ * and their photos, using the adapter defined in res/xml.
+ */
+public class ContactsListActivity extends ListActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.contacts_list);
+        setListAdapter(Adapters.loadAdapter(this, R.xml.contacts));
+    }
+}
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.java b/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.java
new file mode 100644
index 0000000..c84f9d5
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */package com.example.android.xmladapters;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This helper class download images from the Internet and binds those with the provided ImageView.
+ *
+ * <p>It requires the INTERNET permission, which should be added to your application's manifest
+ * file.</p>
+ *
+ * A local cache of downloaded images is maintained internally to improve performance.
+ */
+public class ImageDownloader {
+    private static final String LOG_TAG = "ImageDownloader";
+
+    private static final int HARD_CACHE_CAPACITY = 40;
+    private static final int DELAY_BEFORE_PURGE = 30 * 1000; // in milliseconds
+
+    // Hard cache, with a fixed maximum capacity and a life duration
+    private final HashMap<String, Bitmap> sHardBitmapCache =
+        new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {
+        @Override
+        protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
+            if (size() > HARD_CACHE_CAPACITY) {
+                // Entries push-out of hard reference cache are transferred to soft reference cache
+                sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));
+                return true;
+            } else
+                return false;
+        }
+    };
+
+    // Soft cache for bitmap kicked out of hard cache
+    private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache =
+        new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);
+
+    private final Handler purgeHandler = new Handler();
+
+    private final Runnable purger = new Runnable() {
+        public void run() {
+            clearCache();
+        }
+    };
+
+    /**
+     * Download the specified image from the Internet and binds it to the provided ImageView. The
+     * binding is immediate if the image is found in the cache and will be done asynchronously
+     * otherwise. A null bitmap will be associated to the ImageView if an error occurs.
+     *
+     * @param url The URL of the image to download.
+     * @param imageView The ImageView to bind the downloaded image to.
+     */
+    public void download(String url, ImageView imageView) {
+        download(url, imageView, null);
+    }
+
+    /**
+     * Same as {@link #download(String, ImageView)}, with the possibility to provide an additional
+     * cookie that will be used when the image will be retrieved.
+     *
+     * @param url The URL of the image to download.
+     * @param imageView The ImageView to bind the downloaded image to.
+     * @param cookie A cookie String that will be used by the http connection.
+     */
+    public void download(String url, ImageView imageView, String cookie) {
+        resetPurgeTimer();
+        Bitmap bitmap = getBitmapFromCache(url);
+
+        if (bitmap == null) {
+            forceDownload(url, imageView, cookie);
+        } else {
+            cancelPotentialDownload(url, imageView);
+            imageView.setImageBitmap(bitmap);
+        }
+    }
+
+    /*
+     * Same as download but the image is always downloaded and the cache is not used.
+     * Kept private at the moment as its interest is not clear.
+       private void forceDownload(String url, ImageView view) {
+          forceDownload(url, view, null);
+       }
+     */
+
+    /**
+     * Same as download but the image is always downloaded and the cache is not used.
+     * Kept private at the moment as its interest is not clear.
+     */
+    private void forceDownload(String url, ImageView imageView, String cookie) {
+        // State sanity: url is guaranteed to never be null in DownloadedDrawable and cache keys.
+        if (url == null) {
+            imageView.setImageDrawable(null);
+            return;
+        }
+
+        if (cancelPotentialDownload(url, imageView)) {
+            BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
+            DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
+            imageView.setImageDrawable(downloadedDrawable);
+            task.execute(url, cookie);
+        }
+    }
+
+    /**
+     * Clears the image cache used internally to improve performance. Note that for memory
+     * efficiency reasons, the cache will automatically be cleared after a certain inactivity delay.
+     */
+    public void clearCache() {
+        sHardBitmapCache.clear();
+        sSoftBitmapCache.clear();
+    }
+
+    private void resetPurgeTimer() {
+        purgeHandler.removeCallbacks(purger);
+        purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE);
+    }
+
+    /**
+     * Returns true if the current download has been canceled or if there was no download in
+     * progress on this image view.
+     * Returns false if the download in progress deals with the same url. The download is not
+     * stopped in that case.
+     */
+    private static boolean cancelPotentialDownload(String url, ImageView imageView) {
+        BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
+
+        if (bitmapDownloaderTask != null) {
+            String bitmapUrl = bitmapDownloaderTask.url;
+            if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
+                bitmapDownloaderTask.cancel(true);
+            } else {
+                // The same URL is already being downloaded.
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @param imageView Any imageView
+     * @return Retrieve the currently active download task (if any) associated with this imageView.
+     * null if there is no such task.
+     */
+    private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
+        if (imageView != null) {
+            Drawable drawable = imageView.getDrawable();
+            if (drawable instanceof DownloadedDrawable) {
+                DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
+                return downloadedDrawable.getBitmapDownloaderTask();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @param url The URL of the image that will be retrieved from the cache.
+     * @return The cached bitmap or null if it was not found.
+     */
+    private Bitmap getBitmapFromCache(String url) {
+        // First try the hard reference cache
+        synchronized (sHardBitmapCache) {
+            final Bitmap bitmap = sHardBitmapCache.get(url);
+            if (bitmap != null) {
+                // Bitmap found in hard cache
+                // Move element to first position, so that it is removed last
+                sHardBitmapCache.remove(url);
+                sHardBitmapCache.put(url, bitmap);
+                return bitmap;
+            }
+        }
+
+        // Then try the soft reference cache
+        SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url);
+        if (bitmapReference != null) {
+            final Bitmap bitmap = bitmapReference.get();
+            if (bitmap != null) {
+                // Bitmap found in soft cache
+                return bitmap;
+            } else {
+                // Soft reference has been Garbage Collected
+                sSoftBitmapCache.remove(url);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * The actual AsyncTask that will asynchronously download the image.
+     */
+    class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
+        private static final int IO_BUFFER_SIZE = 4 * 1024;
+        private String url;
+        private final WeakReference<ImageView> imageViewReference;
+
+        public BitmapDownloaderTask(ImageView imageView) {
+            imageViewReference = new WeakReference<ImageView>(imageView);
+        }
+
+        /**
+         * Actual download method.
+         */
+        @Override
+        protected Bitmap doInBackground(String... params) {
+            final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
+            url = params[0];
+            final HttpGet getRequest = new HttpGet(url);
+            String cookie = params[1];
+            if (cookie != null) {
+                getRequest.setHeader("cookie", cookie);
+            }
+
+            try {
+                HttpResponse response = client.execute(getRequest);
+                final int statusCode = response.getStatusLine().getStatusCode();
+                if (statusCode != HttpStatus.SC_OK) {
+                    Log.w("ImageDownloader", "Error " + statusCode +
+                            " while retrieving bitmap from " + url);
+                    return null;
+                }
+
+                final HttpEntity entity = response.getEntity();
+                if (entity != null) {
+                    InputStream inputStream = null;
+                    OutputStream outputStream = null;
+                    try {
+                        inputStream = entity.getContent();
+                        final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+                        outputStream = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
+                        copy(inputStream, outputStream);
+                        outputStream.flush();
+
+                        final byte[] data = dataStream.toByteArray();
+                        final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+
+                        // FIXME : Should use BitmapFactory.decodeStream(inputStream) instead.
+                        //final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
+
+                        return bitmap;
+
+                    } finally {
+                        if (inputStream != null) {
+                            inputStream.close();
+                        }
+                        if (outputStream != null) {
+                            outputStream.close();
+                        }
+                        entity.consumeContent();
+                    }
+                }
+            } catch (IOException e) {
+                getRequest.abort();
+                Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);
+            } catch (IllegalStateException e) {
+                getRequest.abort();
+                Log.w(LOG_TAG, "Incorrect URL: " + url);
+            } catch (Exception e) {
+                getRequest.abort();
+                Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);
+            } finally {
+                if (client != null) {
+                    client.close();
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Once the image is downloaded, associates it to the imageView
+         */
+        @Override
+        protected void onPostExecute(Bitmap bitmap) {
+            if (isCancelled()) {
+                bitmap = null;
+            }
+
+            // Add bitmap to cache
+            if (bitmap != null) {
+                synchronized (sHardBitmapCache) {
+                    sHardBitmapCache.put(url, bitmap);
+                }
+            }
+
+            if (imageViewReference != null) {
+                ImageView imageView = imageViewReference.get();
+                BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
+                // Change bitmap only if this process is still associated with it
+                if (this == bitmapDownloaderTask) {
+                    imageView.setImageBitmap(bitmap);
+                }
+            }
+        }
+
+        public void copy(InputStream in, OutputStream out) throws IOException {
+            byte[] b = new byte[IO_BUFFER_SIZE];
+            int read;
+            while ((read = in.read(b)) != -1) {
+                out.write(b, 0, read);
+            }
+        }
+    }
+
+    /**
+     * A fake Drawable that will be attached to the imageView while the download is in progress.
+     *
+     * <p>Contains a reference to the actual download task, so that a download task can be stopped
+     * if a new binding is required, and makes sure that only the last started download process can
+     * bind its result, independently of the download finish order.</p>
+     */
+    static class DownloadedDrawable extends ColorDrawable {
+        private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
+
+        public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
+            super(Color.BLACK);
+            bitmapDownloaderTaskReference =
+                new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
+        }
+
+        public BitmapDownloaderTask getBitmapDownloaderTask() {
+            return bitmapDownloaderTaskReference.get();
+        }
+    }
+}
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/PhotosListActivity.java b/samples/XmlAdapters/src/com/example/android/xmladapters/PhotosListActivity.java
new file mode 100644
index 0000000..b0007d5
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/PhotosListActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.xmladapters;
+
+import android.app.ListActivity;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * This activity uses a custom cursor adapter which fetches a XML photo feed and parses the XML to
+ * extract the images' URL and their title.
+ */
+public class PhotosListActivity extends ListActivity {
+    private static final String PICASA_FEED_URL =
+        "http://picasaweb.google.com/data/feed/api/featured?max-results=50&thumbsize=144c";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.photos_list);
+        setListAdapter(Adapters.loadCursorAdapter(this, R.xml.photos,
+                "content://xmldocument/?url=" + Uri.encode(PICASA_FEED_URL)));
+    }
+}
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/RssReaderActivity.java b/samples/XmlAdapters/src/com/example/android/xmladapters/RssReaderActivity.java
new file mode 100644
index 0000000..16df246
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/RssReaderActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.xmladapters;
+
+import android.app.ListActivity;
+import android.content.XmlDocumentProvider;
+import android.net.Uri;
+import android.os.Bundle;
+import android.widget.AdapterView.OnItemClickListener;
+
+/**
+ * This example demonstrate the creation of a simple RSS feed reader using the XML adapter syntax.
+ * The different elements of the feed are extracted using an {@link XmlDocumentProvider} and are
+ * binded to the different views. An {@link OnItemClickListener} is also added, which will open a
+ * browser on the associated news item page.
+ */
+public class RssReaderActivity extends ListActivity {
+    private static final String FEED_URI = "http://feeds.nytimes.com/nyt/rss/HomePage";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.rss_feeds_list);
+        setListAdapter(Adapters.loadCursorAdapter(this, R.xml.rss_feed,
+                "content://xmldocument/?url=" + Uri.encode(FEED_URI)));
+
+        getListView().setOnItemClickListener(new UrlIntentListener());
+    }
+}
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/UrlImageBinder.java b/samples/XmlAdapters/src/com/example/android/xmladapters/UrlImageBinder.java
new file mode 100644
index 0000000..7c87598
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/UrlImageBinder.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.xmladapters;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * This CursorBinder binds the provided image URL to an ImageView by downloading the image from the
+ * Internet.
+ */
+public class UrlImageBinder extends Adapters.CursorBinder {
+
+    private final ImageDownloader imageDownloader;
+
+    public UrlImageBinder(Context context, Adapters.CursorTransformation transformation) {
+        super(context, transformation);
+        imageDownloader = new ImageDownloader();
+    }
+
+    @Override
+    public boolean bind(View view, Cursor cursor, int columnIndex) {
+        if (view instanceof ImageView) {
+            final String url = mTransformation.transform(cursor, columnIndex);
+            imageDownloader.download(url, (ImageView) view);
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/samples/XmlAdapters/src/com/example/android/xmladapters/UrlIntentListener.java b/samples/XmlAdapters/src/com/example/android/xmladapters/UrlIntentListener.java
new file mode 100644
index 0000000..af814d1
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/UrlIntentListener.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.xmladapters;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+
+/**
+ * A listener which expects a URL as a tag of the view it is associated with. It then opens the URL
+ * in the browser application.
+ */
+public class UrlIntentListener implements OnItemClickListener {
+
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        final String url = view.getTag().toString();
+        final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        final Context context = parent.getContext();
+        context.startActivity(intent);
+    }
+
+}
diff --git a/samples/source.properties b/samples/source.properties
index 54adea9..8d1cfd6 100644
--- a/samples/source.properties
+++ b/samples/source.properties
@@ -1,5 +1,4 @@
 Pkg.UserSrc=false
 Pkg.Revision=1
-AndroidVersion.ApiLevel=10
-#AndroidVersion.CodeName=gingerbread
-
+AndroidVersion.ApiLevel=12
+#AndroidVersion.CodeName=Honeycomb
diff --git a/sdk/compatibility_README.txt b/sdk/compatibility_README.txt
new file mode 100644
index 0000000..d1f15ed
--- /dev/null
+++ b/sdk/compatibility_README.txt
@@ -0,0 +1,16 @@
+Compatibility Libraries for Android.
+
+This SDK component contains static libraries providing access to newer APIs
+on older platforms. To use those libraries, simply copy them as static libraries
+into your project.
+
+"v4" provides support for using new APIs on Android API 4 (1.6 - Donut) and above.
+
+v4/android-support-v4.jar contains:
+- Fragment API. New in API 11 (3.0 - Honeycomb). http://developer.android.com/reference/android/app/Fragment.html
+- Loader API. New in API 11 (3.0 - Honeycomb). http://developer.android.com/reference/android/app/LoaderManager.html
+- CursorAdapter / ResourceCursorAdapter / SimpleCursorAdapter. These are the API 11 versions.
+- MenuCompat allows calling MenuItem.setShowAsAction which only exists on API 11.
+
+v4/src/ is the source code for the compatibility library
+v4/samples/ provides a version of ApiDemos using the library.
\ No newline at end of file
diff --git a/sdk/compatibility_source.properties b/sdk/compatibility_source.properties
new file mode 100644
index 0000000..ba79b6c
--- /dev/null
+++ b/sdk/compatibility_source.properties
@@ -0,0 +1,2 @@
+Pkg.UserSrc=false
+Pkg.Revision=1
diff --git a/sdk/doc_source.properties b/sdk/doc_source.properties
index 3ed9272..82c3cda 100644
--- a/sdk/doc_source.properties
+++ b/sdk/doc_source.properties
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
 Pkg.Revision=1
-AndroidVersion.ApiLevel=10
+AndroidVersion.ApiLevel=12
 #AndroidVersion.CodeName=
 
diff --git a/sdk/plat_tools_source.properties b/sdk/plat_tools_source.properties
index f23e52a..b75e326 100644
--- a/sdk/plat_tools_source.properties
+++ b/sdk/plat_tools_source.properties
@@ -1,2 +1,2 @@
 Pkg.UserSrc=false
-Pkg.Revision=3
+Pkg.Revision=4
diff --git a/sdk/platform_source.properties b/sdk/platform_source.properties
index 15a398d..6be2cb1 100644
--- a/sdk/platform_source.properties
+++ b/sdk/platform_source.properties
@@ -1,6 +1,6 @@
-Pkg.Desc=Android SDK Platform 2.3.3._r1
+Pkg.Desc=Android SDK Platform 3.1
 Pkg.UserSrc=false
-Platform.Version=2.3.3
+Platform.Version=3.1
 Pkg.Revision=1
-AndroidVersion.ApiLevel=10
+AndroidVersion.ApiLevel=12
 #AndroidVersion.CodeName=
diff --git a/sdk/sdk.properties b/sdk/sdk.properties
new file mode 100644
index 0000000..7f67ae8
--- /dev/null
+++ b/sdk/sdk.properties
@@ -0,0 +1,6 @@
+# SDK properties
+# This file is copied in the root folder of each platform component.
+# If it used by various tools to figure out what the platform can do.
+sdk.ant.templates.revision=1
+sdk.layoutlib.api=5
+sdk.skin.default=WXGA
\ No newline at end of file
diff --git a/sdk/usbdriver_source.properties b/sdk/usbdriver_source.properties
index d7666eb..3f9484b 100755
--- a/sdk/usbdriver_source.properties
+++ b/sdk/usbdriver_source.properties
@@ -1,4 +1,4 @@
-Pkg.Revision=3

+Pkg.Revision=4

 Archive.Os=WINDOWS

 Archive.Arch=ANY

 Extra.Path=usb_driver

diff --git a/sdk_overlay/frameworks/base/core/res/res/values/config.xml b/sdk_overlay/frameworks/base/core/res/res/values/config.xml
new file mode 100644
index 0000000..3296ed1
--- /dev/null
+++ b/sdk_overlay/frameworks/base/core/res/res/values/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Component name of the service providing geocoder API support. -->
+    <string name="config_geocodeProvider">com.google.android.location.GeocodeProvider</string>
+
+    <!-- This device is not "voice capable"; it's data-only. -->
+    <bool name="config_voice_capable">false</bool>
+</resources>
diff --git a/simulator/app/Android.mk b/simulator/app/Android.mk
index 3ce7cd5..5a2d3b5 100644
--- a/simulator/app/Android.mk
+++ b/simulator/app/Android.mk
@@ -70,7 +70,7 @@
 	# without us explicitly setting the LD_LIBRARY_PATH environment variable
 	LOCAL_LDLIBS += -Wl,-z,origin
 	LOCAL_CFLAGS += -DGTK_NO_CHECK_CASTS -D__WXGTK__ -D_FILE_OFFSET_BITS=64 \
-   					-D_LARGE_FILES -D_LARGEFILE_SOURCE=1 
+   					-D_LARGE_FILES -D_LARGEFILE_SOURCE=1 -DNO_GCC_PRAGMA
 	LOCAL_LDLIBS += -lrt
 endif
 ifeq ($(HOST_OS),darwin)
diff --git a/simulator/app/PropertyServer.cpp b/simulator/app/PropertyServer.cpp
index 4a0a2ac..91223ef 100644
--- a/simulator/app/PropertyServer.cpp
+++ b/simulator/app/PropertyServer.cpp
@@ -90,6 +90,9 @@
         { "ro.build.date", "Wed Nov 28 07:44:14 PST 2007" },
         { "ro.build.date.utc", "1196264654" },
         { "ro.build.type", "eng" },
+        { "ro.build.version.sdk", "8" },
+        { "ro.build.version.codename", "Froyo" },
+        { "ro.build.version.release", "Froyo" },
         { "ro.product.device", "simulator" /*"sooner"*/ },
         { "ro.product.brand", "generic" },
         { "ro.build.user", "fadden" },
@@ -99,12 +102,16 @@
         { "ro.radio.use-ppp", "no" },
         { "ro.FOREGROUND_APP_ADJ", "0" },
         { "ro.VISIBLE_APP_ADJ", "1" },
+        { "ro.PERCEPTIBLE_APP_ADJ", "2" },
+        { "ro.HEAVY_WEIGHT_APP_ADJ", "3" },
         { "ro.SECONDARY_SERVER_ADJ", "2" },
         { "ro.HIDDEN_APP_MIN_ADJ", "7" },
         { "ro.CONTENT_PROVIDER_ADJ", "14" },
         { "ro.EMPTY_APP_ADJ", "15" },
         { "ro.FOREGROUND_APP_MEM", "1536" },
         { "ro.VISIBLE_APP_MEM", "2048" },
+        { "ro.PERCEPTIBLE_APP_MEM", "4096" },
+        { "ro.HEAVY_WEIGHT_APP_MEM", "4096" },
         { "ro.SECONDARY_SERVER_MEM", "4096" },
         { "ro.HIDDEN_APP_MEM", "8192" },
         { "ro.EMPTY_APP_MEM", "16384" },
@@ -145,6 +152,7 @@
         { "log.redirect-stdio", "false" },          // -Xlog-stdio
 
         /* SurfaceFlinger options */
+        { "ro.sf.lcd_density", "160" },
         { "debug.sf.nobootanimation", "1" },
         { "debug.sf.showupdates", "0" },
         { "debug.sf.showcpu", "0" },
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index 1928c73..3bd4396 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -465,7 +465,7 @@
     output = ""
     error = None
     if runtime_restart:
-      self.SendShellCommand("setprop ro.monkey 1", retry_count=retry_count)
+      self.SendShellCommand("setprop ro.test_harness 1", retry_count=retry_count)
       # manual rest bootcomplete flag
       self.SendShellCommand("setprop dev.bootcomplete 0",
                             retry_count=retry_count)
diff --git a/testrunner/coverage_targets.xml b/testrunner/coverage_targets.xml
index 775f0e1..b239a87 100644
--- a/testrunner/coverage_targets.xml
+++ b/testrunner/coverage_targets.xml
@@ -71,6 +71,8 @@
         type="APPS" />
     <coverage_target name="Email" build_path="packages/apps/Email"
         type="APPS" />
+    <coverage_target name="Exchange" build_path="packages/apps/Exchange"
+        type="APPS" />
     <coverage_target name="Settings" build_path="packages/apps/Settings"
         type="APPS" />
     <coverage_target name="Phone" build_path="packages/apps/Phone"
@@ -86,6 +88,8 @@
         type="APPS" />
 
    <!-- content providers -->
+    <coverage_target name="ApplicationsProvider"
+        build_path="packages/providers/ApplicationsProvider" type="APPS" />
     <coverage_target name="CalendarProvider"
         build_path="packages/providers/CalendarProvider" type="APPS" />
     <coverage_target name="ContactsProvider"
diff --git a/testrunner/create_test.py b/testrunner/create_test.py
index 2fc3a3c..faea013 100755
--- a/testrunner/create_test.py
+++ b/testrunner/create_test.py
@@ -98,7 +98,7 @@
     IOError: tests/AndroidManifest.xml cannot be opened for writing
   """
   # skip if file already exists
-  tests_path = "%s/%s" % (manifest.app_path, TestsConsts.TESTS_FOLDER)
+  tests_path = "%s/%s" % (manifest.GetAppPath(), TestsConsts.TESTS_FOLDER)
   tests_manifest_path = "%s/%s" % (tests_path, manifest.FILENAME)
   if os.path.exists(tests_manifest_path):
     _PrintMessage("%s already exists, not overwritten" % tests_manifest_path)
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index 4a86a63..19102c6 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -223,9 +223,14 @@
 
   def _DoBuild(self):
     logger.SilentLog("Building tests...")
+
+    tests = self._GetTestsToRun()
+    # turn off dalvik verifier if necessary
+    self._TurnOffVerifier(tests)
+    self._DoFullBuild(tests)
+
     target_set = Set()
     extra_args_set = Set()
-    tests = self._GetTestsToRun()
     for test_suite in tests:
       self._AddBuildTarget(test_suite, target_set, extra_args_set)
 
@@ -251,23 +256,9 @@
           logger.Log(cmd)
           run_command.RunCommand(cmd, return_output=False)
 
-      # hack to build cts dependencies
-      # TODO: remove this when build dependency support added to runtest or
-      # cts dependencies are removed
-      if self._IsCtsTests(tests):
-        # need to use make since these fail building with ONE_SHOT_MAKEFILE
-        cmd = ('make -j%s CtsTestStubs android.core.tests.runner' %
-               self._options.make_jobs)
-        logger.Log(cmd)
-        if not self._options.preview:
-          old_dir = os.getcwd()
-          os.chdir(self._root_path)
-          run_command.RunCommand(cmd, return_output=False)
-          os.chdir(old_dir)
-      # turn off dalvik verifier if necessary
-      self._TurnOffVerifier(tests)
       target_build_string = " ".join(list(target_set))
       extra_args_string = " ".join(list(extra_args_set))
+
       # mmm cannot be used from python, so perform a similar operation using
       # ONE_SHOT_MAKEFILE
       cmd = 'ONE_SHOT_MAKEFILE="%s" make -j%s -C "%s" files %s' % (
@@ -286,12 +277,43 @@
         logger.Log("Syncing to device...")
         self._adb.Sync(runtime_restart=rebuild_libcore)
 
+  def _DoFullBuild(self, tests):
+    """If necessary, run a full 'make' command for the tests that need it."""
+    extra_args_set = Set()
+
+    # hack to build cts dependencies
+    # TODO: remove this when cts dependencies are removed
+    if self._IsCtsTests(tests):
+      # need to use make since these fail building with ONE_SHOT_MAKEFILE
+      extra_args_set.add('CtsTestStubs')
+      extra_args_set.add('android.core.tests.runner')
+    for test in tests:
+      if test.IsFullMake():
+        if test.GetExtraBuildArgs():
+          # extra args contains the args to pass to 'make'
+          extra_args_set.add(test.GetExtraBuildArgs())
+        else:
+          logger.Log("Warning: test %s needs a full build but does not specify"
+                     " extra_build_args" % test.GetName())
+
+    # check if there is actually any tests that required a full build
+    if extra_args_set:
+      cmd = ('make -j%s %s' % (self._options.make_jobs,
+                               ' '.join(list(extra_args_set))))
+      logger.Log(cmd)
+      if not self._options.preview:
+        old_dir = os.getcwd()
+        os.chdir(self._root_path)
+        run_command.RunCommand(cmd, return_output=False)
+        os.chdir(old_dir)
+
   def _AddBuildTarget(self, test_suite, target_set, extra_args_set):
-    build_dir = test_suite.GetBuildPath()
-    if self._AddBuildTargetPath(build_dir, target_set):
-      extra_args_set.add(test_suite.GetExtraBuildArgs())
-    for path in test_suite.GetBuildDependencies(self._options):
-      self._AddBuildTargetPath(path, target_set)
+    if not test_suite.IsFullMake():
+      build_dir = test_suite.GetBuildPath()
+      if self._AddBuildTargetPath(build_dir, target_set):
+        extra_args_set.add(test_suite.GetExtraBuildArgs())
+      for path in test_suite.GetBuildDependencies(self._options):
+        self._AddBuildTargetPath(path, target_set)
 
   def _AddBuildTargetPath(self, build_dir, target_set):
     if build_dir is not None:
@@ -365,6 +387,7 @@
           self._adb.SendCommand("reboot")
           self._adb.SendCommand("wait-for-device", timeout_time=60,
                                 retry_count=3)
+          self._adb.EnableAdbRoot()
 
   def RunTests(self):
     """Main entry method - executes the tests according to command line args."""
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 17a3694..b9d006f 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -125,6 +125,10 @@
     build_path="frameworks/base/libs/utils/tests"
     description="Framework libutils unit tests." />
 
+<test-native name="libinput"
+    build_path="frameworks/base/services/input/tests"
+    description="Framework libinput unit tests." />
+
 <!--  end of framework tests -->
 
 <!-- media framework tests -->
@@ -224,6 +228,13 @@
     runner="android.test.InstrumentationCtsTestRunner"
     suite="cts" />
 
+<test name="cts-accounts"
+    build_path="cts/tests/tests/accounts"
+    package="android.accounts.cts"
+    runner="android.test.InstrumentationTestRunner"
+    coverage_target="framework"
+    suite="cts" />
+
 <test name="cts-api-signature"
     build_path="cts/tests/SignatureTest"
     package="android.tests.sigtest"
@@ -398,15 +409,23 @@
     build_path="development/samples/ApiDemos"
     package="com.example.android.apis.tests" />
 
+<test name="applicationsprov"
+    build_path="packages/providers/ApplicationsProvider"
+    package="com.android.providers.applications.tests"
+    coverage_target="ApplicationsProvider"
+    continuous="true" />
+
 <test name="browser"
     build_path="packages/apps/Browser"
     package="com.android.browser.tests"
-    coverage_target="Browser" />
+    coverage_target="Browser"
+    continuous="true" />
 
 <test name="calculator"
     build_path="packages/apps/Calculator"
     package="com.android.calculator2.tests"
-    coverage_target="Calculator" />
+    coverage_target="Calculator"
+    continuous="true" />
 
 <test name="calendar"
     build_path="packages/apps/Calendar"
@@ -458,6 +477,12 @@
     class="com.android.email.SmallTests"
     coverage_target="Email" />
 
+<test name="exchange"
+    build_path="packages/apps/Exchange"
+    package="com.android.exchange.tests"
+    coverage_target="Exchange"
+    continuous="true" />
+
 <test name="musicplayer"
     build_path="packages/apps/Music"
     package="com.android.music.tests"
@@ -505,6 +530,12 @@
     description="Google test."
     extra_build_args="GTEST_TESTS=1" />
 
+<!-- Libjingle -->
+<test-native name="libjingle"
+    build_path="vendor/google/libraries/libjingle"
+    description="Libjingle."
+    full_make="true"
+    extra_build_args="LIBJINGLE_TESTS=1" />
 
 <!-- host java tests -->
 <test-host name="cts-appsecurity"
diff --git a/testrunner/test_defs.xsd b/testrunner/test_defs.xsd
index 7134459..6781941 100644
--- a/testrunner/test_defs.xsd
+++ b/testrunner/test_defs.xsd
@@ -41,7 +41,7 @@
         <xs:attribute name="name" type="xs:string" use="required" />
 
         <!-- File system path, relative to Android build root, to this
-        package's Android.mk file. -->
+        package's Android.mk file.-->
         <xs:attribute name="build_path" type="xs:string" use="required" />
 
         <!-- Include test in continuous test system. -->
@@ -55,10 +55,17 @@
         test. -->
         <xs:attribute name="description" type="xs:string" use="optional" />
 
+        <!-- Specifies that a full 'make', as opposed to 'mmm' command, is
+        needed to build this test. The build command used will be
+        'make extra_build_args' -->
+        <xs:attribute name="full_make" type="xs:boolean"
+                    use="optional" />
+
         <!--  Extra arguments to append to build command when building this
         test. -->
         <xs:attribute name="extra_build_args" type="xs:string"
                     use="optional" />
+
     </xs:complexType>
 
     <!-- Java on device instrumentation test.
diff --git a/testrunner/test_defs/instrumentation_test.py b/testrunner/test_defs/instrumentation_test.py
index 8782615..40d6bed 100644
--- a/testrunner/test_defs/instrumentation_test.py
+++ b/testrunner/test_defs/instrumentation_test.py
@@ -17,9 +17,6 @@
 
 """TestSuite definition for Android instrumentation tests."""
 
-# python imports
-import os
-
 # local imports
 import coverage
 import errors
diff --git a/testrunner/test_defs/test_suite.py b/testrunner/test_defs/test_suite.py
index 90d5792..102a738 100644
--- a/testrunner/test_defs/test_suite.py
+++ b/testrunner/test_defs/test_suite.py
@@ -32,6 +32,7 @@
     self._suite = None
     self._description = ''
     self._extra_build_args = ''
+    self._is_full_make = False
 
   def GetName(self):
     return self._name
@@ -88,6 +89,13 @@
     self._extra_build_args = build_args
     return self
 
+  def IsFullMake(self):
+    return self._is_full_make
+
+  def SetIsFullMake(self, full_make):
+    self._is_full_make = full_make
+    return self
+
   def Run(self, options, adb):
     """Runs the test.
 
diff --git a/testrunner/test_defs/test_walker.py b/testrunner/test_defs/test_walker.py
index 4ef6923..e34dafc 100755
--- a/testrunner/test_defs/test_walker.py
+++ b/testrunner/test_defs/test_walker.py
@@ -65,20 +65,20 @@
     if not os.path.exists(path):
       logger.Log('%s does not exist' % path)
       return []
-    abspath = os.path.abspath(path)
+    realpath = os.path.realpath(path)
     # ensure path is in ANDROID_BUILD_ROOT
-    self._build_top = android_build.GetTop()
-    if not self._IsPathInBuildTree(abspath):
+    self._build_top = os.path.realpath(android_build.GetTop())
+    if not self._IsPathInBuildTree(realpath):
       logger.Log('%s is not a sub-directory of build root %s' %
                  (path, self._build_top))
       return []
 
     # first, assume path is a parent directory, which specifies to run all
     # tests within this directory
-    tests = self._FindSubTests(abspath, [])
+    tests = self._FindSubTests(realpath, [])
     if not tests:
       logger.SilentLog('No tests found within %s, searching upwards' % path)
-      tests = self._FindUpstreamTests(abspath)
+      tests = self._FindUpstreamTests(realpath)
     return tests
 
   def _IsPathInBuildTree(self, path):
diff --git a/testrunner/test_defs/xml_suite_helper.py b/testrunner/test_defs/xml_suite_helper.py
index b7ed83b..6cf2e6c 100644
--- a/testrunner/test_defs/xml_suite_helper.py
+++ b/testrunner/test_defs/xml_suite_helper.py
@@ -39,6 +39,7 @@
   _SUITE_ATTR = 'suite'
   _DESCRIPTION_ATTR = 'description'
   _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args'
+  _FULL_MAKE_ATTR = 'full_make'
 
   def Parse(self, element):
     """Populates common suite attributes from given suite xml element.
@@ -79,6 +80,9 @@
                                                    default_value=''))
     test_suite.SetExtraBuildArgs(self._ParseAttribute(
         suite_element, self._EXTRA_BUILD_ARGS_ATTR, False, default_value=''))
+    test_suite.SetIsFullMake(self._ParseAttribute(
+        suite_element, self._FULL_MAKE_ATTR, False, default_value=False))
+
 
   def _ParseAttribute(self, suite_element, attribute_name, mandatory,
                       default_value=None):
diff --git a/tools/a3dconvert/Android.mk b/tools/a3dconvert/Android.mk
new file mode 100644
index 0000000..7bc634e
--- /dev/null
+++ b/tools/a3dconvert/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2011 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Host executable
+include $(CLEAR_VARS)
+LOCAL_MODULE := a3dconvert
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -DANDROID_RS_SERIALIZE
+# Needed for colladaDom
+LOCAL_CFLAGS += -DNO_BOOST -DDOM_INCLUDE_TINYXML -DNO_ZAE
+
+LOCAL_SRC_FILES := \
+    a3dconvert.cpp \
+    ObjLoader.cpp \
+    ColladaConditioner.cpp \
+    ColladaGeometry.cpp \
+    ColladaLoader.cpp
+
+
+LOCAL_C_INCLUDES += external/collada/include
+LOCAL_C_INCLUDES += external/collada/include/1.4
+LOCAL_C_INCLUDES += frameworks/base/libs/rs
+
+LOCAL_LDLIBS := -lpthread
+LOCAL_STATIC_LIBRARIES += libRSserialize libutils libcutils
+LOCAL_STATIC_LIBRARIES += colladadom libtinyxml libpcrecpp libpcre
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/a3dconvert/ColladaConditioner.cpp b/tools/a3dconvert/ColladaConditioner.cpp
new file mode 100644
index 0000000..0b0f694
--- /dev/null
+++ b/tools/a3dconvert/ColladaConditioner.cpp
@@ -0,0 +1,203 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#include "ColladaConditioner.h"
+unsigned int ColladaConditioner::getMaxOffset( domInputLocalOffset_Array &input_array ) {
+
+    unsigned int maxOffset = 0;
+    for ( unsigned int i = 0; i < input_array.getCount(); i++ ) {
+        if ( input_array[i]->getOffset() > maxOffset ) {
+            maxOffset = (unsigned int)input_array[i]->getOffset();
+        }
+    }
+    return maxOffset;
+}
+
+void ColladaConditioner::createTrianglesFromPolylist( domMesh *thisMesh, domPolylist *thisPolylist ) {
+
+    // Create a new <triangles> inside the mesh that has the same material as the <polylist>
+    domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
+    //thisTriangles->setCount( 0 );
+    unsigned int triangles = 0;
+    thisTriangles->setMaterial(thisPolylist->getMaterial());
+    domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
+
+    // Give the new <triangles> the same <_dae> and <parameters> as the old <polylist>
+    for(int i=0; i<(int)(thisPolylist->getInput_array().getCount()); i++) {
+
+        thisTriangles->placeElement( thisPolylist->getInput_array()[i]->clone() );
+    }
+
+    // Get the number of inputs and primitives for the polygons array
+    int numberOfInputs = (int)getMaxOffset(thisPolylist->getInput_array()) + 1;
+    int numberOfPrimitives = (int)(thisPolylist->getVcount()->getValue().getCount());
+
+    unsigned int offset = 0;
+
+    // Triangulate all the primitives, this generates all the triangles in a single <p> element
+    for(int j = 0; j < numberOfPrimitives; j++) {
+
+        int triangleCount = (int)thisPolylist->getVcount()->getValue()[j] -2;
+        // Write out the primitives as triangles, just fan using the first element as the base
+        int idx = numberOfInputs;
+        for(int k = 0; k < triangleCount; k++) {
+            // First vertex
+            for(int l = 0; l < numberOfInputs; l++) {
+
+                p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + l]);
+            }
+            // Second vertex
+            for(int l = 0; l < numberOfInputs; l++) {
+
+                p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
+            }
+            // Third vertex
+            idx += numberOfInputs;
+            for(int l = 0; l < numberOfInputs; l++) {
+
+                p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
+            }
+            triangles++;
+        }
+        offset += (unsigned int)thisPolylist->getVcount()->getValue()[j] * numberOfInputs;
+    }
+    thisTriangles->setCount( triangles );
+
+}
+
+void ColladaConditioner::createTrianglesFromPolygons( domMesh *thisMesh, domPolygons *thisPolygons ) {
+
+    // Create a new <triangles> inside the mesh that has the same material as the <polygons>
+    domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
+    thisTriangles->setCount( 0 );
+    thisTriangles->setMaterial(thisPolygons->getMaterial());
+    domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
+
+    // Give the new <triangles> the same <_dae> and <parameters> as the old <polygons>
+    for(int i=0; i<(int)(thisPolygons->getInput_array().getCount()); i++) {
+
+        thisTriangles->placeElement( thisPolygons->getInput_array()[i]->clone() );
+    }
+
+    // Get the number of inputs and primitives for the polygons array
+    int numberOfInputs = (int)getMaxOffset(thisPolygons->getInput_array()) +1;
+    int numberOfPrimitives = (int)(thisPolygons->getP_array().getCount());
+
+    // Triangulate all the primitives, this generates all the triangles in a single <p> element
+    for(int j = 0; j < numberOfPrimitives; j++) {
+
+        // Check the polygons for consistancy (some exported files have had the wrong number of indices)
+        domP * thisPrimitive = thisPolygons->getP_array()[j];
+        int elementCount = (int)(thisPrimitive->getValue().getCount());
+        // Skip the invalid primitive
+        if((elementCount % numberOfInputs) != 0) {
+            continue;
+        } else {
+            int triangleCount = (elementCount/numberOfInputs)-2;
+            // Write out the primitives as triangles, just fan using the first element as the base
+            int idx = numberOfInputs;
+            for(int k = 0; k < triangleCount; k++) {
+                // First vertex
+                for(int l = 0; l < numberOfInputs; l++) {
+
+                    p_triangles->getValue().append(thisPrimitive->getValue()[l]);
+                }
+                // Second vertex
+                for(int l = 0; l < numberOfInputs; l++) {
+
+                    p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
+                }
+                // Third vertex
+                idx += numberOfInputs;
+                for(int l = 0; l < numberOfInputs; l++) {
+
+                    p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
+                }
+                thisTriangles->setCount(thisTriangles->getCount()+1);
+            }
+        }
+    }
+
+}
+
+
+bool ColladaConditioner::triangulate(DAE *dae) {
+
+    int error = 0;
+
+    // How many geometry elements are there?
+    int geometryElementCount = (int)(dae->getDatabase()->getElementCount(NULL, "geometry" ));
+
+    for(int currentGeometry = 0; currentGeometry < geometryElementCount; currentGeometry++) {
+
+        // Find the next geometry element
+        domGeometry *thisGeometry;
+        //      error = _dae->getDatabase()->getElement((daeElement**)&thisGeometry,currentGeometry, NULL, "geometry");
+        daeElement * element = 0;
+        error = dae->getDatabase()->getElement(&element,currentGeometry, NULL, "geometry");
+        thisGeometry = (domGeometry *) element;
+
+        // Get the mesh out of the geometry
+        domMesh *thisMesh = thisGeometry->getMesh();
+
+        if (thisMesh == NULL){
+            continue;
+        }
+
+        // Loop over all the polygon elements
+        for(int currentPolygons = 0; currentPolygons < (int)(thisMesh->getPolygons_array().getCount()); currentPolygons++) {
+
+            // Get the polygons out of the mesh
+            // Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
+            domPolygons *thisPolygons = thisMesh->getPolygons_array()[currentPolygons];
+            createTrianglesFromPolygons( thisMesh, thisPolygons );
+        }
+        while (thisMesh->getPolygons_array().getCount() > 0) {
+
+            domPolygons *thisPolygons = thisMesh->getPolygons_array().get(0);
+            // Remove the polygons from the mesh
+            thisMesh->removeChildElement(thisPolygons);
+        }
+        int polylistElementCount = (int)(thisMesh->getPolylist_array().getCount());
+        for(int currentPolylist = 0; currentPolylist < polylistElementCount; currentPolylist++) {
+
+            // Get the polylist out of the mesh
+            // Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
+            domPolylist *thisPolylist = thisMesh->getPolylist_array()[currentPolylist];
+            createTrianglesFromPolylist( thisMesh, thisPolylist );
+        }
+        while (thisMesh->getPolylist_array().getCount() > 0) {
+
+            domPolylist *thisPolylist = thisMesh->getPolylist_array().get(0);
+            // Remove the polylist from the mesh
+            thisMesh->removeChildElement(thisPolylist);
+        }
+    }
+    return (error == 0);
+}
+
+bool ColladaConditioner::triangulate(const char *inputFile) {
+
+    DAE dae;
+    bool convertSuceeded = true;
+    domCOLLADA* root = dae.open(inputFile);
+
+    if (!root) {
+        printf("Failed to read file %s.\n", inputFile);
+        return false;
+    }
+
+    convertSuceeded = triangulate(&dae);
+
+    dae.writeAll();
+    if(!convertSuceeded) {
+        printf("Encountered errors\n");
+    }
+
+    return convertSuceeded;
+}
\ No newline at end of file
diff --git a/tools/a3dconvert/ColladaConditioner.h b/tools/a3dconvert/ColladaConditioner.h
new file mode 100644
index 0000000..470b7b6
--- /dev/null
+++ b/tools/a3dconvert/ColladaConditioner.h
@@ -0,0 +1,28 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#ifndef COLLADA_CONDITIONER
+#define COLLADA_CONDITIONER
+
+#include <dae.h>
+#include <dom/domConstants.h>
+#include <dom/domCOLLADA.h>
+
+class ColladaConditioner {
+
+private:
+    unsigned int getMaxOffset( domInputLocalOffset_Array &input_array );
+    void createTrianglesFromPolylist( domMesh *thisMesh, domPolylist *thisPolylist );
+    void createTrianglesFromPolygons( domMesh *thisMesh, domPolygons *thisPolygons );
+
+public:
+    bool triangulate(DAE *dae);
+    bool triangulate(const char *inputFile);
+};
+
+#endif //COLLADA_CONDITIONER
diff --git a/tools/a3dconvert/ColladaGeometry.cpp b/tools/a3dconvert/ColladaGeometry.cpp
new file mode 100644
index 0000000..1aba4f1
--- /dev/null
+++ b/tools/a3dconvert/ColladaGeometry.cpp
@@ -0,0 +1,319 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#include "ColladaGeometry.h"
+#include <iostream>
+#include <sstream>
+
+ColladaGeometry::ColladaGeometry() :
+        mPositionFloats(NULL), mPositionOffset(-1),
+        mNormalFloats(NULL), mNormalOffset(-1),
+        mTangentFloats(NULL), mTangentOffset(-1),
+        mBinormalFloats(NULL), mBinormalOffset(-1),
+        mTexture1Floats(NULL), mTexture1Offset(-1),
+        mMultiIndexOffset(-1),
+        mPositionsStride(3), mNormalsStride(3),
+        mTextureCoordsStride(2), mTangentssStride(3), mBinormalsStride(3) {
+
+    mConvertedMesh.appendChannel("position", mPositionsStride);
+    mConvertedMesh.appendChannel("normal", mNormalsStride);
+    mConvertedMesh.appendChannel("texture0", mTextureCoordsStride);
+    mConvertedMesh.appendChannel("binormal", mBinormalsStride);
+    mConvertedMesh.appendChannel("tangent", mTangentssStride);
+
+    mPositions = &mConvertedMesh.mChannels[0].mData;
+    mNormals = &mConvertedMesh.mChannels[1].mData;
+    mTextureCoords = &mConvertedMesh.mChannels[2].mData;
+    mBinormals = &mConvertedMesh.mChannels[3].mData;
+    mTangents = &mConvertedMesh.mChannels[4].mData;
+}
+
+bool ColladaGeometry::init(domGeometryRef geometry) {
+
+    bool convertSuceeded = true;
+
+    const char* geoName = geometry->getName();
+    if (geoName == NULL) {
+        geoName = geometry->getId();
+    }
+    mConvertedMesh.mName = geoName;
+    mMesh = geometry->getMesh();
+
+    // Iterate over all the index groups and build up a simple resolved tri list and vertex array
+    const domTriangles_Array &allTriLists = mMesh->getTriangles_array();
+    int numTriLists = allTriLists.getCount();
+    mConvertedMesh.mTriangleLists.reserve(numTriLists);
+    mConvertedMesh.mTriangleListNames.reserve(numTriLists);
+    for (int i = 0; i < numTriLists; i ++) {
+        addTriangles(allTriLists[i]);
+    }
+
+    return convertSuceeded;
+}
+
+void ColladaGeometry::addTriangles(domTriangles * colladaTriangles) {
+
+    int numTriangles = colladaTriangles->getCount();
+    int triListIndex = mConvertedMesh.mTriangleLists.size();
+    mConvertedMesh.mTriangleLists.resize(triListIndex + 1);
+    std::string materialName = colladaTriangles->getMaterial();
+    if (materialName.size() == 0) {
+        char buffer[128];
+        sprintf(buffer, "index%d", triListIndex);
+        materialName = buffer;
+    }
+    mConvertedMesh.mTriangleListNames.push_back(materialName);
+
+    // It's a good idea to tell stl how much memory we intend to use
+    // to limit the number of reallocations
+    mPositions->reserve(numTriangles * 3);
+    mNormals->reserve(numTriangles * 3);
+    mTangents->reserve(numTriangles * 3);
+    mBinormals->reserve(numTriangles * 3);
+    mTextureCoords->reserve(numTriangles * 3);
+
+    // Stores the pointers to the image data and where in the tri list that data comes from
+    cacheOffsetsAndDataPointers(colladaTriangles);
+
+    // Collapse the multiindex that collada uses
+    const domListOfUInts &colladaIndexList = colladaTriangles->getP()->getValue();
+    std::vector<uint32_t> &a3dIndexList = mConvertedMesh.mTriangleLists[triListIndex];
+    a3dIndexList.resize(numTriangles * 3);
+    for (int i = 0; i < numTriangles * 3; i ++) {
+
+        a3dIndexList[i] = remapIndexAndStoreData(colladaIndexList, i);
+    }
+
+}
+
+void ColladaGeometry::cacheOffsetsAndDataPointers(domTriangles * colladaTriangles) {
+    // Define the names of known vertex channels
+    const char *positionSemantic = "POSITION";
+    const char *vertexSemantic = "VERTEX";
+    const char *normalSemantic = "NORMAL";
+    const char *tangentSemantic = "TANGENT";
+    const char *binormalSemantic = "BINORMAL";
+    const char *texture1Semantic = "TEXCOORD";
+
+    const domInputLocalOffset_Array &inputs = colladaTriangles->getInput_array();
+    mMultiIndexOffset = inputs.getCount();
+
+    // inputs with offsets
+    // There are two places collada can put links to our data
+    // 1 - in the VERTEX, which is its way of saying follow a link to the vertex structure
+    //     then every geometry array you find there is the same size as the position array
+    // 2 - a direct link to the channel from the primitive list. This tells us that there are
+    //     potentially more or less floats in those channels because there is some vertex re-use
+    //     or divergence in that data channel. For example, highly segmented uv set would produce a
+    //     larger array because for every physical vertex position thre might be 2 or more uv coords
+    for (uint32_t i = 0; i < inputs.getCount(); i ++) {
+
+        int currentOffset = inputs[i]->getOffset();
+        const char *currentSemantic = inputs[i]->getSemantic();
+
+        domSource * source = (domSource*) (domElement*) inputs[i]->getSource().getElement();
+        if (strcmp(vertexSemantic, currentSemantic) == 0) {
+            mPositionOffset = currentOffset;
+        }
+        else if (strcmp(normalSemantic, currentSemantic) == 0) {
+            mNormalOffset = currentOffset;
+            mNormalFloats = &source->getFloat_array()->getValue();
+        }
+        else if (strcmp(tangentSemantic, currentSemantic) == 0) {
+            mTangentOffset = currentOffset;
+            mTangentFloats = &source->getFloat_array()->getValue();
+        }
+        else if (strcmp(binormalSemantic, currentSemantic) == 0) {
+            mBinormalOffset = currentOffset;
+            mBinormalFloats = &source->getFloat_array()->getValue();
+        }
+        else if (strcmp(texture1Semantic, currentSemantic) == 0) {
+            mTexture1Offset = currentOffset;
+            mTexture1Floats = & source->getFloat_array()->getValue();
+        }
+    }
+
+    // There are multiple ways of getting to data, so follow them all
+    domVertices * vertices = mMesh->getVertices();
+    const domInputLocal_Array &verticesInputs = vertices->getInput_array();
+    for (uint32_t i = 0; i < verticesInputs.getCount(); i ++) {
+
+        const char *currentSemantic = verticesInputs[i]->getSemantic();
+
+        domSource * source = (domSource*) (domElement*) verticesInputs[i]->getSource().getElement();
+        if (strcmp(positionSemantic, currentSemantic) == 0) {
+            mPositionFloats = & source->getFloat_array()->getValue();
+            // TODO: Querry this from the accessor in the future because
+            // I supopose it's possible to have 4 floats if we hide something in w
+            int numberOfFloatsPerPoint = 3;
+            // We want to cllapse duplicate vertices, otherwise we could just unroll the tri list
+            mVertexRemap.resize(source->getFloat_array()->getCount()/numberOfFloatsPerPoint);
+        }
+        else if (strcmp(normalSemantic, currentSemantic) == 0) {
+            mNormalFloats = & source->getFloat_array()->getValue();
+            mNormalOffset = mPositionOffset;
+        }
+        else if (strcmp(tangentSemantic, currentSemantic) == 0) {
+            mTangentFloats = & source->getFloat_array()->getValue();
+            mTangentOffset = mPositionOffset;
+        }
+        else if (strcmp(binormalSemantic, currentSemantic) == 0) {
+            mBinormalFloats = & source->getFloat_array()->getValue();
+            mBinormalOffset = mPositionOffset;
+        }
+        else if (strcmp(texture1Semantic, currentSemantic) == 0) {
+            mTexture1Floats = & source->getFloat_array()->getValue();
+            mTexture1Offset = mPositionOffset;
+        }
+    }
+}
+
+int ColladaGeometry::remapIndexAndStoreData(const domListOfUInts &colladaIndexList, int indexToRemap) {
+
+    domUint positionIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mPositionOffset];
+
+    float posX = (*mPositionFloats)[positionIndex * mPositionsStride + 0];
+    float posY = (*mPositionFloats)[positionIndex * mPositionsStride + 1];
+    float posZ = (*mPositionFloats)[positionIndex * mPositionsStride + 2];
+
+    float normX = 0;
+    float normY = 0;
+    float normZ = 0;
+
+    if (mNormalOffset != -1) {
+        domUint normalIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mNormalOffset];
+        normX = (*mNormalFloats)[normalIndex * mNormalsStride + 0];
+        normY = (*mNormalFloats)[normalIndex * mNormalsStride + 1];
+        normZ = (*mNormalFloats)[normalIndex * mNormalsStride + 2];
+    }
+
+    float tanX = 0;
+    float tanY = 0;
+    float tanZ = 0;
+
+    if (mTangentOffset != -1) {
+        domUint tangentIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mTangentOffset];
+        tanX = (*mTangentFloats)[tangentIndex * mTangentssStride + 0];
+        tanY = (*mTangentFloats)[tangentIndex * mTangentssStride + 1];
+        tanZ = (*mTangentFloats)[tangentIndex * mTangentssStride + 2];
+    }
+
+    float binormX = 0;
+    float binormY = 0;
+    float binormZ = 0;
+
+    if (mBinormalOffset != -1) {
+        domUint binormalIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mNormalOffset];
+        binormX = (*mBinormalFloats)[binormalIndex * mBinormalsStride + 0];
+        binormY = (*mBinormalFloats)[binormalIndex * mBinormalsStride + 1];
+        binormZ = (*mBinormalFloats)[binormalIndex * mBinormalsStride + 2];
+    }
+
+    float texCoordX = 0;
+    float texCoordY = 0;
+
+    if (mTexture1Offset != -1) {
+        domUint texCoordIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mTexture1Offset];
+        texCoordX = (*mTexture1Floats)[texCoordIndex * mTextureCoordsStride + 0];
+        texCoordY = (*mTexture1Floats)[texCoordIndex * mTextureCoordsStride + 1];
+    }
+
+    std::vector<uint32_t> &ithRemapList = mVertexRemap[positionIndex];
+    // We may have some potential vertices we can reuse
+    // loop over all the potential candidates and see if any match our guy
+    for (uint32_t i = 0; i < ithRemapList.size(); i ++) {
+
+        int ithRemap = ithRemapList[i];
+        // compare existing vertex with the new one
+        if ((*mPositions)[ithRemap * mPositionsStride + 0] != posX ||
+            (*mPositions)[ithRemap * mPositionsStride + 1] != posY ||
+            (*mPositions)[ithRemap * mPositionsStride + 2] != posZ) {
+            continue;
+        }
+
+        // Now go over normals
+        if (mNormalOffset != -1) {
+            if ((*mNormals)[ithRemap * mNormalsStride + 0] != normX ||
+                (*mNormals)[ithRemap * mNormalsStride + 1] != normY ||
+                (*mNormals)[ithRemap * mNormalsStride + 2] != normZ) {
+                continue;
+            }
+        }
+
+        // Now go over tangents
+        if (mTangentOffset != -1) {
+            if ((*mTangents)[ithRemap * mTangentssStride + 0] != tanX ||
+                (*mTangents)[ithRemap * mTangentssStride + 1] != tanY ||
+                (*mTangents)[ithRemap * mTangentssStride + 2] != tanZ) {
+                continue;
+            }
+        }
+
+        // Now go over binormals
+        if (mBinormalOffset != -1) {
+            if ((*mBinormals)[ithRemap * mBinormalsStride + 0] != binormX ||
+                (*mBinormals)[ithRemap * mBinormalsStride + 1] != binormY ||
+                (*mBinormals)[ithRemap * mBinormalsStride + 2] != binormZ) {
+                continue;
+            }
+        }
+
+        // And texcoords
+        if (mTexture1Offset != -1) {
+            if ((*mTextureCoords)[ithRemap * mTextureCoordsStride + 0] != texCoordX ||
+                (*mTextureCoords)[ithRemap * mTextureCoordsStride + 1] != texCoordY) {
+               continue;
+            }
+        }
+
+        // If we got here the new vertex is identical to the one that we already stored
+        return ithRemap;
+    }
+
+    // We did not encounter this vertex yet, store it and return its index
+    mPositions->push_back(posX);
+    mPositions->push_back(posY);
+    mPositions->push_back(posZ);
+
+    if (mNormalOffset != -1) {
+        mNormals->push_back(normX);
+        mNormals->push_back(normY);
+        mNormals->push_back(normZ);
+    }
+
+    if (mTangentOffset != -1) {
+        mTangents->push_back(tanX);
+        mTangents->push_back(tanY);
+        mTangents->push_back(tanZ);
+    }
+
+    if (mBinormalOffset != -1) {
+        mBinormals->push_back(binormX);
+        mBinormals->push_back(binormY);
+        mBinormals->push_back(binormZ);
+    }
+
+    if (mTexture1Offset != -1) {
+        mTextureCoords->push_back(texCoordX);
+        mTextureCoords->push_back(texCoordY);
+    }
+
+    // We need to remember this mapping. Since we are storing floats, not vec3's, need to
+    // divide by position size to get the right index
+    int currentVertexIndex = (mPositions->size()/mPositionsStride) - 1;
+    ithRemapList.push_back(currentVertexIndex);
+
+    return currentVertexIndex;
+}
+
+
+
+
+
+
+
diff --git a/tools/a3dconvert/ColladaGeometry.h b/tools/a3dconvert/ColladaGeometry.h
new file mode 100644
index 0000000..5774997
--- /dev/null
+++ b/tools/a3dconvert/ColladaGeometry.h
@@ -0,0 +1,84 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#ifndef _COLLADA_GEOMETRY_H_
+#define _COLLADA_GEOMETRY_H_
+
+#include <dae.h>
+#include <dom/domCOLLADA.h>
+#include <vector>
+#include <string>
+
+#include "rsContext.h"
+#include "rsMesh.h"
+#include "SimpleMesh.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+class ColladaGeometry {
+public:
+    ColladaGeometry();
+    bool init(domGeometryRef geometry);
+
+    Mesh *getMesh(Context *rsc) {
+        return mConvertedMesh.getMesh(rsc);
+    }
+
+private:
+
+    //Store some collada stuff
+    domMesh *mMesh;
+
+    // Cache the pointers to the collada version of the data
+    // This contains raw vertex data that is not necessarily the same size for all
+    // Offset refers to the way collada packs each triangle's index to position / normal / etc.
+    domListOfFloats *mPositionFloats;
+    int mPositionOffset;
+    domListOfFloats *mNormalFloats;
+    int mNormalOffset;
+    domListOfFloats *mTangentFloats;
+    int mTangentOffset;
+    domListOfFloats *mBinormalFloats;
+    int mBinormalOffset;
+    domListOfFloats *mTexture1Floats;
+    int mTexture1Offset;
+
+    // In the list of triangles, collada uses multiple indecies per triangle to point to the correct
+    // index in all the different arrays. We need to know the total number of these guys so we can
+    // just to the next triangle to process
+    int mMultiIndexOffset;
+
+    // All these vectors would contain the same number of "points"
+    // index*stride would properly get to the uv, normal etc.
+    // collada, like maya and many others keep point array, normal array etc
+    // different size in the cases the same vertex produces divergent normals for different faces
+    std::vector<float> *mPositions;
+    unsigned int mPositionsStride;
+    std::vector<float> *mNormals;
+    unsigned int mNormalsStride;
+    std::vector<float> *mTextureCoords;
+    unsigned int mTextureCoordsStride;
+    std::vector<float> *mTangents;
+    unsigned int mTangentssStride;
+    std::vector<float> *mBinormals;
+    unsigned int mBinormalsStride;
+
+    SimpleMesh mConvertedMesh;
+
+    // This vector is used to remap a position index into a list of all divergent vertices
+    std::vector<std::vector<unsigned int> > mVertexRemap;
+
+    void addTriangles(domTriangles * colladaTriangles);
+    void cacheOffsetsAndDataPointers(domTriangles * colladaTriangles);
+    int remapIndexAndStoreData(const domListOfUInts &colladaIndexList, int indexToRemap);
+
+};
+
+#endif //COLLADA_TO_A3D_GEOMETRY
diff --git a/tools/a3dconvert/ColladaLoader.cpp b/tools/a3dconvert/ColladaLoader.cpp
new file mode 100644
index 0000000..8a74748
--- /dev/null
+++ b/tools/a3dconvert/ColladaLoader.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "ColladaLoader.h"
+#include "ColladaConditioner.h"
+#include "ColladaGeometry.h"
+#include "rsContext.h"
+#include "rsFileA3D.h"
+
+#include <dae.h>
+#include <dom/domCOLLADA.h>
+
+ColladaLoader::ColladaLoader() {
+
+}
+
+ColladaLoader::~ColladaLoader() {
+    clearGeometry();
+}
+
+void ColladaLoader::clearGeometry() {
+    for (uint32_t i = 0; i < mGeometries.size(); i++) {
+        delete mGeometries[i];
+    }
+    mGeometries.clear();
+}
+
+bool ColladaLoader::init(const char *colladaFile) {
+    DAE dae;
+
+    clearGeometry();
+
+    bool convertSuceeded = true;
+
+    domCOLLADA* root = dae.open(colladaFile);
+    if (!root) {
+        fprintf(stderr, "Failed to read file %s.\n", colladaFile);
+        return false;
+    }
+
+    // We only want to deal with triangulated meshes since rendering complex polygons is not feasible
+    ColladaConditioner conditioner;
+    conditioner.triangulate(&dae);
+
+    domLibrary_geometries *allGeometry = daeSafeCast<domLibrary_geometries>(root->getDescendant("library_geometries"));
+
+    if (allGeometry) {
+        convertSuceeded = convertAllGeometry(allGeometry) && convertSuceeded;
+    }
+
+    return convertSuceeded;
+}
+
+bool ColladaLoader::convertToA3D(const char *a3dFile) {
+    if (mGeometries.size() == 0) {
+        return false;
+    }
+    // Now write all this stuff out
+    Context rsc;
+    FileA3D file(&rsc);
+
+    for (uint32_t i = 0; i < mGeometries.size(); i++) {
+        Mesh *exportedMesh = mGeometries[i]->getMesh(&rsc);
+        file.appendToFile(exportedMesh);
+        delete exportedMesh;
+    }
+
+    file.writeFile(a3dFile);
+    return true;
+}
+
+bool ColladaLoader::convertAllGeometry(domLibrary_geometries *allGeometry) {
+
+    bool convertSuceeded = true;
+    domGeometry_Array &geo_array = allGeometry->getGeometry_array();
+    for (size_t i = 0; i < geo_array.getCount(); i++) {
+        domGeometry *geometry = geo_array[i];
+        const char *geometryName = geometry->getName();
+        if (geometryName == NULL) {
+            geometryName = geometry->getId();
+        }
+
+        domMeshRef mesh = geometry->getMesh();
+        if (mesh != NULL) {
+            printf("Converting geometry: %s\n", geometryName);
+            convertSuceeded = convertGeometry(geometry) && convertSuceeded;
+        } else {
+            printf("Skipping geometry: %s, unsupported type\n", geometryName);
+        }
+
+    }
+
+    return convertSuceeded;
+}
+
+bool ColladaLoader::convertGeometry(domGeometry *geometry) {
+    bool convertSuceeded = true;
+
+    domMeshRef mesh = geometry->getMesh();
+
+    ColladaGeometry *convertedGeo = new ColladaGeometry();
+    convertedGeo->init(geometry);
+
+    mGeometries.push_back(convertedGeo);
+
+    return convertSuceeded;
+}
diff --git a/tools/a3dconvert/ColladaLoader.h b/tools/a3dconvert/ColladaLoader.h
new file mode 100644
index 0000000..aa66e7d
--- /dev/null
+++ b/tools/a3dconvert/ColladaLoader.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef _COLLADA_LOADER_H_
+#define _COLLADA_LOADER_H_
+
+#include <vector>
+
+class domLibrary_geometries;
+class domGeometry;
+class ColladaGeometry;
+
+class ColladaLoader {
+public:
+    ColladaLoader();
+    ~ColladaLoader();
+
+    bool init(const char *colladaFile);
+    bool convertToA3D(const char *a3dFile);
+
+private:
+    void clearGeometry();
+    std::vector<ColladaGeometry*> mGeometries;
+
+    bool convertAllGeometry(domLibrary_geometries *allGeometry);
+    bool convertGeometry(domGeometry *geometry);
+
+};
+
+#endif
\ No newline at end of file
diff --git a/tools/a3dconvert/ObjLoader.cpp b/tools/a3dconvert/ObjLoader.cpp
new file mode 100644
index 0000000..4465f4f
--- /dev/null
+++ b/tools/a3dconvert/ObjLoader.cpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "ObjLoader.h"
+#include <rsFileA3D.h>
+#include <sstream>
+
+ObjLoader::ObjLoader() :
+    mPositionsStride(3), mNormalsStride(3), mTextureCoordsStride(2) {
+
+}
+
+bool isWhitespace(char c) {
+    const char whiteSpace[] = { ' ', '\n', '\t', '\f', '\r' };
+    const uint32_t numWhiteSpaceChars = 5;
+    for (uint32_t i = 0; i < numWhiteSpaceChars; i ++) {
+        if (whiteSpace[i] == c) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void eatWhitespace(std::istream &is) {
+    while(is.good() && isWhitespace(is.peek())) {
+        is.get();
+    }
+}
+
+bool getToken(std::istream &is, std::string &token) {
+    eatWhitespace(is);
+    token.clear();
+    char c;
+    while(is.good() && !isWhitespace(is.peek())) {
+        c = is.get();
+        if (is.good()){
+            token += c;
+        }
+    }
+    return token.size() > 0;
+}
+
+void appendDataFromStream(std::vector<float> &dataVec, uint32_t numFloats, std::istream &is) {
+    std::string token;
+    for (uint32_t i = 0; i < numFloats; i ++){
+        bool valid = getToken(is, token);
+        if (valid) {
+            dataVec.push_back((float)atof(token.c_str()));
+        } else {
+            fprintf(stderr, "Encountered error reading geometry data");
+            dataVec.push_back(0.0f);
+        }
+    }
+}
+
+bool checkNegativeIndex(int idx) {
+    if(idx < 0) {
+        fprintf(stderr, "Negative indices are not supported. Skipping face\n");
+        return false;
+    }
+    return true;
+}
+
+void ObjLoader::parseRawFaces(){
+    // We need at least a triangle
+    if (mRawFaces.size() < 3) {
+        return;
+    }
+
+    const char slash = '/';
+    mParsedFaces.resize(mRawFaces.size());
+    for (uint32_t i = 0; i < mRawFaces.size(); i ++) {
+        size_t firstSeparator = mRawFaces[i].find_first_of(slash);
+        size_t nextSeparator = mRawFaces[i].find_last_of(slash);
+
+        // Use the string as a temp buffer to parse the index
+        // Insert 0 instead of the slash to avoid substrings
+        if (firstSeparator != std::string::npos) {
+            mRawFaces[i][firstSeparator] = 0;
+        }
+        // Simple case, only one index
+        int32_t vIdx = atoi(mRawFaces[i].c_str());
+        // We do not support negative indices
+        if (!checkNegativeIndex(vIdx)) {
+            return;
+        }
+        // obj indices things beginning 1
+        mParsedFaces[i].vertIdx = (uint32_t)vIdx - 1;
+
+        if (nextSeparator != std::string::npos && nextSeparator != firstSeparator) {
+            mRawFaces[i][nextSeparator] = 0;
+            uint32_t nIdx = atoi(mRawFaces[i].c_str() + nextSeparator + 1);
+            if (!checkNegativeIndex(nIdx)) {
+                return;
+            }
+            // obj indexes things beginning 1
+            mParsedFaces[i].normIdx = (uint32_t)nIdx - 1;
+        }
+
+        // second case is where we have vertex and texture indices
+        if (nextSeparator != std::string::npos &&
+           (nextSeparator > firstSeparator + 1 || nextSeparator == firstSeparator)) {
+            uint32_t tIdx = atoi(mRawFaces[i].c_str() + firstSeparator + 1);
+            if (!checkNegativeIndex(tIdx)) {
+                return;
+            }
+            // obj indexes things beginning 1
+            mParsedFaces[i].texIdx = (uint32_t)tIdx - 1;
+        }
+    }
+
+    // Make sure a face list exists before we go adding to it
+    if (mMeshes.back().mUnfilteredFaces.size() == 0) {
+        mMeshes.back().appendUnfilteredFaces(mLastMtl);
+    }
+
+    // Now we have our parsed face, that we need to triangulate as necessary
+    // Treat more complex polygons as fans.
+    // This approach will only work only for convex polygons
+    // but concave polygons need to be addressed elsewhere anyway
+    for (uint32_t next = 1; next < mParsedFaces.size() - 1; next ++) {
+        // push it to our current mesh
+        mMeshes.back().mUnfilteredFaces.back().push_back(mParsedFaces[0]);
+        mMeshes.back().mUnfilteredFaces.back().push_back(mParsedFaces[next]);
+        mMeshes.back().mUnfilteredFaces.back().push_back(mParsedFaces[next + 1]);
+    }
+}
+
+void ObjLoader::checkNewMeshCreation(std::string &newGroup) {
+    // start a new mesh if we have some faces
+    // accumulated on the current mesh.
+    // It's possible to have multiple group statements
+    // but we only care to actually start a new mesh
+    // once we can have something we can draw on the previous one
+    if (mMeshes.back().mUnfilteredFaces.size()) {
+        mMeshes.push_back(ObjMesh());
+    }
+
+    mMeshes.back().mName = newGroup;
+    printf("Converting vertex group: %s\n", newGroup.c_str());
+}
+
+void ObjLoader::handleObjLine(char *line) {
+    const char* vtxToken    = "v";
+    const char* normToken   = "vn";
+    const char* texToken    = "vt";
+    const char* groupToken  = "g";
+    const char* mtlToken    = "usemtl";
+    const char* faceToken   = "f";
+
+    std::istringstream lineStream(line, std::istringstream::in);
+
+    std::string token;
+    bool valid = getToken(lineStream, token);
+    if (!valid) {
+        return;
+    }
+
+    if (token == vtxToken) {
+        appendDataFromStream(mObjPositions, 3, lineStream);
+    } else if (token == normToken) {
+        appendDataFromStream(mObjNormals, 3, lineStream);
+    } else if (token == texToken) {
+        appendDataFromStream(mObjTextureCoords, 2, lineStream);
+    } else if (token == groupToken) {
+        valid = getToken(lineStream, token);
+        checkNewMeshCreation(token);
+    } else if (token == faceToken) {
+        mRawFaces.clear();
+        while(getToken(lineStream, token)) {
+            mRawFaces.push_back(token);
+        }
+        parseRawFaces();
+    }
+    // Ignore materials for now
+    else if (token == mtlToken) {
+        valid = getToken(lineStream, token);
+        mLastMtl = token;
+
+        mMeshes.back().appendUnfilteredFaces(token);
+    }
+}
+
+bool ObjLoader::init(const char *fileName) {
+
+    std::ifstream ifs(fileName , std::ifstream::in);
+    if (!ifs.good()) {
+        fprintf(stderr, "Failed to read file %s.\n", fileName);
+        return false;
+    }
+
+    mMeshes.clear();
+
+    const uint32_t maxBufferSize = 2048;
+    char *buffer = new char[maxBufferSize];
+
+    mMeshes.push_back(ObjMesh());
+
+    std::string token;
+    bool isDone = false;
+    while(!isDone) {
+        ifs.getline(buffer, maxBufferSize);
+        if (ifs.good() && ifs.gcount() > 0) {
+            handleObjLine(buffer);
+        } else {
+            isDone = true;
+        }
+    }
+
+    ifs.close();
+    delete buffer;
+
+    reIndexGeometry();
+
+    return true;
+}
+
+bool ObjLoader::convertToA3D(const char *a3dFile) {
+    if (!getNumMeshes()) {
+        return false;
+    }
+    // Now write all this stuff out
+    Context rsc;
+    FileA3D file(&rsc);
+
+    for (uint32_t i = 0; i < getNumMeshes(); i ++) {
+        Mesh *exportedMesh = getMesh(&rsc, i);
+        file.appendToFile(exportedMesh);
+        delete exportedMesh;
+    }
+
+    file.writeFile(a3dFile);
+    return true;
+}
+
+void ObjLoader::reIndexGeometry() {
+    // We want to know where each vertex lands
+    mVertexRemap.resize(mObjPositions.size() / mPositionsStride);
+
+    for (uint32_t m = 0; m < mMeshes.size(); m ++) {
+        // clear the remap vector of old data
+        for (uint32_t r = 0; r < mVertexRemap.size(); r ++) {
+            mVertexRemap[r].clear();
+        }
+
+        for (uint32_t i = 0; i < mMeshes[m].mUnfilteredFaces.size(); i ++) {
+            mMeshes[m].mTriangleLists[i].reserve(mMeshes[m].mUnfilteredFaces[i].size() * 2);
+            for (uint32_t fI = 0; fI < mMeshes[m].mUnfilteredFaces[i].size(); fI ++) {
+                uint32_t newIndex = reIndexGeometryPrim(mMeshes[m], mMeshes[m].mUnfilteredFaces[i][fI]);
+                mMeshes[m].mTriangleLists[i].push_back(newIndex);
+            }
+        }
+    }
+}
+
+uint32_t ObjLoader::reIndexGeometryPrim(ObjMesh &mesh, PrimitiveVtx &prim) {
+
+    std::vector<float> &mPositions = mesh.mChannels[0].mData;
+    std::vector<float> &mNormals = mesh.mChannels[1].mData;
+    std::vector<float> &mTextureCoords = mesh.mChannels[2].mData;
+
+    float posX = mObjPositions[prim.vertIdx * mPositionsStride + 0];
+    float posY = mObjPositions[prim.vertIdx * mPositionsStride + 1];
+    float posZ = mObjPositions[prim.vertIdx * mPositionsStride + 2];
+
+    float normX = 0.0f;
+    float normY = 0.0f;
+    float normZ = 0.0f;
+    if (prim.normIdx != MAX_INDEX) {
+        normX = mObjNormals[prim.normIdx * mNormalsStride + 0];
+        normY = mObjNormals[prim.normIdx * mNormalsStride + 1];
+        normZ = mObjNormals[prim.normIdx * mNormalsStride + 2];
+    }
+
+    float texCoordX = 0.0f;
+    float texCoordY = 0.0f;
+    if (prim.texIdx != MAX_INDEX) {
+        texCoordX = mObjTextureCoords[prim.texIdx * mTextureCoordsStride + 0];
+        texCoordY = mObjTextureCoords[prim.texIdx * mTextureCoordsStride + 1];
+    }
+
+    std::vector<unsigned int> &ithRemapList = mVertexRemap[prim.vertIdx];
+    // We may have some potential vertices we can reuse
+    // loop over all the potential candidates and see if any match our guy
+    for (unsigned int i = 0; i < ithRemapList.size(); i ++) {
+
+        int ithRemap = ithRemapList[i];
+        // compare existing vertex with the new one
+        if (mPositions[ithRemap * mPositionsStride + 0] != posX ||
+            mPositions[ithRemap * mPositionsStride + 1] != posY ||
+            mPositions[ithRemap * mPositionsStride + 2] != posZ) {
+            continue;
+        }
+
+        // Now go over normals
+        if (prim.normIdx != MAX_INDEX) {
+            if (mNormals[ithRemap * mNormalsStride + 0] != normX ||
+                mNormals[ithRemap * mNormalsStride + 1] != normY ||
+                mNormals[ithRemap * mNormalsStride + 2] != normZ) {
+                continue;
+            }
+        }
+
+        // And texcoords
+        if (prim.texIdx != MAX_INDEX) {
+            if (mTextureCoords[ithRemap * mTextureCoordsStride + 0] != texCoordX ||
+                mTextureCoords[ithRemap * mTextureCoordsStride + 1] != texCoordY) {
+                continue;
+            }
+        }
+
+        // If we got here the new vertex is identical to the one that we already stored
+        return ithRemap;
+    }
+
+    // We did not encounter this vertex yet, store it and return its index
+    mPositions.push_back(posX);
+    mPositions.push_back(posY);
+    mPositions.push_back(posZ);
+
+    if (prim.normIdx != MAX_INDEX) {
+        mNormals.push_back(normX);
+        mNormals.push_back(normY);
+        mNormals.push_back(normZ);
+    }
+
+    if (prim.texIdx != MAX_INDEX) {
+        mTextureCoords.push_back(texCoordX);
+        mTextureCoords.push_back(texCoordY);
+    }
+
+    // We need to remember this mapping. Since we are storing floats, not vec3's, need to
+    // divide by position size to get the right index
+    int currentVertexIndex = (mPositions.size()/mPositionsStride) - 1;
+    ithRemapList.push_back(currentVertexIndex);
+
+    return currentVertexIndex;
+}
diff --git a/tools/a3dconvert/ObjLoader.h b/tools/a3dconvert/ObjLoader.h
new file mode 100644
index 0000000..210b35f
--- /dev/null
+++ b/tools/a3dconvert/ObjLoader.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef _OBJ_LOADER_H_
+#define _OBJ_LOADER_H_
+
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+
+#include "SimpleMesh.h"
+#include <rsContext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+#define MAX_INDEX 0xffffffff
+
+class ObjLoader {
+public:
+    ObjLoader();
+    bool init(const char *objFile);
+    bool convertToA3D(const char *a3dFile);
+private:
+
+    Mesh *getMesh(Context *rsc, uint32_t meshIndex) {
+        return mMeshes[meshIndex].getMesh(rsc);
+    }
+    uint32_t getNumMeshes() const {
+        return mMeshes.size();
+    }
+
+    // .obj has a global list of vertex data
+    std::vector<float> mObjPositions;
+    std::vector<float> mObjNormals;
+    std::vector<float> mObjTextureCoords;
+
+    struct PrimitiveVtx {
+        uint32_t vertIdx;
+        uint32_t normIdx;
+        uint32_t texIdx;
+
+        PrimitiveVtx() : vertIdx(MAX_INDEX),
+                         normIdx(MAX_INDEX),
+                         texIdx(MAX_INDEX){
+        }
+    };
+
+    // Scratch buffer for faces
+    std::vector<std::string> mRawFaces;
+    std::vector<PrimitiveVtx> mParsedFaces;
+    std::string mLastMtl;
+
+    // Groups are used to separate multiple meshes within the same .obj file
+    class ObjMesh : public SimpleMesh {
+    public:
+
+        std::vector<std::vector<PrimitiveVtx> > mUnfilteredFaces;
+
+        void appendUnfilteredFaces(std::string name) {
+            appendFaceList(name);
+            mUnfilteredFaces.push_back(std::vector<PrimitiveVtx>());
+            // Reserve some space for index data
+            static const uint32_t numReserveIndecies = 128;
+            mUnfilteredFaces.back().reserve(numReserveIndecies);
+        }
+
+        ObjMesh() {
+            appendChannel("position", 3);
+            appendChannel("normal", 3);
+            appendChannel("texture0", 2);
+        }
+    };
+
+    std::vector<ObjMesh> mMeshes;
+    void checkNewMeshCreation(std::string &newGroup);
+
+    void parseRawFaces();
+    void handleObjLine(char *line);
+
+    void reIndexGeometry();
+    uint32_t reIndexGeometryPrim(ObjMesh &mesh, PrimitiveVtx &prim);
+
+    unsigned int mPositionsStride;
+    unsigned int mNormalsStride;
+    unsigned int mTextureCoordsStride;
+
+    // This vector is used to remap a position index into a list
+    //  of all divergent vertices
+    std::vector<std::vector<unsigned int> > mVertexRemap;
+};
+
+#endif //_OBJ_LOADER_H_
diff --git a/tools/a3dconvert/SimpleMesh.h b/tools/a3dconvert/SimpleMesh.h
new file mode 100644
index 0000000..57e1a7c
--- /dev/null
+++ b/tools/a3dconvert/SimpleMesh.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef _SIMPLE_MESH_H_
+#define _SIMPLE_MESH_H_
+
+#include <rsContext.h>
+#include <rsMesh.h>
+using namespace android;
+using namespace android::renderscript;
+
+class SimpleMesh {
+public:
+    struct Channel {
+        std::vector<float> mData;
+        std::string mName;
+        uint32_t mStride;
+    };
+
+    // Vertex channels (position, normal)
+    // This assumes all the data array are the same size
+    std::vector<Channel> mChannels;
+
+    // Triangle list index data
+    std::vector<std::vector<uint32_t> > mTriangleLists;
+    // Names of all the triangle lists
+    std::vector<std::string> mTriangleListNames;
+    // Name of the entire object
+    std::string mName;
+
+    // Adds another index set to the mesh
+    void appendFaceList(std::string name) {
+        mTriangleListNames.push_back(name);
+        mTriangleLists.push_back(std::vector<uint32_t>());
+    }
+
+    // Adds another data channel (position, normal, etc.)
+    void appendChannel(std::string name, uint32_t stride) {
+        mChannels.push_back(Channel());
+        static const uint32_t reserveVtx = 128;
+        mChannels.back().mData.reserve(reserveVtx*stride);
+        mChannels.back().mName = name;
+        mChannels.back().mStride = stride;
+    }
+
+    SimpleMesh() {
+        // reserve some data in the vectors
+        // simply letting it grow by itself tends to waste a lot of time on
+        // rallocations / copies when dealing with geometry data
+        static const uint32_t reserveFaces = 8;
+        static const uint32_t reserveChannels = 8;
+        mTriangleLists.reserve(reserveFaces);
+        mTriangleListNames.reserve(reserveFaces);
+        mChannels.reserve(reserveChannels);
+    }
+
+    // Generates a renderscript mesh that could be used for a3d serialization
+    Mesh *getMesh(Context *rsc) {
+        if (mChannels.size() == 0) {
+            return NULL;
+        }
+
+        // Generate the element that describes our channel layout
+        rsc->mStateElement.elementBuilderBegin();
+        for (uint32_t c = 0; c < mChannels.size(); c ++) {
+            // Skip empty channels
+            if (mChannels[c].mData.size() == 0) {
+                continue;
+            }
+            const Element *subElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, mChannels[c].mStride);
+            rsc->mStateElement.elementBuilderAdd(subElem, mChannels[c].mName.c_str(), 1);
+        }
+        const Element *vertexDataElem = rsc->mStateElement.elementBuilderCreate(rsc);
+
+        uint32_t numVerts = mChannels[0].mData.size()/mChannels[0].mStride;
+        Type *vertexDataType = Type::getType(rsc, vertexDataElem, numVerts, 0, 0, false, false);
+        vertexDataType->compute();
+
+        Allocation *vertexAlloc = new Allocation(rsc, vertexDataType, RS_ALLOCATION_USAGE_SCRIPT);
+
+        uint32_t vertexSize = vertexDataElem->getSizeBytes()/sizeof(float);
+        // Fill this allocation with some data
+        float *dataPtr = (float*)vertexAlloc->getPtr();
+        for (uint32_t i = 0; i < numVerts; i ++) {
+            // Find the pointer to the current vertex's data
+            uint32_t vertexPos = i*vertexSize;
+            float *vertexPtr = dataPtr + vertexPos;
+
+            for (uint32_t c = 0; c < mChannels.size(); c ++) {
+                // Skip empty channels
+                if (mChannels[c].mData.size() == 0) {
+                    continue;
+                }
+                for (uint32_t cStride = 0; cStride < mChannels[c].mStride; cStride ++) {
+                    *(vertexPtr++) = mChannels[c].mData[i * mChannels[c].mStride + cStride];
+                }
+            }
+        }
+
+        // Now lets write index data
+        const Element *indexElem = Element::create(rsc, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
+
+        Mesh *mesh = new Mesh(rsc);
+        mesh->setName(mName.c_str());
+        mesh->mVertexBufferCount = 1;
+        mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[1];
+        mesh->mVertexBuffers[0].set(vertexAlloc);
+
+        mesh->mPrimitivesCount = mTriangleLists.size();
+        mesh->mPrimitives = new Mesh::Primitive_t *[mesh->mPrimitivesCount];
+
+        // load all primitives
+        for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
+            Mesh::Primitive_t *prim = new Mesh::Primitive_t;
+            mesh->mPrimitives[pCount] = prim;
+
+            uint32_t numIndicies = mTriangleLists[pCount].size();
+            Type *indexType = Type::getType(rsc, indexElem, numIndicies, 0, 0, false, false );
+
+            indexType->compute();
+
+            Allocation *indexAlloc = new Allocation(rsc, indexType, RS_ALLOCATION_USAGE_SCRIPT);
+            uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr();
+            const std::vector<uint32_t> &indexList = mTriangleLists[pCount];
+            uint32_t numTries = numIndicies / 3;
+
+            for (uint32_t i = 0; i < numTries; i ++) {
+                indexPtr[i * 3 + 0] = (uint16_t)indexList[i * 3 + 0];
+                indexPtr[i * 3 + 1] = (uint16_t)indexList[i * 3 + 1];
+                indexPtr[i * 3 + 2] = (uint16_t)indexList[i * 3 + 2];
+            }
+            indexAlloc->setName(mTriangleListNames[pCount].c_str());
+            prim->mIndexBuffer.set(indexAlloc);
+            prim->mPrimitive = RS_PRIMITIVE_TRIANGLE;
+        }
+
+        return mesh;
+    }
+};
+
+#endif
diff --git a/tools/a3dconvert/a3dconvert.cpp b/tools/a3dconvert/a3dconvert.cpp
new file mode 100644
index 0000000..33f5733
--- /dev/null
+++ b/tools/a3dconvert/a3dconvert.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <iostream>
+#include <vector>
+
+#include "ColladaLoader.h"
+#include "ObjLoader.h"
+
+int main (int argc, char * const argv[]) {
+    const char *objExt = ".obj";
+    const char *daeExt = ".dae";
+
+    if(argc != 3) {
+        printf("-----------------------------------------------------------------\n");
+        printf("Usage:\n");
+        printf("a3dconvert input_file a3d_output_file\n");
+        printf("Currently .obj and .dae (collada) input files are accepted\n");
+        printf("-----------------------------------------------------------------\n");
+        return 1;
+    }
+
+    bool isSuccessful = false;
+
+    std::string filename = argv[1];
+    size_t dotPos = filename.find_last_of('.');
+    if (dotPos == std::string::npos) {
+        printf("Invalid input. Currently .obj and .dae (collada) input files are accepted\n");
+        return 1;
+    }
+
+    std::string ext = filename.substr(dotPos);
+    if (ext == daeExt) {
+        ColladaLoader converter;
+        isSuccessful = converter.init(argv[1]);
+        if (isSuccessful) {
+            isSuccessful = converter.convertToA3D(argv[2]);
+        }
+    } else if (ext == objExt) {
+        ObjLoader objConv;
+        isSuccessful = objConv.init(argv[1]);
+        if (isSuccessful) {
+            isSuccessful = objConv.convertToA3D(argv[2]);
+        }
+    } else {
+        printf("Invalid input. Currently .obj and .dae (collada) input files are accepted\n");
+        return 1;
+    }
+
+    if(isSuccessful) {
+        printf("---All done---\n");
+    } else {
+        printf("---Encountered errors, conversion failed---\n");
+    }
+
+    return isSuccessful ? 0 : 1;
+}
diff --git a/tools/a3dconvert/license.txt b/tools/a3dconvert/license.txt
new file mode 100755
index 0000000..354667a
--- /dev/null
+++ b/tools/a3dconvert/license.txt
@@ -0,0 +1,25 @@
+Parts of this code come from colladaDom with the license below. The rest is AOSP.
+
+
+
+The MIT License

+

+Copyright 2006 Sony Computer Entertainment Inc.

+

+Permission is hereby granted, free of charge, to any person obtaining a copy

+of this software and associated documentation files (the "Software"), to deal

+in the Software without restriction, including without limitation the rights

+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

+copies of the Software, and to permit persons to whom the Software is

+furnished to do so, subject to the following conditions:

+

+The above copyright notice and this permission notice shall be included in

+all copies or substantial portions of the Software.

+

+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN

+THE SOFTWARE.

diff --git a/tools/elftree/Android.mk b/tools/elftree/Android.mk
new file mode 100644
index 0000000..0bba0f2
--- /dev/null
+++ b/tools/elftree/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+
+# Target executable
+# TODO: Requires libelf for target
+
+#include $(CLEAR_VARS)
+#LOCAL_MODULE := $(module)
+#LOCAL_SRC_FILES := $(src_files)
+#LOCAL_C_INCLUDES := $(c_includes)
+#LOCAL_SHARED_LIBRARIES := $(shared_libraries)
+#LOCAL_STATIC_LIBRARIES := $(static_libraries)
+#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+#LOCAL_MODULE_TAGS := debug
+#LOCAL_LDLIBS +=
+#include $(BUILD_EXECUTABLE)
+
+# Host executable
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := elftree
+LOCAL_SRC_FILES := elftree.c
+LOCAL_C_INCLUDES := external/elfutils/libelf
+LOCAL_STATIC_LIBRARIES := libelf
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/apps/GraphicsLab/MODULE_LICENSE_APACHE2 b/tools/elftree/MODULE_LICENSE_APACHE2
similarity index 100%
copy from apps/GraphicsLab/MODULE_LICENSE_APACHE2
copy to tools/elftree/MODULE_LICENSE_APACHE2
diff --git a/tools/elftree/elftree.c b/tools/elftree/elftree.c
new file mode 100644
index 0000000..d7ded13
--- /dev/null
+++ b/tools/elftree/elftree.c
@@ -0,0 +1,328 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define PATH_MAX 256
+
+static enum { HIDE_DUPS, PRUNE_DUPS, SHOW_DUPS } dup_mode;
+static char *root_name;
+
+static void app_err(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	fprintf(stderr, "\n");
+}
+
+static void unix_err(const char *fmt, ...)
+{
+	va_list ap;
+	int errsv;
+
+	errsv = errno;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	fprintf(stderr, ": %s\n", strerror(errsv));
+}
+
+static void elf_err(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	fprintf(stderr, ": %s\n", elf_errmsg(-1));
+}
+
+struct seen {
+	char *name;
+	struct seen *next;
+};
+
+struct tree_state {
+	int level;
+	struct seen *seen;
+};
+
+static int seen(struct tree_state *t, char *name)
+{
+	struct seen *s;
+
+	for (s = t->seen; s; s = s->next) {
+		if (!strcmp(s->name, name))
+			return 1;
+	}
+
+	return 0;
+}
+
+static void see(struct tree_state *t, char *name)
+{
+	struct seen *s = malloc(sizeof(*s));
+	s->name = malloc(strlen(name) + 1);
+	strcpy(s->name, name);
+	s->next = t->seen;
+	t->seen = s;
+}
+
+char *indent_str = "  ";
+
+static void indent(struct tree_state *t)
+{
+	int i;
+
+	for (i = 0; i < t->level; i++)
+		printf("%s", indent_str);
+}
+
+struct search_dir {
+	char *path;
+	struct search_dir *next;
+} *dirs = NULL;
+
+static void add_search_dir(char *path)
+{
+	struct search_dir *dir = malloc(sizeof(*dir));
+	dir->path = malloc(strlen(path) + 1);
+	strcpy(dir->path, path);
+	dir->next = dirs;
+	dirs = dir;
+}
+
+struct file_state {
+	struct tree_state *t;
+	Elf *e;
+	Elf_Data *strtab_data;
+};
+
+static Elf_Scn *find_scn(struct file_state *f, GElf_Word sht, Elf_Scn *scn, GElf_Shdr *shdr_out)
+{
+	while ((scn = elf_nextscn(f->e, scn))) {
+		if (!gelf_getshdr(scn, shdr_out))
+			continue;
+
+		if (shdr_out->sh_type == sht)
+			break;
+	}
+
+	return scn;
+}
+
+struct dyn_state {
+	struct file_state *f;
+	Elf_Data *dyn_data;
+	int count;
+};
+
+static int find_dyn(struct dyn_state *d, GElf_Sxword tag, GElf_Dyn *dyn_out)
+{
+	int i;
+
+	for (i = 0; i < d->count; i++) {
+		if (!gelf_getdyn(d->dyn_data, i, dyn_out))
+			continue;
+
+		if (dyn_out->d_tag == tag)
+			return 0;
+	}
+
+	return -1;
+}
+
+static int dump_file(struct tree_state *t, char *name, char *path);
+
+static int dump_needed(struct tree_state *t, char *name)
+{
+	struct search_dir *dir;
+	char path[PATH_MAX];
+	int fd;
+
+	t->level++;
+
+	for (dir = dirs; dir; dir = dir->next) {
+		snprintf(path, PATH_MAX, "%s/%s", dir->path, name);
+		fd = open(path, O_RDONLY);
+		if (fd >= 0) {
+			close(fd);
+			dump_file(t, name, path);
+			t->level--;
+			return 0;
+		}
+	}
+
+	app_err("Couldn't resolve dependency \"%s\".", name);
+	t->level--;
+	return -1;
+}
+
+static int dump_dynamic(struct file_state *f, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+	struct dyn_state d;
+	GElf_Dyn needed_dyn;
+	char *needed_name;
+	int i;
+
+	d.f = f;
+	d.dyn_data = elf_getdata(scn, NULL);
+	if (!d.dyn_data) {
+		elf_err("elf_getdata failed");
+		return -1;
+	}
+	d.count = shdr->sh_size / shdr->sh_entsize;
+
+	for (i = 0; i < d.count; i++) {
+		if (!gelf_getdyn(d.dyn_data, i, &needed_dyn))
+			continue;
+
+		if (needed_dyn.d_tag != DT_NEEDED)
+			continue;
+
+		needed_name = (char *)f->strtab_data->d_buf
+			      + needed_dyn.d_un.d_val;
+
+		dump_needed(f->t, needed_name);
+	}
+
+	return 0;
+}
+
+static int dump_file(struct tree_state *t, char *name, char *file)
+{
+	struct file_state f;
+	int fd;
+	Elf_Scn *scn;
+	GElf_Shdr shdr;
+
+	if ((dup_mode == HIDE_DUPS) && seen(t, name))
+		return 0;
+
+	indent(t); printf("%s", name);
+
+	if ((dup_mode == PRUNE_DUPS) && seen(t, name)) {
+		printf("...\n");
+		return 0;
+	} else {
+		printf(":\n");
+	}
+
+	see(t, name);
+
+	f.t = t;
+
+	fd = open(file, O_RDONLY);
+	if (fd < 0) {
+		unix_err("open(%s) failed", file);
+		return -1;
+	}
+
+	f.e = elf_begin(fd, ELF_C_READ, NULL);
+	if (!f.e) {
+		elf_err("elf_begin failed on %s", file);
+		return -1;
+	}
+
+	scn = find_scn(&f, SHT_STRTAB, NULL, &shdr);
+	f.strtab_data = elf_getdata(scn, NULL);
+	if (!f.strtab_data) {
+		app_err("%s has no strtab section", file);
+		return -1;
+	}
+
+	scn = NULL;
+	while ((scn = find_scn(&f, SHT_DYNAMIC, scn, &shdr))) {
+		dump_dynamic(&f, scn, &shdr);
+	}
+
+	elf_end(f.e);
+	close(fd);
+
+	return 0;
+}
+
+static void usage(void)
+{
+	fprintf(stderr, "Usage: elftree [ -s | -h ] elf-file\n"
+	                "  -S  Duplicate entire subtree when a duplicate is found\n"
+			"  -P  Show duplicates, but only include subtree once\n"
+			"  -H  Show each library at most once, even if duplicated\n"
+			"  -h  Show this help screen\n");
+}
+
+static int parse_args(int argc, char *argv[])
+{
+	int i;
+
+	for (i = 1; i < argc - 1; i++) {
+		if (!strcmp(argv[i], "-S")) {
+			dup_mode = SHOW_DUPS;
+		} else if (!strcmp(argv[i], "-P")) {
+			dup_mode = PRUNE_DUPS;
+		} else if (!strcmp(argv[i], "-H")) {
+			dup_mode = HIDE_DUPS;
+		} else if (!strcmp(argv[i], "-h")) {
+			usage();
+			exit(0);
+		} else {
+			app_err("Unexpected argument \"%s\"!\n", argv[i]);
+			return -1;
+		}
+	}
+
+	root_name = argv[argc - 1];
+
+	return 0;
+}
+
+static void add_search_dirs(void)
+{
+	char *relpath;
+	char path[PATH_MAX];
+
+	relpath = getenv("ANDROID_PRODUCT_OUT");
+	if (!relpath) {
+		app_err("Warning: ANDROID_PRODUCT_OUT not set; "
+		        "using current directory.\n");
+		relpath = ".";
+	}
+
+	snprintf(path, PATH_MAX, "%s/%s", relpath, "system/lib");
+	add_search_dir(path);
+}
+
+int main(int argc, char *argv[])
+{
+	struct tree_state t;
+
+	if (argc < 2 || parse_args(argc, argv)) {
+		usage();
+		exit(EXIT_FAILURE);
+	}
+
+	if (elf_version(EV_CURRENT) == EV_NONE) {
+		elf_err("version mismatch");
+		exit(EXIT_FAILURE);
+	}
+
+	t.level = 0;
+	t.seen  = NULL;
+
+	add_search_dirs();
+
+	dump_file(&t, root_name, root_name);
+
+	return 0;
+}
diff --git a/tools/emulator/skins/WXGA/arrow_down.png b/tools/emulator/skins/WXGA/arrow_down.png
new file mode 100755
index 0000000..b9fde22
--- /dev/null
+++ b/tools/emulator/skins/WXGA/arrow_down.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_left.png b/tools/emulator/skins/WXGA/arrow_left.png
new file mode 100755
index 0000000..281b192
--- /dev/null
+++ b/tools/emulator/skins/WXGA/arrow_left.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_right.png b/tools/emulator/skins/WXGA/arrow_right.png
new file mode 100755
index 0000000..4cbc65d
--- /dev/null
+++ b/tools/emulator/skins/WXGA/arrow_right.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_up.png b/tools/emulator/skins/WXGA/arrow_up.png
new file mode 100755
index 0000000..29c7121
--- /dev/null
+++ b/tools/emulator/skins/WXGA/arrow_up.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/background_land.png b/tools/emulator/skins/WXGA/background_land.png
new file mode 100755
index 0000000..cb10cd8
--- /dev/null
+++ b/tools/emulator/skins/WXGA/background_land.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/background_port.png b/tools/emulator/skins/WXGA/background_port.png
new file mode 100755
index 0000000..76851da
--- /dev/null
+++ b/tools/emulator/skins/WXGA/background_port.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/button.png b/tools/emulator/skins/WXGA/button.png
new file mode 100755
index 0000000..8281d20
--- /dev/null
+++ b/tools/emulator/skins/WXGA/button.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/controls.png b/tools/emulator/skins/WXGA/controls.png
new file mode 100755
index 0000000..04b85e2
--- /dev/null
+++ b/tools/emulator/skins/WXGA/controls.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/hardware.ini b/tools/emulator/skins/WXGA/hardware.ini
new file mode 100755
index 0000000..130592f
--- /dev/null
+++ b/tools/emulator/skins/WXGA/hardware.ini
@@ -0,0 +1,6 @@
+# skin-specific hardware values
+hw.lcd.density=160
+vm.heapSize=48
+hw.ramSize=256
+hw.keyboard.lid=no
+
diff --git a/tools/emulator/skins/WXGA/key.png b/tools/emulator/skins/WXGA/key.png
new file mode 100755
index 0000000..40b03bf
--- /dev/null
+++ b/tools/emulator/skins/WXGA/key.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/keyboard.png b/tools/emulator/skins/WXGA/keyboard.png
new file mode 100755
index 0000000..ca49dcf
--- /dev/null
+++ b/tools/emulator/skins/WXGA/keyboard.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/layout b/tools/emulator/skins/WXGA/layout
new file mode 100755
index 0000000..0aaeb1e
--- /dev/null
+++ b/tools/emulator/skins/WXGA/layout
@@ -0,0 +1,88 @@
+parts {
+    portrait {
+        background {
+            image   background_port.png
+        }
+    }
+    landscape {
+        background {
+            image   background_land.png
+        }
+    }
+
+    device {
+        display {
+            width   1280
+            height  800
+            x       0
+            y       0
+        }
+    }
+    
+}
+
+layouts {
+
+    landscape {
+        width     1333
+        height    855
+        color     0xe0e0e0
+        event     EV_SW:0:1
+
+        part1 {
+            name    portrait
+            x       1400
+            y       0
+        }
+
+        part2 {
+            name    landscape
+            x       0
+            y       0
+        }
+
+        part3 {
+            name      device
+            x         26
+            y         29
+        }
+    }
+
+    portrait {
+        width     853
+        height    1334
+        color     0xe0e0e0
+        event     EV_SW:0:0
+
+        dpad-rotation 3
+        
+        part1 {
+            name    portrait
+            x       0
+            y       0
+        }
+
+        part2 {
+            name    landscape
+            x       1400
+            y       0
+        }
+
+        part3 {
+            name    device
+            x       27
+            y       1307
+            rotation  3
+        }
+    }
+
+}
+
+keyboard {
+    charmap qwerty2
+}
+
+network {
+    speed  full
+    delay  none
+}
diff --git a/tools/emulator/skins/WXGA/select.png b/tools/emulator/skins/WXGA/select.png
new file mode 100755
index 0000000..f4a65d3
--- /dev/null
+++ b/tools/emulator/skins/WXGA/select.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/spacebar.png b/tools/emulator/skins/WXGA/spacebar.png
new file mode 100755
index 0000000..aa459bd
--- /dev/null
+++ b/tools/emulator/skins/WXGA/spacebar.png
Binary files differ
diff --git a/tools/labpretest/README b/tools/labpretest/README
new file mode 100644
index 0000000..0f89035
--- /dev/null
+++ b/tools/labpretest/README
@@ -0,0 +1,53 @@
+Overview:
+
+The labpretest.sh script is designed to emulate a typical automated test lab
+session.  It puts a device into bootloader mode, reboots into bootloader mode,
+determines device type, erases user cache, flashes a generic userdata image,
+updates the bootloader image, updates the radio image, updates the system image
+and reboots, sets up for a monkey run and finally runs a random monkey test.
+It will repeat this based on an optional parameter(-i) or default to 100 times.
+It will detect if it is in a low battery situation and wait for it to charge
+again.
+
+The goal is to see if a device is ready for deployment to automated lab testing
+and can also be used to verify that lab infrastructure is ready for devices.
+The idea is to run this script at the same time for multiple devices, typically
+I would connect 8 devices to a host and run this script in 8 separate shell
+sessions and watch for failures.
+
+Running the script:
+
+If there is only one device attached to the host you can simply just run the
+script, it will detect the device and go through 100 cycles, running the monkey
+for 200 events each cycle.  The script ignores normal monkey failures. If you
+have multiple devices attached use the -d <device_id> parameter to target a
+specific devices.  Additional parameters are -i for how many cycles and -m for
+how many monkey events and finally -x to make it skip the monkey run portion
+altogether.
+
+Adding support for new devices or from scratch:
+
+The script uses included copies of adb and fastboot which are in in the tools/
+sub directory. If you are setting this up with only the script, create a tools
+sub directory and put adb and fastboot in it and make sure they are executable.
+Currently we use userdebug builds.
+
+Here are the steps to add a new device:
+
+  1) Create a new sub directory using the result of "fastboot getvar product".
+  2) Copy a build image to the new sub directory in our format.
+     (i.e. passion-img-24827.zip)
+  3) Copy a boot image to the new sub directory in our format.
+     (i.e. hboot.0.33.2012.img)
+  4) Copy a radio image to the new sub directory in our format.
+     (i.e. radio.4.04.00.03_2.img)
+  5) Copy a userdata.img file, possibly from one of the other directories.
+
+Customizations to the flashing process are handled by adding a custom_flash.sh
+file that is read in before the main loop starts. It allows you to add any non
+generic functions or details to the flashing process. You must use it to define
+the variable "bootpart" which is not defined by default. Also, use this file to
+rewrite the flash_device function and any others, etc...
+
+The script should handle the rest, unless there are radical changes to file
+names or the process.
\ No newline at end of file
diff --git a/tools/labpretest/crespo/custom_flash.sh b/tools/labpretest/crespo/custom_flash.sh
new file mode 100644
index 0000000..16b2583
--- /dev/null
+++ b/tools/labpretest/crespo/custom_flash.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+# Author: bgay@google.com (Bruce Gay)
+#
+# used for flashing bootloader image on sholes
+
+BOOTPART='bootloader'
+
+################################################
+# sets the name of the boot partition and
+# bootfile, then flashes device
+#
+# Globals:
+#   product
+#   ROOT
+#   BOOTPART
+#   bootloaderfile
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_bootloader_image()
+{
+  if [ $product != "crespo" ]; then
+    log_print "Wrong device type, expected crespo!"
+    exit
+  fi
+  if [ "$bootloaderfile" == '' ]; then
+    log_print "getting bootloader file for $product"
+    bootloaderfile=`ls -1 $ROOT/$product/ | sed -n 's/^\(bootloader\.[0-9A-Za-z_]*.img\)\n*/\1/ p'`
+    if [ "$bootloaderfile" == '' ]; then
+      log_print "bootloader file empty: $bootloaderfile"
+      exit
+    fi
+    if [ ! -e "$ROOT/$product/$bootloaderfile" ]; then
+      log_print "bootloader file not found: ./$product/$bootloaderfile"
+      exit
+    fi
+    log_print "using $ROOT/$product/$bootloaderfile as bootloader image file"
+  fi
+  log_print "downloading bootloader image to $device"
+  flash_partition $BOOTPART $ROOT/$product/$bootloaderfile
+  reboot_into_fastboot_from_fastboot
+}
+
+################################################
+# flashes the userdata partition
+#
+# Globals:
+#   product
+#   ROOT
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_userdata_image()
+{
+  #currently not supported so exiting early..."
+  log_print "skipping update of userdata.img, not supported yet."
+}
+
+################################################
+# sets the name of the radio partition and
+# radiofile and flashes device
+#
+# Globals:
+#   product
+#   ROOT
+#   radiofile
+#   radiopart
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_radio_image()
+{
+  #currently not supported so exiting early..."
+  log_print "skipping update of radio partition, not supported yet."
+}
diff --git a/tools/labpretest/labpretest.sh b/tools/labpretest/labpretest.sh
new file mode 100755
index 0000000..5db7960
--- /dev/null
+++ b/tools/labpretest/labpretest.sh
@@ -0,0 +1,582 @@
+#!/bin/bash
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+# Author: bgay@google.com (Bruce Gay)
+#
+# The labpretest.sh script is designed to emulate a typical automated test lab
+# session.  It puts a device into bootloader mode, reboots into bootloader mode,
+# determines device type, erases user cache, flashes a generic userdata image,
+# updates the bootloader image, updates the radio image, updates the system
+# image and reboots, sets up for a monkey run and finally runs a random monkey
+# test. It will repeat this based on an optional parameter(-i) or default to 100
+# times. It will detect if it is in a low battery situation and wait for it to
+# charge again.
+
+
+COUNT=100
+ROOT=$(cd `dirname $0` && pwd)
+ADB="$ROOT/tools/adb"
+FASTBOOT="$ROOT/tools/fastboot"
+MEVENTS=200
+NOMONKEY=0
+
+buildfile=''
+device=''
+product=''
+bootpart=''
+bootfile=''
+
+while getopts "d:i::m:xh" optionName; do
+  case "$optionName" in
+    d) device="$OPTARG";;
+    i) COUNT=$OPTARG;;
+    m) MEVENTS=$OPTARG;;
+    x) NOMONKEY=1;;
+    h) echo "options: [-d <device ID>, -i <loop count>, -m <monkey events> -x (skips monkey)]"; exit;;
+    *) echo "invalid parameter -$optionName"; exit -1;;
+  esac
+done
+
+declare -r COUNT
+declare -r MEVENTS
+declare -r NOMONKEY
+
+
+################################################
+# Prints output to console with time stamp
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+log_print()
+{
+  if [ -z "$1" ]; then
+    echo "# $(date +'%D %T')"
+  else
+    echo "# $(date +'%D %T'): $1"
+  fi
+}
+
+################################################
+# Blocks until battery level is at least
+# above TARGET if below LIMIT
+# Globals:
+#   ADB
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+wait_for_battery()
+{
+  TARGET=80
+  LIMIT=20
+  local battery
+  local tick
+  log_print "checking battery level"
+  while [ "$battery" = "" ]; do
+    battery=`$ADB -s $device shell dumpsys battery | tr -d '\r' | awk '/level:/ {print $2}'`
+    sleep 2
+  done
+  if [ $battery -lt $LIMIT ]; then
+    log_print "Battery is low, waiting for charge"
+    while true; do
+      battery=`$ADB -s $device shell dumpsys battery | tr -d '\r' | awk '/level:/ {print $2}'`
+      if (( $battery >= $TARGET )); then break; fi
+      tick=$[$TARGET - $battery]
+      echo "battery charge level is $battery, sleeping for $tick seconds"
+      sleep $[$TARGET - $battery * 10]
+    done
+    log_print "resuming test run with battery level at $battery%"
+  else
+    log_print "resuming test run with battery level at $battery%"
+  fi
+}
+
+################################################
+# Blocks until device is in fastboot mode or
+# time out is reached
+# Globals:
+#   loop
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+fastboot_wait_for_device()
+{
+  local fdevice=""
+  local n=0
+  while [ "$device" != "$fdevice" -a $n -le 30 ]; do
+    sleep 6
+    fdevice=`$FASTBOOT devices | sed -n "s/\($device\).*/\1/ p"`
+    let n+=1
+  done
+  if [ $n -gt 30 ]; then
+    log_print "device time out after $loop iterations"
+    exit
+  else
+    log_print "device returned and available"
+  fi
+}
+
+################################################
+# reboots device into fastboot mode or
+# time out is reached
+# Globals:
+#   device
+#   ADB
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+reboot_into_fastboot_from_adb()
+{
+  log_print "rebooting into bootloader and waiting for availability via fastboot"
+  $ADB -s $device reboot bootloader
+  fastboot_wait_for_device
+}
+
+################################################
+# reboots device into fastboot mode or
+# times out
+# Globals:
+#   device
+#   FASTBOOT
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+reboot_into_fastboot_from_fastboot()
+{
+  log_print "rebooting into bootloader and waiting for availability via fastboot"
+  $FASTBOOT -s $device reboot-bootloader
+  fastboot_wait_for_device
+}
+
+################################################
+# reboots device from fastboot to adb or
+# times out
+# Globals:
+#   device
+#   FASTBOOT
+#   ADB
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+reboot_into_adb_from_fastboot()
+{
+  log_print "rebooting and waiting for availability via adb"
+  $FASTBOOT -s $device reboot
+  $ADB -s $device wait-for-device
+}
+
+################################################
+# reboots device from fastboot to adb or
+# times out
+# Globals:
+#   device
+#   ADB
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+wait_for_boot_complete()
+{
+  log_print "waiting for device to finish booting"
+  local result=$($ADB -s $device shell getprop dev.bootcomplete)
+  local result_test=${result:1:1}
+  echo -n "."
+  while [ -z $result_test ]; do
+    sleep 1
+    echo -n "."
+    result=$($ADB -s $device shell getprop dev.bootcomplete)
+    result_test=${result:0:1}
+  done
+  log_print "finished booting"
+}
+
+################################################
+# fastboot flashes partition
+#
+# Globals:
+#   device
+#   FASTBOOT
+# Arguments:
+#   command_name
+#   command_parameters
+# Returns:
+#   None
+################################################
+fastboot_command()
+{
+  $FASTBOOT -s $device $1 $2 $3
+  sleep 5
+}
+
+################################################
+# fastboot command wrapper
+#
+# Globals:
+#   device
+#   FASTBOOT
+# Arguments:
+#   partition_name
+#   file_name
+# Returns:
+#   None
+################################################
+flash_partition()
+{
+  $FASTBOOT -s $device flash $1 $2
+  sleep 5
+}
+
+################################################
+# adb command wrapper
+#
+# Globals:
+#   device
+#   ADB
+# Arguments:
+#   command_name
+#   command_parameters
+# Returns:
+#   None
+################################################
+adb_command()
+{
+  $ADB -s $device $1 $2 $3 $4 $5
+  sleep 5
+}
+
+################################################
+# sets the name of the boot partition and
+# bootfile, then flashes device
+#
+# Globals:
+#   product
+#   ROOT
+#   bootloaderfile
+#   bootpart
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_bootloader_image()
+{
+  if [ "$bootpart" == '' ]; then
+    log_print "bootpart not defined"
+    exit
+  fi
+  if [ "$bootloaderfile" == '' ]; then
+    log_print "getting bootloader file for $product"
+    bootloaderfile=`ls -1 $ROOT/$product | sed -n 's/\(.*boot[0-9._]\+img\)/\1/ p'`
+    if [ "$bootloaderfile" == '' ]; then
+      log_print "bootloader file empty: $bootloaderfile"
+      exit
+    fi
+    if [ ! -e "$ROOT/$product/$bootloaderfile" ]; then
+      log_print "bootloader file not found: ./$product/$bootloaderfile"
+      exit
+    fi
+    log_print "using $ROOT/$product/$bootloaderfile as the bootloader image file"
+  fi
+  log_print "downloading bootloader image to $device"
+  flash_partition $bootpart $ROOT/$product/$bootloaderfile
+  reboot_into_fastboot_from_fastboot
+}
+
+################################################
+# sets the name of the radio partition and
+# radiofile and flashes device
+#
+# Globals:
+#   product
+#   ROOT
+#   radiofile
+#   radiopart
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_radio_image()
+{
+  if [ "$radiopart" == '' ]; then
+    log_print "setting radio partion to 'radio'"
+    radiopart='radio'
+  fi
+  if [ "$radiofile" == "" ]; then
+    log_print "getting radio file for $product"
+    radiofile=`ls -1 $ROOT/$product | sed -n 's/\(radio[0-9._A-Za-z]\+img\)/\1/ p'`
+    if [ "$radiofile" == "" ]; then
+      log_print "radio file empty: $radiofile"
+      exit
+    fi
+    if [ ! -e "$ROOT/$product/$radiofile" ]; then
+      log_print "radio file not found: ./$product/$radiofile"
+      exit
+    fi
+    log_print "using $ROOT/$product/$radiofile as the radio image file"
+  fi
+  log_print "downloading radio image to $device"
+  flash_partition $radiopart  $ROOT/$product/$radiofile
+  reboot_into_fastboot_from_fastboot
+}
+
+################################################
+# sets the name of the boot partition and
+# bootfile
+#
+# Globals:
+#   product
+#   ROOT
+#   buildfile
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_system_image()
+{
+  if [ "$buildfile" == "" ]; then
+    log_print "getting build file for $product"
+    buildfile=`\ls -1 $ROOT/$product 2>&1 | sed -n 's/\([a-z]\+-img-[0-9]\+.zip\)/\1/ p'`
+    if [ "$buildfile" == "" ]; then
+      log_print "build file empty: $buildfile"
+      exit
+    fi
+    if [ ! -e "$ROOT/$product/$buildfile" ]; then
+      log_print "build file not found: ./$product/$buildfile"
+      exit
+    fi
+    log_print "using $ROOT/$product/$buildfile as the system image file"
+  fi
+  log_print "downloading system image to $device"
+  fastboot_command update $ROOT/$product/$buildfile
+
+}
+################################################
+# flashes the userdata partition
+#
+# Globals:
+#   product
+#   ROOT
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_userdata_image()
+{
+  log_print "flashing userdata..."
+  if [ -e $ROOT/$product/userdata.img ];then
+    flash_partition userdata $ROOT/$product/userdata.img
+  else
+    log_print "userdata.img file not found: $ROOT/$product/userdata.img"
+    exit
+  fi
+}
+
+
+################################################
+# flashes the device
+#
+# Globals:
+#   product
+#   ROOT
+#   FASTBOOT
+#   bootfile
+#   bootpart
+#   radiofile
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_device()
+{
+  log_print "erasing cache..."
+  fastboot_command erase cache
+  flash_userdata_image
+  flash_bootloader_image
+  flash_radio_image
+  flash_system_image
+  #device has been rebooted
+  adb_command wait-for-device
+}
+
+################################################
+# gets the device product type and sets product
+#
+# Globals:
+#   product
+#   ROOT
+#   FASTBOOT
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+set_product_type()
+{
+  if [ "$product" == "" ]; then
+    log_print "getting device product type"
+    product=`$FASTBOOT -s $device getvar product 2>&1 | sed -n 's/product: \([a-z]*\)\n*/\1/ p'`
+    if [ ! -e "$ROOT/$product" ]; then
+      log_print "device product id not supported: $product"
+      exit
+    fi
+  fi
+  log_print "using $product as device product id"
+}
+
+
+
+#start of script
+#test for dependencies
+if [ ! -e $ADB ]; then
+  echo "Error: adb not in path! Please correct this."
+  exit
+fi
+if [ ! -e $FASTBOOT ]; then
+  echo "Error: fastboot not in path! Please correct this."
+  exit
+fi
+#checks to see if the called device is available
+if [ "$device" != "" ]; then
+  tmpdevice=`$ADB devices | sed -n "s/\($device\).*/\1/ p"`
+  if [ "$device" != "$tmpdevice" ]; then
+      tmpdevice=`$FASTBOOT devices | sed -n "s/\($device\).*/\1/ p"`
+    if [ "$device" != "$tmpdevice" ]; then
+      echo "Warning: device not found... $device"
+      exit
+    else
+      echo "'Device '$device' found!'"
+      reboot_into_adb_from_fastboot
+      wait_for_boot_complete
+    fi
+  fi
+else
+  device=`$ADB devices | sed -n 's/.*\(^[0-9A-Z]\{2\}[0-9A-Z]*\).*/\1/ p'`
+  if [ `echo $device | wc -w` -ne 1 ]; then
+    echo 'There is more than one device found,'
+    echo 'please pass the correct device ID in as a parameter.'
+    exit
+  fi
+fi
+if [ "$device" == "" ]; then
+  echo 'Device not found via adb'
+  device=`$FASTBOOT devices | sed -n 's/.*\(^[0-9A-Z]\{2\}[0-9A-Z]*\).*/\1/ p'`
+  if [ `echo $device | wc -w` -ne 1 ]; then
+    echo "There is more than one device available,"
+    echo "please pass the correct device ID in as a parameter."
+    exit
+  fi
+  if [ "$device" == "" ]; then
+    echo 'Device not found via fastboot, please investigate'
+    exit
+  else
+    echo 'Device '$device' found!'
+    reboot_into_adb_from_fastboot
+    wait_for_boot_complete
+    echo 'Hammering on '$device
+  fi
+else
+  echo 'Hammering on '$device
+fi
+reboot_into_fastboot_from_adb
+set_product_type
+reboot_into_adb_from_fastboot
+wait_for_boot_complete
+
+#check for availability of a custom flash info file and retreive it
+if [ -e "$ROOT/$product/custom_flash.sh" ]; then
+  . $ROOT/$product/custom_flash.sh
+fi
+echo $'\n\n'
+
+#start of looping
+for ((loop=1 ; loop <= $COUNT ; loop++ )) ; do
+  echo ""
+  echo ""
+  echo ________________ $(date +'%D %T') - $loop - $device ______________________
+
+  log_print "setting adb root and sleeping for 7 seconds"
+  adb_command root
+  wait_for_battery
+  log_print "rebooting into bootloader and waiting for availability via fastboot"
+  reboot_into_fastboot_from_adb
+  # not necessary, but useful in testing
+  log_print "using fastboot to reboot to bootloader for test purposes"
+  reboot_into_fastboot_from_fastboot
+
+  #flashing the device
+  flash_device
+
+  #preping device for monkey run
+  log_print "setting adb root"
+  adb_command root
+  log_print "setting ro.test_harness property"
+  adb_command shell setprop ro.test_harness 1
+
+  log_print "waiting for device to finish booting"
+  result=$($ADB -s $device shell getprop dev.bootcomplete)
+  result_test=${result:1:1}
+  echo -n "."
+  while [ -z $result_test ]; do
+    sleep 1
+    echo -n "."
+    result=$($ADB -s $device shell getprop dev.bootcomplete)
+    result_test=${result:0:1}
+  done
+
+  log_print "finished booting"
+  log_print "waiting for the Package Manager"
+  result=$($ADB -s $device shell pm path android)
+  result_test=${result:0:7}
+  echo -n "."
+  while [ $result_test != "package" ]; do
+    sleep 1
+    echo -n "."
+    result=$($ADB -s $device shell pm path android)
+    result_test=${result:0:7}
+  done
+  echo "Package Manager available"
+
+  #lets you see what's going on
+  log_print "setting shell svc power stayon true"
+  adb_command shell svc power stayon true
+
+  #calls the monkey run if not skipped
+  if [ $NOMONKEY == 0 ]; then
+    seed=$(($(date +%s) % 99))
+    log_print "running short monkey run..."
+    $ADB -s $device shell monkey -p com.android.alarmclock -p com.android.browser -p com.android.calculator2 -p com.android.calendar -p com.android.camera -p com.android.contacts -p com.google.android.gm -p com.android.im -p com.android.launcher -p com.google.android.apps.maps -p com.android.mms -p com.android.music -p com.android.phone -p com.android.settings -p com.google.android.street -p com.android.vending -p com.google.android.youtube -p com.android.email -p com.google.android.voicesearch  -c android.intent.category.LAUNCHER  --ignore-security-exceptions  -s $seed $MEVENTS
+    log_print "finished running monkey, rinse, repeat..."
+  else
+    log_print "-x parameter used, skipping the monkey run"
+  fi
+
+  if [ $loop -eq $COUNT ]; then
+    log_print "device $device has returned, testing completed, count = $loop"
+    echo `echo "Device $device has returned, testing completed, count = $loop." > $ROOT/$device.log`
+  else
+    log_print "device $device has returned, rinse and repeat count = $loop"
+    echo `echo "Device $device has returned, rinse and repeat count = $loop." > $ROOT/$device.log`
+  fi
+done
diff --git a/tools/labpretest/nexusone/custom_flash.sh b/tools/labpretest/nexusone/custom_flash.sh
new file mode 100644
index 0000000..ae9d6fa
--- /dev/null
+++ b/tools/labpretest/nexusone/custom_flash.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+# Author: bgay@google.com (Bruce Gay)
+#
+# used for flashing boot image on nexusone
+
+bootpart='hboot'
diff --git a/tools/labpretest/sholes/custom_flash.sh b/tools/labpretest/sholes/custom_flash.sh
new file mode 100644
index 0000000..8a08222
--- /dev/null
+++ b/tools/labpretest/sholes/custom_flash.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+# Author: bgay@google.com (Bruce Gay)
+#
+# used for flashing bootloader image on sholes
+
+BOOTPART='motoboot'
+
+################################################
+# sets the name of the boot partition and
+# bootfile, then flashes device
+#
+# Globals:
+#   product
+#   ROOT
+#   BOOTPART
+#   bootloaderfile
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_bootloader_image()
+{
+  if [ $product != "sholes" ]; then
+    log_print "Wrong device type, expected sholes!"
+    exit
+  fi
+  if [ "$bootloaderfile" == '' ]; then
+    log_print "getting bootloader file for $product"
+    secure=`$fastboot -s $device getvar secure 2>&1 | sed -n 's/secure: \([a-z]*\)\n*/\1/ p'`
+    if [ "$secure" = "no" ]; then
+      bootloaderfile=`ls -1 sholes/ | sed -n 's/^\(motoboot_unsecure.[0-9A-Z]*.img\)\n*/\1/ p'`
+    else
+      bootloaderfile=`ls -1 sholes/ | sed -n 's/^\(motoboot_secure.[0-9A-Z]*.img\)\n*/\1/ p'`
+    fi
+    if [ "$bootloaderfile" == '' ]; then
+      log_print "bootloader file empty: $bootloaderfile"
+      exit
+    fi
+    if [ ! -e "$ROOT/$product/$bootloaderfile" ]; then
+      log_print "bootloader file not found: ./$product/$bootloaderfile"
+      exit
+    fi
+    log_print "using $ROOT/$product/$bootloaderfile as the bootloader image file"
+  fi
+  log_print "downloading bootloader image to $device"
+  flash_partition $BOOTPART $ROOT/$product/$bootloaderfile
+  reboot_into_fastboot_from_fastboot
+}
diff --git a/tools/labpretest/stingray/custom_flash.sh b/tools/labpretest/stingray/custom_flash.sh
new file mode 100644
index 0000000..5bcaf25
--- /dev/null
+++ b/tools/labpretest/stingray/custom_flash.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+# Author: bgay@google.com (Bruce Gay)
+#
+# used for flashing bootloader image on sholes
+
+BOOTPART='motoboot'
+
+################################################
+# sets the name of the boot partition and
+# bootfile, then flashes device
+#
+# Globals:
+#   product
+#   ROOT
+#   BOOTPART
+#   bootloaderfile
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_bootloader_image()
+{
+  if [ $product != "stingray" ]; then
+    log_print "Wrong device type, expected stingray!"
+    exit
+  fi
+  if [ "$bootloaderfile" == '' ]; then
+    log_print "getting bootloader file for $product"
+    bootloaderfile=`ls -1 $product/ | sed -n 's/^\(motoboot.[0-9A-Z]*.img\)\n*/\1/ p'`
+    if [ "$bootloaderfile" == '' ]; then
+      log_print "bootloader file empty: $bootloaderfile"
+      exit
+    fi
+    if [ ! -e "$ROOT/$product/$bootloaderfile" ]; then
+      log_print "bootloader file not found: ./$product/$bootloaderfile"
+      exit
+    fi
+    log_print "using $ROOT/$product/$bootloaderfile as the bootloader image file"
+  fi
+  log_print "downloading bootloader image to $device"
+  flash_partition $BOOTPART $ROOT/$product/$bootloaderfile
+  reboot_into_fastboot_from_fastboot
+}
+
+################################################
+# flashes the userdata partition
+#
+# Globals:
+#   product
+#   ROOT
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_userdata_image()
+{
+  #currently not supported so exiting early..."
+  log_print "skipping update of userdata.img, not supported yet."
+}
+
+################################################
+# sets the name of the radio partition and
+# radiofile and flashes device
+#
+# Globals:
+#   product
+#   ROOT
+#   radiofile
+#   radiopart
+#   device
+# Arguments:
+#   None
+# Returns:
+#   None
+################################################
+flash_radio_image()
+{
+  #currently not supported so exiting early..."
+  log_print "skipping update of radio partition, not supported yet."
+}
diff --git a/tools/makedict/Android.mk b/tools/makedict/Android.mk
deleted file mode 100644
index b9fc553..0000000
--- a/tools/makedict/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_JAR_MANIFEST := etc/manifest.txt
-LOCAL_MODULE := makedict
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-include $(LOCAL_PATH)/etc/Android.mk
diff --git a/tools/makedict/etc/Android.mk b/tools/makedict/etc/Android.mk
deleted file mode 100644
index da16286..0000000
--- a/tools/makedict/etc/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := makedict
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/makedict/etc/makedict b/tools/makedict/etc/makedict
deleted file mode 100755
index 8420d6e..0000000
--- a/tools/makedict/etc/makedict
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-# Copyright 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=makedict.jar
-frameworkdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Djava.ext.dirs="$frameworkdir" -jar "$jarpath" "$@"
diff --git a/tools/makedict/etc/manifest.txt b/tools/makedict/etc/manifest.txt
deleted file mode 100644
index aa3a3e8..0000000
--- a/tools/makedict/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.tools.dict.MakeBinaryDictionary
diff --git a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
deleted file mode 100755
index 77a6401..0000000
--- a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.tools.dict;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Compresses a list of words and frequencies into a tree structured binary dictionary.
- */
-public class MakeBinaryDictionary {
-
-    public static final int ALPHA_SIZE = 256;
-
-    public static final String TAG_WORD = "w";
-    public static final String ATTR_FREQ = "f";
-
-    private static final int FLAG_ADDRESS_MASK  = 0x400000;
-    private static final int FLAG_TERMINAL_MASK = 0x800000;
-    private static final int ADDRESS_MASK = 0x3FFFFF;
-    
-    public static final CharNode EMPTY_NODE = new CharNode();
-
-    List<CharNode> roots;
-    Map<String, Integer> mDictionary;
-    int mWordCount;
-    
-    static class CharNode {
-        char data;
-        int freq;
-        boolean terminal;
-        List<CharNode> children;
-        static int sNodes;
-
-        public CharNode() {
-            sNodes++;
-        }
-    }
-
-    public static void usage() {
-        System.err.println("Usage: makedict <src.xml> <dest.dict>");
-        System.exit(-1);
-    }
-    
-    public static void main(String[] args) {
-        if (args.length < 2) {
-            usage();
-        } else {
-            new MakeBinaryDictionary(args[0], args[1]);
-        }
-    }
-
-    public MakeBinaryDictionary(String srcFilename, String destFilename) {
-        populateDictionary(srcFilename);
-        writeToDict(destFilename);
-        // Enable the code below to verify that the generated tree is traversable.
-        if (false) {
-            traverseDict(0, new char[32], 0);
-        }
-    }
-    
-    private void populateDictionary(String filename) {
-        roots = new ArrayList<CharNode>();
-        try {
-            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
-            parser.parse(new File(filename), new DefaultHandler() {
-                boolean inWord;
-                int freq;
-                StringBuilder wordBuilder = new StringBuilder(48);
-
-                @Override
-                public void startElement(String uri, String localName,
-                        String qName, Attributes attributes) {
-                    if (qName.equals("w")) {
-                        inWord = true;
-                        freq = Integer.parseInt(attributes.getValue(0));
-                        wordBuilder.setLength(0);
-                    }
-                }
-
-                @Override
-                public void characters(char[] data, int offset, int length) {
-                    // Ignore other whitespace
-                    if (!inWord) return;
-                    wordBuilder.append(data, offset, length);
-                }
-
-                @Override
-                public void endElement(String uri, String localName,
-                        String qName) {
-                    if (qName.equals("w")) {
-                        if (wordBuilder.length() > 1) {
-                            addWordTop(wordBuilder.toString(), freq);
-                            mWordCount++;
-                        }
-                        inWord = false;
-                    }
-                }
-            });
-        } catch (Exception ioe) {
-            System.err.println("Exception in parsing\n" + ioe);
-            ioe.printStackTrace();
-        }
-        System.out.println("Nodes = " + CharNode.sNodes);
-    }
-
-    private int indexOf(List<CharNode> children, char c) {
-        if (children == null) {
-            return -1;
-        }
-        for (int i = 0; i < children.size(); i++) {
-            if (children.get(i).data == c) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    private void addWordTop(String word, int occur) {
-        if (occur > 255) occur = 255;
-        char firstChar = word.charAt(0);
-        int index = indexOf(roots, firstChar);
-        if (index == -1) {
-            CharNode newNode = new CharNode();
-            newNode.data = firstChar;
-            newNode.freq = occur;
-            index = roots.size();
-            roots.add(newNode);
-        } else {
-            roots.get(index).freq += occur;
-        }
-        if (word.length() > 1) {
-            addWordRec(roots.get(index), word, 1, occur);
-        } else {
-            roots.get(index).terminal = true;
-        }
-    }
-
-    private void addWordRec(CharNode parent, String word, int charAt, int occur) {
-        CharNode child = null;
-        char data = word.charAt(charAt);
-        if (parent.children == null) {
-            parent.children = new ArrayList<CharNode>();
-        } else {
-            for (int i = 0; i < parent.children.size(); i++) {
-                CharNode node = parent.children.get(i);
-                if (node.data == data) {
-                    child = node;
-                    break;
-                }
-            }
-        }
-        if (child == null) {
-            child = new CharNode();
-            parent.children.add(child);
-        }
-        child.data = data;
-        if (child.freq == 0) child.freq = occur;
-        if (word.length() > charAt + 1) {
-            addWordRec(child, word, charAt + 1, occur);
-        } else {
-            child.terminal = true;
-            child.freq = occur;
-        }
-    }
-
-    byte[] dict;
-    int dictSize;
-    static final int CHAR_WIDTH = 8;
-    static final int FLAGS_WIDTH = 1; // Terminal flag (word end)
-    static final int ADDR_WIDTH = 23; // Offset to children
-    static final int FREQ_WIDTH_BYTES = 1;
-    static final int COUNT_WIDTH_BYTES = 1;
-
-    private void addCount(int count) {
-        dict[dictSize++] = (byte) (0xFF & count);
-    }
-    
-    private void addNode(CharNode node) {
-        int charData = 0xFFFF & node.data;
-        if (charData > 254) {
-            dict[dictSize++] = (byte) 255;
-            dict[dictSize++] = (byte) ((node.data >> 8) & 0xFF);
-            dict[dictSize++] = (byte) (node.data & 0xFF);
-        } else {
-            dict[dictSize++] = (byte) (0xFF & node.data);
-        }
-        if (node.children != null) {
-            dictSize += 3; // Space for children address
-        } else {
-            dictSize += 1; // Space for just the terminal/address flags
-        }
-        if ((0xFFFFFF & node.freq) > 255) {
-            node.freq = 255;
-        }
-        if (node.terminal) {
-            byte freq = (byte) (0xFF & node.freq);
-            dict[dictSize++] = freq;
-        }
-    }
-
-    int nullChildrenCount = 0;
-    int notTerminalCount = 0;
-
-    private void updateNodeAddress(int nodeAddress, CharNode node,
-            int childrenAddress) {
-        if ((dict[nodeAddress] & 0xFF) == 0xFF) { // 3 byte character
-            nodeAddress += 2;
-        }
-        childrenAddress = ADDRESS_MASK & childrenAddress;
-        if (childrenAddress == 0) {
-            nullChildrenCount++;
-        } else {
-            childrenAddress |= FLAG_ADDRESS_MASK;
-        }
-        if (node.terminal) {
-            childrenAddress |= FLAG_TERMINAL_MASK;
-        } else {
-            notTerminalCount++;
-        }
-        dict[nodeAddress + 1] = (byte) (childrenAddress >> 16);
-        if ((childrenAddress & FLAG_ADDRESS_MASK) != 0) {
-            dict[nodeAddress + 2] = (byte) ((childrenAddress & 0xFF00) >> 8);
-            dict[nodeAddress + 3] = (byte) ((childrenAddress & 0xFF));
-        }
-    }
-
-    void writeWordsRec(List<CharNode> children) {
-        if (children == null || children.size() == 0) {
-            return;
-        }
-        final int childCount = children.size();
-        addCount(childCount);
-        //int childrenStart = dictSize;
-        int[] childrenAddresses = new int[childCount];
-        for (int j = 0; j < childCount; j++) {
-            CharNode node = children.get(j);
-            childrenAddresses[j] = dictSize;
-            addNode(node);
-        }
-        for (int j = 0; j < childCount; j++) {
-            CharNode node = children.get(j);
-            int nodeAddress = childrenAddresses[j];
-            int cacheDictSize = dictSize;
-            writeWordsRec(node.children);
-            updateNodeAddress(nodeAddress, node, node.children != null
-                    ? cacheDictSize : 0);
-        }
-    }
-
-    void writeToDict(String dictFilename) {
-        // 4MB max, 22-bit offsets
-        dict = new byte[4 * 1024 * 1024]; // 4MB upper limit. Actual is probably
-                                          // < 1MB in most cases, as there is a limit in the
-                                          // resource size in apks.
-        dictSize = 0;
-        writeWordsRec(roots);
-        System.out.println("Dict Size = " + dictSize);
-        try {
-            FileOutputStream fos = new FileOutputStream(dictFilename);
-            fos.write(dict, 0, dictSize);
-            fos.close();
-        } catch (IOException ioe) {
-            System.err.println("Error writing dict file:" + ioe);
-        }
-    }
-
-    void traverseDict(int pos, char[] word, int depth) {
-        int count = dict[pos++] & 0xFF;
-        for (int i = 0; i < count; i++) {
-            char c = (char) (dict[pos++] & 0xFF);
-            if (c == 0xFF) {
-                c = (char) (((dict[pos] & 0xFF) << 8) | (dict[pos+1] & 0xFF));
-                pos += 2;
-            }
-            word[depth] = c;
-            boolean terminal = (dict[pos] & 0x80) > 0;
-            int address = 0;
-            if ((dict[pos] & (FLAG_ADDRESS_MASK >> 16)) > 0) {
-                address = 
-                    ((dict[pos + 0] & (FLAG_ADDRESS_MASK >> 16)) << 16)
-                    | ((dict[pos + 1] & 0xFF) << 8)
-                    | ((dict[pos + 2] & 0xFF));
-                pos += 2;
-            }
-            pos++;
-            if (terminal) {
-                showWord(word, depth + 1, dict[pos] & 0xFF);
-                pos++;
-            }
-            if (address != 0) {
-                traverseDict(address, word, depth + 1);
-            }
-        }
-    }
-
-    void showWord(char[] word, int size, int freq) {
-        System.out.print(new String(word, 0, size) + " " + freq + "\n");
-    }
-}
diff --git a/tools/zoneinfo/ZoneCompactor.java b/tools/zoneinfo/ZoneCompactor.java
deleted file mode 100644
index 3b5ddfa..0000000
--- a/tools/zoneinfo/ZoneCompactor.java
+++ /dev/null
@@ -1,166 +0,0 @@
-
-import java.io.*;
-import java.util.*;
-
-// usage: java ZoneCompiler <setup file> <top-level directory>
-//
-// Compile a set of tzfile-formatted files into a single file plus
-// an index file.
-//
-// The compilation is controlled by a setup file, which is provided as a
-// command-line argument.  The setup file has the form:
-//
-// Link <toName> <fromName>
-// ...
-// <zone filename>
-// ...
-//
-// Note that the links must be declared prior to the zone names.  A
-// zone name is a filename relative to the source directory such as
-// 'GMT', 'Africa/Dakar', or 'America/Argentina/Jujuy'.
-//
-// Use the 'zic' command-line tool to convert from flat files
-// (e.g., 'africa', 'northamerica') into a suitable source directory
-// hierarchy for this tool (e.g., 'data/Africa/Abidjan').
-//
-// Example:
-//     zic -d data tz2007h
-//     javac ZoneCompactor.java
-//     java ZoneCompactor setup data
-//     <produces zoneinfo.dat and zoneinfo.idx>
-
-public class ZoneCompactor {
-
-    // Zone name synonyms
-    Map<String,String> links = new HashMap<String,String>();
-
-    // File starting bytes by zone name
-    Map<String,Integer> starts = new HashMap<String,Integer>();
-
-    // File lengths by zone name
-    Map<String,Integer> lengths = new HashMap<String,Integer>();
-
-    // Raw GMT offsets by zone name
-    Map<String,Integer> offsets = new HashMap<String,Integer>();
-    int start = 0;
-
-    // Maximum number of characters in a zone name, including '\0' terminator
-    private static final int MAXNAME = 40;
-
-    // Concatenate the contents of 'inFile' onto 'out'
-    // and return the contents as a byte array.
-    private static byte[] copyFile(File inFile, OutputStream out)
-        throws Exception {
-        byte[] ret = new byte[0];
-
-        InputStream in = new FileInputStream(inFile);
-        byte[] buf = new byte[8192];
-        while (true) {
-            int nbytes = in.read(buf);
-            if (nbytes == -1) {
-                break;
-            }
-            out.write(buf, 0, nbytes);
-
-            byte[] nret = new byte[ret.length + nbytes];
-            System.arraycopy(ret, 0, nret, 0, ret.length);
-            System.arraycopy(buf, 0, nret, ret.length, nbytes);
-            ret = nret;
-        }
-        out.flush();
-        return ret;
-    }
-    
-    // Write a 32-bit integer in network byte order
-    private void writeInt(OutputStream os, int x) throws IOException {
-        os.write((x >> 24) & 0xff);
-        os.write((x >> 16) & 0xff);
-        os.write((x >>  8) & 0xff);
-        os.write( x        & 0xff);
-    }
-
-    public ZoneCompactor(String setupFilename, String dirName)
-        throws Exception {
-        File zoneInfoFile = new File("zoneinfo.dat");
-        zoneInfoFile.delete();
-        OutputStream zoneInfo = new FileOutputStream(zoneInfoFile);
-
-        BufferedReader rdr = new BufferedReader(new FileReader(setupFilename));
-    
-        String s;
-        while ((s = rdr.readLine()) != null) {
-            s = s.trim();
-            if (s.startsWith("Link")) {
-                StringTokenizer st = new StringTokenizer(s);
-                st.nextToken();
-                String to = st.nextToken();
-                String from = st.nextToken();
-                links.put(from, to);
-            } else {
-                String link = links.get(s);
-                if (link == null) {
-                    File f = new File(dirName, s);
-                    long length = f.length();
-                    starts.put(s, new Integer(start));
-                    lengths.put(s, new Integer((int)length));
-
-                    start += length;
-                    byte[] data = copyFile(f, zoneInfo);
-
-                    TimeZone tz = ZoneInfo.make(s, data);
-                    int gmtOffset = tz.getRawOffset();
-                    offsets.put(s, new Integer(gmtOffset));
-                }
-            }
-        }
-        zoneInfo.close();
-
-        // Fill in fields for links
-        Iterator<String> iter = links.keySet().iterator();
-        while (iter.hasNext()) {
-            String from = iter.next();
-            String to = links.get(from);
-
-            starts.put(from, starts.get(to));
-            lengths.put(from, lengths.get(to));
-            offsets.put(from, offsets.get(to));
-        }
-
-        File idxFile = new File("zoneinfo.idx");
-        idxFile.delete();
-        FileOutputStream idx = new FileOutputStream(idxFile);
-
-        ArrayList l = new ArrayList();
-        l.addAll(starts.keySet());
-        Collections.sort(l);
-        Iterator<String> ziter = l.iterator();
-        while (ziter.hasNext()) {
-            String zname = ziter.next();
-            if (zname.length() >= MAXNAME) {
-                System.err.println("Error - zone filename exceeds " +
-                                   (MAXNAME - 1) + " characters!");
-            }
-
-            byte[] znameBuf = new byte[MAXNAME];
-            for (int i = 0; i < zname.length(); i++) {
-                znameBuf[i] = (byte)zname.charAt(i);
-            }
-            idx.write(znameBuf);
-            writeInt(idx, starts.get(zname).intValue());
-            writeInt(idx, lengths.get(zname).intValue());
-            writeInt(idx, offsets.get(zname).intValue());
-        }
-        idx.close();
-
-        // System.out.println("maxLength = " + maxLength);
-    }
-
-    public static void main(String[] args) throws Exception {
-        if (args.length != 2) {
-            System.err.println("usage: java ZoneCompactor <setup> <data dir>");
-            System.exit(0);
-        }
-        new ZoneCompactor(args[0], args[1]);
-    }
-
-}
diff --git a/tools/zoneinfo/ZoneInfo.java b/tools/zoneinfo/ZoneInfo.java
deleted file mode 100644
index 99507ae..0000000
--- a/tools/zoneinfo/ZoneInfo.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * Copied from ZoneInfo and ZoneInfoDB in dalvik.
- * {@hide}
- */
-public class ZoneInfo extends TimeZone {
-
-    private static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
-    private static final long MILLISECONDS_PER_400_YEARS =
-        MILLISECONDS_PER_DAY * (400 * 365 + 100 - 3);
-
-    private static final long UNIX_OFFSET = 62167219200000L;
-
-    private static final int[] NORMAL = new int[] {
-        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
-    };
-
-    private static final int[] LEAP = new int[] {
-        0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
-    };
-
-    private static String nullName(byte[] data, int where, int off) {
-        if (off < 0)
-            return null;
-
-        int end = where + off;
-        while (end < data.length && data[end] != '\0')
-            end++;
-
-        return new String(data, where + off, end - (where + off));
-    }
-
-    public static ZoneInfo make(String name, byte[] data) {
-        int ntransition = read4(data, 32);
-        int ngmtoff = read4(data, 36);
-        int base = 44;
-
-        int[] transitions = new int[ntransition];
-        for (int i = 0; i < ntransition; i++)
-            transitions[i] = read4(data, base + 4 * i);
-        base += 4 * ntransition;
-
-        byte[] type = new byte[ntransition];
-        for (int i = 0; i < ntransition; i++)
-            type[i] = data[base + i];
-        base += ntransition;
-
-        int[] gmtoff = new int[ngmtoff];
-        byte[] isdst = new byte[ngmtoff];
-        byte[] abbrev = new byte[ngmtoff];
-        for (int i = 0; i < ngmtoff; i++) {
-            gmtoff[i] = read4(data, base + 6 * i);
-            isdst[i] = data[base + 6 * i + 4];
-            abbrev[i] = data[base + 6 * i + 5];
-        }
-
-        base += 6 * ngmtoff;
-
-        return new ZoneInfo(name, transitions, type, gmtoff, isdst, abbrev, data, base);
-    }
-
-    private static int read4(byte[] data, int off) {
-        return ((data[off    ] & 0xFF) << 24) |
-               ((data[off + 1] & 0xFF) << 16) |
-               ((data[off + 2] & 0xFF) <<  8) |
-               ((data[off + 3] & 0xFF) <<  0);
-    }
-
-    /*package*/ ZoneInfo(String name, int[] transitions, byte[] type,
-                     int[] gmtoff, byte[] isdst, byte[] abbrev,
-                     byte[] data, int abbrevoff) {
-        mTransitions = transitions;
-        mTypes = type;
-        mGmtOffs = gmtoff;
-        mIsDsts = isdst;
-        mUseDst = false;
-        setID(name);
-
-        // Find the latest GMT and non-GMT offsets for their abbreviations
-
-        int lastdst;
-        for (lastdst = mTransitions.length - 1; lastdst >= 0; lastdst--) {
-            if (mIsDsts[mTypes[lastdst] & 0xFF] != 0)
-                break;
-        }
-
-        int laststd;
-        for (laststd = mTransitions.length - 1; laststd >= 0; laststd--) {
-            if (mIsDsts[mTypes[laststd] & 0xFF] == 0)
-                break;
-        }
-
-        if (lastdst >= 0) {
-            mDaylightName = nullName(data, abbrevoff,
-                                     abbrev[mTypes[lastdst] & 0xFF]);
-        }
-        if (laststd >= 0) {
-            mStandardName = nullName(data, abbrevoff,
-                                     abbrev[mTypes[laststd] & 0xFF]);
-        }
-
-        // Use the latest non-DST offset if any as the raw offset
-
-        if (laststd < 0) {
-            laststd = 0;
-        }
-
-        if (laststd >= mTypes.length) {
-            mRawOffset = mGmtOffs[0];
-        } else {
-            mRawOffset = mGmtOffs[mTypes[laststd] & 0xFF];
-        }
-
-        // Subtract the raw offset from all offsets so it can be changed
-        // and affect them too.
-        // Find whether there exist any observances of DST.
-
-        for (int i = 0; i < mGmtOffs.length; i++) {
-            mGmtOffs[i] -= mRawOffset;
-
-            if (mIsDsts[i] != 0) {
-                mUseDst = true;
-            }
-        }
-
-        mRawOffset *= 1000;
-    }
-
-    @Override
-    public int getOffset(@SuppressWarnings("unused") int era,
-        int year, int month, int day,
-        @SuppressWarnings("unused") int dayOfWeek,
-        int millis) {
-        // XXX This assumes Gregorian always; Calendar switches from
-        // Julian to Gregorian in 1582.  What calendar system are the
-        // arguments supposed to come from?
-
-        long calc = (year / 400) * MILLISECONDS_PER_400_YEARS;
-        year %= 400;
-
-        calc += year * (365 * MILLISECONDS_PER_DAY);
-        calc += ((year + 3) / 4) * MILLISECONDS_PER_DAY;
-
-        if (year > 0)
-            calc -= ((year - 1) / 100) * MILLISECONDS_PER_DAY;
-
-        boolean isLeap = (year == 0 || (year % 4 == 0 && year % 100 != 0));
-        int[] mlen = isLeap ? LEAP : NORMAL;
-
-        calc += mlen[month] * MILLISECONDS_PER_DAY;
-        calc += (day - 1) * MILLISECONDS_PER_DAY;
-        calc += millis;
-
-        calc -= mRawOffset;
-        calc -= UNIX_OFFSET;
-
-        return getOffset(calc);
-    }
-
-    @Override
-    public int getOffset(long when) {
-        int unix = (int) (when / 1000);
-        int trans = Arrays.binarySearch(mTransitions, unix);
-
-        if (trans == ~0) {
-            return mGmtOffs[0] * 1000 + mRawOffset;
-        }
-        if (trans < 0) {
-            trans = ~trans - 1;
-        }
-
-        return mGmtOffs[mTypes[trans] & 0xFF] * 1000 + mRawOffset;
-    }
-
-    @Override
-    public int getRawOffset() {
-        return mRawOffset;
-    }
-
-    @Override
-    public void setRawOffset(int off) {
-        mRawOffset = off;
-    }
-
-    @Override
-    public boolean inDaylightTime(Date when) {
-        int unix = (int) (when.getTime() / 1000);
-        int trans = Arrays.binarySearch(mTransitions, unix);
-
-        if (trans == ~0) {
-            return mIsDsts[0] != 0;
-        }
-        if (trans < 0) {
-            trans = ~trans - 1;
-        }
-
-        return mIsDsts[mTypes[trans] & 0xFF] != 0;
-    }
-
-    @Override
-    public boolean useDaylightTime() {
-        return mUseDst;
-    }
-
-    private int mRawOffset;
-    private int[] mTransitions;
-    private int[] mGmtOffs;
-    private byte[] mTypes;
-    private byte[] mIsDsts;
-    private boolean mUseDst;
-    private String mDaylightName;
-    private String mStandardName;
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof ZoneInfo)) {
-           return false;
-        }
-        ZoneInfo other = (ZoneInfo) obj;
-        return mUseDst == other.mUseDst
-                && (mDaylightName == null ? other.mDaylightName == null :
-                        mDaylightName.equals(other.mDaylightName))
-                && (mStandardName == null ? other.mStandardName == null :
-                        mStandardName.equals(other.mStandardName))
-                && mRawOffset == other.mRawOffset
-                // Arrays.equals returns true if both arrays are null
-                && Arrays.equals(mGmtOffs, other.mGmtOffs)
-                && Arrays.equals(mIsDsts, other.mIsDsts)
-                && Arrays.equals(mTypes, other.mTypes)
-                && Arrays.equals(mTransitions, other.mTransitions);
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((mDaylightName == null) ? 0 :
-                mDaylightName.hashCode());
-        result = prime * result + Arrays.hashCode(mGmtOffs);
-        result = prime * result + Arrays.hashCode(mIsDsts);
-        result = prime * result + mRawOffset;
-        result = prime * result + ((mStandardName == null) ? 0 :
-                mStandardName.hashCode());
-        result = prime * result + Arrays.hashCode(mTransitions);
-        result = prime * result + Arrays.hashCode(mTypes);
-        result = prime * result + (mUseDst ? 1231 : 1237);
-        return result;
-    }
-}
diff --git a/tools/zoneinfo/generate b/tools/zoneinfo/generate
deleted file mode 100755
index a34a1fa..0000000
--- a/tools/zoneinfo/generate
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-
-version=tzdata2010k
-
-mkdir data
-
-for i in $version/africa \
-    $version/antarctica \
-    $version/asia \
-    $version/australasia \
-    $version/etcetera \
-    $version/europe \
-    $version/factory \
-    $version/northamerica \
-    $version/solar87 \
-    $version/solar88 \
-    $version/solar89 \
-    $version/southamerica
-do
-    zic -d data $i
-done
-
-javac -target 1.5 ZoneCompactor.java ZoneInfo.java
-
-(
-    cat $version/* | grep '^Link' | awk '{print $1, $2, $3}'
-    (
-        cat $version/* | grep '^Zone' | awk '{print $2}'
-        cat $version/* | grep '^Link' | awk '{print $3}'
-    ) | LC_ALL="C" sort
-) | grep -v Riyadh8 > setup
-
-java ZoneCompactor setup data
-
-cp zoneinfo.dat zoneinfo.idx ../../../bionic/libc/zoneinfo
-
-echo $version | sed 's/tzdata//' > ../../../bionic/libc/zoneinfo/zoneinfo.version
diff --git a/tools/zoneinfo/tzdata2010k/MODULE_LICENSE_PUBLIC_DOMAIN b/tools/zoneinfo/tzdata2010k/MODULE_LICENSE_PUBLIC_DOMAIN
deleted file mode 100644
index e69de29..0000000
--- a/tools/zoneinfo/tzdata2010k/MODULE_LICENSE_PUBLIC_DOMAIN
+++ /dev/null
diff --git a/tools/zoneinfo/tzdata2010k/africa b/tools/zoneinfo/tzdata2010k/africa
deleted file mode 100644
index 0c37506..0000000
--- a/tools/zoneinfo/tzdata2010k/africa
+++ /dev/null
@@ -1,1048 +0,0 @@
-# <pre>
-# @(#)africa	8.27
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert (2006-03-22):
-#
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
-# San Diego: ACS Publications, Inc. (2003).
-#
-# Gwillim Law writes that a good source
-# for recent time zone data is the International Air Transport
-# Association's Standard Schedules Information Manual (IATA SSIM),
-# published semiannually.  Law sent in several helpful summaries
-# of the IATA's data after 1990.
-#
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1990, and IATA SSIM is the source for entries afterwards.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
-#
-# Previous editions of this database used WAT, CAT, SAT, and EAT
-# for +0:00 through +3:00, respectively,
-# but Mark R V Murray reports that
-# `SAST' is the official abbreviation for +2:00 in the country of South Africa,
-# `CAT' is commonly used for +2:00 in countries north of South Africa, and
-# `WAT' is probably the best name for +1:00, as the common phrase for
-# the area that includes Nigeria is ``West Africa''.
-# He has heard of ``Western Sahara Time'' for +0:00 but can find no reference.
-#
-# To make things confusing, `WAT' seems to have been used for -1:00 long ago;
-# I'd guess that this was because people needed _some_ name for -1:00,
-# and at the time, far west Africa was the only major land area in -1:00.
-# This usage is now obsolete, as the last use of -1:00 on the African
-# mainland seems to have been 1976 in Western Sahara.
-#
-# To summarize, the following abbreviations seem to have some currency:
-#	-1:00	WAT	West Africa Time (no longer used)
-#	 0:00	GMT	Greenwich Mean Time
-#	 2:00	CAT	Central Africa Time
-#	 2:00	SAST	South Africa Standard Time
-# and Murray suggests the following abbreviation:
-#	 1:00	WAT	West Africa Time
-# I realize that this leads to `WAT' being used for both -1:00 and 1:00
-# for times before 1976, but this is the best I can think of
-# until we get more information.
-#
-# I invented the following abbreviations; corrections are welcome!
-#	 2:00	WAST	West Africa Summer Time
-#	 2:30	BEAT	British East Africa Time (no longer used)
-#	 2:44:45 BEAUT	British East Africa Unified Time (no longer used)
-#	 3:00	CAST	Central Africa Summer Time (no longer used)
-#	 3:00	SAST	South Africa Summer Time (no longer used)
-#	 3:00	EAT	East Africa Time
-#	 4:00	EAST	East Africa Summer Time (no longer used)
-
-# Algeria
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Algeria	1916	only	-	Jun	14	23:00s	1:00	S
-Rule	Algeria	1916	1919	-	Oct	Sun>=1	23:00s	0	-
-Rule	Algeria	1917	only	-	Mar	24	23:00s	1:00	S
-Rule	Algeria	1918	only	-	Mar	 9	23:00s	1:00	S
-Rule	Algeria	1919	only	-	Mar	 1	23:00s	1:00	S
-Rule	Algeria	1920	only	-	Feb	14	23:00s	1:00	S
-Rule	Algeria	1920	only	-	Oct	23	23:00s	0	-
-Rule	Algeria	1921	only	-	Mar	14	23:00s	1:00	S
-Rule	Algeria	1921	only	-	Jun	21	23:00s	0	-
-Rule	Algeria	1939	only	-	Sep	11	23:00s	1:00	S
-Rule	Algeria	1939	only	-	Nov	19	 1:00	0	-
-Rule	Algeria	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
-Rule	Algeria	1944	only	-	Oct	 8	 2:00	0	-
-Rule	Algeria	1945	only	-	Sep	16	 1:00	0	-
-Rule	Algeria	1971	only	-	Apr	25	23:00s	1:00	S
-Rule	Algeria	1971	only	-	Sep	26	23:00s	0	-
-Rule	Algeria	1977	only	-	May	 6	 0:00	1:00	S
-Rule	Algeria	1977	only	-	Oct	21	 0:00	0	-
-Rule	Algeria	1978	only	-	Mar	24	 1:00	1:00	S
-Rule	Algeria	1978	only	-	Sep	22	 3:00	0	-
-Rule	Algeria	1980	only	-	Apr	25	 0:00	1:00	S
-Rule	Algeria	1980	only	-	Oct	31	 2:00	0	-
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
-# more precise 0:09:21.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Algiers	0:12:12 -	LMT	1891 Mar 15 0:01
-			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
-			0:00	Algeria	WE%sT	1940 Feb 25 2:00
-			1:00	Algeria	CE%sT	1946 Oct  7
-			0:00	-	WET	1956 Jan 29
-			1:00	-	CET	1963 Apr 14
-			0:00	Algeria	WE%sT	1977 Oct 21
-			1:00	Algeria	CE%sT	1979 Oct 26
-			0:00	Algeria	WE%sT	1981 May
-			1:00	-	CET
-
-# Angola
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Luanda	0:52:56	-	LMT	1892
-			0:52:04	-	AOT	1911 May 26 # Angola Time
-			1:00	-	WAT
-
-# Benin
-# Whitman says they switched to 1:00 in 1946, not 1934;
-# go with Shanks & Pottenger.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Porto-Novo	0:10:28	-	LMT	1912
-			0:00	-	GMT	1934 Feb 26
-			1:00	-	WAT
-
-# Botswana
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Gaborone	1:43:40 -	LMT	1885
-			2:00	-	CAT	1943 Sep 19 2:00
-			2:00	1:00	CAST	1944 Mar 19 2:00
-			2:00	-	CAT
-
-# Burkina Faso
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Ouagadougou	-0:06:04 -	LMT	1912
-			 0:00	-	GMT
-
-# Burundi
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Bujumbura	1:57:28	-	LMT	1890
-			2:00	-	CAT
-
-# Cameroon
-# Whitman says they switched to 1:00 in 1920; go with Shanks & Pottenger.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Douala	0:38:48	-	LMT	1912
-			1:00	-	WAT
-
-# Cape Verde
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/Cape_Verde -1:34:04 -	LMT	1907			# Praia
-			-2:00	-	CVT	1942 Sep
-			-2:00	1:00	CVST	1945 Oct 15
-			-2:00	-	CVT	1975 Nov 25 2:00
-			-1:00	-	CVT
-
-# Central African Republic
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Bangui	1:14:20	-	LMT	1912
-			1:00	-	WAT
-
-# Chad
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Ndjamena	1:00:12 -	LMT	1912
-			1:00	-	WAT	1979 Oct 14
-			1:00	1:00	WAST	1980 Mar  8
-			1:00	-	WAT
-
-# Comoros
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Indian/Comoro	2:53:04 -	LMT	1911 Jul   # Moroni, Gran Comoro
-			3:00	-	EAT
-
-# Democratic Republic of Congo
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Kinshasa	1:01:12 -	LMT	1897 Nov 9
-			1:00	-	WAT
-Zone Africa/Lubumbashi	1:49:52 -	LMT	1897 Nov 9
-			2:00	-	CAT
-
-# Republic of the Congo
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Brazzaville	1:01:08 -	LMT	1912
-			1:00	-	WAT
-
-# Cote D'Ivoire
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Abidjan	-0:16:08 -	LMT	1912
-			 0:00	-	GMT
-
-# Djibouti
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Djibouti	2:52:36 -	LMT	1911 Jul
-			3:00	-	EAT
-
-###############################################################################
-
-# Egypt
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Egypt	1940	only	-	Jul	15	0:00	1:00	S
-Rule	Egypt	1940	only	-	Oct	 1	0:00	0	-
-Rule	Egypt	1941	only	-	Apr	15	0:00	1:00	S
-Rule	Egypt	1941	only	-	Sep	16	0:00	0	-
-Rule	Egypt	1942	1944	-	Apr	 1	0:00	1:00	S
-Rule	Egypt	1942	only	-	Oct	27	0:00	0	-
-Rule	Egypt	1943	1945	-	Nov	 1	0:00	0	-
-Rule	Egypt	1945	only	-	Apr	16	0:00	1:00	S
-Rule	Egypt	1957	only	-	May	10	0:00	1:00	S
-Rule	Egypt	1957	1958	-	Oct	 1	0:00	0	-
-Rule	Egypt	1958	only	-	May	 1	0:00	1:00	S
-Rule	Egypt	1959	1981	-	May	 1	1:00	1:00	S
-Rule	Egypt	1959	1965	-	Sep	30	3:00	0	-
-Rule	Egypt	1966	1994	-	Oct	 1	3:00	0	-
-Rule	Egypt	1982	only	-	Jul	25	1:00	1:00	S
-Rule	Egypt	1983	only	-	Jul	12	1:00	1:00	S
-Rule	Egypt	1984	1988	-	May	 1	1:00	1:00	S
-Rule	Egypt	1989	only	-	May	 6	1:00	1:00	S
-Rule	Egypt	1990	1994	-	May	 1	1:00	1:00	S
-# IATA (after 1990) says transitions are at 0:00.
-# Go with IATA starting in 1995, except correct 1995 entry from 09-30 to 09-29.
-Rule	Egypt	1995	max	-	Apr	lastFri	 0:00s	1:00	S
-Rule	Egypt	1995	2005	-	Sep	lastThu	23:00s	0	-
-# From Steffen Thorsen (2006-09-19):
-# The Egyptian Gazette, issue 41,090 (2006-09-18), page 1, reports:
-# Egypt will turn back clocks by one hour at the midnight of Thursday
-# after observing the daylight saving time since May.
-# http://news.gom.com.eg/gazette/pdf/2006/09/18/01.pdf
-Rule	Egypt	2006	only	-	Sep	21	23:00s	0	-
-# From Dirk Losch (2007-08-14):
-# I received a mail from an airline which says that the daylight
-# saving time in Egypt will end in the night of 2007-09-06 to 2007-09-07.
-# From Jesper Norgaard Welen (2007-08-15): [The following agree:]
-# http://www.nentjes.info/Bill/bill5.htm 
-# http://www.timeanddate.com/worldclock/city.html?n=53
-# From Steffen Thorsen (2007-09-04): The official information...:
-# http://www.sis.gov.eg/En/EgyptOnline/Miscellaneous/000002/0207000000000000001580.htm
-Rule	Egypt	2007	only	-	Sep	Thu>=1	23:00s	0	-
-# From Abdelrahman Hassan (2007-09-06):
-# Due to the Hijri (lunar Islamic calendar) year being 11 days shorter
-# than the year of the Gregorian calendar, Ramadan shifts earlier each
-# year. This year it will be observed September 13 (September is quite
-# hot in Egypt), and the idea is to make fasting easier for workers by
-# shifting business hours one hour out of daytime heat. Consequently,
-# unless discontinued, next DST may end Thursday 28 August 2008.
-# From Paul Eggert (2007-08-17):
-# For lack of better info, assume the new rule is last Thursday in August.
-
-# From Petr Machata (2009-04-06):
-# The following appeared in Red Hat bugzilla[1] (edited):
-#
-# > $ zdump -v /usr/share/zoneinfo/Africa/Cairo | grep 2009
-# > /usr/share/zoneinfo/Africa/Cairo  Thu Apr 23 21:59:59 2009 UTC = Thu =
-# Apr 23
-# > 23:59:59 2009 EET isdst=0 gmtoff=7200
-# > /usr/share/zoneinfo/Africa/Cairo  Thu Apr 23 22:00:00 2009 UTC = Fri =
-# Apr 24
-# > 01:00:00 2009 EEST isdst=1 gmtoff=10800
-# > /usr/share/zoneinfo/Africa/Cairo  Thu Aug 27 20:59:59 2009 UTC = Thu =
-# Aug 27
-# > 23:59:59 2009 EEST isdst=1 gmtoff=10800
-# > /usr/share/zoneinfo/Africa/Cairo  Thu Aug 27 21:00:00 2009 UTC = Thu =
-# Aug 27
-# > 23:00:00 2009 EET isdst=0 gmtoff=7200
-#
-# > end date should be Thu Sep 24 2009 (Last Thursday in September at 23:59=
-# :59)
-# > http://support.microsoft.com/kb/958729/
-#
-# timeanddate[2] and another site I've found[3] also support that.
-#
-# [1] <a href="https://bugzilla.redhat.com/show_bug.cgi?id=492263">
-# https://bugzilla.redhat.com/show_bug.cgi?id=492263
-# </a>
-# [2] <a href="http://www.timeanddate.com/worldclock/clockchange.html?n=53">
-# http://www.timeanddate.com/worldclock/clockchange.html?n=53
-# </a>
-# [3] <a href="http://wwp.greenwichmeantime.com/time-zone/africa/egypt/">
-# http://wwp.greenwichmeantime.com/time-zone/africa/egypt/
-# </a>
-
-# From Arthur David Olson (2009-04-20):
-# In 2009 (and for the next several years), Ramadan ends before the fourth
-# Thursday in September; Egypt is expected to revert to the last Thursday
-# in September.
-
-# From Steffen Thorsen (2009-08-11):
-# We have been able to confirm the August change with the Egyptian Cabinet 
-# Information and Decision Support Center:
-# <a href="http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html">
-# http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html
-# </a>
-# 
-# The Middle East News Agency
-# <a href="http://www.mena.org.eg/index.aspx">
-# http://www.mena.org.eg/index.aspx
-# </a>
-# also reports "Egypt starts winter time on August 21"
-# today in article numbered "71, 11/08/2009 12:25 GMT." 
-# Only the title above is available without a subscription to their service,
-# and can be found by searching for "winter" in their search engine
-# (at least today).
-
-# From Alexander Krivenyshev (2010-07-20):
-# According to News from Egypt -  Al-Masry Al-Youm Egypt's cabinet has
-# decided that Daylight Saving Time will not be used in Egypt during
-# Ramadan.
-#
-# Arabic translation:
-# "Clocks to go back during Ramadan--and then forward again"
-# <a href="http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again">
-# http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt02.html">
-# http://www.worldtimezone.com/dst_news/dst_news_egypt02.html
-# </a>
-
-Rule	Egypt	2008	only	-	Aug	lastThu	23:00s	0	-
-Rule	Egypt	2009	only	-	Aug	20	23:00s	0	-
-Rule	Egypt	2010	only	-	Aug	10	23:00s	0	-
-Rule	Egypt	2010	only	-	Sep	9	0:00s	1:00	S
-Rule	Egypt	2010	max	-	Sep	lastThu	23:00s	0	-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
-			2:00	Egypt	EE%sT
-
-# Equatorial Guinea
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Malabo	0:35:08 -	LMT	1912
-			0:00	-	GMT	1963 Dec 15
-			1:00	-	WAT
-
-# Eritrea
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Asmara	2:35:32 -	LMT	1870
-			2:35:32	-	AMT	1890	      # Asmara Mean Time
-			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
-			3:00	-	EAT
-
-# Ethiopia
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time zones
-# between 1870 and 1890, and that they merged to 38E50 (2:35:20) in 1890.
-# We'll guess that 38E50 is for Adis Dera.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Addis_Ababa	2:34:48 -	LMT	1870
-			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
-			3:00	-	EAT
-
-# Gabon
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Libreville	0:37:48 -	LMT	1912
-			1:00	-	WAT
-
-# Gambia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Banjul	-1:06:36 -	LMT	1912
-			-1:06:36 -	BMT	1935	# Banjul Mean Time
-			-1:00	-	WAT	1964
-			 0:00	-	GMT
-
-# Ghana
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Whitman says DST was observed from 1931 to ``the present'';
-# go with Shanks & Pottenger.
-Rule	Ghana	1936	1942	-	Sep	 1	0:00	0:20	GHST
-Rule	Ghana	1936	1942	-	Dec	31	0:00	0	GMT
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Accra	-0:00:52 -	LMT	1918
-			 0:00	Ghana	%s
-
-# Guinea
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Conakry	-0:54:52 -	LMT	1912
-			 0:00	-	GMT	1934 Feb 26
-			-1:00	-	WAT	1960
-			 0:00	-	GMT
-
-# Guinea-Bissau
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Bissau	-1:02:20 -	LMT	1911 May 26
-			-1:00	-	WAT	1975
-			 0:00	-	GMT
-
-# Kenya
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Nairobi	2:27:16	-	LMT	1928 Jul
-			3:00	-	EAT	1930
-			2:30	-	BEAT	1940
-			2:44:45	-	BEAUT	1960
-			3:00	-	EAT
-
-# Lesotho
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Maseru	1:50:00 -	LMT	1903 Mar
-			2:00	-	SAST	1943 Sep 19 2:00
-			2:00	1:00	SAST	1944 Mar 19 2:00
-			2:00	-	SAST
-
-# Liberia
-# From Paul Eggert (2006-03-22):
-# In 1972 Liberia was the last country to switch
-# from a UTC offset that was not a multiple of 15 or 20 minutes.
-# Howse reports that it was in honor of their president's birthday.
-# Shank & Pottenger report the date as May 1, whereas Howse reports Jan;
-# go with Shanks & Pottenger.
-# For Liberia before 1972, Shanks & Pottenger report -0:44, whereas Howse and
-# Whitman each report -0:44:30; go with the more precise figure.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Monrovia	-0:43:08 -	LMT	1882
-			-0:43:08 -	MMT	1919 Mar # Monrovia Mean Time
-			-0:44:30 -	LRT	1972 May # Liberia Time
-			 0:00	-	GMT
-
-###############################################################################
-
-# Libya
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
-Rule	Libya	1952	only	-	Jan	 1	0:00	0	-
-Rule	Libya	1953	only	-	Oct	 9	2:00	1:00	S
-Rule	Libya	1954	only	-	Jan	 1	0:00	0	-
-Rule	Libya	1955	only	-	Sep	30	0:00	1:00	S
-Rule	Libya	1956	only	-	Jan	 1	0:00	0	-
-Rule	Libya	1982	1984	-	Apr	 1	0:00	1:00	S
-Rule	Libya	1982	1985	-	Oct	 1	0:00	0	-
-Rule	Libya	1985	only	-	Apr	 6	0:00	1:00	S
-Rule	Libya	1986	only	-	Apr	 4	0:00	1:00	S
-Rule	Libya	1986	only	-	Oct	 3	0:00	0	-
-Rule	Libya	1987	1989	-	Apr	 1	0:00	1:00	S
-Rule	Libya	1987	1989	-	Oct	 1	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Tripoli	0:52:44 -	LMT	1920
-			1:00	Libya	CE%sT	1959
-			2:00	-	EET	1982
-			1:00	Libya	CE%sT	1990 May  4
-# The following entries are from Shanks & Pottenger;
-# the IATA SSIM data contain some obvious errors.
-			2:00	-	EET	1996 Sep 30
-			1:00	-	CET	1997 Apr  4
-			1:00	1:00	CEST	1997 Oct  4
-			2:00	-	EET
-
-# Madagascar
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Indian/Antananarivo 3:10:04 -	LMT	1911 Jul
-			3:00	-	EAT	1954 Feb 27 23:00s
-			3:00	1:00	EAST	1954 May 29 23:00s
-			3:00	-	EAT
-
-# Malawi
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Blantyre	2:20:00 -	LMT	1903 Mar
-			2:00	-	CAT
-
-# Mali
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Bamako	-0:32:00 -	LMT	1912
-			 0:00	-	GMT	1934 Feb 26
-			-1:00	-	WAT	1960 Jun 20
-			 0:00	-	GMT
-
-# Mauritania
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Nouakchott	-1:03:48 -	LMT	1912
-			 0:00	-	GMT	1934 Feb 26
-			-1:00	-	WAT	1960 Nov 28
-			 0:00	-	GMT
-
-# Mauritius
-
-# From Steffen Thorsen (2008-06-25):
-# Mauritius plans to observe DST from 2008-11-01 to 2009-03-31 on a trial
-# basis....
-# It seems that Mauritius observed daylight saving time from 1982-10-10 to 
-# 1983-03-20 as well, but that was not successful....
-# http://www.timeanddate.com/news/time/mauritius-daylight-saving-time.html
-
-# From Alex Krivenyshev (2008-06-25):
-# http://economicdevelopment.gov.mu/portal/site/Mainhomepage/menuitem.a42b24128104d9845dabddd154508a0c/?content_id=0a7cee8b5d69a110VgnVCM1000000a04a8c0RCRD
-
-# From Arthur David Olson (2008-06-30):
-# The www.timeanddate.com article cited by Steffen Thorsen notes that "A
-# final decision has yet to be made on the times that daylight saving
-# would begin and end on these dates." As a place holder, use midnight.
-
-# From Paul Eggert (2008-06-30):
-# Follow Thorsen on DST in 1982/1983, instead of Shanks & Pottenger.
-
-# From Steffen Thorsen (2008-07-10):
-# According to
-# <a href="http://www.lexpress.mu/display_article.php?news_id=111216">
-# http://www.lexpress.mu/display_article.php?news_id=111216
-# </a>
-# (in French), Mauritius will start and end their DST a few days earlier
-# than previously announced (2008-11-01 to 2009-03-31).  The new start
-# date is 2008-10-26 at 02:00 and the new end date is 2009-03-27 (no time
-# given, but it is probably at either 2 or 3 wall clock time).
-# 
-# A little strange though, since the article says that they moved the date 
-# to align itself with Europe and USA which also change time on that date, 
-# but that means they have not paid attention to what happened in 
-# USA/Canada last year (DST ends first Sunday in November). I also wonder 
-# why that they end on a Friday, instead of aligning with Europe which 
-# changes two days later.
-
-# From Alex Krivenyshev (2008-07-11):
-# Seems that English language article "The revival of daylight saving
-# time:  Energy conservation?"-# No. 16578 (07/11/2008) was originally
-# published on Monday, June 30, 2008...
-#
-# I guess that article in French "Le gouvernement avance l'introduction
-# de l'heure d'ete" stating that DST in Mauritius starting on October 26
-# and ending on March 27, 2009 is the most recent one.
-# ...
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html">
-# http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html
-# </a>
-
-# From Riad M. Hossen Ally (2008-08-03):
-# The Government of Mauritius weblink
-# <a href="http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD">
-# http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD
-# </a>
-# Cabinet Decision of July 18th, 2008 states as follows:
-#
-# 4. ...Cabinet has agreed to the introduction into the National Assembly
-# of the Time Bill which provides for the introduction of summer time in
-# Mauritius. The summer time period which will be of one hour ahead of
-# the standard time, will be aligned with that in Europe and the United
-# States of America. It will start at two o'clock in the morning on the
-# last Sunday of October and will end at two o'clock in the morning on
-# the last Sunday of March the following year. The summer time for the
-# year 2008 - 2009 will, therefore, be effective as from 26 October 2008
-# and end on 29 March 2009.
-
-# From Ed Maste (2008-10-07):
-# THE TIME BILL (No. XXVII of 2008) Explanatory Memorandum states the
-# beginning / ending of summer time is 2 o'clock standard time in the
-# morning of the last Sunday of October / last Sunday of March.
-# <a href="http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf">
-# http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf
-# </a>
-
-# From Steffen Thorsen (2009-06-05):
-# According to several sources, Mauritius will not continue to observe
-# DST the coming summer...
-#
-# Some sources, in French:
-# <a href="http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB">
-# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB
-# </a>
-# <a href="http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints-">
-# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints-
-# </a>
-#
-# Our wrap-up:
-# <a href="http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html">
-# http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html
-# </a>
-
-# From Arthur David Olson (2009-07-11):
-# The "mauritius-dst-will-not-repeat" wrapup includes this: 
-# "The trial ended on March 29, 2009, when the clocks moved back by one hour
-# at 2am (or 02:00) local time..."
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule Mauritius	1982	only	-	Oct	10	0:00	1:00	S
-Rule Mauritius	1983	only	-	Mar	21	0:00	0	-
-Rule Mauritius	2008	only	-	Oct	lastSun	2:00	1:00	S
-Rule Mauritius	2009	only	-	Mar	lastSun	2:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Indian/Mauritius	3:50:00 -	LMT	1907		# Port Louis
-			4:00 Mauritius	MU%sT	# Mauritius Time
-# Agalega Is, Rodriguez
-# no information; probably like Indian/Mauritius
-
-# Mayotte
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
-			3:00	-	EAT
-
-# Morocco
-# See the `europe' file for Spanish Morocco (Africa/Ceuta).
-
-# From Alex Krivenyshev (2008-05-09):
-# Here is an article that Morocco plan to introduce Daylight Saving Time between
-# 1 June, 2008 and 27 September, 2008.
-#
-# "... Morocco is to save energy by adjusting its clock during summer so it will
-# be one hour ahead of GMT between 1 June and 27 September, according to
-# Communication Minister and Gov ernment Spokesman, Khalid Naciri...."
-#
-# <a href="http://www.worldtimezone.net/dst_news/dst_news_morocco01.html">
-# http://www.worldtimezone.net/dst_news/dst_news_morocco01.html
-# </a>
-# OR
-# <a href="http://en.afrik.com/news11892.html">
-# http://en.afrik.com/news11892.html
-# </a>
-
-# From Alex Krivenyshev (2008-05-09):
-# The Morocco time change can be confirmed on Morocco web site Maghreb Arabe Presse:
-# <a href="http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view">
-# http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view
-# </a>
-#
-# Morocco shifts to daylight time on June 1st through September 27, Govt.
-# spokesman.
-
-# From Patrice Scattolin (2008-05-09):
-# According to this article:
-# <a href="http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html">
-# http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html
-# </a>
-# (and republished here:
-# <a href="http://www.actu.ma/heure-dete-comment_i127896_0.html">
-# http://www.actu.ma/heure-dete-comment_i127896_0.html
-# </a>
-# )
-# the changes occurs at midnight:
-#
-# saturday night may 31st at midnight (which in french is to be
-# intrepreted as the night between saturday and sunday)
-# sunday night the 28th  at midnight
-#
-# Seeing that the 28th is monday, I am guessing that she intends to say
-# the midnight of the 28th which is the midnight between sunday and
-# monday, which jives with other sources that say that it's inclusive
-# june1st to sept 27th.
-#
-# The decision was taken by decree *2-08-224 *but I can't find the decree
-# published on the web.
-#
-# It's also confirmed here:
-# <a href="http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm">
-# http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm
-# </a>
-# on a government portal as being  between june 1st and sept 27th (not yet
-# posted in english).
-#
-# The following google query will generate many relevant hits:
-# <a href="http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search">
-# http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search
-# </a>
-
-# From Alex Krivenyshev (2008-05-09):
-# Is Western Sahara (part which administrated by Morocco) going to follow
-# Morocco DST changes?  Any information?  What about other part of
-# Western Sahara - under administration of POLISARIO Front (also named
-# SADR Saharawi Arab Democratic Republic)?
-
-# From Arthur David Olson (2008-05-09):
-# XXX--guess that it is only Morocco for now; guess only 2008 for now.
-
-# From Steffen Thorsen (2008-08-27):
-# Morocco will change the clocks back on the midnight between August 31 
-# and September 1. They originally planned to observe DST to near the end 
-# of September:
-#
-# One article about it (in French):
-# <a href="http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default">
-# http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default
-# </a>
-#
-# We have some further details posted here:
-# <a href="http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html">
-# http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html
-# </a>
-
-# From Steffen Thorsen (2009-03-17):
-# Morocco will observe DST from 2009-06-01 00:00 to 2009-08-21 00:00 according
-# to many sources, such as
-# <a href="http://news.marweb.com/morocco/entertainment/morocco-daylight-saving.html">
-# http://news.marweb.com/morocco/entertainment/morocco-daylight-saving.html
-# </a>
-# <a href="http://www.medi1sat.ma/fr/depeche.aspx?idp=2312">
-# http://www.medi1sat.ma/fr/depeche.aspx?idp=2312
-# </a>
-# (French)
-#
-# Our summary:
-# <a href="http://www.timeanddate.com/news/time/morocco-starts-dst-2009.html">
-# http://www.timeanddate.com/news/time/morocco-starts-dst-2009.html
-# </a>
-
-# From Alexander Krivenyshev (2009-03-17):
-# Here is a link to official document from Royaume du Maroc Premier Ministre,
-# Ministere de la Modernisation des Secteurs Publics
-#
-# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 june 1967)
-# concerning the amendment of the legal time, the Ministry of Modernization of
-# Public Sectors announced that the official time in the Kingdom will be
-# advanced 60 minutes from Sunday 31 May 2009 at midnight.
-#
-# <a href="http://www.mmsp.gov.ma/francais/Actualites_fr/PDF_Actualites_Fr/HeureEte_FR.pdf">
-# http://www.mmsp.gov.ma/francais/Actualites_fr/PDF_Actualites_Fr/HeureEte_FR.pdf
-# </a>
-#
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_morocco03.html">
-# http://www.worldtimezone.com/dst_news/dst_news_morocco03.html
-# </a>
-
-# From Steffen Thorsen (2010-04-13):
-# Several news media in Morocco report that the Ministry of Modernization
-# of Public Sectors has announced that Morocco will have DST from
-# 2010-05-02 to 2010-08-08.
-#
-# Example:
-# <a href="http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html">
-# http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html
-# </a>
-# (French)
-# Our page:
-# <a href="http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html">
-# http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html
-# </a>
-
-# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-
-Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
-Rule	Morocco	1939	only	-	Nov	19	 0:00	0	-
-Rule	Morocco	1940	only	-	Feb	25	 0:00	1:00	S
-Rule	Morocco	1945	only	-	Nov	18	 0:00	0	-
-Rule	Morocco	1950	only	-	Jun	11	 0:00	1:00	S
-Rule	Morocco	1950	only	-	Oct	29	 0:00	0	-
-Rule	Morocco	1967	only	-	Jun	 3	12:00	1:00	S
-Rule	Morocco	1967	only	-	Oct	 1	 0:00	0	-
-Rule	Morocco	1974	only	-	Jun	24	 0:00	1:00	S
-Rule	Morocco	1974	only	-	Sep	 1	 0:00	0	-
-Rule	Morocco	1976	1977	-	May	 1	 0:00	1:00	S
-Rule	Morocco	1976	only	-	Aug	 1	 0:00	0	-
-Rule	Morocco	1977	only	-	Sep	28	 0:00	0	-
-Rule	Morocco	1978	only	-	Jun	 1	 0:00	1:00	S
-Rule	Morocco	1978	only	-	Aug	 4	 0:00	0	-
-Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	S
-Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
-Rule	Morocco	2009	only	-	Jun	 1	 0:00	1:00	S
-Rule	Morocco	2009	only	-	Aug	 21	 0:00	0	-
-Rule	Morocco	2010	only	-	May	 2	 0:00	1:00	S
-Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
-			 0:00	Morocco	WE%sT	1984 Mar 16
-			 1:00	-	CET	1986
-			 0:00	Morocco	WE%sT
-# Western Sahara
-Zone Africa/El_Aaiun	-0:52:48 -	LMT	1934 Jan
-			-1:00	-	WAT	1976 Apr 14
-			 0:00	-	WET
-
-# Mozambique
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Maputo	2:10:20 -	LMT	1903 Mar
-			2:00	-	CAT
-
-# Namibia
-# The 1994-04-03 transition is from Shanks & Pottenger.
-# Shanks & Pottenger report no DST after 1998-04; go with IATA.
-
-# From Petronella Sibeene (2007-03-30) in
-# <http://allafrica.com/stories/200703300178.html>:
-# While the entire country changes its time, Katima Mulilo and other
-# settlements in Caprivi unofficially will not because the sun there
-# rises and sets earlier compared to other regions.  Chief of
-# Forecasting Riaan van Zyl explained that the far eastern parts of
-# the country are close to 40 minutes earlier in sunrise than the rest
-# of the country.
-# 
-# From Paul Eggert (2007-03-31):
-# Apparently the Caprivi Strip informally observes Botswana time, but
-# we have no details.  In the meantime people there can use Africa/Gaborone.
-
-# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Namibia	1994	max	-	Sep	Sun>=1	2:00	1:00	S
-Rule	Namibia	1995	max	-	Apr	Sun>=1	2:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Windhoek	1:08:24 -	LMT	1892 Feb 8
-			1:30	-	SWAT	1903 Mar	# SW Africa Time
-			2:00	-	SAST	1942 Sep 20 2:00
-			2:00	1:00	SAST	1943 Mar 21 2:00
-			2:00	-	SAST	1990 Mar 21 # independence
-			2:00	-	CAT	1994 Apr  3
-			1:00	Namibia	WA%sT
-
-# Niger
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Niamey	 0:08:28 -	LMT	1912
-			-1:00	-	WAT	1934 Feb 26
-			 0:00	-	GMT	1960
-			 1:00	-	WAT
-
-# Nigeria
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Lagos	0:13:36 -	LMT	1919 Sep
-			1:00	-	WAT
-
-# Reunion
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Indian/Reunion	3:41:52 -	LMT	1911 Jun	# Saint-Denis
-			4:00	-	RET	# Reunion Time
-#
-# Scattered Islands (Iles Eparses) administered from Reunion are as follows.
-# The following information about them is taken from
-# Iles Eparses (www.outre-mer.gouv.fr/domtom/ile.htm, 1997-07-22, in French;
-# no longer available as of 1999-08-17).
-# We have no info about their time zone histories.
-#
-# Bassas da India - uninhabited
-# Europa Island - inhabited from 1905 to 1910 by two families
-# Glorioso Is - inhabited until at least 1958
-# Juan de Nova - uninhabited
-# Tromelin - inhabited until at least 1958
-
-# Rwanda
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Kigali	2:00:16 -	LMT	1935 Jun
-			2:00	-	CAT
-
-# St Helena
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/St_Helena	-0:22:48 -	LMT	1890		# Jamestown
-			-0:22:48 -	JMT	1951	# Jamestown Mean Time
-			 0:00	-	GMT
-# The other parts of the St Helena territory are similar:
-#	Tristan da Cunha: on GMT, say Whitman and the CIA
-#	Ascension: on GMT, says usno1995 and the CIA
-#	Gough (scientific station since 1955; sealers wintered previously):
-#		on GMT, says the CIA
-#	Inaccessible, Nightingale: no information, but probably GMT
-
-# Sao Tome and Principe
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Sao_Tome	 0:26:56 -	LMT	1884
-			-0:36:32 -	LMT	1912	# Lisbon Mean Time
-			 0:00	-	GMT
-
-# Senegal
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Dakar	-1:09:44 -	LMT	1912
-			-1:00	-	WAT	1941 Jun
-			 0:00	-	GMT
-
-# Seychelles
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Indian/Mahe	3:41:48 -	LMT	1906 Jun	# Victoria
-			4:00	-	SCT	# Seychelles Time
-# From Paul Eggert (2001-05-30):
-# Aldabra, Farquhar, and Desroches, originally dependencies of the
-# Seychelles, were transferred to the British Indian Ocean Territory
-# in 1965 and returned to Seychelles control in 1976.  We don't know
-# whether this affected their time zone, so omit this for now.
-# Possibly the islands were uninhabited.
-
-# Sierra Leone
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks & Pottenger.
-Rule	SL	1935	1942	-	Jun	 1	0:00	0:40	SLST
-Rule	SL	1935	1942	-	Oct	 1	0:00	0	WAT
-Rule	SL	1957	1962	-	Jun	 1	0:00	1:00	SLST
-Rule	SL	1957	1962	-	Sep	 1	0:00	0	GMT
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Freetown	-0:53:00 -	LMT	1882
-			-0:53:00 -	FMT	1913 Jun # Freetown Mean Time
-			-1:00	SL	%s	1957
-			 0:00	SL	%s
-
-# Somalia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Mogadishu	3:01:28 -	LMT	1893 Nov
-			3:00	-	EAT	1931
-			2:30	-	BEAT	1957
-			3:00	-	EAT
-
-# South Africa
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	SA	1942	1943	-	Sep	Sun>=15	2:00	1:00	-
-Rule	SA	1943	1944	-	Mar	Sun>=15	2:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Johannesburg 1:52:00 -	LMT	1892 Feb 8
-			1:30	-	SAST	1903 Mar
-			2:00	SA	SAST
-# Marion and Prince Edward Is
-# scientific station since 1947
-# no information
-
-# Sudan
-#
-# From <a href="http://www.sunanews.net/sn13jane.html">
-# Sudan News Agency (2000-01-13)
-# </a>, also reported by Michael De Beukelaer-Dossche via Steffen Thorsen:
-# Clocks will be moved ahead for 60 minutes all over the Sudan as of noon
-# Saturday....  This was announced Thursday by Caretaker State Minister for
-# Manpower Abdul-Rahman Nur-Eddin.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Sudan	1970	only	-	May	 1	0:00	1:00	S
-Rule	Sudan	1970	1985	-	Oct	15	0:00	0	-
-Rule	Sudan	1971	only	-	Apr	30	0:00	1:00	S
-Rule	Sudan	1972	1985	-	Apr	lastSun	0:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Khartoum	2:10:08 -	LMT	1931
-			2:00	Sudan	CA%sT	2000 Jan 15 12:00
-			3:00	-	EAT
-
-# Swaziland
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Mbabane	2:04:24 -	LMT	1903 Mar
-			2:00	-	SAST
-
-# Tanzania
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Dar_es_Salaam 2:37:08 -	LMT	1931
-			3:00	-	EAT	1948
-			2:44:45	-	BEAUT	1961
-			3:00	-	EAT
-
-# Togo
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Lome	0:04:52 -	LMT	1893
-			0:00	-	GMT
-
-# Tunisia
-
-# From Gwillim Law (2005-04-30):
-# My correspondent, Risto Nykanen, has alerted me to another adoption of DST,
-# this time in Tunisia.  According to Yahoo France News
-# <http://fr.news.yahoo.com/050426/5/4dumk.html>, in a story attributed to AP
-# and dated 2005-04-26, "Tunisia has decided to advance its official time by
-# one hour, starting on Sunday, May 1.  Henceforth, Tunisian time will be
-# UTC+2 instead of UTC+1.  The change will take place at 23:00 UTC next
-# Saturday."  (My translation)
-#
-# From Oscar van Vlijmen (2005-05-02):
-# LaPresse, the first national daily newspaper ...
-# <http://www.lapresse.tn/archives/archives280405/actualites/lheure.html>
-# ... DST for 2005: on: Sun May 1 0h standard time, off: Fri Sept. 30,
-# 1h standard time.
-#
-# From Atef Loukil (2006-03-28):
-# The daylight saving time will be the same each year:
-# Beginning      : the last Sunday of March at 02:00
-# Ending         : the last Sunday of October at 03:00 ...
-# http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=1188&Itemid=50
-
-# From Steffen Thorsen (2009-03-16):
-# According to several news sources, Tunisia will not observe DST this year.
-# (Arabic)
-# <a href="http://www.elbashayer.com/?page=viewn&nid=42546">
-# http://www.elbashayer.com/?page=viewn&nid=42546
-# </a>
-# <a href="http://www.babnet.net/kiwidetail-15295.asp">
-# http://www.babnet.net/kiwidetail-15295.asp
-# </a>
-#
-# We have also confirmed this with the US embassy in Tunisia.
-# We have a wrap-up about this on the following page:
-# <a href="http://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html">
-# http://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html
-# </a>
-
-# From Alexander Krivenyshev (2009-03-17):
-# Here is a link to Tunis Afrique Presse News Agency
-#
-# Standard time to be kept the whole year long (tap.info.tn):
-#
-# (in English)
-# <a href="http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=26813&Itemid=157">
-# http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=26813&Itemid=157
-# </a>
-#
-# (in Arabic)
-# <a href="http://www.tap.info.tn/ar/index.php?option=com_content&task=view&id=61240&Itemid=1">
-# http://www.tap.info.tn/ar/index.php?option=com_content&task=view&id=61240&Itemid=1
-# </a>
-
-# From Arthur David Olson (2009--3-18):
-# The Tunis Afrique Presse News Agency notice contains this: "This measure is due to the fact
-# that the fasting month of ramadan coincides with the period concerned by summer time.
-# Therefore, the standard time will be kept unchanged the whole year long."
-# So foregoing DST seems to be an exception (albeit one that may be repeated in the  future).
-
-# From Alexander Krivenyshev (2010-03-27):
-# According to some news reports Tunis confirmed not to use DST in 2010
-#
-# (translation):
-# "The Tunisian government has decided to abandon DST, which was scheduled on
-# Sunday...
-# Tunisian authorities had suspended the DST for the first time last year also
-# coincided with the month of Ramadan..."
-#
-# (in Arabic)
-# <a href="http://www.moheet.com/show_news.aspx?nid=358861&pg=1">
-# http://www.moheet.com/show_news.aspx?nid=358861&pg=1
-# <a href="http://www.almadenahnews.com/newss/news.php?c=118&id=38036">
-# http://www.almadenahnews.com/newss/news.php?c=118&id=38036
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_tunis02.html">
-# http://www.worldtimezone.com/dst_news/dst_news_tunis02.html
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Tunisia	1939	only	-	Apr	15	23:00s	1:00	S
-Rule	Tunisia	1939	only	-	Nov	18	23:00s	0	-
-Rule	Tunisia	1940	only	-	Feb	25	23:00s	1:00	S
-Rule	Tunisia	1941	only	-	Oct	 6	 0:00	0	-
-Rule	Tunisia	1942	only	-	Mar	 9	 0:00	1:00	S
-Rule	Tunisia	1942	only	-	Nov	 2	 3:00	0	-
-Rule	Tunisia	1943	only	-	Mar	29	 2:00	1:00	S
-Rule	Tunisia	1943	only	-	Apr	17	 2:00	0	-
-Rule	Tunisia	1943	only	-	Apr	25	 2:00	1:00	S
-Rule	Tunisia	1943	only	-	Oct	 4	 2:00	0	-
-Rule	Tunisia	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
-Rule	Tunisia	1944	only	-	Oct	 8	 0:00	0	-
-Rule	Tunisia	1945	only	-	Sep	16	 0:00	0	-
-Rule	Tunisia	1977	only	-	Apr	30	 0:00s	1:00	S
-Rule	Tunisia	1977	only	-	Sep	24	 0:00s	0	-
-Rule	Tunisia	1978	only	-	May	 1	 0:00s	1:00	S
-Rule	Tunisia	1978	only	-	Oct	 1	 0:00s	0	-
-Rule	Tunisia	1988	only	-	Jun	 1	 0:00s	1:00	S
-Rule	Tunisia	1988	1990	-	Sep	lastSun	 0:00s	0	-
-Rule	Tunisia	1989	only	-	Mar	26	 0:00s	1:00	S
-Rule	Tunisia	1990	only	-	May	 1	 0:00s	1:00	S
-Rule	Tunisia	2005	only	-	May	 1	 0:00s	1:00	S
-Rule	Tunisia	2005	only	-	Sep	30	 1:00s	0	-
-Rule	Tunisia	2006	2008	-	Mar	lastSun	 2:00s	1:00	S
-Rule	Tunisia	2006	2008	-	Oct	lastSun	 2:00s	0	-
-
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
-# more precise 0:09:21.
-# Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Tunis	0:40:44 -	LMT	1881 May 12
-			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
-			1:00	Tunisia	CE%sT
-
-# Uganda
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Kampala	2:09:40 -	LMT	1928 Jul
-			3:00	-	EAT	1930
-			2:30	-	BEAT	1948
-			2:44:45	-	BEAUT	1957
-			3:00	-	EAT
-
-# Zambia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Lusaka	1:53:08 -	LMT	1903 Mar
-			2:00	-	CAT
-
-# Zimbabwe
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Harare	2:04:12 -	LMT	1903 Mar
-			2:00	-	CAT
diff --git a/tools/zoneinfo/tzdata2010k/antarctica b/tools/zoneinfo/tzdata2010k/antarctica
deleted file mode 100644
index 629b2d7..0000000
--- a/tools/zoneinfo/tzdata2010k/antarctica
+++ /dev/null
@@ -1,411 +0,0 @@
-# <pre>
-# @(#)antarctica	8.8
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# From Paul Eggert (1999-11-15):
-# To keep things manageable, we list only locations occupied year-round; see
-# <a href="http://www.comnap.aq/comnap/comnap.nsf/P/Stations/">
-# COMNAP - Stations and Bases
-# </a>
-# and
-# <a href="http://www.spri.cam.ac.uk/bob/periant.htm">
-# Summary of the Peri-Antarctic Islands (1998-07-23)
-# </a>
-# for information.
-# Unless otherwise specified, we have no time zone information.
-#
-# Except for the French entries,
-# I made up all time zone abbreviations mentioned here; corrections welcome!
-# FORMAT is `zzz' and GMTOFF is 0 for locations while uninhabited.
-
-# These rules are stolen from the `europe' file.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	RussAQ	1981	1984	-	Apr	 1	 0:00	1:00	S
-Rule	RussAQ	1981	1983	-	Oct	 1	 0:00	0	-
-Rule	RussAQ	1984	1991	-	Sep	lastSun	 2:00s	0	-
-Rule	RussAQ	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
-Rule	RussAQ	1992	only	-	Mar	lastSat	 23:00	1:00	S
-Rule	RussAQ	1992	only	-	Sep	lastSat	 23:00	0	-
-Rule	RussAQ	1993	max	-	Mar	lastSun	 2:00s	1:00	S
-Rule	RussAQ	1993	1995	-	Sep	lastSun	 2:00s	0	-
-Rule	RussAQ	1996	max	-	Oct	lastSun	 2:00s	0	-
-
-# These rules are stolen from the `southamerica' file.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	ArgAQ	1964	1966	-	Mar	 1	0:00	0	-
-Rule	ArgAQ	1964	1966	-	Oct	15	0:00	1:00	S
-Rule	ArgAQ	1967	only	-	Apr	 2	0:00	0	-
-Rule	ArgAQ	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
-Rule	ArgAQ	1968	1969	-	Apr	Sun>=1	0:00	0	-
-Rule	ArgAQ	1974	only	-	Jan	23	0:00	1:00	S
-Rule	ArgAQ	1974	only	-	May	 1	0:00	0	-
-Rule	ChileAQ	1972	1986	-	Mar	Sun>=9	3:00u	0	-
-Rule	ChileAQ	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	ChileAQ	1987	only	-	Apr	12	3:00u	0	-
-Rule	ChileAQ	1988	1989	-	Mar	Sun>=9	3:00u	0	-
-Rule	ChileAQ	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
-Rule	ChileAQ	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	ChileAQ	1990	only	-	Mar	18	3:00u	0	-
-Rule	ChileAQ	1990	only	-	Sep	16	4:00u	1:00	S
-Rule	ChileAQ	1991	1996	-	Mar	Sun>=9	3:00u	0	-
-Rule	ChileAQ	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	ChileAQ	1997	only	-	Mar	30	3:00u	0	-
-Rule	ChileAQ	1998	only	-	Mar	Sun>=9	3:00u	0	-
-Rule	ChileAQ	1998	only	-	Sep	27	4:00u	1:00	S
-Rule	ChileAQ	1999	only	-	Apr	 4	3:00u	0	-
-Rule	ChileAQ	1999	max	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	ChileAQ	2000	max	-	Mar	Sun>=9	3:00u	0	-
-
-# These rules are stolen from the `australasia' file.
-Rule	AusAQ	1917	only	-	Jan	 1	0:01	1:00	-
-Rule	AusAQ	1917	only	-	Mar	25	2:00	0	-
-Rule	AusAQ	1942	only	-	Jan	 1	2:00	1:00	-
-Rule	AusAQ	1942	only	-	Mar	29	2:00	0	-
-Rule	AusAQ	1942	only	-	Sep	27	2:00	1:00	-
-Rule	AusAQ	1943	1944	-	Mar	lastSun	2:00	0	-
-Rule	AusAQ	1943	only	-	Oct	 3	2:00	1:00	-
-Rule	ATAQ	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	1968	only	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	1968	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	ATAQ	1969	1971	-	Mar	Sun>=8	2:00s	0	-
-Rule	ATAQ	1972	only	-	Feb	lastSun	2:00s	0	-
-Rule	ATAQ	1973	1981	-	Mar	Sun>=1	2:00s	0	-
-Rule	ATAQ	1982	1983	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	1984	1986	-	Mar	Sun>=1	2:00s	0	-
-Rule	ATAQ	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
-Rule	ATAQ	1987	1990	-	Mar	Sun>=15	2:00s	0	-
-Rule	ATAQ	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
-Rule	ATAQ	1988	1990	-	Oct	lastSun	2:00s	1:00	-
-Rule	ATAQ	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	1991	2005	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	2000	only	-	Aug	lastSun	2:00s	1:00	-
-Rule	ATAQ	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	2006	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	ATAQ	2007	only	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	2008	max	-	Apr	Sun>=1	2:00s	0	-
-
-# Argentina - year-round bases
-# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
-# Esperanza, San Martin Land, -6323-05659, since 1952-12-17
-# Jubany, Potter Peninsula, King George Island, -6414-0602320, since 1982-01
-# Marambio, Seymour I, -6414-05637, since 1969-10-29
-# Orcadas, Laurie I, -6016-04444, since 1904-02-22
-# San Martin, Debenham I, -6807-06708, since 1951-03-21
-#	(except 1960-03 / 1976-03-21)
-
-# Australia - territories
-# Heard Island, McDonald Islands (uninhabited)
-#	previously sealers and scientific personnel wintered
-#	<a href="http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html">
-#	Margaret Turner reports
-#	</a> (1999-09-30) that they're UTC+5, with no DST;
-#	presumably this is when they have visitors.
-#
-# year-round bases
-# Casey, Bailey Peninsula, -6617+11032, since 1969
-# Davis, Vestfold Hills, -6835+07759, since 1957-01-13
-#	(except 1964-11 - 1969-02)
-# Mawson, Holme Bay, -6736+06253, since 1954-02-13
-
-# From Steffen Thorsen (2009-03-11):
-# Three Australian stations in Antarctica have changed their time zone:
-# Casey moved from UTC+8 to UTC+11
-# Davis moved from UTC+7 to UTC+5
-# Mawson moved from UTC+6 to UTC+5
-# The changes occurred on 2009-10-18 at 02:00 (local times).
-#
-# Government source: (Australian Antarctic Division)
-# <a href="http://www.aad.gov.au/default.asp?casid=37079">
-# http://www.aad.gov.au/default.asp?casid=37079
-# </a>
-#
-# We have more background information here:
-# <a href="http://www.timeanddate.com/news/time/antarctica-new-times.html">
-# http://www.timeanddate.com/news/time/antarctica-new-times.html
-# </a>
-
-# From Steffen Thorsen (2010-03-10):
-# We got these changes from the Australian Antarctic Division:
-# - Macquarie Island will stay on UTC+11 for winter and therefore not
-# switch back from daylight savings time when other parts of Australia do
-# on 4 April.
-#
-# - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
-# The change to UTC+11 is being considered as a regular summer thing but
-# has not been decided yet.
-#
-# - Davis station will revert to its normal time of UTC+7 at 10 March 2010
-# 20:00 UTC.
-#
-# - Mawson station stays on UTC+5.
-#
-# In addition to the Rule changes for Casey/Davis, it means that Macquarie
-# will no longer be like Hobart and will have to have its own Zone created.
-#
-# Background:
-# <a href="http://www.timeanddate.com/news/time/antartica-time-changes-2010.html">
-# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
-# </a>
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Casey	0	-	zzz	1969
-			8:00	-	WST	2009 Oct 18 2:00
-						# Western (Aus) Standard Time
-			11:00	-	CAST	2010 Mar 5 2:00
-						# Casey Time
-			8:00	-	WST
-Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
-			7:00	-	DAVT	1964 Nov # Davis Time
-			0	-	zzz	1969 Feb
-			7:00	-	DAVT	2009 Oct 18 2:00
-			5:00	-	DAVT	2010 Mar 10 20:00u
-			7:00	-	DAVT
-Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
-			6:00	-	MAWT	2009 Oct 18 2:00
-						# Mawson Time
-			5:00	-	MAWT
-Zone Antarctica/Macquarie 0	-	zzz	1911
-			10:00	-	EST	1916 Oct 1 2:00
-			10:00	1:00	EST	1917 Feb
-			10:00	AusAQ	EST	1967
-			10:00	ATAQ	EST	2010 Apr 4 3:00
-			11:00	-	MIST	# Macquarie Island Time
-# References:
-# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
-# Casey Weather (1998-02-26)
-# </a>
-# <a href="http://www.antdiv.gov.au/aad/exop/sfo/davis/video.html">
-# Davis Station, Antarctica (1998-02-26)
-# </a>
-# <a href="http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.html">
-# Mawson Station, Antarctica (1998-02-25)
-# </a>
-
-# Brazil - year-round base
-# Comandante Ferraz, King George Island, -6205+05824, since 1983/4
-
-# Chile - year-round bases and towns
-# Escudero, South Shetland Is, -621157-0585735, since 1994
-# Presidente Eduadro Frei, King George Island, -6214-05848, since 1969-03-07
-# General Bernardo O'Higgins, Antarctic Peninsula, -6319-05704, since 1948-02
-# Capitan Arturo Prat, -6230-05941
-# Villa Las Estrellas (a town), around the Frei base, since 1984-04-09
-# These locations have always used Santiago time; use TZ='America/Santiago'.
-
-# China - year-round bases
-# Great Wall, King George Island, -6213-05858, since 1985-02-20
-# Zhongshan, Larsemann Hills, Prydz Bay, -6922+07623, since 1989-02-26
-
-# France - year-round bases
-#
-# From Antoine Leca (1997-01-20):
-# Time data are from Nicole Pailleau at the IFRTP
-# (French Institute for Polar Research and Technology).
-# She confirms that French Southern Territories and Terre Adelie bases
-# don't observe daylight saving time, even if Terre Adelie supplies came
-# from Tasmania.
-#
-# French Southern Territories with year-round inhabitants
-#
-# Martin-de-Vivies Base, Amsterdam Island, -374105+0773155, since 1950
-# Alfred-Faure Base, Crozet Islands, -462551+0515152, since 1964
-# Port-aux-Francais, Kerguelen Islands, -492110+0701303, since 1951;
-#	whaling & sealing station operated 1908/1914, 1920/1929, and 1951/1956
-#
-# St Paul Island - near Amsterdam, uninhabited
-#	fishing stations operated variously 1819/1931
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Indian/Kerguelen	0	-	zzz	1950	# Port-aux-Francais
-			5:00	-	TFT	# ISO code TF Time
-#
-# year-round base in the main continent
-# Dumont-d'Urville, Ile des Petrels, -6640+14001, since 1956-11
-#
-# Another base at Port-Martin, 50km east, began operation in 1947.
-# It was destroyed by fire on 1952-01-14.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/DumontDUrville 0 -	zzz	1947
-			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
-			0	-	zzz	1956 Nov
-			10:00	-	DDUT	# Dumont-d'Urville Time
-# Reference:
-# <a href="http://en.wikipedia.org/wiki/Dumont_d'Urville_Station">
-# Dumont d'Urville Station (2005-12-05)
-# </a>
-
-# Germany - year-round base
-# Georg von Neumayer, -7039-00815
-
-# India - year-round base
-# Dakshin Gangotri, -7005+01200
-
-# Japan - year-round bases
-# Dome Fuji, -7719+03942
-# Syowa, -690022+0393524
-#
-# From Hideyuki Suzuki (1999-02-06):
-# In all Japanese stations, +0300 is used as the standard time.
-#
-# Syowa station, which is the first antarctic station of Japan,
-# was established on 1957-01-29.  Since Syowa station is still the main
-# station of Japan, it's appropriate for the principal location.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Syowa	0	-	zzz	1957 Jan 29
-			3:00	-	SYOT	# Syowa Time
-# See:
-# <a href="http://www.nipr.ac.jp/english/ara01.html">
-# NIPR Antarctic Research Activities (1999-08-17)
-# </a>
-
-# S Korea - year-round base
-# King Sejong, King George Island, -6213-05847, since 1988
-
-# New Zealand - claims
-# Balleny Islands (never inhabited)
-# Scott Island (never inhabited)
-#
-# year-round base
-# Scott, Ross Island, since 1957-01, is like Antarctica/McMurdo.
-#
-# These rules for New Zealand are stolen from the `australasia' file.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	NZAQ	1974	only	-	Nov	 3	2:00s	1:00	D
-Rule	NZAQ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
-Rule	NZAQ	1989	only	-	Oct	 8	2:00s	1:00	D
-Rule	NZAQ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
-Rule	NZAQ	1975	only	-	Feb	23	2:00s	0	S
-Rule	NZAQ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
-Rule	NZAQ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
-Rule	NZAQ	2007	max	-	Sep	lastSun	2:00s	1:00	D
-Rule	NZAQ	2008	max	-	Apr	Sun>=1	2:00s	0	S
-
-# Norway - territories
-# Bouvet (never inhabited)
-#
-# claims
-# Peter I Island (never inhabited)
-
-# Poland - year-round base
-# Arctowski, King George Island, -620945-0582745, since 1977
-
-# Russia - year-round bases
-# Bellingshausen, King George Island, -621159-0585337, since 1968-02-22
-# Mirny, Davis coast, -6633+09301, since 1956-02
-# Molodezhnaya, Alasheyev Bay, -6740+04551,
-#	year-round from 1962-02 to 1999-07-01
-# Novolazarevskaya, Queen Maud Land, -7046+01150,
-#	year-round from 1960/61 to 1992
-
-# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
-# <a href="http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP">
-# From Craig Mundell (1994-12-15)</a>:
-# Vostok, which is one of the Russian stations, is set on the same
-# time as Moscow, Russia.
-#
-# From Lee Hotz (2001-03-08):
-# I queried the folks at Columbia who spent the summer at Vostok and this is
-# what they had to say about time there:
-# ``in the US Camp (East Camp) we have been on New Zealand (McMurdo)
-# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
-# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
-# of GMT). This is a time zone I think two hours east of Moscow. The
-# natural time zone is in between the two: 8 hours ahead of GMT.''
-#
-# From Paul Eggert (2001-05-04):
-# This seems to be hopelessly confusing, so I asked Lee Hotz about it
-# in person.  He said that some Antartic locations set their local
-# time so that noon is the warmest part of the day, and that this
-# changes during the year and does not necessarily correspond to mean
-# solar noon.  So the Vostok time might have been whatever the clocks
-# happened to be during their visit.  So we still don't really know what time
-# it is at Vostok.  But we'll guess UTC+6.
-#
-Zone Antarctica/Vostok	0	-	zzz	1957 Dec 16
-			6:00	-	VOST	# Vostok time
-
-# S Africa - year-round bases
-# Marion Island, -4653+03752
-# Sanae, -7141-00250
-
-# UK
-#
-# British Antarctic Territories (BAT) claims
-# South Orkney Islands
-#	scientific station from 1903
-#	whaling station at Signy I 1920/1926
-# South Shetland Islands
-#
-# year-round bases
-# Bird Island, South Georgia, -5400-03803, since 1983
-# Deception Island, -6259-06034, whaling station 1912/1931,
-#	scientific station 1943/1967,
-#	previously sealers and a scientific expedition wintered by accident,
-#	and a garrison was deployed briefly
-# Halley, Coates Land, -7535-02604, since 1956-01-06
-#	Halley is on a moving ice shelf and is periodically relocated
-#	so that it is never more than 10km from its nominal location.
-# Rothera, Adelaide Island, -6734-6808, since 1976-12-01
-#
-# From Paul Eggert (2002-10-22)
-# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Rothera	0	-	zzz	1976 Dec  1
-			-3:00	-	ROTT	# Rothera time
-
-# Uruguay - year round base
-# Artigas, King George Island, -621104-0585107
-
-# USA - year-round bases
-#
-# Palmer, Anvers Island, since 1965 (moved 2 miles in 1968)
-#
-# From Ethan Dicks (1996-10-06):
-# It keeps the same time as Punta Arenas, Chile, because, just like us
-# and the South Pole, that's the other end of their supply line....
-# I verified with someone who was there that since 1980,
-# Palmer has followed Chile.  Prior to that, before the Falklands War,
-# Palmer used to be supplied from Argentina.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Palmer	0	-	zzz	1965
-			-4:00	ArgAQ	AR%sT	1969 Oct 5
-			-3:00	ArgAQ	AR%sT	1982 May
-			-4:00	ChileAQ	CL%sT
-#
-#
-# McMurdo, Ross Island, since 1955-12
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/McMurdo	0	-	zzz	1956
-			12:00	NZAQ	NZ%sT
-#
-# Amundsen-Scott, South Pole, continuously occupied since 1956-11-20
-#
-# From Paul Eggert (1996-09-03):
-# Normally it wouldn't have a separate entry, since it's like the
-# larger Antarctica/McMurdo since 1970, but it's too famous to omit.
-#
-# From Chris Carrier (1996-06-27):
-# Siple, the first commander of the South Pole station,
-# stated that he would have liked to have kept GMT at the station,
-# but that he found it more convenient to keep GMT+12
-# as supplies for the station were coming from McMurdo Sound,
-# which was on GMT+12 because New Zealand was on GMT+12 all year
-# at that time (1957).  (Source: Siple's book 90 degrees SOUTH.)
-#
-# From Susan Smith
-# http://www.cybertours.com/whs/pole10.html
-# (1995-11-13 16:24:56 +1300, no longer available):
-# We use the same time as McMurdo does.
-# And they use the same time as Christchurch, NZ does....
-# One last quirk about South Pole time.
-# All the electric clocks are usually wrong.
-# Something about the generators running at 60.1hertz or something
-# makes all of the clocks run fast.  So every couple of days,
-# we have to go around and set them back 5 minutes or so.
-# Maybe if we let them run fast all of the time, we'd get to leave here sooner!!
-#
-Link	Antarctica/McMurdo	Antarctica/South_Pole
diff --git a/tools/zoneinfo/tzdata2010k/asia b/tools/zoneinfo/tzdata2010k/asia
deleted file mode 100644
index 78ff2ff..0000000
--- a/tools/zoneinfo/tzdata2010k/asia
+++ /dev/null
@@ -1,2573 +0,0 @@
-# @(#)asia	8.60
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert (2006-03-22):
-#
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
-# San Diego: ACS Publications, Inc. (2003).
-#
-# Gwillim Law writes that a good source
-# for recent time zone data is the International Air Transport
-# Association's Standard Schedules Information Manual (IATA SSIM),
-# published semiannually.  Law sent in several helpful summaries
-# of the IATA's data after 1990.
-#
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1990, and IATA SSIM is the source for entries afterwards.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
-#
-# I invented the abbreviations marked `*' in the following table;
-# the rest are from earlier versions of this file, or from other sources.
-# Corrections are welcome!
-#	     std  dst
-#	     LMT	Local Mean Time
-#	2:00 EET  EEST	Eastern European Time
-#	2:00 IST  IDT	Israel
-#	3:00 AST  ADT	Arabia*
-#	3:30 IRST IRDT	Iran
-#	4:00 GST	Gulf*
-#	5:30 IST	India
-#	7:00 ICT	Indochina*
-#	7:00 WIT	west Indonesia
-#	8:00 CIT	central Indonesia
-#	8:00 CST	China
-#	9:00 CJT	Central Japanese Time (1896/1937)*
-#	9:00 EIT	east Indonesia
-#	9:00 JST  JDT	Japan
-#	9:00 KST  KDT	Korea
-#	9:30 CST	(Australian) Central Standard Time
-#
-# See the `europe' file for Russia and Turkey in Asia.
-
-# From Guy Harris:
-# Incorporates data for Singapore from Robert Elz' asia 1.1, as well as
-# additional information from Tom Yap, Sun Microsystems Intercontinental
-# Technical Support (including a page from the Official Airline Guide -
-# Worldwide Edition).  The names for time zones are guesses.
-
-###############################################################################
-
-# These rules are stolen from the `europe' file.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	EUAsia	1981	max	-	Mar	lastSun	 1:00u	1:00	S
-Rule	EUAsia	1979	1995	-	Sep	lastSun	 1:00u	0	-
-Rule	EUAsia	1996	max	-	Oct	lastSun	 1:00u	0	-
-Rule E-EurAsia	1981	max	-	Mar	lastSun	 0:00	1:00	S
-Rule E-EurAsia	1979	1995	-	Sep	lastSun	 0:00	0	-
-Rule E-EurAsia	1996	max	-	Oct	lastSun	 0:00	0	-
-Rule RussiaAsia	1981	1984	-	Apr	1	 0:00	1:00	S
-Rule RussiaAsia	1981	1983	-	Oct	1	 0:00	0	-
-Rule RussiaAsia	1984	1991	-	Sep	lastSun	 2:00s	0	-
-Rule RussiaAsia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
-Rule RussiaAsia	1992	only	-	Mar	lastSat	23:00	1:00	S
-Rule RussiaAsia	1992	only	-	Sep	lastSat	23:00	0	-
-Rule RussiaAsia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
-Rule RussiaAsia	1993	1995	-	Sep	lastSun	 2:00s	0	-
-Rule RussiaAsia	1996	max	-	Oct	lastSun	 2:00s	0	-
-
-# Afghanistan
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Kabul	4:36:48 -	LMT	1890
-			4:00	-	AFT	1945
-			4:30	-	AFT
-
-# Armenia
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger have Yerevan switching to 3:00 (with Russian DST)
-# in spring 1991, then to 4:00 with no DST in fall 1995, then
-# readopting Russian DST in 1997.  Go with Shanks & Pottenger, even
-# when they disagree with others.  Edgar Der-Danieliantz
-# reported (1996-05-04) that Yerevan probably wouldn't use DST
-# in 1996, though it did use DST in 1995.  IATA SSIM (1991/1998) reports that
-# Armenia switched from 3:00 to 4:00 in 1998 and observed DST after 1991,
-# but started switching at 3:00s in 1998.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Yerevan	2:58:00 -	LMT	1924 May  2
-			3:00	-	YERT	1957 Mar    # Yerevan Time
-			4:00 RussiaAsia YER%sT	1991 Mar 31 2:00s
-			3:00	1:00	YERST	1991 Sep 23 # independence
-			3:00 RussiaAsia	AM%sT	1995 Sep 24 2:00s
-			4:00	-	AMT	1997
-			4:00 RussiaAsia	AM%sT
-
-# Azerbaijan
-# From Rustam Aliyev of the Azerbaijan Internet Forum (2005-10-23):
-# According to the resolution of Cabinet of Ministers, 1997
-# Resolution available at: http://aif.az/docs/daylight_res.pdf
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Azer	1997	max	-	Mar	lastSun	 4:00	1:00	S
-Rule	Azer	1997	max	-	Oct	lastSun	 5:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
-			3:00	-	BAKT	1957 Mar    # Baku Time
-			4:00 RussiaAsia BAK%sT	1991 Mar 31 2:00s
-			3:00	1:00	BAKST	1991 Aug 30 # independence
-			3:00 RussiaAsia	AZ%sT	1992 Sep lastSat 23:00
-			4:00	-	AZT	1996 # Azerbaijan time
-			4:00	EUAsia	AZ%sT	1997
-			4:00	Azer	AZ%sT
-
-# Bahrain
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
-			4:00	-	GST	1972 Jun
-			3:00	-	AST
-
-# Bangladesh
-# From Alexander Krivenyshev (2009-05-13):
-# According to newspaper Asian Tribune (May 6, 2009) Bangladesh may introduce
-# Daylight Saving Time from June 16 to Sept 30
-#
-# Bangladesh to introduce daylight saving time likely from June 16
-# <a href="http://www.asiantribune.com/?q=node/17288">
-# http://www.asiantribune.com/?q=node/17288
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh02.html">
-# http://www.worldtimezone.com/dst_news/dst_news_bangladesh02.html
-# </a>
-#
-# "... Bangladesh government has decided to switch daylight saving time from
-# June
-# 16 till September 30 in a bid to ensure maximum use of daylight to cope with
-# crippling power crisis. "
-#
-# The switch will remain in effect from June 16 to Sept 30 (2009) but if
-# implemented the next year, it will come in force from April 1, 2010
-
-# From Steffen Thorsen (2009-06-02):
-# They have finally decided now, but changed the start date to midnight between
-# the 19th and 20th, and they have not set the end date yet.
-#
-# Some sources:
-# <a href="http://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601">
-# http://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601
-# </a>
-# <a href="http://bdnews24.com/details.php?id=85889&cid=2">
-# http://bdnews24.com/details.php?id=85889&cid=2
-# </a>
-#
-# Our wrap-up:
-# <a href="http://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html">
-# http://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html
-# </a>
-
-# From A. N. M. Kamrus Saadat (2009-06-15):
-# Finally we've got the official mail regarding DST start time where DST start 
-# time is mentioned as Jun 19 2009, 23:00 from BTRC (Bangladesh 
-# Telecommunication Regulatory Commission). 
-#
-# No DST end date has been announced yet.
-
-# From Alexander Krivenyshev (2009-09-25):
-# Bangladesh won't go back to Standard Time from October 1, 2009, 
-# instead it will continue DST measure till the cabinet makes a fresh decision. 
-#
-# Following report by same newspaper-"The Daily Star Friday":
-# "DST change awaits cabinet decision-Clock won't go back by 1-hr from Oct 1"
-# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=107021">
-# http://www.thedailystar.net/newDesign/news-details.php?nid=107021
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html">
-# http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html
-# </a>
-
-# From Steffen Thorsen (2009-10-13):
-# IANS (Indo-Asian News Service) now reports:
-# Bangladesh has decided that the clock advanced by an hour to make 
-# maximum use of daylight hours as an energy saving measure would 
-# "continue for an indefinite period."
-#
-# One of many places where it is published:
-# <a href="http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html">
-# http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
-# </a>
-
-# From Alexander Krivenyshev (2009-12-24):
-# According to Bangladesh newspaper "The Daily Star,"
-# Bangladesh will change its clock back to Standard Time on Dec 31, 2009.
-#
-# Clock goes back 1-hr on Dec 31 night.
-# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=119228">
-# http://www.thedailystar.net/newDesign/news-details.php?nid=119228
-# </a>
-# and
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh05.html">
-# http://www.worldtimezone.com/dst_news/dst_news_bangladesh05.html
-# </a>
-#
-# "...The government yesterday decided to put the clock back by one hour
-# on December 31 midnight and the new time will continue until March 31,
-# 2010 midnight. The decision came at a cabinet meeting at the Prime
-# Minister's Office last night..."
-
-# From Alexander Krivenyshev (2010-03-22):
-# According to Bangladesh newspaper "The Daily Star,"
-# Cabinet cancels Daylight Saving Time 
-# <a href="http://www.thedailystar.net/newDesign/latest_news.php?nid=22817">
-# http://www.thedailystar.net/newDesign/latest_news.php?nid=22817
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html">
-# http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html
-# </a>
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Dhaka	2009	only	-	Jun	19	23:00	1:00	S
-Rule	Dhaka	2009	only	-	Dec	31	23:59	0	-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Dhaka	6:01:40 -	LMT	1890
-			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
-			6:30	-	BURT	1942 May 15 # Burma Time
-			5:30	-	IST	1942 Sep
-			6:30	-	BURT	1951 Sep 30
-			6:00	-	DACT	1971 Mar 26 # Dacca Time
-			6:00	-	BDT	2009
-			6:00	Dhaka	BD%sT
-
-# Bhutan
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Thimphu	5:58:36 -	LMT	1947 Aug 15 # or Thimbu
-			5:30	-	IST	1987 Oct
-			6:00	-	BTT	# Bhutan Time
-
-# British Indian Ocean Territory
-# Whitman and the 1995 CIA time zone map say 5:00, but the
-# 1997 and later maps say 6:00.  Assume the switch occurred in 1996.
-# We have no information as to when standard time was introduced;
-# assume it occurred in 1907, the same year as Mauritius (which
-# then contained the Chagos Archipelago).
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Indian/Chagos	4:49:40	-	LMT	1907
-			5:00	-	IOT	1996 # BIOT Time
-			6:00	-	IOT
-
-# Brunei
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Brunei	7:39:40 -	LMT	1926 Mar   # Bandar Seri Begawan
-			7:30	-	BNT	1933
-			8:00	-	BNT
-
-# Burma / Myanmar
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Rangoon	6:24:40 -	LMT	1880		# or Yangon
-			6:24:36	-	RMT	1920	   # Rangoon Mean Time?
-			6:30	-	BURT	1942 May   # Burma Time
-			9:00	-	JST	1945 May 3
-			6:30	-	MMT		   # Myanmar Time
-
-# Cambodia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Phnom_Penh	6:59:40 -	LMT	1906 Jun  9
-			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
-			7:00	-	ICT	1912 May
-			8:00	-	ICT	1931 May
-			7:00	-	ICT
-
-# China
-
-# From Guy Harris:
-# People's Republic of China.  Yes, they really have only one time zone.
-
-# From Bob Devine (1988-01-28):
-# No they don't.  See TIME mag, 1986-02-17 p.52.  Even though
-# China is across 4 physical time zones, before Feb 1, 1986 only the
-# Peking (Bejing) time zone was recognized.  Since that date, China
-# has two of 'em -- Peking's and Urumqi (named after the capital of
-# the Xinjiang Uyghur Autonomous Region).  I don't know about DST for it.
-#
-# . . .I just deleted the DST table and this editor makes it too
-# painful to suck in another copy..  So, here is what I have for
-# DST start/end dates for Peking's time zone (info from AP):
-#
-#     1986 May 4 - Sept 14
-#     1987 mid-April - ??
-
-# From U. S. Naval Observatory (1989-01-19):
-# CHINA               8 H  AHEAD OF UTC  ALL OF CHINA, INCL TAIWAN
-# CHINA               9 H  AHEAD OF UTC  APR 17 - SEP 10
-
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger write that China (except for Hong Kong and Macau)
-# has had a single time zone since 1980 May 1, observing summer DST
-# from 1986 through 1991; this contradicts Devine's
-# note about Time magazine, though apparently _something_ happened in 1986.
-# Go with Shanks & Pottenger for now.  I made up names for the other
-# pre-1980 time zones.
-
-# From Shanks & Pottenger:
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Shang	1940	only	-	Jun	 3	0:00	1:00	D
-Rule	Shang	1940	1941	-	Oct	 1	0:00	0	S
-Rule	Shang	1941	only	-	Mar	16	0:00	1:00	D
-Rule	PRC	1986	only	-	May	 4	0:00	1:00	D
-Rule	PRC	1986	1991	-	Sep	Sun>=11	0:00	0	S
-Rule	PRC	1987	1991	-	Apr	Sun>=10	0:00	1:00	D
-
-# From Anthony Fok (2001-12-20):
-# BTW, I did some research on-line and found some info regarding these five
-# historic timezones from some Taiwan websites.  And yes, there are official
-# Chinese names for these locales (before 1949).
-#
-# From Jesper Norgaard Welen (2006-07-14):
-# I have investigated the timezones around 1970 on the
-# http://www.astro.com/atlas site [with provinces and county
-# boundaries summarized below]....  A few other exceptions were two
-# counties on the Sichuan side of the Xizang-Sichuan border,
-# counties Dege and Baiyu which lies on the Sichuan side and are
-# therefore supposed to be GMT+7, Xizang region being GMT+6, but Dege
-# county is GMT+8 according to astro.com while Baiyu county is GMT+6
-# (could be true), for the moment I am assuming that those two
-# counties are mistakes in the astro.com data.
-
-# From Paul Eggert (2008-02-11):
-# I just now checked Google News for western news sources that talk
-# about China's single time zone, and couldn't find anything before 1986
-# talking about China being in one time zone.  (That article was: Jim
-# Mann, "A clumsy embrace for another western custom: China on daylight
-# time--sort of", Los Angeles Times, 1986-05-05.  By the way, this
-# article confirms the tz database's data claiming that China began
-# observing daylight saving time in 1986.
-#
-# From Thomas S. Mullaney (2008-02-11):
-# I think you're combining two subjects that need to treated 
-# separately: daylight savings (which, you're correct, wasn't 
-# implemented until the 1980s) and the unified time zone centered near 
-# Beijing (which was implemented in 1949). Briefly, there was also a 
-# "Lhasa Time" in Tibet and "Urumqi Time" in Xinjiang. The first was 
-# ceased, and the second eventually recognized (again, in the 1980s).
-#
-# From Paul Eggert (2008-06-30):
-# There seems to be a good chance China switched to a single time zone in 1949
-# rather than in 1980 as Shanks & Pottenger have it, but we don't have a
-# reliable documentary source saying so yet, so for now we still go with
-# Shanks & Pottenger.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# Changbai Time ("Long-white Time", Long-white = Heilongjiang area)
-# Heilongjiang (except Mohe county), Jilin
-Zone	Asia/Harbin	8:26:44	-	LMT	1928 # or Haerbin
-			8:30	-	CHAT	1932 Mar # Changbai Time
-			8:00	-	CST	1940
-			9:00	-	CHAT	1966 May
-			8:30	-	CHAT	1980 May
-			8:00	PRC	C%sT
-# Zhongyuan Time ("Central plain Time")
-# most of China
-Zone	Asia/Shanghai	8:05:52	-	LMT	1928
-			8:00	Shang	C%sT	1949
-			8:00	PRC	C%sT
-# Long-shu Time (probably due to Long and Shu being two names of that area)
-# Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
-# most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
-# counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
-# Yangchun, Yangjiang, Yu'nan, and Yunfu.
-Zone	Asia/Chongqing	7:06:20	-	LMT	1928 # or Chungking
-			7:00	-	LONT	1980 May # Long-shu Time
-			8:00	PRC	C%sT
-# Xin-zang Time ("Xinjiang-Tibet Time")
-# The Gansu counties Aksay, Anxi, Dunhuang, Subei; west Qinghai;
-# the Guangdong counties  Xuwen, Haikang, Suixi, Lianjiang,
-# Zhanjiang, Wuchuan, Huazhou, Gaozhou, Maoming, Dianbai, and Xinyi;
-# east Tibet, including Lhasa, Chamdo, Shigaise, Jimsar, Shawan and Hutubi;
-# east Xinjiang, including Urumqi, Turpan, Karamay, Korla, Minfeng, Jinghe,
-# Wusu, Qiemo, Xinyan, Wulanwusu, Jinghe, Yumin, Tacheng, Tuoli, Emin,
-# Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
-# Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
-Zone	Asia/Urumqi	5:50:20	-	LMT	1928 # or Urumchi
-			6:00	-	URUT	1980 May # Urumqi Time
-			8:00	PRC	C%sT
-# Kunlun Time
-# West Tibet, including Pulan, Aheqi, Shufu, Shule;
-# West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
-# Zhaosu, Tekesi, Gongliu, Chabuchaer, Huocheng, Bole, Pishan, Suiding,
-# and Yarkand.
-
-# From Luther Ma (2009-10-17):
-# Almost all (>99.9%) ethnic Chinese (properly ethnic Han) living in
-# Xinjiang use Chinese Standard Time. Some are aware of Xinjiang time,
-# but have no need of it. All planes, trains, and schools function on
-# what is called "Beijing time." When Han make an appointment in Chinese
-# they implicitly use Beijing time.
-#
-# On the other hand, ethnic Uyghurs, who make up about half the
-# population of Xinjiang, typically use "Xinjiang time" which is two
-# hours behind Beijing time, or UTC +0600. The government of the Xinjiang
-# Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as
-# local governments such as the Urumqi city government use both times in
-# publications, referring to what is popularly called Xinjiang time as
-# "Urumqi time." When Uyghurs make an appointment in the Uyghur language
-# they almost invariably use Xinjiang time.
-#
-# (Their ethnic Han compatriots would typically have no clue of its
-# widespread use, however, because so extremely few of them are fluent in
-# Uyghur, comparable to the number of Anglo-Americans fluent in Navajo.)
-#
-# (...As with the rest of China there was a brief interval ending in 1990
-# or 1991 when summer time was in use.  The confusion was severe, with
-# the province not having dual times but four times in use at the same
-# time. Some areas remained on standard Xinjiang time or Beijing time and
-# others moving their clocks ahead.)
-#
-# ...an example of an official website using of Urumqi time.
-#
-# The first few lines of the Google translation of
-# <a href="http://www.fjysgl.gov.cn/show.aspx?id=2379&cid=39">
-# http://www.fjysgl.gov.cn/show.aspx?id=2379&cid=39
-# </a>
-# (retrieved 2009-10-13)
-# > Urumqi fire seven people are missing the alleged losses of at least
-# > 500 million yuan
-# >
-# > (Reporter Dong Liu) the day before 20:20 or so (Urumqi Time 18:20),
-# > Urumqi City Department of International Plaza Luther Qiantang River
-# > burst fire. As of yesterday, 18:30, Urumqi City Fire officers and men
-# > have worked continuously for 22 hours...
-
-# From Luther Ma (2009-11-19):
-# With the risk of being redundant to previous answers these are the most common
-# English "transliterations" (w/o using non-English symbols):
-#
-# 1. Wulumuqi...
-# 2. Kashi...
-# 3. Urumqi...
-# 4. Kashgar...
-# ...
-# 5. It seems that Uyghurs in Urumqi has been using Xinjiang since at least the
-# 1960's. I know of one Han, now over 50, who grew up in the surrounding
-# countryside and used Xinjiang time as a child.
-#
-# 6. Likewise for Kashgar and the rest of south Xinjiang I don't know of any
-# start date for Xinjiang time.
-#
-# Without having access to local historical records, nor the ability to legally
-# publish them, I would go with October 1, 1949, when Xinjiang became the Uyghur
-# Autonomous Region under the PRC. (Before that Uyghurs, of course, would also
-# not be using Beijing time, but some local time.)
-
-Zone	Asia/Kashgar	5:03:56	-	LMT	1928 # or Kashi or Kaxgar
-			5:30	-	KAST	1940	 # Kashgar Time
-			5:00	-	KAST	1980 May
-			8:00	PRC	C%sT
-
-
-# From Lee Yiu Chung (2009-10-24):
-# I found there are some mistakes for the...DST rule for Hong
-# Kong. [According] to the DST record from Hong Kong Observatory (actually,
-# it is not [an] observatory, but the official meteorological agency of HK,
-# and also serves as the official timing agency), there are some missing
-# and incorrect rules. Although the exact switch over time is missing, I
-# think 3:30 is correct. The official DST record for Hong Kong can be
-# obtained from
-# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
-# http://www.hko.gov.hk/gts/time/Summertime.htm
-# </a>.
-
-# From Arthur David Olson (2009-10-28):
-# Here are the dates given at
-# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
-# http://www.hko.gov.hk/gts/time/Summertime.htm
-# </a>
-# as of 2009-10-28:
-# Year        Period
-# 1941        1 Apr to 30 Sep
-# 1942        Whole year 
-# 1943        Whole year
-# 1944        Whole year
-# 1945        Whole year
-# 1946        20 Apr to 1 Dec
-# 1947        13 Apr to 30 Dec
-# 1948        2 May to 31 Oct
-# 1949        3 Apr to 30 Oct
-# 1950        2 Apr to 29 Oct
-# 1951        1 Apr to 28 Oct
-# 1952        6 Apr to 25 Oct
-# 1953        5 Apr to 1 Nov
-# 1954        21 Mar to 31 Oct
-# 1955        20 Mar to 6 Nov
-# 1956        18 Mar to 4 Nov
-# 1957        24 Mar to 3 Nov
-# 1958        23 Mar to 2 Nov
-# 1959        22 Mar to 1 Nov
-# 1960        20 Mar to 6 Nov
-# 1961        19 Mar to 5 Nov
-# 1962        18 Mar to 4 Nov
-# 1963        24 Mar to 3 Nov
-# 1964        22 Mar to 1 Nov
-# 1965        18 Apr to 17 Oct
-# 1966        17 Apr to 16 Oct
-# 1967        16 Apr to 22 Oct
-# 1968        21 Apr to 20 Oct
-# 1969        20 Apr to 19 Oct
-# 1970        19 Apr to 18 Oct
-# 1971        18 Apr to 17 Oct
-# 1972        16 Apr to 22 Oct
-# 1973        22 Apr to 21 Oct
-# 1973/74     30 Dec 73 to 20 Oct 74
-# 1975        20 Apr to 19 Oct
-# 1976        18 Apr to 17 Oct
-# 1977        Nil
-# 1978        Nil
-# 1979        13 May to 21 Oct
-# 1980 to Now Nil
-# The page does not give start or end times of day.
-# The page does not give a start date for 1942.
-# The page does not givw an end date for 1945.
-# The Japanese occupation of Hong Kong began on 1941-12-25.
-# The Japanese surrender of Hong Kong was signed 1945-09-15.
-# For lack of anything better, use start of those days as the transition times.
-
-# Hong Kong (Xianggang)
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
-Rule	HK	1941	only	-	Sep	30	3:30	0	-
-Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
-Rule	HK	1946	only	-	Dec	1	3:30	0	-
-Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
-Rule	HK	1947	only	-	Dec	30	3:30	0	-
-Rule	HK	1948	only	-	May	2	3:30	1:00	S
-Rule	HK	1948	1951	-	Oct	lastSun	3:30	0	-
-Rule	HK	1952	only	-	Oct	25	3:30	0	-
-Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
-Rule	HK	1953	only	-	Nov	1	3:30	0	-
-Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
-Rule	HK	1954	only	-	Oct	31	3:30	0	-
-Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
-Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
-Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
-Rule	HK	1973	only	-	Dec	30	3:30	1:00	S
-Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
-Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
-			8:00	HK	HK%sT	1941 Dec 25
-			9:00	-	JST	1945 Sep 15
-			8:00	HK	HK%sT
-
-###############################################################################
-
-# Taiwan
-
-# Shanks & Pottenger write that Taiwan observed DST during 1945, when it
-# was still controlled by Japan.  This is hard to believe, but we don't
-# have any other information.
-
-# From smallufo (2010-04-03):
-# According to Taiwan's CWB,
-# <a href="http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm">
-# http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm
-# </a>
-# Taipei has DST in 1979 between July 1st and Sep 30.
-
-# From Arthur David Olson (2010-04-07):
-# Here's Google's translation of the table at the bottom of the "summert.htm" page:
-# Decade 	                                                    Name                      Start and end date
-# Republic of China 34 years to 40 years (AD 1945-1951 years) Summer Time               May 1 to September 30 
-# 41 years of the Republic of China (AD 1952)                 Daylight Saving Time      March 1 to October 31 
-# Republic of China 42 years to 43 years (AD 1953-1954 years) Daylight Saving Time      April 1 to October 31 
-# In the 44 years to 45 years (AD 1955-1956 years)            Daylight Saving Time      April 1 to September 30 
-# Republic of China 46 years to 48 years (AD 1957-1959)       Summer Time               April 1 to September 30 
-# Republic of China 49 years to 50 years (AD 1960-1961)       Summer Time               June 1 to September 30 
-# Republic of China 51 years to 62 years (AD 1962-1973 years) Stop Summer Time 
-# Republic of China 63 years to 64 years (1974-1975 AD)       Daylight Saving Time      April 1 to September 30 
-# Republic of China 65 years to 67 years (1976-1978 AD)       Stop Daylight Saving Time 
-# Republic of China 68 years (AD 1979)                        Daylight Saving Time      July 1 to September 30 
-# Republic of China since 69 years (AD 1980)                  Stop Daylight Saving Time
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Taiwan	1945	1951	-	May	1	0:00	1:00	D
-Rule	Taiwan	1945	1951	-	Oct	1	0:00	0	S
-Rule	Taiwan	1952	only	-	Mar	1	0:00	1:00	D
-Rule	Taiwan	1952	1954	-	Nov	1	0:00	0	S
-Rule	Taiwan	1953	1959	-	Apr	1	0:00	1:00	D
-Rule	Taiwan	1955	1961	-	Oct	1	0:00	0	S
-Rule	Taiwan	1960	1961	-	Jun	1	0:00	1:00	D
-Rule	Taiwan	1974	1975	-	Apr	1	0:00	1:00	D
-Rule	Taiwan	1974	1975	-	Oct	1	0:00	0	S
-Rule	Taiwan	1979	only	-	Jun	30	0:00	1:00	D
-Rule	Taiwan	1979	only	-	Sep	30	0:00	0	S
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Taipei	8:06:00 -	LMT	1896 # or Taibei or T'ai-pei
-			8:00	Taiwan	C%sT
-
-# Macau (Macao, Aomen)
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Macau	1961	1962	-	Mar	Sun>=16	3:30	1:00	S
-Rule	Macau	1961	1964	-	Nov	Sun>=1	3:30	0	-
-Rule	Macau	1963	only	-	Mar	Sun>=16	0:00	1:00	S
-Rule	Macau	1964	only	-	Mar	Sun>=16	3:30	1:00	S
-Rule	Macau	1965	only	-	Mar	Sun>=16	0:00	1:00	S
-Rule	Macau	1965	only	-	Oct	31	0:00	0	-
-Rule	Macau	1966	1971	-	Apr	Sun>=16	3:30	1:00	S
-Rule	Macau	1966	1971	-	Oct	Sun>=16	3:30	0	-
-Rule	Macau	1972	1974	-	Apr	Sun>=15	0:00	1:00	S
-Rule	Macau	1972	1973	-	Oct	Sun>=15	0:00	0	-
-Rule	Macau	1974	1977	-	Oct	Sun>=15	3:30	0	-
-Rule	Macau	1975	1977	-	Apr	Sun>=15	3:30	1:00	S
-Rule	Macau	1978	1980	-	Apr	Sun>=15	0:00	1:00	S
-Rule	Macau	1978	1980	-	Oct	Sun>=15	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Macau	7:34:20 -	LMT	1912
-			8:00	Macau	MO%sT	1999 Dec 20 # return to China
-			8:00	PRC	C%sT
-
-
-###############################################################################
-
-# Cyprus
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Cyprus	1975	only	-	Apr	13	0:00	1:00	S
-Rule	Cyprus	1975	only	-	Oct	12	0:00	0	-
-Rule	Cyprus	1976	only	-	May	15	0:00	1:00	S
-Rule	Cyprus	1976	only	-	Oct	11	0:00	0	-
-Rule	Cyprus	1977	1980	-	Apr	Sun>=1	0:00	1:00	S
-Rule	Cyprus	1977	only	-	Sep	25	0:00	0	-
-Rule	Cyprus	1978	only	-	Oct	2	0:00	0	-
-Rule	Cyprus	1979	1997	-	Sep	lastSun	0:00	0	-
-Rule	Cyprus	1981	1998	-	Mar	lastSun	0:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Nicosia	2:13:28 -	LMT	1921 Nov 14
-			2:00	Cyprus	EE%sT	1998 Sep
-			2:00	EUAsia	EE%sT
-# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
-
-# Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72.
-# However, for various reasons many users expect to find it under Europe.
-Link	Asia/Nicosia	Europe/Nicosia
-
-# Georgia
-# From Paul Eggert (1994-11-19):
-# Today's _Economist_ (p 60) reports that Georgia moved its clocks forward
-# an hour recently, due to a law proposed by Zurab Murvanidze,
-# an MP who went on a hunger strike for 11 days to force discussion about it!
-# We have no details, but we'll guess they didn't move the clocks back in fall.
-#
-# From Mathew Englander, quoting AP (1996-10-23 13:05-04):
-# Instead of putting back clocks at the end of October, Georgia
-# will stay on daylight savings time this winter to save energy,
-# President Eduard Shevardnadze decreed Wednesday.
-#
-# From the BBC via Joseph S. Myers (2004-06-27):
-#
-# Georgia moved closer to Western Europe on Sunday...  The former Soviet
-# republic has changed its time zone back to that of Moscow.  As a result it
-# is now just four hours ahead of Greenwich Mean Time, rather than five hours
-# ahead.  The switch was decreed by the pro-Western president of Georgia,
-# Mikhail Saakashvili, who said the change was partly prompted by the process
-# of integration into Europe.
-
-# From Teimuraz Abashidze (2005-11-07):
-# Government of Georgia ... decided to NOT CHANGE daylight savings time on
-# [Oct.] 30, as it was done before during last more than 10 years.
-# Currently, we are in fact GMT +4:00, as before 30 October it was GMT
-# +3:00.... The problem is, there is NO FORMAL LAW or governmental document
-# about it.  As far as I can find, I was told, that there is no document,
-# because we just DIDN'T ISSUE document about switching to winter time....
-# I don't know what can be done, especially knowing that some years ago our
-# DST rules where changed THREE TIMES during one month.
-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Tbilisi	2:59:16 -	LMT	1880
-			2:59:16	-	TBMT	1924 May  2 # Tbilisi Mean Time
-			3:00	-	TBIT	1957 Mar    # Tbilisi Time
-			4:00 RussiaAsia TBI%sT	1991 Mar 31 2:00s
-			3:00	1:00	TBIST	1991 Apr  9 # independence
-			3:00 RussiaAsia GE%sT	1992 # Georgia Time
-			3:00 E-EurAsia	GE%sT	1994 Sep lastSun
-			4:00 E-EurAsia	GE%sT	1996 Oct lastSun
-			4:00	1:00	GEST	1997 Mar lastSun
-			4:00 E-EurAsia	GE%sT	2004 Jun 27
-			3:00 RussiaAsia	GE%sT	2005 Mar lastSun 2:00
-			4:00	-	GET
-
-# East Timor
-
-# See Indonesia for the 1945 transition.
-
-# From Joao Carrascalao, brother of the former governor of East Timor, in
-# <a href="http://etan.org/et99c/december/26-31/30ETMAY.htm">
-# East Timor may be late for its millennium
-# </a> (1999-12-26/31):
-# Portugal tried to change the time forward in 1974 because the sun
-# rises too early but the suggestion raised a lot of problems with the
-# Timorese and I still don't think it would work today because it
-# conflicts with their way of life.
-
-# From Paul Eggert (2000-12-04):
-# We don't have any record of the above attempt.
-# Most likely our records are incomplete, but we have no better data.
-
-# <a href="http://www.hri.org/news/world/undh/last/00-08-16.undh.html">
-# From Manoel de Almeida e Silva, Deputy Spokesman for the UN Secretary-General
-# (2000-08-16)</a>:
-# The Cabinet of the East Timor Transition Administration decided
-# today to advance East Timor's time by one hour.  The time change,
-# which will be permanent, with no seasonal adjustment, will happen at
-# midnight on Saturday, September 16.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Dili	8:22:20 -	LMT	1912
-			8:00	-	TLT	1942 Feb 21 23:00 # E Timor Time
-			9:00	-	JST	1945 Sep 23
-			9:00	-	TLT	1976 May  3
-			8:00	-	CIT	2000 Sep 17 00:00
-			9:00	-	TLT
-
-# India
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Kolkata	5:53:28 -	LMT	1880	# Kolkata
-			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
-			6:30	-	BURT	1942 May 15 # Burma Time
-			5:30	-	IST	1942 Sep
-			5:30	1:00	IST	1945 Oct 15
-			5:30	-	IST
-# The following are like Asia/Kolkata:
-#	Andaman Is
-#	Lakshadweep (Laccadive, Minicoy and Amindivi Is)
-#	Nicobar Is
-
-# Indonesia
-#
-# From Gwillim Law (2001-05-28), overriding Shanks & Pottenger:
-# <http://www.sumatera-inc.com/go_to_invest/about_indonesia.asp#standtime>
-# says that Indonesia's time zones changed on 1988-01-01.  Looking at some
-# time zone maps, I think that must refer to Western Borneo (Kalimantan Barat
-# and Kalimantan Tengah) switching from UTC+8 to UTC+7.
-#
-# From Paul Eggert (2007-03-10):
-# Here is another correction to Shanks & Pottenger.
-# JohnTWB writes that Japanese forces did not surrender control in
-# Indonesia until 1945-09-01 00:00 at the earliest (in Jakarta) and
-# other formal surrender ceremonies were September 9, 11, and 13, plus
-# September 12 for the regional surrender to Mountbatten in Singapore.
-# These would be the earliest possible times for a change.
-# Regimes horaires pour le monde entier, by Henri Le Corre, (Editions
-# Traditionnelles, 1987, Paris) says that Java and Madura switched
-# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
-# (Hollandia).  For now, assume all Indonesian locations other than Jayapura
-# switched on 1945-09-23.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Asia/Jakarta	7:07:12 -	LMT	1867 Aug 10
-# Shanks & Pottenger say the next transition was at 1924 Jan 1 0:13,
-# but this must be a typo.
-			7:07:12	-	JMT	1923 Dec 31 23:47:12 # Jakarta
-			7:20	-	JAVT	1932 Nov	 # Java Time
-			7:30	-	WIT	1942 Mar 23
-			9:00	-	JST	1945 Sep 23
-			7:30	-	WIT	1948 May
-			8:00	-	WIT	1950 May
-			7:30	-	WIT	1964
-			7:00	-	WIT
-Zone Asia/Pontianak	7:17:20	-	LMT	1908 May
-			7:17:20	-	PMT	1932 Nov    # Pontianak MT
-			7:30	-	WIT	1942 Jan 29
-			9:00	-	JST	1945 Sep 23
-			7:30	-	WIT	1948 May
-			8:00	-	WIT	1950 May
-			7:30	-	WIT	1964
-			8:00	-	CIT	1988 Jan  1
-			7:00	-	WIT
-Zone Asia/Makassar	7:57:36 -	LMT	1920
-			7:57:36	-	MMT	1932 Nov    # Macassar MT
-			8:00	-	CIT	1942 Feb  9
-			9:00	-	JST	1945 Sep 23
-			8:00	-	CIT
-Zone Asia/Jayapura	9:22:48 -	LMT	1932 Nov
-			9:00	-	EIT	1944 Sep  1
-			9:30	-	CST	1964
-			9:00	-	EIT
-
-# Iran
-
-# From Roozbeh Pournader (2003-03-15):
-# This is an English translation of what I just found (originally in Persian).
-# The Gregorian dates in brackets are mine:
-#
-#	Official Newspaper No. 13548-1370/6/25 [1991-09-16]
-#	No. 16760/T233 H				1370/6/10 [1991-09-01]
-#
-#	The Rule About Change of the Official Time of the Country
-#
-#	The Board of Ministers, in the meeting dated 1370/5/23 [1991-08-14],
-#	based on the suggestion number 2221/D dated 1370/4/22 [1991-07-13]
-#	of the Country's Organization for Official and Employment Affairs,
-#	and referring to the law for equating the working hours of workers
-#	and officers in the whole country dated 1359/4/23 [1980-07-14], and
-#	for synchronizing the official times of the country, agreed that:
-#
-#	The official time of the country will should move forward one hour
-#	at the 24[:00] hours of the first day of Farvardin and should return
-#	to its previous state at the 24[:00] hours of the 30th day of
-#	Shahrivar.
-#
-#	First Deputy to the President - Hassan Habibi
-#
-# From personal experience, that agrees with what has been followed
-# for at least the last 5 years.  Before that, for a few years, the
-# date used was the first Thursday night of Farvardin and the last
-# Thursday night of Shahrivar, but I can't give exact dates....
-# I have also changed the abbreviations to what is considered correct
-# here in Iran, IRST for regular time and IRDT for daylight saving time.
-#
-# From Roozbeh Pournader (2005-04-05):
-# The text of the Iranian law, in effect since 1925, clearly mentions
-# that the true solar year is the measure, and there is no arithmetic
-# leap year calculation involved.  There has never been any serious
-# plan to change that law....
-#
-# From Paul Eggert (2006-03-22):
-# Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
-# I used Ed Reingold's cal-persia in GNU Emacs 21.2 to check Persian dates,
-# stopping after 2037 when 32-bit time_t's overflow.
-# That cal-persia used Birashk's approximation, which disagrees with the solar
-# calendar predictions for the year 2025, so I corrected those dates by hand.
-#
-# From Oscar van Vlijmen (2005-03-30), writing about future
-# discrepancies between cal-persia and the Iranian calendar:
-# For 2091 solar-longitude-after yields 2091-03-20 08:40:07.7 UT for
-# the vernal equinox and that gets so close to 12:00 some local
-# Iranian time that the definition of the correct location needs to be
-# known exactly, amongst other factors.  2157 is even closer:
-# 2157-03-20 08:37:15.5 UT.  But the Gregorian year 2025 should give
-# no interpretation problem whatsoever.  By the way, another instant
-# in the near future where there will be a discrepancy between
-# arithmetical and astronomical Iranian calendars will be in 2058:
-# vernal equinox on 2058-03-20 09:03:05.9 UT.  The Java version of
-# Reingold's/Dershowitz' calculator gives correctly the Gregorian date
-# 2058-03-21 for 1 Farvardin 1437 (astronomical).
-#
-# From Steffen Thorsen (2006-03-22):
-# Several of my users have reported that Iran will not observe DST anymore:
-# http://www.irna.ir/en/news/view/line-17/0603193812164948.htm
-#
-# From Reuters (2007-09-16), with a heads-up from Jesper Norgaard Welen:
-# ... the Guardian Council ... approved a law on Sunday to re-introduce
-# daylight saving time ...
-# http://uk.reuters.com/article/oilRpt/idUKBLA65048420070916
-#
-# From Roozbeh Pournader (2007-11-05):
-# This is quoted from Official Gazette of the Islamic Republic of
-# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24
-# [2007-10-16]. I am doing the best translation I can:...
-# The official time of the country will be moved forward for one hour
-# on the 24 hours of the first day of the month of Farvardin and will
-# be changed back to its previous state on the 24 hours of the
-# thirtieth day of Shahrivar.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Iran	1978	1980	-	Mar	21	0:00	1:00	D
-Rule	Iran	1978	only	-	Oct	21	0:00	0	S
-Rule	Iran	1979	only	-	Sep	19	0:00	0	S
-Rule	Iran	1980	only	-	Sep	23	0:00	0	S
-Rule	Iran	1991	only	-	May	 3	0:00	1:00	D
-Rule	Iran	1992	1995	-	Mar	22	0:00	1:00	D
-Rule	Iran	1991	1995	-	Sep	22	0:00	0	S
-Rule	Iran	1996	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	1996	only	-	Sep	21	0:00	0	S
-Rule	Iran	1997	1999	-	Mar	22	0:00	1:00	D
-Rule	Iran	1997	1999	-	Sep	22	0:00	0	S
-Rule	Iran	2000	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	2000	only	-	Sep	21	0:00	0	S
-Rule	Iran	2001	2003	-	Mar	22	0:00	1:00	D
-Rule	Iran	2001	2003	-	Sep	22	0:00	0	S
-Rule	Iran	2004	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	2004	only	-	Sep	21	0:00	0	S
-Rule	Iran	2005	only	-	Mar	22	0:00	1:00	D
-Rule	Iran	2005	only	-	Sep	22	0:00	0	S
-Rule	Iran	2008	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	2008	only	-	Sep	21	0:00	0	S
-Rule	Iran	2009	2011	-	Mar	22	0:00	1:00	D
-Rule	Iran	2009	2011	-	Sep	22	0:00	0	S
-Rule	Iran	2012	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	2012	only	-	Sep	21	0:00	0	S
-Rule	Iran	2013	2015	-	Mar	22	0:00	1:00	D
-Rule	Iran	2013	2015	-	Sep	22	0:00	0	S
-Rule	Iran	2016	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	2016	only	-	Sep	21	0:00	0	S
-Rule	Iran	2017	2019	-	Mar	22	0:00	1:00	D
-Rule	Iran	2017	2019	-	Sep	22	0:00	0	S
-Rule	Iran	2020	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	2020	only	-	Sep	21	0:00	0	S
-Rule	Iran	2021	2023	-	Mar	22	0:00	1:00	D
-Rule	Iran	2021	2023	-	Sep	22	0:00	0	S
-Rule	Iran	2024	only	-	Mar	21	0:00	1:00	D
-Rule	Iran	2024	only	-	Sep	21	0:00	0	S
-Rule	Iran	2025	2027	-	Mar	22	0:00	1:00	D
-Rule	Iran	2025	2027	-	Sep	22	0:00	0	S
-Rule	Iran	2028	2029	-	Mar	21	0:00	1:00	D
-Rule	Iran	2028	2029	-	Sep	21	0:00	0	S
-Rule	Iran	2030	2031	-	Mar	22	0:00	1:00	D
-Rule	Iran	2030	2031	-	Sep	22	0:00	0	S
-Rule	Iran	2032	2033	-	Mar	21	0:00	1:00	D
-Rule	Iran	2032	2033	-	Sep	21	0:00	0	S
-Rule	Iran	2034	2035	-	Mar	22	0:00	1:00	D
-Rule	Iran	2034	2035	-	Sep	22	0:00	0	S
-Rule	Iran	2036	2037	-	Mar	21	0:00	1:00	D
-Rule	Iran	2036	2037	-	Sep	21	0:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Tehran	3:25:44	-	LMT	1916
-			3:25:44	-	TMT	1946	# Tehran Mean Time
-			3:30	-	IRST	1977 Nov
-			4:00	Iran	IR%sT	1979
-			3:30	Iran	IR%sT
-
-
-# Iraq
-#
-# From Jonathan Lennox (2000-06-12):
-# An article in this week's Economist ("Inside the Saddam-free zone", p. 50 in
-# the U.S. edition) on the Iraqi Kurds contains a paragraph:
-# "The three northern provinces ... switched their clocks this spring and
-# are an hour ahead of Baghdad."
-#
-# But Rives McDow (2000-06-18) quotes a contact in Iraqi-Kurdistan as follows:
-# In the past, some Kurdish nationalists, as a protest to the Iraqi
-# Government, did not adhere to daylight saving time.  They referred
-# to daylight saving as Saddam time.  But, as of today, the time zone
-# in Iraqi-Kurdistan is on standard time with Baghdad, Iraq.
-#
-# So we'll ignore the Economist's claim.
-
-# From Steffen Thorsen (2008-03-10):
-# The cabinet in Iraq abolished DST last week, according to the following
-# news sources (in Arabic):
-# <a href="http://www.aljeeran.net/wesima_articles/news-20080305-98602.html">
-# http://www.aljeeran.net/wesima_articles/news-20080305-98602.html
-# </a>
-# <a href="http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10">
-# http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10
-# </a>
-#
-# We have published a short article in English about the change:
-# <a href="http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html">
-# http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html
-# </a>
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Iraq	1982	only	-	May	1	0:00	1:00	D
-Rule	Iraq	1982	1984	-	Oct	1	0:00	0	S
-Rule	Iraq	1983	only	-	Mar	31	0:00	1:00	D
-Rule	Iraq	1984	1985	-	Apr	1	0:00	1:00	D
-Rule	Iraq	1985	1990	-	Sep	lastSun	1:00s	0	S
-Rule	Iraq	1986	1990	-	Mar	lastSun	1:00s	1:00	D
-# IATA SSIM (1991/1996) says Apr 1 12:01am UTC; guess the `:01' is a typo.
-# Shanks & Pottenger say Iraq did not observe DST 1992/1997; ignore this.
-#
-Rule	Iraq	1991	2007	-	Apr	 1	3:00s	1:00	D
-Rule	Iraq	1991	2007	-	Oct	 1	3:00s	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Baghdad	2:57:40	-	LMT	1890
-			2:57:36	-	BMT	1918	    # Baghdad Mean Time?
-			3:00	-	AST	1982 May
-			3:00	Iraq	A%sT
-
-
-###############################################################################
-
-# Israel
-
-# From Ephraim Silverberg (2001-01-11):
-#
-# I coined "IST/IDT" circa 1988.  Until then there were three
-# different abbreviations in use:
-#
-# JST  Jerusalem Standard Time [Danny Braniss, Hebrew University]
-# IZT  Israel Zonal (sic) Time [Prof. Haim Papo, Technion]
-# EEST Eastern Europe Standard Time [used by almost everyone else]
-#
-# Since timezones should be called by country and not capital cities,
-# I ruled out JST.  As Israel is in Asia Minor and not Eastern Europe,
-# EEST was equally unacceptable.  Since "zonal" was not compatible with
-# any other timezone abbreviation, I felt that 'IST' was the way to go
-# and, indeed, it has received almost universal acceptance in timezone
-# settings in Israeli computers.
-#
-# In any case, I am happy to share timezone abbreviations with India,
-# high on my favorite-country list (and not only because my wife's
-# family is from India).
-
-# From Shanks & Pottenger:
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Zion	1940	only	-	Jun	 1	0:00	1:00	D
-Rule	Zion	1942	1944	-	Nov	 1	0:00	0	S
-Rule	Zion	1943	only	-	Apr	 1	2:00	1:00	D
-Rule	Zion	1944	only	-	Apr	 1	0:00	1:00	D
-Rule	Zion	1945	only	-	Apr	16	0:00	1:00	D
-Rule	Zion	1945	only	-	Nov	 1	2:00	0	S
-Rule	Zion	1946	only	-	Apr	16	2:00	1:00	D
-Rule	Zion	1946	only	-	Nov	 1	0:00	0	S
-Rule	Zion	1948	only	-	May	23	0:00	2:00	DD
-Rule	Zion	1948	only	-	Sep	 1	0:00	1:00	D
-Rule	Zion	1948	1949	-	Nov	 1	2:00	0	S
-Rule	Zion	1949	only	-	May	 1	0:00	1:00	D
-Rule	Zion	1950	only	-	Apr	16	0:00	1:00	D
-Rule	Zion	1950	only	-	Sep	15	3:00	0	S
-Rule	Zion	1951	only	-	Apr	 1	0:00	1:00	D
-Rule	Zion	1951	only	-	Nov	11	3:00	0	S
-Rule	Zion	1952	only	-	Apr	20	2:00	1:00	D
-Rule	Zion	1952	only	-	Oct	19	3:00	0	S
-Rule	Zion	1953	only	-	Apr	12	2:00	1:00	D
-Rule	Zion	1953	only	-	Sep	13	3:00	0	S
-Rule	Zion	1954	only	-	Jun	13	0:00	1:00	D
-Rule	Zion	1954	only	-	Sep	12	0:00	0	S
-Rule	Zion	1955	only	-	Jun	11	2:00	1:00	D
-Rule	Zion	1955	only	-	Sep	11	0:00	0	S
-Rule	Zion	1956	only	-	Jun	 3	0:00	1:00	D
-Rule	Zion	1956	only	-	Sep	30	3:00	0	S
-Rule	Zion	1957	only	-	Apr	29	2:00	1:00	D
-Rule	Zion	1957	only	-	Sep	22	0:00	0	S
-Rule	Zion	1974	only	-	Jul	 7	0:00	1:00	D
-Rule	Zion	1974	only	-	Oct	13	0:00	0	S
-Rule	Zion	1975	only	-	Apr	20	0:00	1:00	D
-Rule	Zion	1975	only	-	Aug	31	0:00	0	S
-Rule	Zion	1985	only	-	Apr	14	0:00	1:00	D
-Rule	Zion	1985	only	-	Sep	15	0:00	0	S
-Rule	Zion	1986	only	-	May	18	0:00	1:00	D
-Rule	Zion	1986	only	-	Sep	 7	0:00	0	S
-Rule	Zion	1987	only	-	Apr	15	0:00	1:00	D
-Rule	Zion	1987	only	-	Sep	13	0:00	0	S
-Rule	Zion	1988	only	-	Apr	 9	0:00	1:00	D
-Rule	Zion	1988	only	-	Sep	 3	0:00	0	S
-
-# From Ephraim Silverberg
-# (1997-03-04, 1998-03-16, 1998-12-28, 2000-01-17, 2000-07-25, 2004-12-22,
-# and 2005-02-17):
-
-# According to the Office of the Secretary General of the Ministry of
-# Interior, there is NO set rule for Daylight-Savings/Standard time changes.
-# One thing is entrenched in law, however: that there must be at least 150
-# days of daylight savings time annually.  From 1993-1998, the change to
-# daylight savings time was on a Friday morning from midnight IST to
-# 1 a.m IDT; up until 1998, the change back to standard time was on a
-# Saturday night from midnight daylight savings time to 11 p.m. standard
-# time.  1996 is an exception to this rule where the change back to standard
-# time took place on Sunday night instead of Saturday night to avoid
-# conflicts with the Jewish New Year.  In 1999, the change to
-# daylight savings time was still on a Friday morning but from
-# 2 a.m. IST to 3 a.m. IDT; furthermore, the change back to standard time
-# was also on a Friday morning from 2 a.m. IDT to 1 a.m. IST for
-# 1999 only.  In the year 2000, the change to daylight savings time was
-# similar to 1999, but although the change back will be on a Friday, it
-# will take place from 1 a.m. IDT to midnight IST.  Starting in 2001, all
-# changes to/from will take place at 1 a.m. old time, but now there is no
-# rule as to what day of the week it will take place in as the start date
-# (except in 2003) is the night after the Passover Seder (i.e. the eve
-# of the 16th of Nisan in the lunar Hebrew calendar) and the end date
-# (except in 2002) is three nights before Yom Kippur [Day of Atonement]
-# (the eve of the 7th of Tishrei in the lunar Hebrew calendar).
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Zion	1989	only	-	Apr	30	0:00	1:00	D
-Rule	Zion	1989	only	-	Sep	 3	0:00	0	S
-Rule	Zion	1990	only	-	Mar	25	0:00	1:00	D
-Rule	Zion	1990	only	-	Aug	26	0:00	0	S
-Rule	Zion	1991	only	-	Mar	24	0:00	1:00	D
-Rule	Zion	1991	only	-	Sep	 1	0:00	0	S
-Rule	Zion	1992	only	-	Mar	29	0:00	1:00	D
-Rule	Zion	1992	only	-	Sep	 6	0:00	0	S
-Rule	Zion	1993	only	-	Apr	 2	0:00	1:00	D
-Rule	Zion	1993	only	-	Sep	 5	0:00	0	S
-
-# The dates for 1994-1995 were obtained from Office of the Spokeswoman for the
-# Ministry of Interior, Jerusalem, Israel.  The spokeswoman can be reached by
-# calling the office directly at 972-2-6701447 or 972-2-6701448.
-
-# Rule	NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule	Zion	1994	only	-	Apr	 1	0:00	1:00	D
-Rule	Zion	1994	only	-	Aug	28	0:00	0	S
-Rule	Zion	1995	only	-	Mar	31	0:00	1:00	D
-Rule	Zion	1995	only	-	Sep	 3	0:00	0	S
-
-# The dates for 1996 were determined by the Minister of Interior of the
-# time, Haim Ramon.  The official announcement regarding 1996-1998
-# (with the dates for 1997-1998 no longer being relevant) can be viewed at:
-#
-#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/1996-1998.ramon.ps.gz
-#
-# The dates for 1997-1998 were altered by his successor, Rabbi Eli Suissa.
-#
-# The official announcements for the years 1997-1999 can be viewed at:
-#
-#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/YYYY.ps.gz
-#
-#       where YYYY is the relevant year.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Zion	1996	only	-	Mar	15	0:00	1:00	D
-Rule	Zion	1996	only	-	Sep	16	0:00	0	S
-Rule	Zion	1997	only	-	Mar	21	0:00	1:00	D
-Rule	Zion	1997	only	-	Sep	14	0:00	0	S
-Rule	Zion	1998	only	-	Mar	20	0:00	1:00	D
-Rule	Zion	1998	only	-	Sep	 6	0:00	0	S
-Rule	Zion	1999	only	-	Apr	 2	2:00	1:00	D
-Rule	Zion	1999	only	-	Sep	 3	2:00	0	S
-
-# The Knesset Interior Committee has changed the dates for 2000 for
-# the third time in just over a year and have set new dates for the
-# years 2001-2004 as well.
-#
-# The official announcement for the start date of 2000 can be viewed at:
-#
-#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-start.ps.gz
-#
-# The official announcement for the end date of 2000 and the dates
-# for the years 2001-2004 can be viewed at:
-#
-#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-2004.ps.gz
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Zion	2000	only	-	Apr	14	2:00	1:00	D
-Rule	Zion	2000	only	-	Oct	 6	1:00	0	S
-Rule	Zion	2001	only	-	Apr	 9	1:00	1:00	D
-Rule	Zion	2001	only	-	Sep	24	1:00	0	S
-Rule	Zion	2002	only	-	Mar	29	1:00	1:00	D
-Rule	Zion	2002	only	-	Oct	 7	1:00	0	S
-Rule	Zion	2003	only	-	Mar	28	1:00	1:00	D
-Rule	Zion	2003	only	-	Oct	 3	1:00	0	S
-Rule	Zion	2004	only	-	Apr	 7	1:00	1:00	D
-Rule	Zion	2004	only	-	Sep	22	1:00	0	S
-
-# The proposed law agreed upon by the Knesset Interior Committee on
-# 2005-02-14 is that, for 2005 and beyond, DST starts at 02:00 the
-# last Friday before April 2nd (i.e. the last Friday in March or April
-# 1st itself if it falls on a Friday) and ends at 02:00 on the Saturday
-# night _before_ the fast of Yom Kippur.
-#
-# Those who can read Hebrew can view the announcement at:
-#
-#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2005+beyond.ps
-
-# From Paul Eggert (2005-02-22):
-# I used Ephraim Silverberg's dst-israel.el program
-# <ftp://ftp.cs.huji.ac.il/pub/tz/software/dst-israel.el> (2005-02-20)
-# along with Ed Reingold's cal-hebrew in GNU Emacs 21.4,
-# to generate the transitions in this list.
-# (I replaced "lastFri" with "Fri>=26" by hand.)
-# The spring transitions below all correspond to the following Rule:
-#
-# Rule	Zion	2005	max	-	Mar	Fri>=26	2:00	1:00	D
-#
-# but older zic implementations (e.g., Solaris 8) do not support
-# "Fri>=26" to mean April 1 in years like 2005, so for now we list the
-# springtime transitions explicitly.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Zion	2005	only	-	Apr	 1	2:00	1:00	D
-Rule	Zion	2005	only	-	Oct	 9	2:00	0	S
-Rule	Zion	2006	2010	-	Mar	Fri>=26	2:00	1:00	D
-Rule	Zion	2006	only	-	Oct	 1	2:00	0	S
-Rule	Zion	2007	only	-	Sep	16	2:00	0	S
-Rule	Zion	2008	only	-	Oct	 5	2:00	0	S
-Rule	Zion	2009	only	-	Sep	27	2:00	0	S
-Rule	Zion	2010	only	-	Sep	12	2:00	0	S
-Rule	Zion	2011	only	-	Apr	 1	2:00	1:00	D
-Rule	Zion	2011	only	-	Oct	 2	2:00	0	S
-Rule	Zion	2012	2015	-	Mar	Fri>=26	2:00	1:00	D
-Rule	Zion	2012	only	-	Sep	23	2:00	0	S
-Rule	Zion	2013	only	-	Sep	 8	2:00	0	S
-Rule	Zion	2014	only	-	Sep	28	2:00	0	S
-Rule	Zion	2015	only	-	Sep	20	2:00	0	S
-Rule	Zion	2016	only	-	Apr	 1	2:00	1:00	D
-Rule	Zion	2016	only	-	Oct	 9	2:00	0	S
-Rule	Zion	2017	2021	-	Mar	Fri>=26	2:00	1:00	D
-Rule	Zion	2017	only	-	Sep	24	2:00	0	S
-Rule	Zion	2018	only	-	Sep	16	2:00	0	S
-Rule	Zion	2019	only	-	Oct	 6	2:00	0	S
-Rule	Zion	2020	only	-	Sep	27	2:00	0	S
-Rule	Zion	2021	only	-	Sep	12	2:00	0	S
-Rule	Zion	2022	only	-	Apr	 1	2:00	1:00	D
-Rule	Zion	2022	only	-	Oct	 2	2:00	0	S
-Rule	Zion	2023	2032	-	Mar	Fri>=26	2:00	1:00	D
-Rule	Zion	2023	only	-	Sep	24	2:00	0	S
-Rule	Zion	2024	only	-	Oct	 6	2:00	0	S
-Rule	Zion	2025	only	-	Sep	28	2:00	0	S
-Rule	Zion	2026	only	-	Sep	20	2:00	0	S
-Rule	Zion	2027	only	-	Oct	10	2:00	0	S
-Rule	Zion	2028	only	-	Sep	24	2:00	0	S
-Rule	Zion	2029	only	-	Sep	16	2:00	0	S
-Rule	Zion	2030	only	-	Oct	 6	2:00	0	S
-Rule	Zion	2031	only	-	Sep	21	2:00	0	S
-Rule	Zion	2032	only	-	Sep	12	2:00	0	S
-Rule	Zion	2033	only	-	Apr	 1	2:00	1:00	D
-Rule	Zion	2033	only	-	Oct	 2	2:00	0	S
-Rule	Zion	2034	2037	-	Mar	Fri>=26	2:00	1:00	D
-Rule	Zion	2034	only	-	Sep	17	2:00	0	S
-Rule	Zion	2035	only	-	Oct	 7	2:00	0	S
-Rule	Zion	2036	only	-	Sep	28	2:00	0	S
-Rule	Zion	2037	only	-	Sep	13	2:00	0	S
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Jerusalem	2:20:56 -	LMT	1880
-			2:20:40	-	JMT	1918	# Jerusalem Mean Time?
-			2:00	Zion	I%sT
-
-
-
-###############################################################################
-
-# Japan
-
-# `9:00' and `JST' is from Guy Harris.
-
-# From Paul Eggert (1995-03-06):
-# Today's _Asahi Evening News_ (page 4) reports that Japan had
-# daylight saving between 1948 and 1951, but ``the system was discontinued
-# because the public believed it would lead to longer working hours.''
-
-# From Mayumi Negishi in the 2005-08-10 Japan Times
-# <http://www.japantimes.co.jp/cgi-bin/getarticle.pl5?nn20050810f2.htm>:
-# Occupation authorities imposed daylight-saving time on Japan on
-# [1948-05-01]....  But lack of prior debate and the execution of
-# daylight-saving time just three days after the bill was passed generated
-# deep hatred of the concept....  The Diet unceremoniously passed a bill to
-# dump the unpopular system in October 1951, less than a month after the San
-# Francisco Peace Treaty was signed.  (A government poll in 1951 showed 53%
-# of the Japanese wanted to scrap daylight-saving time, as opposed to 30% who
-# wanted to keep it.)
-
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger write that DST in Japan during those years was as follows:
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Japan	1948	only	-	May	Sun>=1	2:00	1:00	D
-Rule	Japan	1948	1951	-	Sep	Sat>=8	2:00	0	S
-Rule	Japan	1949	only	-	Apr	Sun>=1	2:00	1:00	D
-Rule	Japan	1950	1951	-	May	Sun>=1	2:00	1:00	D
-# but the only locations using it (for birth certificates, presumably, since
-# their audience is astrologers) were US military bases.  For now, assume
-# that for most purposes daylight-saving time was observed; otherwise, what
-# would have been the point of the 1951 poll?
-
-# From Hideyuki Suzuki (1998-11-09):
-# 'Tokyo' usually stands for the former location of Tokyo Astronomical
-# Observatory: E 139 44' 40".90 (9h 18m 58s.727), N 35 39' 16".0.
-# This data is from 'Rika Nenpyou (Chronological Scientific Tables) 1996'
-# edited by National Astronomical Observatory of Japan....
-# JST (Japan Standard Time) has been used since 1888-01-01 00:00 (JST).
-# The law is enacted on 1886-07-07.
-
-# From Hideyuki Suzuki (1998-11-16):
-# The ordinance No. 51 (1886) established "standard time" in Japan,
-# which stands for the time on E 135 degree.
-# In the ordinance No. 167 (1895), "standard time" was renamed to "central
-# standard time".  And the same ordinance also established "western standard
-# time", which stands for the time on E 120 degree....  But "western standard
-# time" was abolished in the ordinance No. 529 (1937).  In the ordinance No.
-# 167, there is no mention regarding for what place western standard time is
-# standard....
-#
-# I wrote "ordinance" above, but I don't know how to translate.
-# In Japanese it's "chokurei", which means ordinance from emperor.
-
-# Shanks & Pottenger claim JST in use since 1896, and that a few
-# places (e.g. Ishigaki) use +0800; go with Suzuki.  Guess that all
-# ordinances took effect on Jan 1.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Tokyo	9:18:59	-	LMT	1887 Dec 31 15:00u
-			9:00	-	JST	1896
-			9:00	-	CJT	1938
-			9:00	Japan	J%sT
-# Since 1938, all Japanese possessions have been like Asia/Tokyo.
-
-# Jordan
-#
-# From <a href="http://star.arabia.com/990701/JO9.html">
-# Jordan Week (1999-07-01) </a> via Steffen Thorsen (1999-09-09):
-# Clocks in Jordan were forwarded one hour on Wednesday at midnight,
-# in accordance with the government's decision to implement summer time
-# all year round.
-#
-# From <a href="http://star.arabia.com/990930/JO9.html">
-# Jordan Week (1999-09-30) </a> via Steffen Thorsen (1999-11-09):
-# Winter time starts today Thursday, 30 September. Clocks will be turned back
-# by one hour.  This is the latest government decision and it's final!
-# The decision was taken because of the increase in working hours in
-# government's departments from six to seven hours.
-#
-# From Paul Eggert (2005-11-22):
-# Starting 2003 transitions are from Steffen Thorsen's web site timeanddate.com.
-#
-# From Steffen Thorsen (2005-11-23):
-# For Jordan I have received multiple independent user reports every year
-# about DST end dates, as the end-rule is different every year.
-#
-# From Steffen Thorsen (2006-10-01), after a heads-up from Hilal Malawi:
-# http://www.petranews.gov.jo/nepras/2006/Sep/05/4000.htm
-# "Jordan will switch to winter time on Friday, October 27".
-#
-
-# From Phil Pizzey (2009-04-02):
-# ...I think I may have spotted an error in the timezone data for
-# Jordan.
-# The current (2009d) asia file shows Jordan going to daylight
-# saving
-# time on the last Thursday in March.
-#
-# Rule  Jordan      2000  max	-  Mar   lastThu     0:00s 1:00  S
-#
-# However timeanddate.com, which I usually find reliable, shows Jordan
-# going to daylight saving time on the last Friday in March since 2002.
-# Please see
-# <a href="http://www.timeanddate.com/worldclock/timezone.html?n=11">
-# http://www.timeanddate.com/worldclock/timezone.html?n=11
-# </a>
-
-# From Steffen Thorsen (2009-04-02):
-# This single one might be good enough, (2009-03-24, Arabic):
-# <a href="http://petra.gov.jo/Artical.aspx?Lng=2&Section=8&Artical=95279">
-# http://petra.gov.jo/Artical.aspx?Lng=2&Section=8&Artical=95279
-# </a>
-#
-# Google's translation:
-#
-# > The Council of Ministers decided in 2002 to adopt the principle of timely
-# > submission of the summer at 60 minutes as of midnight on the last Thursday
-# > of the month of March of each year.
-#
-# So - this means the midnight between Thursday and Friday since 2002.
-
-# From Arthur David Olson (2009-04-06):
-# We still have Jordan switching to DST on Thursdays in 2000 and 2001.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Jordan	1973	only	-	Jun	6	0:00	1:00	S
-Rule	Jordan	1973	1975	-	Oct	1	0:00	0	-
-Rule	Jordan	1974	1977	-	May	1	0:00	1:00	S
-Rule	Jordan	1976	only	-	Nov	1	0:00	0	-
-Rule	Jordan	1977	only	-	Oct	1	0:00	0	-
-Rule	Jordan	1978	only	-	Apr	30	0:00	1:00	S
-Rule	Jordan	1978	only	-	Sep	30	0:00	0	-
-Rule	Jordan	1985	only	-	Apr	1	0:00	1:00	S
-Rule	Jordan	1985	only	-	Oct	1	0:00	0	-
-Rule	Jordan	1986	1988	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Jordan	1986	1990	-	Oct	Fri>=1	0:00	0	-
-Rule	Jordan	1989	only	-	May	8	0:00	1:00	S
-Rule	Jordan	1990	only	-	Apr	27	0:00	1:00	S
-Rule	Jordan	1991	only	-	Apr	17	0:00	1:00	S
-Rule	Jordan	1991	only	-	Sep	27	0:00	0	-
-Rule	Jordan	1992	only	-	Apr	10	0:00	1:00	S
-Rule	Jordan	1992	1993	-	Oct	Fri>=1	0:00	0	-
-Rule	Jordan	1993	1998	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Jordan	1994	only	-	Sep	Fri>=15	0:00	0	-
-Rule	Jordan	1995	1998	-	Sep	Fri>=15	0:00s	0	-
-Rule	Jordan	1999	only	-	Jul	 1	0:00s	1:00	S
-Rule	Jordan	1999	2002	-	Sep	lastFri	0:00s	0	-
-Rule	Jordan	2000	2001	-	Mar	lastThu	0:00s	1:00	S
-Rule	Jordan	2002	max	-	Mar	lastThu	24:00	1:00	S
-Rule	Jordan	2003	only	-	Oct	24	0:00s	0	-
-Rule	Jordan	2004	only	-	Oct	15	0:00s	0	-
-Rule	Jordan	2005	only	-	Sep	lastFri	0:00s	0	-
-Rule	Jordan	2006	max	-	Oct	lastFri	0:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Amman	2:23:44 -	LMT	1931
-			2:00	Jordan	EE%sT
-
-
-# Kazakhstan
-
-# From Paul Eggert (1996-11-22):
-# Andrew Evtichov (1996-04-13) writes that Kazakhstan
-# stayed in sync with Moscow after 1990, and that Aqtobe (formerly Aktyubinsk)
-# and Aqtau (formerly Shevchenko) are the largest cities in their zones.
-# Guess that Aqtau and Aqtobe diverged in 1995, since that's the first time
-# IATA SSIM mentions a third time zone in Kazakhstan.
-
-# From Paul Eggert (2006-03-22):
-# German Iofis, ELSI, Almaty (2001-10-09) reports that Kazakhstan uses
-# RussiaAsia rules, instead of switching at 00:00 as the IATA has it.
-# Go with Shanks & Pottenger, who have them always using RussiaAsia rules.
-# Also go with the following claims of Shanks & Pottenger:
-#
-# - Kazakhstan did not observe DST in 1991.
-# - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00.
-# - Oral switched from +5:00 to +4:00 in spring 1989.
-
-# <a href="http://www.kazsociety.org.uk/news/2005/03/30.htm">
-# From Kazakhstan Embassy's News Bulletin #11 (2005-03-21):
-# </a>
-# The Government of Kazakhstan passed a resolution March 15 abolishing
-# daylight saving time citing lack of economic benefits and health
-# complications coupled with a decrease in productivity.
-#
-# From Branislav Kojic (in Astana) via Gwillim Law (2005-06-28):
-# ... what happened was that the former Kazakhstan Eastern time zone
-# was "blended" with the Central zone.  Therefore, Kazakhstan now has
-# two time zones, and difference between them is one hour.  The zone
-# closer to UTC is the former Western zone (probably still called the
-# same), encompassing four provinces in the west: Aqtobe, Atyrau,
-# Mangghystau, and West Kazakhstan.  The other zone encompasses
-# everything else....  I guess that would make Kazakhstan time zones
-# de jure UTC+5 and UTC+6 respectively.
-
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-#
-# Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
-Zone	Asia/Almaty	5:07:48 -	LMT	1924 May  2 # or Alma-Ata
-			5:00	-	ALMT	1930 Jun 21 # Alma-Ata Time
-			6:00 RussiaAsia ALM%sT	1991
-			6:00	-	ALMT	1992
-			6:00 RussiaAsia	ALM%sT	2005 Mar 15
-			6:00	-	ALMT
-# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.)
-Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
-			4:00	-	KIZT	1930 Jun 21 # Kizilorda Time
-			5:00	-	KIZT	1981 Apr  1
-			5:00	1:00	KIZST	1981 Oct  1
-			6:00	-	KIZT	1982 Apr  1
-			5:00 RussiaAsia	KIZ%sT	1991
-			5:00	-	KIZT	1991 Dec 16 # independence
-			5:00	-	QYZT	1992 Jan 19 2:00
-			6:00 RussiaAsia	QYZ%sT	2005 Mar 15
-			6:00	-	QYZT
-# Aqtobe (aka Aktobe, formerly Akt'ubinsk)
-Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
-			4:00	-	AKTT	1930 Jun 21 # Aktyubinsk Time
-			5:00	-	AKTT	1981 Apr  1
-			5:00	1:00	AKTST	1981 Oct  1
-			6:00	-	AKTT	1982 Apr  1
-			5:00 RussiaAsia	AKT%sT	1991
-			5:00	-	AKTT	1991 Dec 16 # independence
-			5:00 RussiaAsia	AQT%sT	2005 Mar 15 # Aqtobe Time
-			5:00	-	AQTT
-# Mangghystau
-# Aqtau was not founded until 1963, but it represents an inhabited region,
-# so include time stamps before 1963.
-Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2
-			4:00	-	FORT	1930 Jun 21 # Fort Shevchenko T
-			5:00	-	FORT	1963
-			5:00	-	SHET	1981 Oct  1 # Shevchenko Time
-			6:00	-	SHET	1982 Apr  1
-			5:00 RussiaAsia	SHE%sT	1991
-			5:00	-	SHET	1991 Dec 16 # independence
-			5:00 RussiaAsia	AQT%sT	1995 Mar lastSun 2:00 # Aqtau Time
-			4:00 RussiaAsia	AQT%sT	2005 Mar 15
-			5:00	-	AQTT
-# West Kazakhstan
-Zone	Asia/Oral	3:25:24	-	LMT	1924 May  2 # or Ural'sk
-			4:00	-	URAT	1930 Jun 21 # Ural'sk time
-			5:00	-	URAT	1981 Apr  1
-			5:00	1:00	URAST	1981 Oct  1
-			6:00	-	URAT	1982 Apr  1
-			5:00 RussiaAsia	URA%sT	1989 Mar 26 2:00
-			4:00 RussiaAsia	URA%sT	1991
-			4:00	-	URAT	1991 Dec 16 # independence
-			4:00 RussiaAsia	ORA%sT	2005 Mar 15 # Oral Time
-			5:00	-	ORAT
-
-# Kyrgyzstan (Kirgizstan)
-# Transitions through 1991 are from Shanks & Pottenger.
-
-# From Paul Eggert (2005-08-15):
-# According to an article dated today in the Kyrgyzstan Development Gateway
-# <http://eng.gateway.kg/cgi-bin/page.pl?id=1&story_name=doc9979.shtml>
-# Kyrgyzstan is canceling the daylight saving time system.  I take the article
-# to mean that they will leave their clocks at 6 hours ahead of UTC.
-# From Malik Abdugaliev (2005-09-21):
-# Our government cancels daylight saving time 6th of August 2005.
-# From 2005-08-12 our GMT-offset is +6, w/o any daylight saving.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Kyrgyz	1992	1996	-	Apr	Sun>=7	0:00s	1:00	S
-Rule	Kyrgyz	1992	1996	-	Sep	lastSun	0:00	0	-
-Rule	Kyrgyz	1997	2005	-	Mar	lastSun	2:30	1:00	S
-Rule	Kyrgyz	1997	2004	-	Oct	lastSun	2:30	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
-			5:00	-	FRUT	1930 Jun 21 # Frunze Time
-			6:00 RussiaAsia FRU%sT	1991 Mar 31 2:00s
-			5:00	1:00	FRUST	1991 Aug 31 2:00 # independence
-			5:00	Kyrgyz	KG%sT	2005 Aug 12    # Kyrgyzstan Time
-			6:00	-	KGT
-
-###############################################################################
-
-# Korea (North and South)
-
-# From Annie I. Bang (2006-07-10) in
-# <http://www.koreaherald.co.kr/SITE/data/html_dir/2006/07/10/200607100012.asp>:
-# The Ministry of Commerce, Industry and Energy has already
-# commissioned a research project [to reintroduce DST] and has said
-# the system may begin as early as 2008....  Korea ran a daylight
-# saving program from 1949-61 but stopped it during the 1950-53 Korean War.
-
-# From Shanks & Pottenger:
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	ROK	1960	only	-	May	15	0:00	1:00	D
-Rule	ROK	1960	only	-	Sep	13	0:00	0	S
-Rule	ROK	1987	1988	-	May	Sun>=8	0:00	1:00	D
-Rule	ROK	1987	1988	-	Oct	Sun>=8	0:00	0	S
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Seoul	8:27:52	-	LMT	1890
-			8:30	-	KST	1904 Dec
-			9:00	-	KST	1928
-			8:30	-	KST	1932
-			9:00	-	KST	1954 Mar 21
-			8:00	ROK	K%sT	1961 Aug 10
-			8:30	-	KST	1968 Oct
-			9:00	ROK	K%sT
-Zone	Asia/Pyongyang	8:23:00 -	LMT	1890
-			8:30	-	KST	1904 Dec
-			9:00	-	KST	1928
-			8:30	-	KST	1932
-			9:00	-	KST	1954 Mar 21
-			8:00	-	KST	1961 Aug 10
-			9:00	-	KST
-
-###############################################################################
-
-# Kuwait
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# From the Arab Times (2007-03-14):
-# The Civil Service Commission (CSC) has approved a proposal forwarded
-# by MP Ahmad Baqer on implementing the daylight saving time (DST) in
-# Kuwait starting from April until the end of Sept this year, reports Al-Anba.
-# <http://www.arabtimesonline.com/arabtimes/kuwait/Viewdet.asp?ID=9950>.
-# From Paul Eggert (2007-03-29):
-# We don't know the details, or whether the approval means it'll happen,
-# so for now we assume no DST.
-Zone	Asia/Kuwait	3:11:56 -	LMT	1950
-			3:00	-	AST
-
-# Laos
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Vientiane	6:50:24 -	LMT	1906 Jun  9 # or Viangchan
-			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
-			7:00	-	ICT	1912 May
-			8:00	-	ICT	1931 May
-			7:00	-	ICT
-
-# Lebanon
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Lebanon	1920	only	-	Mar	28	0:00	1:00	S
-Rule	Lebanon	1920	only	-	Oct	25	0:00	0	-
-Rule	Lebanon	1921	only	-	Apr	3	0:00	1:00	S
-Rule	Lebanon	1921	only	-	Oct	3	0:00	0	-
-Rule	Lebanon	1922	only	-	Mar	26	0:00	1:00	S
-Rule	Lebanon	1922	only	-	Oct	8	0:00	0	-
-Rule	Lebanon	1923	only	-	Apr	22	0:00	1:00	S
-Rule	Lebanon	1923	only	-	Sep	16	0:00	0	-
-Rule	Lebanon	1957	1961	-	May	1	0:00	1:00	S
-Rule	Lebanon	1957	1961	-	Oct	1	0:00	0	-
-Rule	Lebanon	1972	only	-	Jun	22	0:00	1:00	S
-Rule	Lebanon	1972	1977	-	Oct	1	0:00	0	-
-Rule	Lebanon	1973	1977	-	May	1	0:00	1:00	S
-Rule	Lebanon	1978	only	-	Apr	30	0:00	1:00	S
-Rule	Lebanon	1978	only	-	Sep	30	0:00	0	-
-Rule	Lebanon	1984	1987	-	May	1	0:00	1:00	S
-Rule	Lebanon	1984	1991	-	Oct	16	0:00	0	-
-Rule	Lebanon	1988	only	-	Jun	1	0:00	1:00	S
-Rule	Lebanon	1989	only	-	May	10	0:00	1:00	S
-Rule	Lebanon	1990	1992	-	May	1	0:00	1:00	S
-Rule	Lebanon	1992	only	-	Oct	4	0:00	0	-
-Rule	Lebanon	1993	max	-	Mar	lastSun	0:00	1:00	S
-Rule	Lebanon	1993	1998	-	Sep	lastSun	0:00	0	-
-Rule	Lebanon	1999	max	-	Oct	lastSun	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Beirut	2:22:00 -	LMT	1880
-			2:00	Lebanon	EE%sT
-
-# Malaysia
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	NBorneo	1935	1941	-	Sep	14	0:00	0:20	TS # one-Third Summer
-Rule	NBorneo	1935	1941	-	Dec	14	0:00	0	-
-#
-# peninsular Malaysia
-# The data here are taken from Mok Ly Yng (2003-10-30)
-# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Asia/Kuala_Lumpur	6:46:46 -	LMT	1901 Jan  1
-			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
-			7:00	-	MALT	1933 Jan  1 # Malaya Time
-			7:00	0:20	MALST	1936 Jan  1
-			7:20	-	MALT	1941 Sep  1
-			7:30	-	MALT	1942 Feb 16
-			9:00	-	JST	1945 Sep 12
-			7:30	-	MALT	1982 Jan  1
-			8:00	-	MYT	# Malaysia Time
-# Sabah & Sarawak
-# From Paul Eggert (2006-03-22):
-# The data here are mostly from Shanks & Pottenger, but the 1942, 1945 and 1982
-# transition dates are from Mok Ly Yng.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Asia/Kuching	7:21:20	-	LMT	1926 Mar
-			7:30	-	BORT	1933	# Borneo Time
-			8:00	NBorneo	BOR%sT	1942 Feb 16
-			9:00	-	JST	1945 Sep 12
-			8:00	-	BORT	1982 Jan  1
-			8:00	-	MYT
-
-# Maldives
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Indian/Maldives	4:54:00 -	LMT	1880	# Male
-			4:54:00	-	MMT	1960	# Male Mean Time
-			5:00	-	MVT		# Maldives Time
-
-# Mongolia
-
-# Shanks & Pottenger say that Mongolia has three time zones, but
-# usno1995 and the CIA map Standard Time Zones of the World (2005-03)
-# both say that it has just one.
-
-# From Oscar van Vlijmen (1999-12-11):
-# <a href="http://www.mongoliatourism.gov.mn/general.htm">
-# General Information Mongolia
-# </a> (1999-09)
-# "Time: Mongolia has two time zones. Three westernmost provinces of
-# Bayan-Ulgii, Uvs, and Hovd are one hour earlier than the capital city, and
-# the rest of the country follows the Ulaanbaatar time, which is UTC/GMT plus
-# eight hours."
-
-# From Rives McDow (1999-12-13):
-# Mongolia discontinued the use of daylight savings time in 1999; 1998
-# being the last year it was implemented.  The dates of implementation I am
-# unsure of, but most probably it was similar to Russia, except for the time
-# of implementation may have been different....
-# Some maps in the past have indicated that there was an additional time
-# zone in the eastern part of Mongolia, including the provinces of Dornod,
-# Suhbaatar, and possibly Khentij.
-
-# From Paul Eggert (1999-12-15):
-# Naming and spelling is tricky in Mongolia.
-# We'll use Hovd (also spelled Chovd and Khovd) to represent the west zone;
-# the capital of the Hovd province is sometimes called Hovd, sometimes Dund-Us,
-# and sometimes Jirgalanta (with variant spellings), but the name Hovd
-# is good enough for our purposes.
-
-# From Rives McDow (2001-05-13):
-# In addition to Mongolia starting daylight savings as reported earlier
-# (adopted DST on 2001-04-27 02:00 local time, ending 2001-09-28),
-# there are three time zones.
-#
-# Provinces [at 7:00]: Bayan-ulgii, Uvs, Khovd, Zavkhan, Govi-Altai
-# Provinces [at 8:00]: Khovsgol, Bulgan, Arkhangai, Khentii, Tov,
-#	Bayankhongor, Ovorkhangai, Dundgovi, Dornogovi, Omnogovi
-# Provinces [at 9:00]: Dornod, Sukhbaatar
-#
-# [The province of Selenge is omitted from the above lists.]
-
-# From Ganbold Ts., Ulaanbaatar (2004-04-17):
-# Daylight saving occurs at 02:00 local time last Saturday of March.
-# It will change back to normal at 02:00 local time last Saturday of
-# September.... As I remember this rule was changed in 2001.
-#
-# From Paul Eggert (2004-04-17):
-# For now, assume Rives McDow's informant got confused about Friday vs
-# Saturday, and that his 2001 dates should have 1 added to them.
-
-# From Paul Eggert (2005-07-26):
-# We have wildly conflicting information about Mongolia's time zones.
-# Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
-# there is only one time zone and that DST is observed, citing Microsoft
-# Windows XP as the source.  Risto Nykanen (2005-05-16) reports that
-# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
-# Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
-# Washington, DC says there are two time zones, with DST observed.
-# He also found
-# <http://ubpost.mongolnews.mn/index.php?subaction=showcomments&id=1111634894&archive=&start_from=&ucat=1&>
-# which also says that there is DST, and which has a comment by "Toddius"
-# (2005-03-31 06:05 +0700) saying "Mongolia actually has 3.5 time zones.
-# The West (OLGII) is +7 GMT, most of the country is ULAT is +8 GMT
-# and some Eastern provinces are +9 GMT but Sukhbaatar Aimag is SUHK +8.5 GMT.
-# The SUKH timezone is new this year, it is one of the few things the
-# parliament passed during the tumultuous winter session."
-# For now, let's ignore this information, until we have more confirmation.
-
-# From Ganbold Ts. (2007-02-26):
-# Parliament of Mongolia has just changed the daylight-saving rule in February.
-# They decided not to adopt daylight-saving time....
-# http://www.mongolnews.mn/index.php?module=unuudur&sec=view&id=15742
-
-# From Deborah Goldsmith (2008-03-30):
-# We received a bug report claiming that the tz database UTC offset for
-# Asia/Choibalsan (GMT+09:00) is incorrect, and that it should be GMT
-# +08:00 instead. Different sources appear to disagree with the tz
-# database on this, e.g.:
-#
-# <a href="http://www.timeanddate.com/worldclock/city.html?n=1026">
-# http://www.timeanddate.com/worldclock/city.html?n=1026
-# </a>
-# <a href="http://www.worldtimeserver.com/current_time_in_MN.aspx">
-# http://www.worldtimeserver.com/current_time_in_MN.aspx
-# </a>
-#
-# both say GMT+08:00.
-
-# From Steffen Thorsen (2008-03-31):
-# eznis airways, which operates several domestic flights, has a flight
-# schedule here:
-# <a href="http://www.eznis.com/Container.jsp?id=112">
-# http://www.eznis.com/Container.jsp?id=112
-# </a>
-# (click the English flag for English)
-#
-# There it appears that flights between Choibalsan and Ulaanbatar arrive
-# about 1:35 - 1:50 hours later in local clock time, no matter the
-# direction, while Ulaanbaatar-Khvod takes 2 hours in the Eastern
-# direction and 3:35 back, which indicates that Ulaanbatar and Khvod are
-# in different time zones (like we know about), while Choibalsan and
-# Ulaanbatar are in the same time zone (correction needed).
-
-# From Arthur David Olson (2008-05-19):
-# Assume that Choibalsan is indeed offset by 8:00.
-# XXX--in the absence of better information, assume that transition
-# was at the start of 2008-03-31 (the day of Steffen Thorsen's report);
-# this is almost surely wrong.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Mongol	1983	1984	-	Apr	1	0:00	1:00	S
-Rule	Mongol	1983	only	-	Oct	1	0:00	0	-
-# Shanks & Pottenger and IATA SSIM say 1990s switches occurred at 00:00,
-# but McDow says the 2001 switches occurred at 02:00.  Also, IATA SSIM
-# (1996-09) says 1996-10-25.  Go with Shanks & Pottenger through 1998.
-#
-# Shanks & Pottenger say that the Sept. 1984 through Sept. 1990 switches
-# in Choibalsan (more precisely, in Dornod and Sukhbaatar) took place
-# at 02:00 standard time, not at 00:00 local time as in the rest of
-# the country.  That would be odd, and possibly is a result of their
-# correction of 02:00 (in the previous edition) not being done correctly
-# in the latest edition; so ignore it for now.
-
-Rule	Mongol	1985	1998	-	Mar	lastSun	0:00	1:00	S
-Rule	Mongol	1984	1998	-	Sep	lastSun	0:00	0	-
-# IATA SSIM (1999-09) says Mongolia no longer observes DST.
-Rule	Mongol	2001	only	-	Apr	lastSat	2:00	1:00	S
-Rule	Mongol	2001	2006	-	Sep	lastSat	2:00	0	-
-Rule	Mongol	2002	2006	-	Mar	lastSat	2:00	1:00	S
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# Hovd, a.k.a. Chovd, Dund-Us, Dzhargalant, Khovd, Jirgalanta
-Zone	Asia/Hovd	6:06:36 -	LMT	1905 Aug
-			6:00	-	HOVT	1978	# Hovd Time
-			7:00	Mongol	HOV%sT
-# Ulaanbaatar, a.k.a. Ulan Bataar, Ulan Bator, Urga
-Zone	Asia/Ulaanbaatar 7:07:32 -	LMT	1905 Aug
-			7:00	-	ULAT	1978	# Ulaanbaatar Time
-			8:00	Mongol	ULA%sT
-# Choibalsan, a.k.a. Bajan Tuemen, Bajan Tumen, Chojbalsan,
-# Choybalsan, Sanbejse, Tchoibalsan
-Zone	Asia/Choibalsan	7:38:00 -	LMT	1905 Aug
-			7:00	-	ULAT	1978
-			8:00	-	ULAT	1983 Apr
-			9:00	Mongol	CHO%sT	2008 Mar 31 # Choibalsan Time
-			8:00	Mongol	CHO%sT
-
-# Nepal
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Kathmandu	5:41:16 -	LMT	1920
-			5:30	-	IST	1986
-			5:45	-	NPT	# Nepal Time
-
-# Oman
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Muscat	3:54:20 -	LMT	1920
-			4:00	-	GST
-
-# Pakistan
-
-# From Rives McDow (2002-03-13):
-# I have been advised that Pakistan has decided to adopt dst on a
-# TRIAL basis for one year, starting 00:01 local time on April 7, 2002
-# and ending at 00:01 local time October 6, 2002.  This is what I was
-# told, but I believe that the actual time of change may be 00:00; the
-# 00:01 was to make it clear which day it was on.
-
-# From Paul Eggert (2002-03-15):
-# Jesper Norgaard found this URL:
-# http://www.pak.gov.pk/public/news/app/app06_dec.htm
-# (dated 2001-12-06) which says that the Cabinet adopted a scheme "to
-# advance the clocks by one hour on the night between the first
-# Saturday and Sunday of April and revert to the original position on
-# 15th October each year".  This agrees with McDow's 04-07 at 00:00,
-# but disagrees about the October transition, and makes it sound like
-# it's not on a trial basis.  Also, the "between the first Saturday
-# and Sunday of April" phrase, if taken literally, means that the
-# transition takes place at 00:00 on the first Sunday on or after 04-02.
-
-# From Paul Eggert (2003-02-09):
-# DAWN <http://www.dawn.com/2002/10/06/top13.htm> reported on 2002-10-05
-# that 2002 DST ended that day at midnight.  Go with McDow for now.
-
-# From Steffen Thorsen (2003-03-14):
-# According to http://www.dawn.com/2003/03/07/top15.htm
-# there will be no DST in Pakistan this year:
-#
-# ISLAMABAD, March 6: Information and Media Development Minister Sheikh
-# Rashid Ahmed on Thursday said the cabinet had reversed a previous
-# decision to advance clocks by one hour in summer and put them back by
-# one hour in winter with the aim of saving light hours and energy.
-#
-# The minister told a news conference that the experiment had rather
-# shown 8 per cent higher consumption of electricity.
-
-# From Alex Krivenyshev (2008-05-15):
-# 
-# Here is an article that Pakistan plan to introduce Daylight Saving Time 
-# on June 1, 2008 for 3 months.
-# 
-# "... The federal cabinet on Wednesday announced a new conservation plan to help 
-# reduce load shedding by approving the closure of commercial centres at 9pm and 
-# moving clocks forward by one hour for the next three months. 
-# ...."
-# 
-# <a href="http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html">
-# http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html
-# </a>
-# OR
-# <a href="http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4">
-# http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4
-# </a>
-
-# From Arthur David Olson (2008-05-19):
-# XXX--midnight transitions is a guess; 2008 only is a guess.
-
-# From Alexander Krivenyshev (2008-08-28):
-# Pakistan government has decided to keep the watches one-hour advanced
-# for another 2 months--plan to return to Standard Time on October 31
-# instead of August 31.
-#
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html">
-# http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html
-# </a>
-# OR
-# <a href="http://dailymailnews.com/200808/28/news/dmbrn03.html">
-# http://dailymailnews.com/200808/28/news/dmbrn03.html
-# </a>
-
-# From Alexander Krivenyshev (2009-04-08):
-# Based on previous media reports that "... proposed plan to
-# advance clocks by one hour from May 1 will cause disturbance
-# to the working schedules rather than bringing discipline in
-# official working."
-# <a href="http://www.thenews.com.pk/daily_detail.asp?id=171280">
-# http://www.thenews.com.pk/daily_detail.asp?id=171280
-# </a>
-#
-# recent news that instead of May 2009 - Pakistan plan to
-# introduce DST from April 15, 2009
-#
-# FYI: Associated Press Of Pakistan
-# April 08, 2009
-# Cabinet okays proposal to advance clocks by one hour from April 15
-# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=73043&Itemid=1">
-# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=73043&Itemid=1
-# </a>
-#
-# or
-#
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan05.html">
-# http://www.worldtimezone.com/dst_news/dst_news_pakistan05.html
-# </a>
-#
-# ....
-# The Federal Cabinet on Wednesday approved the proposal to
-# advance clocks in the country by one hour from April 15 to
-# conserve energy"
-
-# From Steffen Thorsen (2009-09-17):
-# "The News International," Pakistan reports that: "The Federal
-# Government has decided to restore the previous time by moving the
-# clocks backward by one hour from October 1. A formal announcement to
-# this effect will be made after the Prime Minister grants approval in
-# this regard." 
-# <a href="http://www.thenews.com.pk/updates.asp?id=87168">
-# http://www.thenews.com.pk/updates.asp?id=87168
-# </a>
-
-# From Alexander Krivenyshev (2009-09-28):
-# According to Associated Press Of Pakistan, it is confirmed that
-# Pakistan clocks across the country would be turned back by an hour from October
-# 1, 2009.
-#
-# "Clocks to go back one hour from 1 Oct"
-# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2">
-# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm">
-# http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm
-# </a>
-
-# From Steffen Thorsen (2009-09-29):
-# Alexander Krivenyshev wrote:
-# > According to Associated Press Of Pakistan, it is confirmed that
-# > Pakistan clocks across the country would be turned back by an hour from October
-# > 1, 2009.
-#
-# Now they seem to have changed their mind, November 1 is the new date:
-# <a href="http://www.thenews.com.pk/top_story_detail.asp?Id=24742">
-# http://www.thenews.com.pk/top_story_detail.asp?Id=24742
-# </a>
-# "The country's clocks will be reversed by one hour on November 1.
-# Officials of Federal Ministry for Interior told this to Geo News on
-# Monday."
-#
-# And more importantly, it seems that these dates will be kept every year:
-# "It has now been decided that clocks will be wound forward by one hour
-# on April 15 and reversed by an hour on November 1 every year without
-# obtaining prior approval, the officials added."
-#
-# We have confirmed this year's end date with both with the Ministry of
-# Water and Power and the Pakistan Electric Power Company:
-# <a href="http://www.timeanddate.com/news/time/pakistan-ends-dst09.html">
-# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html
-# </a>
-
-# From Christoph Goehre (2009-10-01):
-# [T]he German Consulate General in Karachi reported me today that Pakistan
-# will go back to standard time on 1st of November.
-
-# From Steffen Thorsen (2010-03-26):
-# Steffen Thorsen wrote:
-# > On Thursday (2010-03-25) it was announced that DST would start in
-# > Pakistan on 2010-04-01.
-# >
-# > Then today, the president said that they might have to revert the
-# > decision if it is not supported by the parliament. So at the time
-# > being, it seems unclear if DST will be actually observed or not - but
-# > April 1 could be a more likely date than April 15.
-# Now, it seems that the decision to not observe DST in final:
-#
-# "Govt Withdraws Plan To Advance Clocks"
-# <a href="http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041">
-# http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041
-# </a>
-#
-# "People laud PM's announcement to end DST"
-# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2">
-# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2
-# </a>
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
-Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
-Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
-Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
-Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
-Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Karachi	4:28:12 -	LMT	1907
-			5:30	-	IST	1942 Sep
-			5:30	1:00	IST	1945 Oct 15
-			5:30	-	IST	1951 Sep 30
-			5:00	-	KART	1971 Mar 26 # Karachi Time
-			5:00 Pakistan	PK%sT	# Pakistan Time
-
-# Palestine
-
-# From Amos Shapir (1998-02-15):
-#
-# From 1917 until 1948-05-15, all of Palestine, including the parts now
-# known as the Gaza Strip and the West Bank, was under British rule.
-# Therefore the rules given for Israel for that period, apply there too...
-#
-# The Gaza Strip was under Egyptian rule between 1948-05-15 until 1967-06-05
-# (except a short occupation by Israel from 1956-11 till 1957-03, but no
-# time zone was affected then).  It was never formally annexed to Egypt,
-# though.
-#
-# The rest of Palestine was under Jordanian rule at that time, formally
-# annexed in 1950 as the West Bank (and the word "Trans" was dropped from
-# the country's previous name of "the Hashemite Kingdom of the
-# Trans-Jordan").  So the rules for Jordan for that time apply.  Major
-# towns in that area are Nablus (Shchem), El-Halil (Hebron), Ramallah, and
-# East Jerusalem.
-#
-# Both areas were occupied by Israel in June 1967, but not annexed (except
-# for East Jerusalem).  They were on Israel time since then; there might
-# have been a Military Governor's order about time zones, but I'm not aware
-# of any (such orders may have been issued semi-annually whenever summer
-# time was in effect, but maybe the legal aspect of time was just neglected).
-#
-# The Palestinian Authority was established in 1993, and got hold of most
-# towns in the West Bank and Gaza by 1995.  I know that in order to
-# demonstrate...independence, they have been switching to
-# summer time and back on a different schedule than Israel's, but I don't
-# know when this was started, or what algorithm is used (most likely the
-# Jordanian one).
-#
-# To summarize, the table should probably look something like that:
-#
-# Area \ when | 1918-1947 | 1948-1967 | 1967-1995 | 1996-
-# ------------+-----------+-----------+-----------+-----------
-# Israel      | Zion      | Zion      | Zion      | Zion
-# West bank   | Zion      | Jordan    | Zion      | Jordan
-# Gaza        | Zion      | Egypt     | Zion      | Jordan
-#
-# I guess more info may be available from the PA's web page (if/when they
-# have one).
-
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger write that Gaza did not observe DST until 1957, but go
-# with Shapir and assume that it observed DST from 1940 through 1947,
-# and that it used Jordanian rules starting in 1996.
-# We don't yet need a separate entry for the West Bank, since
-# the only differences between it and Gaza that we know about
-# occurred before our cutoff date of 1970.
-# However, as we get more information, we may need to add entries
-# for parts of the West Bank as they transitioned from Israel's rules
-# to Palestine's rules.  If you have more info about this, please
-# send it to tz@elsie.nci.nih.gov for incorporation into future editions.
-
-# From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
-# forwarded by Ephraim Silverberg:
-#
-# Despite the fact that Israel changed over to daylight savings time
-# last week, the PLO Authority (PA) has decided not to turn its clocks
-# one-hour forward at this time.  As a sign of independence from Israeli rule,
-# the PA has decided to implement DST in April.
-
-# From Paul Eggert (1999-09-20):
-# Daoud Kuttab writes in
-# <a href="http://www.jpost.com/com/Archive/22.Apr.1999/Opinion/Article-2.html">
-# Holiday havoc
-# </a> (Jerusalem Post, 1999-04-22) that
-# the Palestinian National Authority changed to DST on 1999-04-15.
-# I vaguely recall that they switch back in October (sorry, forgot the source).
-# For now, let's assume that the spring switch was at 24:00,
-# and that they switch at 0:00 on the 3rd Fridays of April and October.
-
-# From Paul Eggert (2005-11-22):
-# Starting 2004 transitions are from Steffen Thorsen's web site timeanddate.com.
-
-# From Steffen Thorsen (2005-11-23):
-# A user from Gaza reported that Gaza made the change early because of
-# the Ramadan.  Next year Ramadan will be even earlier, so I think
-# there is a good chance next year's end date will be around two weeks
-# earlier--the same goes for Jordan.
-
-# From Steffen Thorsen (2006-08-17):
-# I was informed by a user in Bethlehem that in Bethlehem it started the
-# same day as Israel, and after checking with other users in the area, I
-# was informed that they started DST one day after Israel.  I was not
-# able to find any authoritative sources at the time, nor details if
-# Gaza changed as well, but presumed Gaza to follow the same rules as
-# the West Bank.
-
-# From Steffen Thorsen (2006-09-26):
-# according to the Palestine News Network (2006-09-19):
-# http://english.pnn.ps/index.php?option=com_content&task=view&id=596&Itemid=5
-# > The Council of Ministers announced that this year its winter schedule
-# > will begin early, as of midnight Thursday.  It is also time to turn
-# > back the clocks for winter.  Friday will begin an hour late this week.
-# I guess it is likely that next year's date will be moved as well,
-# because of the Ramadan.
-
-# From Jesper Norgaard Welen (2007-09-18):
-# According to Steffen Thorsen's web site the Gaza Strip and the rest of the
-# Palestinian territories left DST early on 13.th. of September at 2:00.
-
-# From Paul Eggert (2007-09-20):
-# My understanding is that Gaza and the West Bank disagree even over when
-# the weekend is (Thursday+Friday versus Friday+Saturday), so I'd be a bit
-# surprised if they agreed about DST.  But for now, assume they agree.
-# For lack of better information, predict that future changes will be
-# the 2nd Thursday of September at 02:00.
-
-# From Alexander Krivenyshev (2008-08-28):
-# Here is an article, that Mideast running on different clocks at Ramadan.
-#
-# Gaza Strip (as Egypt) ended DST at midnight Thursday (Aug 28, 2008), while
-# the West Bank will end Daylight Saving Time at midnight Sunday (Aug 31, 2008).
-#
-# <a href="http://www.guardian.co.uk/world/feedarticle/7759001">
-# http://www.guardian.co.uk/world/feedarticle/7759001
-# </a>
-# <a href="http://www.abcnews.go.com/International/wireStory?id=5676087">
-# http://www.abcnews.go.com/International/wireStory?id=5676087
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html">
-# http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html
-# </a>
-
-# From Alexander Krivenyshev (2009-03-26):
-# According to the Palestine News Network (arabic.pnn.ps), Palestinian
-# government decided to start Daylight Time on Thursday night March
-# 26 and continue until the night of 27 September 2009.
-#
-# (in Arabic)
-# <a href="http://arabic.pnn.ps/index.php?option=com_content&task=view&id=50850">
-# http://arabic.pnn.ps/index.php?option=com_content&task=view&id=50850
-# </a>
-#
-# or
-# (English translation)
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank01.html">
-# http://www.worldtimezone.com/dst_news/dst_news_westbank01.html
-# </a>
-
-# From Steffen Thorsen (2009-08-31):
-# Palestine's Council of Ministers announced that they will revert back to
-# winter time on Friday, 2009-09-04.
-#
-# One news source:
-# <a href="http://www.safa.ps/ara/?action=showdetail&seid=4158">
-# http://www.safa.ps/ara/?action=showdetail&seid=4158
-# </a>
-# (Palestinian press agency, Arabic),
-# Google translate: "Decided that the Palestinian government in Ramallah
-# headed by Salam Fayyad, the start of work in time for the winter of
-# 2009, starting on Friday approved the fourth delay Sept. clock sixty
-# minutes per hour as of Friday morning."
-#
-# We are not sure if Gaza will do the same, last year they had a different
-# end date, we will keep this page updated:
-# <a href="http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html">
-# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
-# </a>
-
-# From Alexander Krivenyshev (2009-09-02):
-# Seems that Gaza Strip will go back to Winter Time same date as West Bank.
-#
-# According to Palestinian Ministry Of Interior, West Bank and Gaza Strip plan
-# to change time back to Standard time on September 4, 2009.
-#
-# "Winter time unite the West Bank and Gaza"
-# (from Palestinian National Authority):
-# <a href="http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
-# http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html>
-# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
-# </a>
-
-# From Alexander Krivenyshev (2010-03-19):
-# According to Voice of Palestine DST will last for 191 days, from March
-# 26, 2010 till "the last Sunday before the tenth day of Tishri
-# (October), each year" (October 03, 2010?)
-#
-# <a href="http://palvoice.org/forums/showthread.php?t=245697">
-# http://palvoice.org/forums/showthread.php?t=245697
-# </a>
-# (in Arabic)
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank03.html">
-# http://www.worldtimezone.com/dst_news/dst_news_westbank03.html
-# </a>
-
-# From Steffen Thorsen (2010-03-24):
-# ...Ma'an News Agency reports that Hamas cabinet has decided it will
-# start one day later, at 12:01am. Not sure if they really mean 12:01am or
-# noon though:
-#
-# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=271178">
-# http://www.maannews.net/eng/ViewDetails.aspx?ID=271178
-# </a>
-# (Ma'an News Agency)
-# "At 12:01am Friday, clocks in Israel and the West Bank will change to
-# 1:01am, while Gaza clocks will change at 12:01am Saturday morning."
-
-# The rules for Egypt are stolen from the `africa' file.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
-Rule EgyptAsia	1957	1958	-	Oct	 1	0:00	0	-
-Rule EgyptAsia	1958	only	-	May	 1	0:00	1:00	S
-Rule EgyptAsia	1959	1967	-	May	 1	1:00	1:00	S
-Rule EgyptAsia	1959	1965	-	Sep	30	3:00	0	-
-Rule EgyptAsia	1966	only	-	Oct	 1	3:00	0	-
-
-Rule Palestine	1999	2005	-	Apr	Fri>=15	0:00	1:00	S
-Rule Palestine	1999	2003	-	Oct	Fri>=15	0:00	0	-
-Rule Palestine	2004	only	-	Oct	 1	1:00	0	-
-Rule Palestine	2005	only	-	Oct	 4	2:00	0	-
-Rule Palestine	2006	2008	-	Apr	 1	0:00	1:00	S
-Rule Palestine	2006	only	-	Sep	22	0:00	0	-
-Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
-Rule Palestine	2008	only	-	Aug	lastFri	2:00	0	-
-Rule Palestine	2009	only	-	Mar	lastFri	0:00	1:00	S
-Rule Palestine	2010	max	-	Mar	lastSat	0:01	1:00	S
-Rule Palestine	2009	max	-	Sep	Fri>=1	2:00	0	-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
-			2:00	Zion	EET	1948 May 15
-			2:00 EgyptAsia	EE%sT	1967 Jun  5
-			2:00	Zion	I%sT	1996
-			2:00	Jordan	EE%sT	1999
-			2:00 Palestine	EE%sT
-
-# Paracel Is
-# no information
-
-# Philippines
-# On 1844-08-16, Narciso Claveria, governor-general of the
-# Philippines, issued a proclamation announcing that 1844-12-30 was to
-# be immediately followed by 1845-01-01.  Robert H. van Gent has a
-# transcript of the decree in <http://www.phys.uu.nl/~vgent/idl/idl.htm>.
-# The rest of the data are from Shanks & Pottenger.
-
-# From Paul Eggert (2006-04-25):
-# Tomorrow's Manila Standard reports that the Philippines Department of
-# Trade and Industry is considering adopting DST this June when the
-# rainy season begins.  See
-# <http://www.manilastandardtoday.com/?page=politics02_april26_2006>.
-# For now, we'll ignore this, since it's not definite and we lack details.
-#
-# From Jesper Norgaard Welen (2006-04-26):
-# ... claims that Philippines had DST last time in 1990:
-# http://story.philippinetimes.com/p.x/ct/9/id/145be20cc6b121c0/cid/3e5bbccc730d258c/
-# [a story dated 2006-04-25 by Cris Larano of Dow Jones Newswires,
-# but no details]
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Phil	1936	only	-	Nov	1	0:00	1:00	S
-Rule	Phil	1937	only	-	Feb	1	0:00	0	-
-Rule	Phil	1954	only	-	Apr	12	0:00	1:00	S
-Rule	Phil	1954	only	-	Jul	1	0:00	0	-
-Rule	Phil	1978	only	-	Mar	22	0:00	1:00	S
-Rule	Phil	1978	only	-	Sep	21	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Manila	-15:56:00 -	LMT	1844 Dec 31
-			8:04:00 -	LMT	1899 May 11
-			8:00	Phil	PH%sT	1942 May
-			9:00	-	JST	1944 Nov
-			8:00	Phil	PH%sT
-
-# Qatar
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Qatar	3:26:08 -	LMT	1920	# Al Dawhah / Doha
-			4:00	-	GST	1972 Jun
-			3:00	-	AST
-
-# Saudi Arabia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Riyadh	3:06:52 -	LMT	1950
-			3:00	-	AST
-
-# Singapore
-# The data here are taken from Mok Ly Yng (2003-10-30)
-# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Singapore	6:55:25 -	LMT	1901 Jan  1
-			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
-			7:00	-	MALT	1933 Jan  1 # Malaya Time
-			7:00	0:20	MALST	1936 Jan  1
-			7:20	-	MALT	1941 Sep  1
-			7:30	-	MALT	1942 Feb 16
-			9:00	-	JST	1945 Sep 12
-			7:30	-	MALT	1965 Aug  9 # independence
-			7:30	-	SGT	1982 Jan  1 # Singapore Time
-			8:00	-	SGT
-
-# Spratly Is
-# no information
-
-# Sri Lanka
-# From Paul Eggert (1996-09-03):
-# "Sri Lanka advances clock by an hour to avoid blackout"
-# (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
-# no longer available as of 1999-08-17)
-# reported ``the country's standard time will be put forward by one hour at
-# midnight Friday (1830 GMT) `in the light of the present power crisis'.''
-#
-# From Dharmasiri Senanayake, Sri Lanka Media Minister (1996-10-24), as quoted
-# by Shamindra in
-# <a href="news:54rka5$m5h@mtinsc01-mgt.ops.worldnet.att.net">
-# Daily News - Hot News Section (1996-10-26)
-# </a>:
-# With effect from 12.30 a.m. on 26th October 1996
-# Sri Lanka will be six (06) hours ahead of GMT.
-
-# From Jesper Norgaard Welen (2006-04-14), quoting Sri Lanka News Online
-# <http://news.sinhalaya.com/wmview.php?ArtID=11002> (2006-04-13):
-# 0030 hrs on April 15, 2006 (midnight of April 14, 2006 +30 minutes)
-# at present, become 2400 hours of April 14, 2006 (midnight of April 14, 2006).
-
-# From Peter Apps and Ranga Sirila of Reuters (2006-04-12) in:
-# <http://today.reuters.co.uk/news/newsArticle.aspx?type=scienceNews&storyID=2006-04-12T172228Z_01_COL295762_RTRIDST_0_SCIENCE-SRILANKA-TIME-DC.XML>
-# [The Tamil Tigers] never accepted the original 1996 time change and simply
-# kept their clocks set five and a half hours ahead of Greenwich Mean
-# Time (GMT), in line with neighbor India.
-# From Paul Eggert (2006-04-18):
-# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
-# as that zone has agreed with the Tamil areas since our cutoff date of 1970.
-
-# From K Sethu (2006-04-25):
-# I think the abbreviation LKT originated from the world of computers at
-# the time of or subsequent to the time zone changes by SL Government
-# twice in 1996 and probably SL Government or its standardization
-# agencies never declared an abbreviation as a national standard.
-#
-# I recollect before the recent change the government annoucemments
-# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka
-# Time and no mention was made about the abbreviation.
-#
-# If we look at Sri Lanka Department of Government's "Official News
-# Website of Sri Lanka" ... http://www.news.lk/ we can see that they
-# use SLT as abbreviation in time stamp at the beginning of each news
-# item....
-#
-# Within Sri Lanka I think LKT is well known among computer users and
-# adminsitrators.  In my opinion SLT may not be a good choice because the
-# nation's largest telcom / internet operator Sri Lanka Telcom is well
-# known by that abbreviation - simply as SLT (there IP domains are
-# slt.lk and sltnet.lk).
-#
-# But if indeed our government has adopted SLT as standard abbreviation
-# (that we have not known so far) then  it is better that it be used for
-# all computers.
-
-# From Paul Eggert (2006-04-25):
-# One possibility is that we wait for a bit for the dust to settle down
-# and then see what people actually say in practice.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Colombo	5:19:24 -	LMT	1880
-			5:19:32	-	MMT	1906	# Moratuwa Mean Time
-			5:30	-	IST	1942 Jan  5
-			5:30	0:30	IHST	1942 Sep
-			5:30	1:00	IST	1945 Oct 16 2:00
-			5:30	-	IST	1996 May 25 0:00
-			6:30	-	LKT	1996 Oct 26 0:30
-			6:00	-	LKT	2006 Apr 15 0:30
-			5:30	-	IST
-
-# Syria
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Syria	1920	1923	-	Apr	Sun>=15	2:00	1:00	S
-Rule	Syria	1920	1923	-	Oct	Sun>=1	2:00	0	-
-Rule	Syria	1962	only	-	Apr	29	2:00	1:00	S
-Rule	Syria	1962	only	-	Oct	1	2:00	0	-
-Rule	Syria	1963	1965	-	May	1	2:00	1:00	S
-Rule	Syria	1963	only	-	Sep	30	2:00	0	-
-Rule	Syria	1964	only	-	Oct	1	2:00	0	-
-Rule	Syria	1965	only	-	Sep	30	2:00	0	-
-Rule	Syria	1966	only	-	Apr	24	2:00	1:00	S
-Rule	Syria	1966	1976	-	Oct	1	2:00	0	-
-Rule	Syria	1967	1978	-	May	1	2:00	1:00	S
-Rule	Syria	1977	1978	-	Sep	1	2:00	0	-
-Rule	Syria	1983	1984	-	Apr	9	2:00	1:00	S
-Rule	Syria	1983	1984	-	Oct	1	2:00	0	-
-Rule	Syria	1986	only	-	Feb	16	2:00	1:00	S
-Rule	Syria	1986	only	-	Oct	9	2:00	0	-
-Rule	Syria	1987	only	-	Mar	1	2:00	1:00	S
-Rule	Syria	1987	1988	-	Oct	31	2:00	0	-
-Rule	Syria	1988	only	-	Mar	15	2:00	1:00	S
-Rule	Syria	1989	only	-	Mar	31	2:00	1:00	S
-Rule	Syria	1989	only	-	Oct	1	2:00	0	-
-Rule	Syria	1990	only	-	Apr	1	2:00	1:00	S
-Rule	Syria	1990	only	-	Sep	30	2:00	0	-
-Rule	Syria	1991	only	-	Apr	 1	0:00	1:00	S
-Rule	Syria	1991	1992	-	Oct	 1	0:00	0	-
-Rule	Syria	1992	only	-	Apr	 8	0:00	1:00	S
-Rule	Syria	1993	only	-	Mar	26	0:00	1:00	S
-Rule	Syria	1993	only	-	Sep	25	0:00	0	-
-# IATA SSIM (1998-02) says 1998-04-02;
-# (1998-09) says 1999-03-29 and 1999-09-29; (1999-02) says 1999-04-02,
-# 2000-04-02, and 2001-04-02; (1999-09) says 2000-03-31 and 2001-03-31;
-# (2006) says 2006-03-31 and 2006-09-22;
-# for now ignore all these claims and go with Shanks & Pottenger,
-# except for the 2006-09-22 claim (which seems right for Ramadan).
-Rule	Syria	1994	1996	-	Apr	 1	0:00	1:00	S
-Rule	Syria	1994	2005	-	Oct	 1	0:00	0	-
-Rule	Syria	1997	1998	-	Mar	lastMon	0:00	1:00	S
-Rule	Syria	1999	2006	-	Apr	 1	0:00	1:00	S
-# From Stephen Colebourne (2006-09-18):
-# According to IATA data, Syria will change DST on 21st September [21:00 UTC]
-# this year [only]....  This is probably related to Ramadan, like Egypt.
-Rule	Syria	2006	only	-	Sep	22	0:00	0	-
-# From Paul Eggert (2007-03-29):
-# Today the AP reported "Syria will switch to summertime at midnight Thursday."
-# http://www.iht.com/articles/ap/2007/03/29/africa/ME-GEN-Syria-Time-Change.php
-Rule	Syria	2007	only	-	Mar	lastFri	0:00	1:00	S
-# From Jesper Norgard (2007-10-27):
-# The sister center ICARDA of my work CIMMYT is confirming that Syria DST will
-# not take place 1.st November at 0:00 o'clock but 1.st November at 24:00 or
-# rather Midnight between Thursday and Friday. This does make more sence than
-# having it between Wednesday and Thursday (two workdays in Syria) since the
-# weekend in Syria is not Saturday and Sunday, but Friday and Saturday. So now
-# it is implemented at midnight of the last workday before weekend...
-# 
-# From Steffen Thorsen (2007-10-27):
-# Jesper Norgaard Welen wrote:
-# 
-# > "Winter local time in Syria will be observed at midnight of Thursday 1
-# > November 2007, and the clock will be put back 1 hour."
-# 
-# I found confirmation on this in this gov.sy-article (Arabic):
-# http://wehda.alwehda.gov.sy/_print_veiw.asp?FileName=12521710520070926111247
-# 
-# which using Google's translate tools says:
-# Council of Ministers also approved the commencement of work on 
-# identifying the winter time as of Friday, 2/11/2007 where the 60th 
-# minute delay at midnight Thursday 1/11/2007.
-Rule	Syria	2007	only	-	Nov	 Fri>=1	0:00	0	-
-
-# From Stephen Colebourne (2008-03-17):
-# For everyone's info, I saw an IATA time zone change for [Syria] for
-# this month (March 2008) in the last day or so...This is the data IATA
-# are now using:
-# Country     Time Standard   --- DST Start ---   --- DST End ---  DST
-# Name        Zone Variation   Time    Date        Time    Date
-# Variation
-# Syrian Arab
-# Republic    SY    +0200      2200  03APR08       2100  30SEP08   +0300
-#                              2200  02APR09       2100  30SEP09   +0300
-#                              2200  01APR10       2100  30SEP10   +0300
-
-# From Arthur David Olson (2008-03-17):
-# Here's a link to English-language coverage by the Syrian Arab News
-# Agency (SANA)...
-# <a href="http://www.sana.sy/eng/21/2008/03/11/165173.htm">
-# http://www.sana.sy/eng/21/2008/03/11/165173.htm
-# </a>...which reads (in part) "The Cabinet approved the suggestion of the
-# Ministry of Electricity to begin daylight savings time on Friday April
-# 4th, advancing clocks one hour ahead on midnight of Thursday April 3rd."
-# Since Syria is two hours east of UTC, the 2200 and 2100 transition times
-# shown above match up with midnight in Syria.
-
-# From Arthur David Olson (2008-03-18):
-# My buest guess at a Syrian rule is "the Friday nearest April 1";
-# coding that involves either using a "Mar Fri>=29" construct that old time zone
-# compilers can't handle  or having multiple Rules (a la Israel).
-# For now, use "Apr Fri>=1", and go with IATA on a uniform Sep 30 end.
-
-# From Steffen Thorsen (2008-10-07):
-# Syria has now officially decided to end DST on 2008-11-01 this year,
-# according to the following article in the Syrian Arab News Agency (SANA).
-#
-# The article is in Arabic, and seems to tell that they will go back to
-# winter time on 2008-11-01 at 00:00 local daylight time (delaying/setting
-# clocks back 60 minutes).
-#
-# <a href="http://sana.sy/ara/2/2008/10/07/195459.htm">
-# http://sana.sy/ara/2/2008/10/07/195459.htm
-# </a>
-
-# From Steffen Thorsen (2009-03-19):
-# Syria will start DST on 2009-03-27 00:00 this year according to many sources,
-# two examples:
-#
-# <a href="http://www.sana.sy/eng/21/2009/03/17/217563.htm">
-# http://www.sana.sy/eng/21/2009/03/17/217563.htm
-# </a>
-# (English, Syrian Arab News # Agency)
-# <a href="http://thawra.alwehda.gov.sy/_View_news2.asp?FileName=94459258720090318012209">
-# http://thawra.alwehda.gov.sy/_View_news2.asp?FileName=94459258720090318012209
-# </a>
-# (Arabic, gov-site)
-#
-# We have not found any sources saying anything about when DST ends this year.
-#
-# Our summary
-# <a href="http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html">
-# http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html
-# </a>
-
-# From Steffen Thorsen (2009-10-27):
-# The Syrian Arab News Network on 2009-09-29 reported that Syria will 
-# revert back to winter (standard) time on midnight between Thursday 
-# 2009-10-29 and Friday 2009-10-30:
-# <a href="http://www.sana.sy/ara/2/2009/09/29/247012.htm">
-# http://www.sana.sy/ara/2/2009/09/29/247012.htm (Arabic)
-# </a>
-
-# From Arthur David Olson (2009-10-28):
-# We'll see if future DST switching times turn out to be end of the last
-# Thursday of the month or the start of the last Friday of the month or
-# something else. For now, use the start of the last Friday.
-
-# From Steffen Thorsen (2010-03-17):
-# The "Syrian News Station" reported on 2010-03-16 that the Council of
-# Ministers has decided that Syria will start DST on midnight Thursday
-# 2010-04-01: (midnight between Thursday and Friday):
-# <a href="http://sns.sy/sns/?path=news/read/11421">
-# http://sns.sy/sns/?path=news/read/11421 (Arabic)
-# </a>
-
-Rule	Syria	2008	only	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Syria	2008	only	-	Nov	1	0:00	0	-
-Rule	Syria	2009	only	-	Mar	lastFri	0:00	1:00	S
-Rule	Syria	2010	max	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Syria	2009	max	-	Oct	lastFri	0:00	0	-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
-			2:00	Syria	EE%sT
-
-# Tajikistan
-# From Shanks & Pottenger.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
-			5:00	-	DUST	1930 Jun 21 # Dushanbe Time
-			6:00 RussiaAsia DUS%sT	1991 Mar 31 2:00s
-			5:00	1:00	DUSST	1991 Sep  9 2:00s
-			5:00	-	TJT		    # Tajikistan Time
-
-# Thailand
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Bangkok	6:42:04	-	LMT	1880
-			6:42:04	-	BMT	1920 Apr # Bangkok Mean Time
-			7:00	-	ICT
-
-# Turkmenistan
-# From Shanks & Pottenger.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Ashgabat	3:53:32 -	LMT	1924 May  2 # or Ashkhabad
-			4:00	-	ASHT	1930 Jun 21 # Ashkhabad Time
-			5:00 RussiaAsia	ASH%sT	1991 Mar 31 2:00
-			4:00 RussiaAsia	ASH%sT	1991 Oct 27 # independence
-			4:00 RussiaAsia	TM%sT	1992 Jan 19 2:00
-			5:00	-	TMT
-
-# United Arab Emirates
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Dubai	3:41:12 -	LMT	1920
-			4:00	-	GST
-
-# Uzbekistan
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Samarkand	4:27:12 -	LMT	1924 May  2
-			4:00	-	SAMT	1930 Jun 21 # Samarkand Time
-			5:00	-	SAMT	1981 Apr  1
-			5:00	1:00	SAMST	1981 Oct  1
-			6:00	-	TAST	1982 Apr  1 # Tashkent Time
-			5:00 RussiaAsia	SAM%sT	1991 Sep  1 # independence
-			5:00 RussiaAsia	UZ%sT	1992
-			5:00	-	UZT
-Zone	Asia/Tashkent	4:37:12 -	LMT	1924 May  2
-			5:00	-	TAST	1930 Jun 21 # Tashkent Time
-			6:00 RussiaAsia	TAS%sT	1991 Mar 31 2:00
-			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
-			5:00 RussiaAsia	UZ%sT	1992
-			5:00	-	UZT
-
-# Vietnam
-
-# From Arthur David Olson (2008-03-18):
-# The English-language name of Vietnam's most populous city is "Ho Chi Min City";
-# we use Ho_Chi_Minh below to avoid a name of more than 14 characters.
-
-# From Shanks & Pottenger:
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Ho_Chi_Minh	7:06:40 -	LMT	1906 Jun  9
-			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
-			7:00	-	ICT	1912 May
-			8:00	-	ICT	1931 May
-			7:00	-	ICT
-
-# Yemen
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Aden	3:00:48	-	LMT	1950
-			3:00	-	AST
diff --git a/tools/zoneinfo/tzdata2010k/australasia b/tools/zoneinfo/tzdata2010k/australasia
deleted file mode 100644
index 36a81b0..0000000
--- a/tools/zoneinfo/tzdata2010k/australasia
+++ /dev/null
@@ -1,1539 +0,0 @@
-# <pre>
-# @(#)australasia	8.18
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# This file also includes Pacific islands.
-
-# Notes are at the end of this file
-
-###############################################################################
-
-# Australia
-
-# Please see the notes below for the controversy about "EST" versus "AEST" etc.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Aus	1917	only	-	Jan	 1	0:01	1:00	-
-Rule	Aus	1917	only	-	Mar	25	2:00	0	-
-Rule	Aus	1942	only	-	Jan	 1	2:00	1:00	-
-Rule	Aus	1942	only	-	Mar	29	2:00	0	-
-Rule	Aus	1942	only	-	Sep	27	2:00	1:00	-
-Rule	Aus	1943	1944	-	Mar	lastSun	2:00	0	-
-Rule	Aus	1943	only	-	Oct	 3	2:00	1:00	-
-# Go with Whitman and the Australian National Standards Commission, which
-# says W Australia didn't use DST in 1943/1944.  Ignore Whitman's claim that
-# 1944/1945 was just like 1943/1944.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# Northern Territory
-Zone Australia/Darwin	 8:43:20 -	LMT	1895 Feb
-			 9:00	-	CST	1899 May
-			 9:30	Aus	CST
-# Western Australia
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	AW	1974	only	-	Oct	lastSun	2:00s	1:00	-
-Rule	AW	1975	only	-	Mar	Sun>=1	2:00s	0	-
-Rule	AW	1983	only	-	Oct	lastSun	2:00s	1:00	-
-Rule	AW	1984	only	-	Mar	Sun>=1	2:00s	0	-
-Rule	AW	1991	only	-	Nov	17	2:00s	1:00	-
-Rule	AW	1992	only	-	Mar	Sun>=1	2:00s	0	-
-Rule	AW	2006	only	-	Dec	 3	2:00s	1:00	-
-Rule	AW	2007	2009	-	Mar	lastSun	2:00s	0	-
-Rule	AW	2007	2008	-	Oct	lastSun	2:00s	1:00	-
-Zone Australia/Perth	 7:43:24 -	LMT	1895 Dec
-			 8:00	Aus	WST	1943 Jul
-			 8:00	AW	WST
-Zone Australia/Eucla	 8:35:28 -	LMT	1895 Dec
-			 8:45	Aus	CWST	1943 Jul
-			 8:45	AW	CWST
-
-# Queensland
-#
-# From Alex Livingston (1996-11-01):
-# I have heard or read more than once that some resort islands off the coast
-# of Queensland chose to keep observing daylight-saving time even after
-# Queensland ceased to.
-#
-# From Paul Eggert (1996-11-22):
-# IATA SSIM (1993-02/1994-09) say that the Holiday Islands (Hayman, Lindeman,
-# Hamilton) observed DST for two years after the rest of Queensland stopped.
-# Hamilton is the largest, but there is also a Hamilton in Victoria,
-# so use Lindeman.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	AQ	1971	only	-	Oct	lastSun	2:00s	1:00	-
-Rule	AQ	1972	only	-	Feb	lastSun	2:00s	0	-
-Rule	AQ	1989	1991	-	Oct	lastSun	2:00s	1:00	-
-Rule	AQ	1990	1992	-	Mar	Sun>=1	2:00s	0	-
-Rule	Holiday	1992	1993	-	Oct	lastSun	2:00s	1:00	-
-Rule	Holiday	1993	1994	-	Mar	Sun>=1	2:00s	0	-
-Zone Australia/Brisbane	10:12:08 -	LMT	1895
-			10:00	Aus	EST	1971
-			10:00	AQ	EST
-Zone Australia/Lindeman  9:55:56 -	LMT	1895
-			10:00	Aus	EST	1971
-			10:00	AQ	EST	1992 Jul
-			10:00	Holiday	EST
-
-# South Australia
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	AS	1971	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	AS	1986	only	-	Oct	19	2:00s	1:00	-
-Rule	AS	1987	2007	-	Oct	lastSun	2:00s	1:00	-
-Rule	AS	1972	only	-	Feb	27	2:00s	0	-
-Rule	AS	1973	1985	-	Mar	Sun>=1	2:00s	0	-
-Rule	AS	1986	1989	-	Mar	Sun>=15	2:00s	0	-
-Rule	AS	1990	only	-	Mar	Sun>=18	2:00s	0	-
-Rule	AS	1991	only	-	Mar	Sun>=1	2:00s	0	-
-Rule	AS	1992	only	-	Mar	Sun>=18	2:00s	0	-
-Rule	AS	1993	only	-	Mar	Sun>=1	2:00s	0	-
-Rule	AS	1994	only	-	Mar	Sun>=18	2:00s	0	-
-Rule	AS	1995	2005	-	Mar	lastSun	2:00s	0	-
-Rule	AS	2006	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	AS	2007	only	-	Mar	lastSun	2:00s	0	-
-Rule	AS	2008	max	-	Apr	Sun>=1	2:00s	0	-
-Rule	AS	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Australia/Adelaide	9:14:20 -	LMT	1895 Feb
-			9:00	-	CST	1899 May
-			9:30	Aus	CST	1971
-			9:30	AS	CST
-
-# Tasmania
-#
-# From Paul Eggert (2005-08-16):
-# <http://www.bom.gov.au/climate/averages/tables/dst_times.shtml>
-# says King Island didn't observe DST from WWII until late 1971.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	AT	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	AT	1968	only	-	Mar	lastSun	2:00s	0	-
-Rule	AT	1968	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	AT	1969	1971	-	Mar	Sun>=8	2:00s	0	-
-Rule	AT	1972	only	-	Feb	lastSun	2:00s	0	-
-Rule	AT	1973	1981	-	Mar	Sun>=1	2:00s	0	-
-Rule	AT	1982	1983	-	Mar	lastSun	2:00s	0	-
-Rule	AT	1984	1986	-	Mar	Sun>=1	2:00s	0	-
-Rule	AT	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
-Rule	AT	1987	1990	-	Mar	Sun>=15	2:00s	0	-
-Rule	AT	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
-Rule	AT	1988	1990	-	Oct	lastSun	2:00s	1:00	-
-Rule	AT	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	AT	1991	2005	-	Mar	lastSun	2:00s	0	-
-Rule	AT	2000	only	-	Aug	lastSun	2:00s	1:00	-
-Rule	AT	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	AT	2006	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	AT	2007	only	-	Mar	lastSun	2:00s	0	-
-Rule	AT	2008	max	-	Apr	Sun>=1	2:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Australia/Hobart	9:49:16	-	LMT	1895 Sep
-			10:00	-	EST	1916 Oct 1 2:00
-			10:00	1:00	EST	1917 Feb
-			10:00	Aus	EST	1967
-			10:00	AT	EST
-Zone Australia/Currie	9:35:28	-	LMT	1895 Sep
-			10:00	-	EST	1916 Oct 1 2:00
-			10:00	1:00	EST	1917 Feb
-			10:00	Aus	EST	1971 Jul
-			10:00	AT	EST
-
-# Victoria
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	AV	1971	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	AV	1972	only	-	Feb	lastSun	2:00s	0	-
-Rule	AV	1973	1985	-	Mar	Sun>=1	2:00s	0	-
-Rule	AV	1986	1990	-	Mar	Sun>=15	2:00s	0	-
-Rule	AV	1986	1987	-	Oct	Sun>=15	2:00s	1:00	-
-Rule	AV	1988	1999	-	Oct	lastSun	2:00s	1:00	-
-Rule	AV	1991	1994	-	Mar	Sun>=1	2:00s	0	-
-Rule	AV	1995	2005	-	Mar	lastSun	2:00s	0	-
-Rule	AV	2000	only	-	Aug	lastSun	2:00s	1:00	-
-Rule	AV	2001	2007	-	Oct	lastSun	2:00s	1:00	-
-Rule	AV	2006	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	AV	2007	only	-	Mar	lastSun	2:00s	0	-
-Rule	AV	2008	max	-	Apr	Sun>=1	2:00s	0	-
-Rule	AV	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Australia/Melbourne 9:39:52 -	LMT	1895 Feb
-			10:00	Aus	EST	1971
-			10:00	AV	EST
-
-# New South Wales
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	AN	1971	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	AN	1972	only	-	Feb	27	2:00s	0	-
-Rule	AN	1973	1981	-	Mar	Sun>=1	2:00s	0	-
-Rule	AN	1982	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	AN	1983	1985	-	Mar	Sun>=1	2:00s	0	-
-Rule	AN	1986	1989	-	Mar	Sun>=15	2:00s	0	-
-Rule	AN	1986	only	-	Oct	19	2:00s	1:00	-
-Rule	AN	1987	1999	-	Oct	lastSun	2:00s	1:00	-
-Rule	AN	1990	1995	-	Mar	Sun>=1	2:00s	0	-
-Rule	AN	1996	2005	-	Mar	lastSun	2:00s	0	-
-Rule	AN	2000	only	-	Aug	lastSun	2:00s	1:00	-
-Rule	AN	2001	2007	-	Oct	lastSun	2:00s	1:00	-
-Rule	AN	2006	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	AN	2007	only	-	Mar	lastSun	2:00s	0	-
-Rule	AN	2008	max	-	Apr	Sun>=1	2:00s	0	-
-Rule	AN	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Australia/Sydney	10:04:52 -	LMT	1895 Feb
-			10:00	Aus	EST	1971
-			10:00	AN	EST
-Zone Australia/Broken_Hill 9:25:48 -	LMT	1895 Feb
-			10:00	-	EST	1896 Aug 23
-			9:00	-	CST	1899 May
-			9:30	Aus	CST	1971
-			9:30	AN	CST	2000
-			9:30	AS	CST
-
-# Lord Howe Island
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	LH	1981	1984	-	Oct	lastSun	2:00	1:00	-
-Rule	LH	1982	1985	-	Mar	Sun>=1	2:00	0	-
-Rule	LH	1985	only	-	Oct	lastSun	2:00	0:30	-
-Rule	LH	1986	1989	-	Mar	Sun>=15	2:00	0	-
-Rule	LH	1986	only	-	Oct	19	2:00	0:30	-
-Rule	LH	1987	1999	-	Oct	lastSun	2:00	0:30	-
-Rule	LH	1990	1995	-	Mar	Sun>=1	2:00	0	-
-Rule	LH	1996	2005	-	Mar	lastSun	2:00	0	-
-Rule	LH	2000	only	-	Aug	lastSun	2:00	0:30	-
-Rule	LH	2001	2007	-	Oct	lastSun	2:00	0:30	-
-Rule	LH	2006	only	-	Apr	Sun>=1	2:00	0	-
-Rule	LH	2007	only	-	Mar	lastSun	2:00	0	-
-Rule	LH	2008	max	-	Apr	Sun>=1	2:00	0	-
-Rule	LH	2008	max	-	Oct	Sun>=1	2:00	0:30	-
-Zone Australia/Lord_Howe 10:36:20 -	LMT	1895 Feb
-			10:00	-	EST	1981 Mar
-			10:30	LH	LHST
-
-# Australian miscellany
-#
-# Ashmore Is, Cartier
-# no indigenous inhabitants; only seasonal caretakers
-# no times are set
-#
-# Coral Sea Is
-# no indigenous inhabitants; only meteorologists
-# no times are set
-#
-# Macquarie
-# permanent occupation (scientific station) since 1948;
-# sealing and penguin oil station operated 1888/1917
-# like Australia/Hobart
-
-# Christmas
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Indian/Christmas	7:02:52 -	LMT	1895 Feb
-			7:00	-	CXT	# Christmas Island Time
-
-# Cook Is
-# From Shanks & Pottenger:
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Cook	1978	only	-	Nov	12	0:00	0:30	HS
-Rule	Cook	1979	1991	-	Mar	Sun>=1	0:00	0	-
-Rule	Cook	1979	1990	-	Oct	lastSun	0:00	0:30	HS
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Rarotonga	-10:39:04 -	LMT	1901		# Avarua
-			-10:30	-	CKT	1978 Nov 12	# Cook Is Time
-			-10:00	Cook	CK%sT
-
-# Cocos
-# These islands were ruled by the Ross family from about 1830 to 1978.
-# We don't know when standard time was introduced; for now, we guess 1900.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Indian/Cocos	6:27:40	-	LMT	1900
-			6:30	-	CCT	# Cocos Islands Time
-
-# Fiji
-# From Alexander Krivenyshev (2009-11-10):
-# According to Fiji Broadcasting Corporation,  Fiji plans to re-introduce DST
-# from November 29th 2009  to April 25th 2010.
-#
-# "Daylight savings to commence this month"
-# <a href="http://www.radiofiji.com.fj/fullstory.php?id=23719">
-# http://www.radiofiji.com.fj/fullstory.php?id=23719
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_fiji01.html">
-# http://www.worldtimezone.com/dst_news/dst_news_fiji01.html
-# </a>
-
-# From Steffen Thorsen (2009-11-10):
-# The Fiji Government has posted some more details about the approved
-# amendments:
-# <a href="http://www.fiji.gov.fj/publish/page_16198.shtml">
-# http://www.fiji.gov.fj/publish/page_16198.shtml
-# </a>
-
-# From Steffen Thorsen (2010-03-03):
-# The Cabinet in Fiji has decided to end DST about a month early, on
-# 2010-03-28 at 03:00.
-# The plan is to observe DST again, from 2010-10-24 to sometime in March
-# 2011 (last Sunday a good guess?).
-#
-# Official source:
-# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166">
-# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166
-# </a>
-#
-# A bit more background info here:
-# <a href="http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html">
-# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
-# </a>
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
-Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
-Rule	Fiji	2009	only	-	Nov	29	2:00	1:00	S
-Rule	Fiji	2010	only	-	Mar	lastSun	3:00	0	-
-Rule	Fiji	2010	only	-	Oct	24	2:00	1:00	S
-Rule	Fiji	2011	only	-	Mar	lastSun 3:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
-			12:00	Fiji	FJ%sT	# Fiji Time
-
-# French Polynesia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Gambier	 -8:59:48 -	LMT	1912 Oct	# Rikitea
-			 -9:00	-	GAMT	# Gambier Time
-Zone	Pacific/Marquesas -9:18:00 -	LMT	1912 Oct
-			 -9:30	-	MART	# Marquesas Time
-Zone	Pacific/Tahiti	 -9:58:16 -	LMT	1912 Oct	# Papeete
-			-10:00	-	TAHT	# Tahiti Time
-# Clipperton (near North America) is administered from French Polynesia;
-# it is uninhabited.
-
-# Guam
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Guam	-14:21:00 -	LMT	1844 Dec 31
-			 9:39:00 -	LMT	1901		# Agana
-			10:00	-	GST	2000 Dec 23	# Guam
-			10:00	-	ChST	# Chamorro Standard Time
-
-# Kiribati
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Tarawa	 11:32:04 -	LMT	1901		# Bairiki
-			 12:00	-	GILT		 # Gilbert Is Time
-Zone Pacific/Enderbury	-11:24:20 -	LMT	1901
-			-12:00	-	PHOT	1979 Oct # Phoenix Is Time
-			-11:00	-	PHOT	1995
-			 13:00	-	PHOT
-Zone Pacific/Kiritimati	-10:29:20 -	LMT	1901
-			-10:40	-	LINT	1979 Oct # Line Is Time
-			-10:00	-	LINT	1995
-			 14:00	-	LINT
-
-# N Mariana Is
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Saipan	-14:17:00 -	LMT	1844 Dec 31
-			 9:43:00 -	LMT	1901
-			 9:00	-	MPT	1969 Oct # N Mariana Is Time
-			10:00	-	MPT	2000 Dec 23
-			10:00	-	ChST	# Chamorro Standard Time
-
-# Marshall Is
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Majuro	11:24:48 -	LMT	1901
-			11:00	-	MHT	1969 Oct # Marshall Islands Time
-			12:00	-	MHT
-Zone Pacific/Kwajalein	11:09:20 -	LMT	1901
-			11:00	-	MHT	1969 Oct
-			-12:00	-	KWAT	1993 Aug 20	# Kwajalein Time
-			12:00	-	MHT
-
-# Micronesia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Chuuk	10:07:08 -	LMT	1901
-			10:00	-	CHUT			# Chuuk Time
-Zone Pacific/Pohnpei	10:32:52 -	LMT	1901		# Kolonia
-			11:00	-	PONT			# Pohnpei Time
-Zone Pacific/Kosrae	10:51:56 -	LMT	1901
-			11:00	-	KOST	1969 Oct	# Kosrae Time
-			12:00	-	KOST	1999
-			11:00	-	KOST
-
-# Nauru
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Nauru	11:07:40 -	LMT	1921 Jan 15	# Uaobe
-			11:30	-	NRT	1942 Mar 15	# Nauru Time
-			9:00	-	JST	1944 Aug 15
-			11:30	-	NRT	1979 May
-			12:00	-	NRT
-
-# New Caledonia
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	NC	1977	1978	-	Dec	Sun>=1	0:00	1:00	S
-Rule	NC	1978	1979	-	Feb	27	0:00	0	-
-Rule	NC	1996	only	-	Dec	 1	2:00s	1:00	S
-# Shanks & Pottenger say the following was at 2:00; go with IATA.
-Rule	NC	1997	only	-	Mar	 2	2:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Noumea	11:05:48 -	LMT	1912 Jan 13
-			11:00	NC	NC%sT
-
-
-###############################################################################
-
-# New Zealand
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	NZ	1927	only	-	Nov	 6	2:00	1:00	S
-Rule	NZ	1928	only	-	Mar	 4	2:00	0	M
-Rule	NZ	1928	1933	-	Oct	Sun>=8	2:00	0:30	S
-Rule	NZ	1929	1933	-	Mar	Sun>=15	2:00	0	M
-Rule	NZ	1934	1940	-	Apr	lastSun	2:00	0	M
-Rule	NZ	1934	1940	-	Sep	lastSun	2:00	0:30	S
-Rule	NZ	1946	only	-	Jan	 1	0:00	0	S
-# Since 1957 Chatham has been 45 minutes ahead of NZ, but there's no
-# convenient notation for this so we must duplicate the Rule lines.
-Rule	NZ	1974	only	-	Nov	Sun>=1	2:00s	1:00	D
-Rule	Chatham	1974	only	-	Nov	Sun>=1	2:45s	1:00	D
-Rule	NZ	1975	only	-	Feb	lastSun	2:00s	0	S
-Rule	Chatham	1975	only	-	Feb	lastSun	2:45s	0	S
-Rule	NZ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
-Rule	Chatham	1975	1988	-	Oct	lastSun	2:45s	1:00	D
-Rule	NZ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
-Rule	Chatham	1976	1989	-	Mar	Sun>=1	2:45s	0	S
-Rule	NZ	1989	only	-	Oct	Sun>=8	2:00s	1:00	D
-Rule	Chatham	1989	only	-	Oct	Sun>=8	2:45s	1:00	D
-Rule	NZ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
-Rule	Chatham	1990	2006	-	Oct	Sun>=1	2:45s	1:00	D
-Rule	NZ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
-Rule	Chatham	1990	2007	-	Mar	Sun>=15	2:45s	0	S
-Rule	NZ	2007	max	-	Sep	lastSun	2:00s	1:00	D
-Rule	Chatham	2007	max	-	Sep	lastSun	2:45s	1:00	D
-Rule	NZ	2008	max	-	Apr	Sun>=1	2:00s	0	S
-Rule	Chatham	2008	max	-	Apr	Sun>=1	2:45s	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Auckland	11:39:04 -	LMT	1868 Nov  2
-			11:30	NZ	NZ%sT	1946 Jan  1
-			12:00	NZ	NZ%sT
-Zone Pacific/Chatham	12:13:48 -	LMT	1957 Jan  1
-			12:45	Chatham	CHA%sT
-
-
-# Auckland Is
-# uninhabited; Maori and Moriori, colonial settlers, pastoralists, sealers,
-# and scientific personnel have wintered
-
-# Campbell I
-# minor whaling stations operated 1909/1914
-# scientific station operated 1941/1995;
-# previously whalers, sealers, pastoralists, and scientific personnel wintered
-# was probably like Pacific/Auckland
-
-###############################################################################
-
-
-# Niue
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Niue	-11:19:40 -	LMT	1901		# Alofi
-			-11:20	-	NUT	1951	# Niue Time
-			-11:30	-	NUT	1978 Oct 1
-			-11:00	-	NUT
-
-# Norfolk
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Norfolk	11:11:52 -	LMT	1901		# Kingston
-			11:12	-	NMT	1951	# Norfolk Mean Time
-			11:30	-	NFT		# Norfolk Time
-
-# Palau (Belau)
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Palau	8:57:56 -	LMT	1901		# Koror
-			9:00	-	PWT	# Palau Time
-
-# Papua New Guinea
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Port_Moresby 9:48:40 -	LMT	1880
-			9:48:32	-	PMMT	1895	# Port Moresby Mean Time
-			10:00	-	PGT		# Papua New Guinea Time
-
-# Pitcairn
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Pitcairn	-8:40:20 -	LMT	1901		# Adamstown
-			-8:30	-	PNT	1998 Apr 27 00:00
-			-8:00	-	PST	# Pitcairn Standard Time
-
-# American Samoa
-Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
-			-11:22:48 -	LMT	1911
-			-11:30	-	SAMT	1950		# Samoa Time
-			-11:00	-	NST	1967 Apr	# N=Nome
-			-11:00	-	BST	1983 Nov 30	# B=Bering
-			-11:00	-	SST			# S=Samoa
-
-# Samoa
-
-# From Steffen Thorsen (2009-10-16):
-# We have been in contact with the government of Samoa again, and received
-# the following info:
-#
-# "Cabinet has now approved Daylight Saving to be effected next year
-# commencing from the last Sunday of September 2010 and conclude first
-# Sunday of April 2011."
-#
-# Background info:
-# <a href="http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html">
-# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
-# </a>
-#
-# Samoa's Daylight Saving Time Act 2009 is available here, but does not
-# contain any dates:
-# <a href="http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf">
-# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
-# </a>
-
-Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
-			-11:26:56 -	LMT	1911
-			-11:30	-	SAMT	1950		# Samoa Time
-			-11:00	-	WST	2010 Sep 26
-			-11:00	1:00	WSDT	2011 Apr 3
-			-11:00	-	WST
-
-# Solomon Is
-# excludes Bougainville, for which see Papua New Guinea
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Guadalcanal 10:39:48 -	LMT	1912 Oct	# Honiara
-			11:00	-	SBT	# Solomon Is Time
-
-# Tokelau Is
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Fakaofo	-11:24:56 -	LMT	1901
-			-10:00	-	TKT	# Tokelau Time
-
-# Tonga
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Tonga	1999	only	-	Oct	 7	2:00s	1:00	S
-Rule	Tonga	2000	only	-	Mar	19	2:00s	0	-
-Rule	Tonga	2000	2001	-	Nov	Sun>=1	2:00	1:00	S
-Rule	Tonga	2001	2002	-	Jan	lastSun	2:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Tongatapu	12:19:20 -	LMT	1901
-			12:20	-	TOT	1941 # Tonga Time
-			13:00	-	TOT	1999
-			13:00	Tonga	TO%sT
-
-# Tuvalu
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Funafuti	11:56:52 -	LMT	1901
-			12:00	-	TVT	# Tuvalu Time
-
-
-# US minor outlying islands
-
-# Howland, Baker
-# Howland was mined for guano by American companies 1857-1878 and British
-# 1886-1891; Baker was similar but exact dates are not known.
-# Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
-# uninhabited thereafter.
-# Howland observed Hawaii Standard Time (UTC-10:30) in 1937;
-# see page 206 of Elgen M. Long and Marie K. Long,
-# Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
-# So most likely Howland and Baker observed Hawaii Time from 1935
-# until they were abandoned after the war.
-
-# Jarvis
-# Mined for guano by American companies 1857-1879 and British 1883?-1891?.
-# Inhabited by civilians 1935-1942; IGY scientific base 1957-1958;
-# uninhabited thereafter.
-# no information; was probably like Pacific/Kiritimati
-
-# Johnston
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Johnston	-10:00	-	HST
-
-# Kingman
-# uninhabited
-
-# Midway
-#
-# From Mark Brader (2005-01-23):
-# [Fallacies and Fantasies of Air Transport History, by R.E.G. Davies,
-# published 1994 by Paladwr Press, McLean, VA, USA; ISBN 0-9626483-5-3]
-# reproduced a Pan American Airways timeables from 1936, for their weekly
-# "Orient Express" flights between San Francisco and Manila, and connecting
-# flights to Chicago and the US East Coast.  As it uses some time zone
-# designations that I've never seen before:....
-# Fri. 6:30A Lv. HONOLOLU (Pearl Harbor), H.I.   H.L.T. Ar. 5:30P Sun.
-#  "   3:00P Ar. MIDWAY ISLAND . . . . . . . . . M.L.T. Lv. 6:00A  "
-#
-Zone Pacific/Midway	-11:49:28 -	LMT	1901
-			-11:00	-	NST	1956 Jun  3
-			-11:00	1:00	NDT	1956 Sep  2
-			-11:00	-	NST	1967 Apr	# N=Nome
-			-11:00	-	BST	1983 Nov 30	# B=Bering
-			-11:00	-	SST			# S=Samoa
-
-# Palmyra
-# uninhabited since World War II; was probably like Pacific/Kiritimati
-
-# Wake
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Wake	11:06:28 -	LMT	1901
-			12:00	-	WAKT	# Wake Time
-
-
-# Vanuatu
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Vanuatu	1983	only	-	Sep	25	0:00	1:00	S
-Rule	Vanuatu	1984	1991	-	Mar	Sun>=23	0:00	0	-
-Rule	Vanuatu	1984	only	-	Oct	23	0:00	1:00	S
-Rule	Vanuatu	1985	1991	-	Sep	Sun>=23	0:00	1:00	S
-Rule	Vanuatu	1992	1993	-	Jan	Sun>=23	0:00	0	-
-Rule	Vanuatu	1992	only	-	Oct	Sun>=23	0:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Efate	11:13:16 -	LMT	1912 Jan 13		# Vila
-			11:00	Vanuatu	VU%sT	# Vanuatu Time
-
-# Wallis and Futuna
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Wallis	12:15:20 -	LMT	1901
-			12:00	-	WFT	# Wallis & Futuna Time
-
-###############################################################################
-
-# NOTES
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
-# San Diego: ACS Publications, Inc. (2003).
-#
-# Gwillim Law writes that a good source
-# for recent time zone data is the International Air Transport
-# Association's Standard Schedules Information Manual (IATA SSIM),
-# published semiannually.  Law sent in several helpful summaries
-# of the IATA's data after 1990.
-#
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1990, and IATA SSIM is the source for entries afterwards.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
-#
-# I invented the abbreviations marked `*' in the following table;
-# the rest are from earlier versions of this file, or from other sources.
-# Corrections are welcome!
-#		std dst
-#		LMT	Local Mean Time
-#	  8:00	WST WST	Western Australia
-#	  8:45	CWST CWST Central Western Australia*
-#	  9:00	JST	Japan
-#	  9:30	CST CST	Central Australia
-#	 10:00	EST EST	Eastern Australia
-#	 10:00	ChST	Chamorro
-#	 10:30	LHST LHST Lord Howe*
-#	 11:30	NZMT NZST New Zealand through 1945
-#	 12:00	NZST NZDT New Zealand 1946-present
-#	 12:45	CHAST CHADT Chatham*
-#	-11:00	SST	Samoa
-#	-10:00	HST	Hawaii
-#	- 8:00	PST	Pitcairn*
-#
-# See the `northamerica' file for Hawaii.
-# See the `southamerica' file for Easter I and the Galapagos Is.
-
-###############################################################################
-
-# Australia
-
-# From Paul Eggert (2005-12-08):
-# <a href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">
-# Implementation Dates of Daylight Saving Time within Australia
-# </a> summarizes daylight saving issues in Australia.
-
-# From Arthur David Olson (2005-12-12):
-# <a href="http://www.lawlink.nsw.gov.au/lawlink/Corporate/ll_agdinfo.nsf/pages/community_relations_daylight_saving">
-# Lawlink NSW:Daylight Saving in New South Wales
-# </a> covers New South Wales in particular.
-
-# From John Mackin (1991-03-06):
-# We in Australia have _never_ referred to DST as `daylight' time.
-# It is called `summer' time.  Now by a happy coincidence, `summer'
-# and `standard' happen to start with the same letter; hence, the
-# abbreviation does _not_ change...
-# The legislation does not actually define abbreviations, at least
-# in this State, but the abbreviation is just commonly taken to be the
-# initials of the phrase, and the legislation here uniformly uses
-# the phrase `summer time' and does not use the phrase `daylight
-# time'.
-# Announcers on the Commonwealth radio network, the ABC (for Australian
-# Broadcasting Commission), use the phrases `Eastern Standard Time'
-# or `Eastern Summer Time'.  (Note, though, that as I say in the
-# current australasia file, there is really no such thing.)  Announcers
-# on its overseas service, Radio Australia, use the same phrases
-# prefixed by the word `Australian' when referring to local times;
-# time announcements on that service, naturally enough, are made in UTC.
-
-# From Arthur David Olson (1992-03-08):
-# Given the above, what's chosen for year-round use is:
-#	CST	for any place operating at a GMTOFF of 9:30
-#	WST	for any place operating at a GMTOFF of 8:00
-#	EST	for any place operating at a GMTOFF of 10:00
-
-# From Chuck Soper (2006-06-01):
-# I recently found this Australian government web page on time zones:
-# <http://www.australia.gov.au/about-australia-13time>
-# And this government web page lists time zone names and abbreviations:
-# <http://www.bom.gov.au/climate/averages/tables/daysavtm.shtml>
-
-# From Paul Eggert (2001-04-05), summarizing a long discussion about "EST"
-# versus "AEST" etc.:
-#
-# I see the following points of dispute:
-#
-# * How important are unique time zone abbreviations?
-#
-#   Here I tend to agree with the point (most recently made by Chris
-#   Newman) that unique abbreviations should not be essential for proper
-#   operation of software.  We have other instances of ambiguity
-#   (e.g. "IST" denoting both "Israel Standard Time" and "Indian
-#   Standard Time"), and they are not likely to go away any time soon.
-#   In the old days, some software mistakenly relied on unique
-#   abbreviations, but this is becoming less true with time, and I don't
-#   think it's that important to cater to such software these days.
-#
-#   On the other hand, there is another motivation for unambiguous
-#   abbreviations: it cuts down on human confusion.  This is
-#   particularly true for Australia, where "EST" can mean one thing for
-#   time T and a different thing for time T plus 1 second.
-#
-# * Does the relevant legislation indicate which abbreviations should be used?
-#
-#   Here I tend to think that things are a mess, just as they are in
-#   many other countries.  We Americans are currently disagreeing about
-#   which abbreviation to use for the newly legislated Chamorro Standard
-#   Time, for example.
-#
-#   Personally, I would prefer to use common practice; I would like to
-#   refer to legislation only for examples of common practice, or as a
-#   tiebreaker.
-#
-# * Do Australians more often use "Eastern Daylight Time" or "Eastern
-#   Summer Time"?  Do they typically prefix the time zone names with
-#   the word "Australian"?
-#
-#   My own impression is that both "Daylight Time" and "Summer Time" are
-#   common and are widely understood, but that "Summer Time" is more
-#   popular; and that the leading "A" is also common but is omitted more
-#   often than not.  I just used AltaVista advanced search and got the
-#   following count of page hits:
-#
-#     1,103 "Eastern Summer Time" AND domain:au
-#       971 "Australian Eastern Summer Time" AND domain:au
-#       613 "Eastern Daylight Time" AND domain:au
-#       127 "Australian Eastern Daylight Time" AND domain:au
-#
-#   Here "Summer" seems quite a bit more popular than "Daylight",
-#   particularly when we know the time zone is Australian and not US,
-#   say.  The "Australian" prefix seems to be popular for Eastern Summer
-#   Time, but unpopular for Eastern Daylight Time.
-#
-#   For abbreviations, tools like AltaVista are less useful because of
-#   ambiguity.  Many hits are not really time zones, unfortunately, and
-#   many hits denote US time zones and not Australian ones.  But here
-#   are the hit counts anyway:
-#
-#     161,304 "EST" and domain:au
-#      25,156 "EDT" and domain:au
-#      18,263 "AEST" and domain:au
-#      10,416 "AEDT" and domain:au
-#
-#      14,538 "CST" and domain:au
-#       5,728 "CDT" and domain:au
-#         176 "ACST" and domain:au
-#          29 "ACDT" and domain:au
-#
-#       7,539 "WST" and domain:au
-#          68 "AWST" and domain:au
-#
-#   This data suggest that Australians tend to omit the "A" prefix in
-#   practice.  The situation for "ST" versus "DT" is less clear, given
-#   the ambiguities involved.
-#
-# * How do Australians feel about the abbreviations in the tz database?
-#
-#   If you just count Australians on this list, I count 2 in favor and 3
-#   against.  One of the "against" votes (David Keegel) counseled delay,
-#   saying that both AEST/AEDT and EST/EST are widely used and
-#   understood in Australia.
-
-# From Paul Eggert (1995-12-19):
-# Shanks & Pottenger report 2:00 for all autumn changes in Australia and NZ.
-# Mark Prior writes that his newspaper
-# reports that NSW's fall 1995 change will occur at 2:00,
-# but Robert Elz says it's been 3:00 in Victoria since 1970
-# and perhaps the newspaper's `2:00' is referring to standard time.
-# For now we'll continue to assume 2:00s for changes since 1960.
-
-# From Eric Ulevik (1998-01-05):
-#
-# Here are some URLs to Australian time legislation. These URLs are stable,
-# and should probably be included in the data file. There are probably more
-# relevant entries in this database.
-#
-# NSW (including LHI and Broken Hill):
-# <a href="http://www.austlii.edu.au/au/legis/nsw/consol_act/sta1987137/index.html">
-# Standard Time Act 1987 (updated 1995-04-04)
-# </a>
-# ACT
-# <a href="http://www.austlii.edu.au/au/legis/act/consol_act/stasta1972279/index.html">
-# Standard Time and Summer Time Act 1972
-# </a>
-# SA
-# <a href="http://www.austlii.edu.au/au/legis/sa/consol_act/sta1898137/index.html">
-# Standard Time Act, 1898
-# </a>
-
-# From David Grosz (2005-06-13):
-# It was announced last week that Daylight Saving would be extended by
-# one week next year to allow for the 2006 Commonwealth Games.
-# Daylight Saving is now to end for next year only on the first Sunday
-# in April instead of the last Sunday in March.
-#
-# From Gwillim Law (2005-06-14):
-# I did some Googling and found that all of those states (and territory) plan
-# to extend DST together in 2006.
-# ACT: http://www.cmd.act.gov.au/mediareleases/fileread.cfm?file=86.txt
-# New South Wales: http://www.thecouriermail.news.com.au/common/story_page/0,5936,15538869%255E1702,00.html
-# South Australia: http://www.news.com.au/story/0,10117,15555031-1246,00.html
-# Tasmania: http://www.media.tas.gov.au/release.php?id=14772
-# Victoria: I wasn't able to find anything separate, but the other articles
-# allude to it.
-# But not Queensland
-# http://www.news.com.au/story/0,10117,15564030-1248,00.html.
-
-# Northern Territory
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# # The NORTHERN TERRITORY..  [ Courtesy N.T. Dept of the Chief Minister ]
-# #					[ Nov 1990 ]
-# #	N.T. have never utilised any DST due to sub-tropical/tropical location.
-# ...
-# Zone        Australia/North         9:30    -       CST
-
-# From Bradley White (1991-03-04):
-# A recent excerpt from an Australian newspaper...
-# the Northern Territory do[es] not have daylight saving.
-
-# Western Australia
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# #  The state of WESTERN AUSTRALIA..  [ Courtesy W.A. dept Premier+Cabinet ]
-# #						[ Nov 1990 ]
-# #	W.A. suffers from a great deal of public and political opposition to
-# #	DST in principle. A bill is brought before parliament in most years, but
-# #	usually defeated either in the upper house, or in party caucus
-# #	before reaching parliament.
-# ...
-# Zone	Australia/West		8:00	AW	%sST
-# ...
-# Rule	AW	1974	only	-	Oct	lastSun	2:00	1:00	D
-# Rule	AW	1975	only	-	Mar	Sun>=1	3:00	0	W
-# Rule	AW	1983	only	-	Oct	lastSun	2:00	1:00	D
-# Rule	AW	1984	only	-	Mar	Sun>=1	3:00	0	W
-
-# From Bradley White (1991-03-04):
-# A recent excerpt from an Australian newspaper...
-# Western Australia...do[es] not have daylight saving.
-
-# From John D. Newman via Bradley White (1991-11-02):
-# Western Australia is still on "winter time". Some DH in Sydney
-# rang me at home a few days ago at 6.00am. (He had just arrived at
-# work at 9.00am.)
-# W.A. is switching to Summer Time on Nov 17th just to confuse
-# everybody again.
-
-# From Arthur David Olson (1992-03-08):
-# The 1992 ending date used in the rules is a best guess;
-# it matches what was used in the past.
-
-# <a href="http://www.bom.gov.au/faq/faqgen.htm">
-# The Australian Bureau of Meteorology FAQ
-# </a> (1999-09-27) writes that Giles Meteorological Station uses
-# South Australian time even though it's located in Western Australia.
-
-# Queensland
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# #   The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ]
-# #						[ Dec 1990 ]
-# ...
-# Zone	Australia/Queensland	10:00	AQ	%sST
-# ...
-# Rule	AQ	1971	only	-	Oct	lastSun	2:00	1:00	D
-# Rule	AQ	1972	only	-	Feb	lastSun	3:00	0	E
-# Rule	AQ	1989	max	-	Oct	lastSun	2:00	1:00	D
-# Rule	AQ	1990	max	-	Mar	Sun>=1	3:00	0	E
-
-# From Bradley White (1989-12-24):
-# "Australia/Queensland" now observes daylight time (i.e. from
-# October 1989).
-
-# From Bradley White (1991-03-04):
-# A recent excerpt from an Australian newspaper...
-# ...Queensland...[has] agreed to end daylight saving
-# at 3am tomorrow (March 3)...
-
-# From John Mackin (1991-03-06):
-# I can certainly confirm for my part that Daylight Saving in NSW did in fact
-# end on Sunday, 3 March.  I don't know at what hour, though.  (It surprised
-# me.)
-
-# From Bradley White (1992-03-08):
-# ...there was recently a referendum in Queensland which resulted
-# in the experimental daylight saving system being abandoned. So, ...
-# ...
-# Rule	QLD	1989	1991	-	Oct	lastSun	2:00	1:00	D
-# Rule	QLD	1990	1992	-	Mar	Sun>=1	3:00	0	S
-# ...
-
-# From Arthur David Olson (1992-03-08):
-# The chosen rules the union of the 1971/1972 change and the 1989-1992 changes.
-
-# From Christopher Hunt (2006-11-21), after an advance warning
-# from Jesper Norgaard Welen (2006-11-01):
-# WA are trialing DST for three years.
-# <http://www.parliament.wa.gov.au/parliament/bills.nsf/9A1B183144403DA54825721200088DF1/$File/Bill175-1B.pdf>
-
-# From Rives McDow (2002-04-09):
-# The most interesting region I have found consists of three towns on the
-# southern coast....  South Australia observes daylight saving time; Western
-# Australia does not.  The two states are one and a half hours apart.  The
-# residents decided to forget about this nonsense of changing the clock so
-# much and set the local time 20 hours and 45 minutes from the
-# international date line, or right in the middle of the time of South
-# Australia and Western Australia....
-#
-# From Paul Eggert (2002-04-09):
-# This is confirmed by the section entitled
-# "What's the deal with time zones???" in
-# <http://www.earthsci.unimelb.edu.au/~awatkins/null.html>.
-#
-# From Alex Livingston (2006-12-07):
-# ... it was just on four years ago that I drove along the Eyre Highway,
-# which passes through eastern Western Australia close to the southern
-# coast of the continent.
-#
-# I paid particular attention to the time kept there. There can be no
-# dispute that UTC+08:45 was considered "the time" from the border
-# village just inside the border with South Australia to as far west
-# as just east of Caiguna. There can also be no dispute that Eucla is
-# the largest population centre in this zone....
-#
-# Now that Western Australia is observing daylight saving, the
-# question arose whether this part of the state would follow suit. I
-# just called the border village and confirmed that indeed they have,
-# meaning that they are now observing UTC+09:45.
-#
-# (2006-12-09):
-# I personally doubt that either experimentation with daylight saving
-# in WA or its introduction in SA had anything to do with the genesis
-# of this time zone.  My hunch is that it's been around since well
-# before 1975.  I remember seeing it noted on road maps decades ago.
-
-# From Paul Eggert (2006-12-15):
-# For lack of better info, assume the tradition dates back to the
-# introduction of standard time in 1895.
-
-
-# southeast Australia
-#
-# From Paul Eggert (2007-07-23):
-# Starting autumn 2008 Victoria, NSW, South Australia, Tasmania and the ACT
-# end DST the first Sunday in April and start DST the first Sunday in October.
-# http://www.theage.com.au/news/national/daylight-savings-to-span-six-months/2007/06/27/1182623966703.html
-
-
-# South Australia
-
-# From Bradley White (1991-03-04):
-# A recent excerpt from an Australian newspaper...
-# ...South Australia...[has] agreed to end daylight saving
-# at 3am tomorrow (March 3)...
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# #   The state of SOUTH AUSTRALIA....[ Courtesy of S.A. Dept of Labour ]
-# #						[ Nov 1990 ]
-# ...
-# Zone	Australia/South		9:30	AS	%sST
-# ...
-# Rule	 AS	1971	max	-	Oct	lastSun	2:00	1:00	D
-# Rule	 AS	1972	1985	-	Mar	Sun>=1	3:00	0	C
-# Rule	 AS	1986	1990	-	Mar	Sun>=15	3:00	0	C
-# Rule	 AS	1991	max	-	Mar	Sun>=1	3:00	0	C
-
-# From Bradley White (1992-03-11):
-# Recent correspondence with a friend in Adelaide
-# contained the following exchange:  "Due to the Adelaide Festival,
-# South Australia delays setting back our clocks for a few weeks."
-
-# From Robert Elz (1992-03-13):
-# I heard that apparently (or at least, it appears that)
-# South Aus will have an extra 3 weeks daylight saving every even
-# numbered year (from 1990).  That's when the Adelaide Festival
-# is on...
-
-# From Robert Elz (1992-03-16, 00:57:07 +1000):
-# DST didn't end in Adelaide today (yesterday)....
-# But whether it's "4th Sunday" or "2nd last Sunday" I have no idea whatever...
-# (it's just as likely to be "the Sunday we pick for this year"...).
-
-# From Bradley White (1994-04-11):
-# If Sun, 15 March, 1992 was at +1030 as kre asserts, but yet Sun, 20 March,
-# 1994 was at +0930 as John Connolly's customer seems to assert, then I can
-# only conclude that the actual rule is more complicated....
-
-# From John Warburton (1994-10-07):
-# The new Daylight Savings dates for South Australia ...
-# was gazetted in the Government Hansard on Sep 26 1994....
-# start on last Sunday in October and end in last sunday in March.
-
-# From Paul Eggert (2007-07-23):
-# See "southeast Australia" above for 2008 and later.
-
-# Tasmania
-
-# The rules for 1967 through 1991 were reported by George Shepherd
-# via Simon Woodhead via Robert Elz (1991-03-06):
-# #  The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ]
-# #					[ Nov 1990 ]
-
-# From Bill Hart via Guy Harris (1991-10-10):
-# Oh yes, the new daylight savings rules are uniquely tasmanian, we have
-# 6 weeks a year now when we are out of sync with the rest of Australia
-# (but nothing new about that).
-
-# From Alex Livingston (1999-10-04):
-# I heard on the ABC (Australian Broadcasting Corporation) radio news on the
-# (long) weekend that Tasmania, which usually goes its own way in this regard,
-# has decided to join with most of NSW, the ACT, and most of Victoria
-# (Australia) and start daylight saving on the last Sunday in August in 2000
-# instead of the first Sunday in October.
-
-# Sim Alam (2000-07-03) reported a legal citation for the 2000/2001 rules:
-# http://www.thelaw.tas.gov.au/fragview/42++1968+GS3A@EN+2000070300
-
-# From Paul Eggert (2007-07-23):
-# See "southeast Australia" above for 2008 and later.
-
-# Victoria
-
-# The rules for 1971 through 1991 were reported by George Shepherd
-# via Simon Woodhead via Robert Elz (1991-03-06):
-# #   The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ]
-# #						[ Nov 1990 ]
-
-# From Scott Harrington (2001-08-29):
-# On KQED's "City Arts and Lectures" program last night I heard an
-# interesting story about daylight savings time.  Dr. John Heilbron was
-# discussing his book "The Sun in the Church: Cathedrals as Solar
-# Observatories"[1], and in particular the Shrine of Remembrance[2] located
-# in Melbourne, Australia.
-#
-# Apparently the shrine's main purpose is a beam of sunlight which
-# illuminates a special spot on the floor at the 11th hour of the 11th day
-# of the 11th month (Remembrance Day) every year in memory of Australia's
-# fallen WWI soldiers.  And if you go there on Nov. 11, at 11am local time,
-# you will indeed see the sunbeam illuminate the special spot at the
-# expected time.
-#
-# However, that is only because of some special mirror contraption that had
-# to be employed, since due to daylight savings time, the true solar time of
-# the remembrance moment occurs one hour later (or earlier?).  Perhaps
-# someone with more information on this jury-rig can tell us more.
-#
-# [1] http://www.hup.harvard.edu/catalog/HEISUN.html
-# [2] http://www.shrine.org.au
-
-# From Paul Eggert (2007-07-23):
-# See "southeast Australia" above for 2008 and later.
-
-# New South Wales
-
-# From Arthur David Olson:
-# New South Wales and subjurisdictions have their own ideas of a fun time.
-# Based on law library research by John Mackin,
-# who notes:
-#	In Australia, time is not legislated federally, but rather by the
-#	individual states.  Thus, while such terms as ``Eastern Standard Time''
-#	[I mean, of course, Australian EST, not any other kind] are in common
-#	use, _they have NO REAL MEANING_, as they are not defined in the
-#	legislation.  This is very important to understand.
-#	I have researched New South Wales time only...
-
-# From Eric Ulevik (1999-05-26):
-# DST will start in NSW on the last Sunday of August, rather than the usual
-# October in 2000.  [See: Matthew Moore,
-# <a href="http://www.smh.com.au/news/9905/26/pageone/pageone4.html">
-# Two months more daylight saving
-# </a>
-# Sydney Morning Herald (1999-05-26).]
-
-# From Paul Eggert (1999-09-27):
-# See the following official NSW source:
-# <a href="http://dir.gis.nsw.gov.au/cgi-bin/genobject/document/other/daylightsaving/tigGmZ">
-# Daylight Saving in New South Wales.
-# </a>
-#
-# Narrabri Shire (NSW) council has announced it will ignore the extension of
-# daylight saving next year.  See:
-# <a href="http://abc.net.au/news/regionals/neweng/monthly/regeng-22jul1999-1.htm">
-# Narrabri Council to ignore daylight saving
-# </a> (1999-07-22).  For now, we'll wait to see if this really happens.
-#
-# Victoria will following NSW.  See:
-# <a href="http://abc.net.au/local/news/olympics/1999/07/item19990728112314_1.htm">
-# Vic to extend daylight saving
-# </a> (1999-07-28).
-#
-# However, South Australia rejected the DST request.  See:
-# <a href="http://abc.net.au/news/olympics/1999/07/item19990719151754_1.htm">
-# South Australia rejects Olympics daylight savings request
-# </a> (1999-07-19).
-#
-# Queensland also will not observe DST for the Olympics.  See:
-# <a href="http://abc.net.au/news/olympics/1999/06/item19990601114608_1.htm">
-# Qld says no to daylight savings for Olympics
-# </a> (1999-06-01), which quotes Queensland Premier Peter Beattie as saying
-# ``Look you've got to remember in my family when this came up last time
-# I voted for it, my wife voted against it and she said to me it's all very
-# well for you, you don't have to worry about getting the children out of
-# bed, getting them to school, getting them to sleep at night.
-# I've been through all this argument domestically...my wife rules.''
-#
-# Broken Hill will stick with South Australian time in 2000.  See:
-# <a href="http://abc.net.au/news/regionals/brokenh/monthly/regbrok-21jul1999-6.htm">
-# Broken Hill to be behind the times
-# </a> (1999-07-21).
-
-# IATA SSIM (1998-09) says that the spring 2000 change for Australian
-# Capital Territory, New South Wales except Lord Howe Island and Broken
-# Hill, and Victoria will be August 27, presumably due to the Sydney Olympics.
-
-# From Eric Ulevik, referring to Sydney's Sun Herald (2000-08-13), page 29:
-# The Queensland Premier Peter Beattie is encouraging northern NSW
-# towns to use Queensland time.
-
-# From Paul Eggert (2007-07-23):
-# See "southeast Australia" above for 2008 and later.
-
-# Yancowinna
-
-# From John Mackin (1989-01-04):
-# `Broken Hill' means the County of Yancowinna.
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# # YANCOWINNA..  [ Confirmation courtesy of Broken Hill Postmaster ]
-# #					[ Dec 1990 ]
-# ...
-# # Yancowinna uses Central Standard Time, despite [its] location on the
-# # New South Wales side of the S.A. border. Most business and social dealings
-# # are with CST zones, therefore CST is legislated by local government
-# # although the switch to Summer Time occurs in line with N.S.W. There have
-# # been years when this did not apply, but the historical data is not
-# # presently available.
-# Zone	Australia/Yancowinna	9:30	 AY	%sST
-# ...
-# Rule	 AY	1971	1985	-	Oct	lastSun	2:00	1:00	D
-# Rule	 AY	1972	only	-	Feb	lastSun	3:00	0	C
-# [followed by other Rules]
-
-# Lord Howe Island
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# LHI...		[ Courtesy of Pauline Van Winsen ]
-#					[ Dec 1990 ]
-# Lord Howe Island is located off the New South Wales coast, and is half an
-# hour ahead of NSW time.
-
-# From James Lonergan, Secretary, Lord Howe Island Board (2000-01-27):
-# Lord Howe Island summer time in 2000/2001 will commence on the same
-# date as the rest of NSW (i.e. 2000-08-27).  For your information the
-# Lord Howe Island Board (controlling authority for the Island) is
-# seeking the community's views on various options for summer time
-# arrangements on the Island, e.g. advance clocks by 1 full hour
-# instead of only 30 minutes.  Dependant on the wishes of residents
-# the Board may approach the NSW government to change the existing
-# arrangements.  The starting date for summer time on the Island will
-# however always coincide with the rest of NSW.
-
-# From James Lonergan, Secretary, Lord Howe Island Board (2000-10-25):
-# Lord Howe Island advances clocks by 30 minutes during DST in NSW and retards
-# clocks by 30 minutes when DST finishes. Since DST was most recently
-# introduced in NSW, the "changeover" time on the Island has been 02:00 as
-# shown on clocks on LHI. I guess this means that for 30 minutes at the start
-# of DST, LHI is actually 1 hour ahead of the rest of NSW.
-
-# From Paul Eggert (2006-03-22):
-# For Lord Howe dates we use Shanks & Pottenger through 1989, and
-# Lonergan thereafter.  For times we use Lonergan.
-
-# From Paul Eggert (2007-07-23):
-# See "southeast Australia" above for 2008 and later.
-
-# From Steffen Thorsen (2009-04-28):
-# According to the official press release, South Australia's extended daylight 
-# saving period will continue with the same rules as used during the 2008-2009 
-# summer (southern hemisphere).
-# 
-# From
-# <a href="http://www.safework.sa.gov.au/uploaded_files/DaylightDatesSet.pdf">
-# http://www.safework.sa.gov.au/uploaded_files/DaylightDatesSet.pdf
-# </a>
-# The extended daylight saving period that South Australia has been trialling 
-# for over the last year is now set to be ongoing.
-# Daylight saving will continue to start on the first Sunday in October each 
-# year and finish on the first Sunday in April the following year.
-# Industrial Relations Minister, Paul Caica, says this provides South Australia 
-# with a consistent half hour time difference with NSW, Victoria, Tasmania and 
-# the ACT for all 52 weeks of the year...
-# 
-# We have a wrap-up here:
-# <a href="http://www.timeanddate.com/news/time/south-australia-extends-dst.html">
-# http://www.timeanddate.com/news/time/south-australia-extends-dst.html
-# </a>
-###############################################################################
-
-# New Zealand
-
-# From Mark Davies (1990-10-03):
-# the 1989/90 year was a trial of an extended "daylight saving" period.
-# This trial was deemed successful and the extended period adopted for
-# subsequent years (with the addition of a further week at the start).
-# source -- phone call to Ministry of Internal Affairs Head Office.
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# # The Country of New Zealand   (Australia's east island -) Gee they hate that!
-# #				   or is Australia the west island of N.Z.
-# #	[ courtesy of Geoff Tribble.. Auckland N.Z. ]
-# #				[ Nov 1990 ]
-# ...
-# Rule	NZ      1974    1988	-	Oct	lastSun	2:00	1:00	D
-# Rule	NZ	1989	max	-	Oct	Sun>=1	2:00	1:00	D
-# Rule	NZ      1975    1989	-	Mar	Sun>=1	3:00	0	S
-# Rule	NZ	1990	max	-	Mar	lastSun	3:00	0	S
-# ...
-# Zone	NZ			12:00	NZ		NZ%sT	# New Zealand
-# Zone	NZ-CHAT			12:45	-		NZ-CHAT # Chatham Island
-
-# From Arthur David Olson (1992-03-08):
-# The chosen rules use the Davies October 8 values for the start of DST in 1989
-# rather than the October 1 value.
-
-# From Paul Eggert (1995-12-19);
-# Shank & Pottenger report 2:00 for all autumn changes in Australia and NZ.
-# Robert Uzgalis writes that the New Zealand Daylight
-# Savings Time Order in Council dated 1990-06-18 specifies 2:00 standard
-# time on both the first Sunday in October and the third Sunday in March.
-# As with Australia, we'll assume the tradition is 2:00s, not 2:00.
-#
-# From Paul Eggert (2006-03-22):
-# The Department of Internal Affairs (DIA) maintains a brief history,
-# as does Carol Squires; see tz-link.htm for the full references.
-# Use these sources in preference to Shanks & Pottenger.
-#
-# For Chatham, IATA SSIM (1991/1999) gives the NZ rules but with
-# transitions at 2:45 local standard time; this confirms that Chatham
-# is always exactly 45 minutes ahead of Auckland.
-
-# From Colin Sharples (2007-04-30):
-# DST will now start on the last Sunday in September, and end on the
-# first Sunday in April.  The changes take effect this year, meaning
-# that DST will begin on 2007-09-30 2008-04-06.
-# http://www.dia.govt.nz/diawebsite.nsf/wpg_URL/Services-Daylight-Saving-Daylight-saving-to-be-extended
-
-###############################################################################
-
-
-# Fiji
-
-# Howse writes (p 153) that in 1879 the British governor of Fiji
-# enacted an ordinance standardizing the islands on Antipodean Time
-# instead of the American system (which was one day behind).
-
-# From Rives McDow (1998-10-08):
-# Fiji will introduce DST effective 0200 local time, 1998-11-01
-# until 0300 local time 1999-02-28.  Each year the DST period will
-# be from the first Sunday in November until the last Sunday in February.
-
-# From Paul Eggert (2000-01-08):
-# IATA SSIM (1999-09) says DST ends 0100 local time.  Go with McDow.
-
-# From the BBC World Service (1998-10-31 11:32 UTC):
-# The Fijiian government says the main reasons for the time change is to
-# improve productivity and reduce road accidents.  But correspondents say it
-# also hopes the move will boost Fiji's ability to compete with other pacific
-# islands in the effort to attract tourists to witness the dawning of the new
-# millenium.
-
-# http://www.fiji.gov.fj/press/2000_09/2000_09_13-05.shtml (2000-09-13)
-# reports that Fiji has discontinued DST.
-
-# Johnston
-
-# Johnston data is from usno1995.
-
-
-# Kiribati
-
-# From Paul Eggert (1996-01-22):
-# Today's _Wall Street Journal_ (page 1) reports that Kiribati
-# ``declared it the same day throught the country as of Jan. 1, 1995''
-# as part of the competition to be first into the 21st century.
-
-
-# Kwajalein
-
-# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
-# I wonder what happened in Kwajalein, where there was NO Friday,
-# 1993-08-20.  Thursday night at midnight Kwajalein switched sides with
-# respect to the International Date Line, to rejoin its fellow islands,
-# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
-
-
-# N Mariana Is, Guam
-
-# Howse writes (p 153) ``The Spaniards, on the other hand, reached the
-# Philippines and the Ladrones from America,'' and implies that the Ladrones
-# (now called the Marianas) kept American date for quite some time.
-# For now, we assume the Ladrones switched at the same time as the Philippines;
-# see Asia/Manila.
-
-# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
-# under the name "Chamorro Standard Time".  There is no official abbreviation,
-# but Congressman Robert A. Underwood, author of the bill that became law,
-# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
-
-
-# Micronesia
-
-# Alan Eugene Davis writes (1996-03-16),
-# ``I am certain, having lived there for the past decade, that "Truk"
-# (now properly known as Chuuk) ... is in the time zone GMT+10.''
-#
-# Shanks & Pottenger write that Truk switched from UTC+10 to UTC+11
-# on 1978-10-01; ignore this for now.
-
-# From Paul Eggert (1999-10-29):
-# The Federated States of Micronesia Visitors Board writes in
-# <a href="http://www.fsmgov.org/info/clocks.html">
-# The Federated States of Micronesia - Visitor Information
-# </a> (1999-01-26)
-# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
-# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
-
-
-# Midway
-
-# From Charles T O'Connor, KMTH DJ (1956),
-# quoted in the KTMH section of the Radio Heritage Collection
-# <http://radiodx.com/spdxr/KMTH.htm> (2002-12-31):
-# For the past two months we've been on what is known as Daylight
-# Saving Time.  This time has put us on air at 5am in the morning,
-# your time down there in New Zealand.  Starting September 2, 1956
-# we'll again go back to Standard Time.  This'll mean that we'll go to
-# air at 6am your time.
-#
-# From Paul Eggert (2003-03-23):
-# We don't know the date of that quote, but we'll guess they
-# started DST on June 3.  Possibly DST was observed other years
-# in Midway, but we have no record of it.
-
-
-# Pitcairn
-
-# From Rives McDow (1999-11-08):
-# A Proclamation was signed by the Governor of Pitcairn on the 27th March 1998
-# with regard to Pitcairn Standard Time.  The Proclamation is as follows.
-#
-#	The local time for general purposes in the Islands shall be
-#	Co-ordinated Universal time minus 8 hours and shall be known
-#	as Pitcairn Standard Time.
-#
-# ... I have also seen Pitcairn listed as UTC minus 9 hours in several
-# references, and can only assume that this was an error in interpretation
-# somehow in light of this proclamation.
-
-# From Rives McDow (1999-11-09):
-# The Proclamation regarding Pitcairn time came into effect on 27 April 1998
-# ... at midnight.
-
-# From Howie Phelps (1999-11-10), who talked to a Pitcairner via shortwave:
-# Betty Christian told me yesterday that their local time is the same as
-# Pacific Standard Time. They used to be 1/2 hour different from us here in
-# Sacramento but it was changed a couple of years ago.
-
-
-# Samoa
-
-# Howse writes (p 153, citing p 10 of the 1883-11-18 New York Herald)
-# that in 1879 the King of Samoa decided to change
-# ``the date in his kingdom from the Antipodean to the American system,
-# ordaining -- by a masterpiece of diplomatic flattery -- that
-# the Fourth of July should be celebrated twice in that year.''
-
-
-# Tonga
-
-# From Paul Eggert (1996-01-22):
-# Today's _Wall Street Journal_ (p 1) reports that ``Tonga has been plotting
-# to sneak ahead of [New Zealanders] by introducing daylight-saving time.''
-# Since Kiribati has moved the Date Line it's not clear what Tonga will do.
-
-# Don Mundell writes in the 1997-02-20 Tonga Chronicle
-# <a href="http://www.tongatapu.net.to/tonga/homeland/timebegins.htm">
-# How Tonga became `The Land where Time Begins'
-# </a>:
-
-# Until 1941 Tonga maintained a standard time 50 minutes ahead of NZST
-# 12 hours and 20 minutes ahead of GMT.  When New Zealand adjusted its
-# standard time in 1940s, Tonga had the choice of subtracting from its
-# local time to come on the same standard time as New Zealand or of
-# advancing its time to maintain the differential of 13 degrees
-# (approximately 50 minutes ahead of New Zealand time).
-#
-# Because His Majesty King Taufa'ahau Tupou IV, then Crown Prince
-# Tungi, preferred to ensure Tonga's title as the land where time
-# begins, the Legislative Assembly approved the latter change.
-#
-# But some of the older, more conservative members from the outer
-# islands objected. "If at midnight on Dec. 31, we move ahead 40
-# minutes, as your Royal Highness wishes, what becomes of the 40
-# minutes we have lost?"
-#
-# The Crown Prince, presented an unanswerable argument: "Remember that
-# on the World Day of Prayer, you would be the first people on Earth
-# to say your prayers in the morning."
-
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger say the transition was on 1968-10-01; go with Mundell.
-
-# From Eric Ulevik (1999-05-03):
-# Tonga's director of tourism, who is also secretary of the National Millenium
-# Committee, has a plan to get Tonga back in front.
-# He has proposed a one-off move to tropical daylight saving for Tonga from
-# October to March, which has won approval in principle from the Tongan
-# Government.
-
-# From Steffen Thorsen (1999-09-09):
-# * Tonga will introduce DST in November
-#
-# I was given this link by John Letts:
-# <a href="http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm">
-# http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm
-# </a>
-#
-# I have not been able to find exact dates for the transition in November
-# yet. By reading this article it seems like Fiji will be 14 hours ahead
-# of UTC as well, but as far as I know Fiji will only be 13 hours ahead
-# (12 + 1 hour DST).
-
-# From Arthur David Olson (1999-09-20):
-# According to <a href="http://www.tongaonline.com/news/sept1799.html">
-# http://www.tongaonline.com/news/sept1799.html
-# </a>:
-# "Daylight Savings Time will take effect on Oct. 2 through April 15, 2000
-# and annually thereafter from the first Saturday in October through the
-# third Saturday of April.  Under the system approved by Privy Council on
-# Sept. 10, clocks must be turned ahead one hour on the opening day and
-# set back an hour on the closing date."
-# Alas, no indication of the time of day.
-
-# From Rives McDow (1999-10-06):
-# Tonga started its Daylight Saving on Saturday morning October 2nd at 0200am.
-# Daylight Saving ends on April 16 at 0300am which is Sunday morning.
-
-# From Steffen Thorsen (2000-10-31):
-# Back in March I found a notice on the website http://www.tongaonline.com
-# that Tonga changed back to standard time one month early, on March 19
-# instead of the original reported date April 16. Unfortunately, the article
-# is no longer available on the site, and I did not make a copy of the
-# text, and I have forgotten to report it here.
-# (Original URL was: http://www.tongaonline.com/news/march162000.htm )
-
-# From Rives McDow (2000-12-01):
-# Tonga is observing DST as of 2000-11-04 and will stop on 2001-01-27.
-
-# From Sione Moala-Mafi (2001-09-20) via Rives McDow:
-# At 2:00am on the first Sunday of November, the standard time in the Kingdom
-# shall be moved forward by one hour to 3:00am.  At 2:00am on the last Sunday
-# of January the standard time in the Kingdom shall be moved backward by one
-# hour to 1:00am.
-
-# From Pulu 'Anau (2002-11-05):
-# The law was for 3 years, supposedly to get renewed.  It wasn't.
-
-
-# Wake
-
-# From Vernice Anderson, Personal Secretary to Philip Jessup,
-# US Ambassador At Large (oral history interview, 1971-02-02):
-#
-# Saturday, the 14th [of October, 1950] -- ...  The time was all the
-# more confusing at that point, because we had crossed the
-# International Date Line, thus getting two Sundays.  Furthermore, we
-# discovered that Wake Island had two hours of daylight saving time
-# making calculation of time in Washington difficult if not almost
-# impossible.
-#
-# http://www.trumanlibrary.org/wake/meeting.htm
-
-# From Paul Eggert (2003-03-23):
-# We have no other report of DST in Wake Island, so omit this info for now.
-
-###############################################################################
-
-# The International Date Line
-
-# From Gwillim Law (2000-01-03):
-#
-# The International Date Line is not defined by any international standard,
-# convention, or treaty.  Mapmakers are free to draw it as they please.
-# Reputable mapmakers will simply ensure that every point of land appears on
-# the correct side of the IDL, according to the date legally observed there.
-#
-# When Kiribati adopted a uniform date in 1995, thereby moving the Phoenix and
-# Line Islands to the west side of the IDL (or, if you prefer, moving the IDL
-# to the east side of the Phoenix and Line Islands), I suppose that most
-# mapmakers redrew the IDL following the boundary of Kiribati.  Even that line
-# has a rather arbitrary nature.  The straight-line boundaries between Pacific
-# island nations that are shown on many maps are based on an international
-# convention, but are not legally binding national borders.... The date is
-# governed by the IDL; therefore, even on the high seas, there may be some
-# places as late as fourteen hours later than UTC.  And, since the IDL is not
-# an international standard, there are some places on the high seas where the
-# correct date is ambiguous.
-
-# From Wikipedia <http://en.wikipedia.org/wiki/Time_zone> (2005-08-31):
-# Before 1920, all ships kept local apparent time on the high seas by setting
-# their clocks at night or at the morning sight so that, given the ship's
-# speed and direction, it would be 12 o'clock when the Sun crossed the ship's
-# meridian (12 o'clock = local apparent noon).  During 1917, at the
-# Anglo-French Conference on Time-keeping at Sea, it was recommended that all
-# ships, both military and civilian, should adopt hourly standard time zones
-# on the high seas.  Whenever a ship was within the territorial waters of any
-# nation it would use that nation's standard time.  The captain was permitted
-# to change his ship's clocks at a time of his choice following his ship's
-# entry into another zone time--he often chose midnight.  These zones were
-# adopted by all major fleets between 1920 and 1925 but not by many
-# independent merchant ships until World War II.
-
-# From Paul Eggert, using references suggested by Oscar van Vlijmen
-# (2005-03-20):
-#
-# The American Practical Navigator (2002)
-# <http://pollux.nss.nima.mil/pubs/pubs_j_apn_sections.html?rid=187>
-# talks only about the 180-degree meridian with respect to ships in
-# international waters; it ignores the international date line.
diff --git a/tools/zoneinfo/tzdata2010k/backward b/tools/zoneinfo/tzdata2010k/backward
deleted file mode 100644
index f1f95a8..0000000
--- a/tools/zoneinfo/tzdata2010k/backward
+++ /dev/null
@@ -1,118 +0,0 @@
-# <pre>
-# @(#)backward	8.9
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# This file provides links between current names for time zones
-# and their old names.  Many names changed in late 1993.
-
-Link	Africa/Asmara		Africa/Asmera
-Link	Africa/Bamako		Africa/Timbuktu
-Link	America/Argentina/Catamarca	America/Argentina/ComodRivadavia
-Link	America/Adak		America/Atka
-Link	America/Argentina/Buenos_Aires	America/Buenos_Aires
-Link	America/Argentina/Catamarca	America/Catamarca
-Link	America/Atikokan	America/Coral_Harbour
-Link	America/Argentina/Cordoba	America/Cordoba
-Link	America/Tijuana		America/Ensenada
-Link	America/Indiana/Indianapolis	America/Fort_Wayne
-Link	America/Indiana/Indianapolis	America/Indianapolis
-Link	America/Argentina/Jujuy	America/Jujuy
-Link	America/Indiana/Knox	America/Knox_IN
-Link	America/Kentucky/Louisville	America/Louisville
-Link	America/Argentina/Mendoza	America/Mendoza
-Link	America/Rio_Branco	America/Porto_Acre
-Link	America/Argentina/Cordoba	America/Rosario
-Link	America/St_Thomas	America/Virgin
-Link	Asia/Ashgabat		Asia/Ashkhabad
-Link	Asia/Chongqing		Asia/Chungking
-Link	Asia/Dhaka		Asia/Dacca
-Link	Asia/Kathmandu		Asia/Katmandu
-Link	Asia/Kolkata		Asia/Calcutta
-Link	Asia/Macau		Asia/Macao
-Link	Asia/Jerusalem		Asia/Tel_Aviv
-Link	Asia/Ho_Chi_Minh	Asia/Saigon
-Link	Asia/Thimphu		Asia/Thimbu
-Link	Asia/Makassar		Asia/Ujung_Pandang
-Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
-Link	Atlantic/Faroe		Atlantic/Faeroe
-Link	Europe/Oslo		Atlantic/Jan_Mayen
-Link	Australia/Sydney	Australia/ACT
-Link	Australia/Sydney	Australia/Canberra
-Link	Australia/Lord_Howe	Australia/LHI
-Link	Australia/Sydney	Australia/NSW
-Link	Australia/Darwin	Australia/North
-Link	Australia/Brisbane	Australia/Queensland
-Link	Australia/Adelaide	Australia/South
-Link	Australia/Hobart	Australia/Tasmania
-Link	Australia/Melbourne	Australia/Victoria
-Link	Australia/Perth		Australia/West
-Link	Australia/Broken_Hill	Australia/Yancowinna
-Link	America/Rio_Branco	Brazil/Acre
-Link	America/Noronha		Brazil/DeNoronha
-Link	America/Sao_Paulo	Brazil/East
-Link	America/Manaus		Brazil/West
-Link	America/Halifax		Canada/Atlantic
-Link	America/Winnipeg	Canada/Central
-Link	America/Regina		Canada/East-Saskatchewan
-Link	America/Toronto		Canada/Eastern
-Link	America/Edmonton	Canada/Mountain
-Link	America/St_Johns	Canada/Newfoundland
-Link	America/Vancouver	Canada/Pacific
-Link	America/Regina		Canada/Saskatchewan
-Link	America/Whitehorse	Canada/Yukon
-Link	America/Santiago	Chile/Continental
-Link	Pacific/Easter		Chile/EasterIsland
-Link	America/Havana		Cuba
-Link	Africa/Cairo		Egypt
-Link	Europe/Dublin		Eire
-Link	Europe/London		Europe/Belfast
-Link	Europe/Chisinau		Europe/Tiraspol
-Link	Europe/London		GB
-Link	Europe/London		GB-Eire
-Link	Etc/GMT			GMT+0
-Link	Etc/GMT			GMT-0
-Link	Etc/GMT			GMT0
-Link	Etc/GMT			Greenwich
-Link	Asia/Hong_Kong		Hongkong
-Link	Atlantic/Reykjavik	Iceland
-Link	Asia/Tehran		Iran
-Link	Asia/Jerusalem		Israel
-Link	America/Jamaica		Jamaica
-Link	Asia/Tokyo		Japan
-Link	Pacific/Kwajalein	Kwajalein
-Link	Africa/Tripoli		Libya
-Link	America/Tijuana		Mexico/BajaNorte
-Link	America/Mazatlan	Mexico/BajaSur
-Link	America/Mexico_City	Mexico/General
-Link	Pacific/Auckland	NZ
-Link	Pacific/Chatham		NZ-CHAT
-Link	America/Denver		Navajo
-Link	Asia/Shanghai		PRC
-Link	Pacific/Pago_Pago	Pacific/Samoa
-Link	Pacific/Chuuk		Pacific/Yap
-Link	Pacific/Chuuk		Pacific/Truk
-Link	Pacific/Pohnpei		Pacific/Ponape
-Link	Europe/Warsaw		Poland
-Link	Europe/Lisbon		Portugal
-Link	Asia/Taipei		ROC
-Link	Asia/Seoul		ROK
-Link	Asia/Singapore		Singapore
-Link	Europe/Istanbul		Turkey
-Link	Etc/UCT			UCT
-Link	America/Anchorage	US/Alaska
-Link	America/Adak		US/Aleutian
-Link	America/Phoenix		US/Arizona
-Link	America/Chicago		US/Central
-Link	America/Indiana/Indianapolis	US/East-Indiana
-Link	America/New_York	US/Eastern
-Link	Pacific/Honolulu	US/Hawaii
-Link	America/Indiana/Knox	US/Indiana-Starke
-Link	America/Detroit		US/Michigan
-Link	America/Denver		US/Mountain
-Link	America/Los_Angeles	US/Pacific
-Link	Pacific/Pago_Pago	US/Samoa
-Link	Etc/UTC			UTC
-Link	Etc/UTC			Universal
-Link	Europe/Moscow		W-SU
-Link	Etc/UTC			Zulu
diff --git a/tools/zoneinfo/tzdata2010k/etcetera b/tools/zoneinfo/tzdata2010k/etcetera
deleted file mode 100644
index 5c93682..0000000
--- a/tools/zoneinfo/tzdata2010k/etcetera
+++ /dev/null
@@ -1,83 +0,0 @@
-# <pre>
-# @(#)etcetera	8.2
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# These entries are mostly present for historical reasons, so that
-# people in areas not otherwise covered by the tz files could "zic -l"
-# to a time zone that was right for their area.  These days, the
-# tz files cover almost all the inhabited world, and the only practical
-# need now for the entries that are not on UTC are for ships at sea
-# that cannot use POSIX TZ settings.
-
-Zone	Etc/GMT		0	-	GMT
-Zone	Etc/UTC		0	-	UTC
-Zone	Etc/UCT		0	-	UCT
-
-# The following link uses older naming conventions,
-# but it belongs here, not in the file `backward',
-# as functions like gmtime load the "GMT" file to handle leap seconds properly.
-# We want this to work even on installations that omit the other older names.
-Link	Etc/GMT				GMT
-
-Link	Etc/UTC				Etc/Universal
-Link	Etc/UTC				Etc/Zulu
-
-Link	Etc/GMT				Etc/Greenwich
-Link	Etc/GMT				Etc/GMT-0
-Link	Etc/GMT				Etc/GMT+0
-Link	Etc/GMT				Etc/GMT0
-
-# We use POSIX-style signs in the Zone names and the output abbreviations,
-# even though this is the opposite of what many people expect.
-# POSIX has positive signs west of Greenwich, but many people expect
-# positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
-# the abbreviation "GMT+4" and corresponds to 4 hours behind UTC
-# (i.e. west of Greenwich) even though many people would expect it to
-# mean 4 hours ahead of UTC (i.e. east of Greenwich).
-#
-# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation
-# (which is not yet supported by the tz code) allows for
-# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
-# ISO 8601 you can use TZ='<-0400>+4'.  Thus the commonly-expected
-# offset is kept within the angle bracket (and is used for display)
-# while the POSIX sign is kept outside the angle bracket (and is used
-# for calculation).
-#
-# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
-# GMT but uses the completely misleading abbreviation "GMT".
-
-# Earlier incarnations of this package were not POSIX-compliant,
-# and had lines such as
-#		Zone	GMT-12		-12	-	GMT-1200
-# We did not want things to change quietly if someone accustomed to the old
-# way does a
-#		zic -l GMT-12
-# so we moved the names into the Etc subdirectory.
-
-Zone	Etc/GMT-14	14	-	GMT-14	# 14 hours ahead of GMT
-Zone	Etc/GMT-13	13	-	GMT-13
-Zone	Etc/GMT-12	12	-	GMT-12
-Zone	Etc/GMT-11	11	-	GMT-11
-Zone	Etc/GMT-10	10	-	GMT-10
-Zone	Etc/GMT-9	9	-	GMT-9
-Zone	Etc/GMT-8	8	-	GMT-8
-Zone	Etc/GMT-7	7	-	GMT-7
-Zone	Etc/GMT-6	6	-	GMT-6
-Zone	Etc/GMT-5	5	-	GMT-5
-Zone	Etc/GMT-4	4	-	GMT-4
-Zone	Etc/GMT-3	3	-	GMT-3
-Zone	Etc/GMT-2	2	-	GMT-2
-Zone	Etc/GMT-1	1	-	GMT-1
-Zone	Etc/GMT+1	-1	-	GMT+1
-Zone	Etc/GMT+2	-2	-	GMT+2
-Zone	Etc/GMT+3	-3	-	GMT+3
-Zone	Etc/GMT+4	-4	-	GMT+4
-Zone	Etc/GMT+5	-5	-	GMT+5
-Zone	Etc/GMT+6	-6	-	GMT+6
-Zone	Etc/GMT+7	-7	-	GMT+7
-Zone	Etc/GMT+8	-8	-	GMT+8
-Zone	Etc/GMT+9	-9	-	GMT+9
-Zone	Etc/GMT+10	-10	-	GMT+10
-Zone	Etc/GMT+11	-11	-	GMT+11
-Zone	Etc/GMT+12	-12	-	GMT+12
diff --git a/tools/zoneinfo/tzdata2010k/europe b/tools/zoneinfo/tzdata2010k/europe
deleted file mode 100644
index 8ca6d8f..0000000
--- a/tools/zoneinfo/tzdata2010k/europe
+++ /dev/null
@@ -1,2724 +0,0 @@
-# <pre>
-# @(#)europe	8.27
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
-# San Diego: ACS Publications, Inc. (2003).
-#
-# Gwillim Law writes that a good source
-# for recent time zone data is the International Air Transport
-# Association's Standard Schedules Information Manual (IATA SSIM),
-# published semiannually.  Law sent in several helpful summaries
-# of the IATA's data after 1990.
-#
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1991, and IATA SSIM is the source for entries afterwards.
-#
-# Other sources occasionally used include:
-#
-#	Edward W. Whitman, World Time Differences,
-#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
-#	which I found in the UCLA library.
-#
-#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
-#	William Willett, The Waste of Daylight, 19th edition
-#	</a> (1914-03)
-#
-#	Brazil's Departamento Servico da Hora (DSH),
-#	<a href="http://pcdsh01.on.br/HISTHV.htm">
-#	History of Summer Time
-#	</a> (1998-09-21, in Portuguese)
-
-#
-# I invented the abbreviations marked `*' in the following table;
-# the rest are from earlier versions of this file, or from other sources.
-# Corrections are welcome!
-#                   std dst  2dst
-#                   LMT           Local Mean Time
-#       -4:00       AST ADT       Atlantic
-#       -3:00       WGT WGST      Western Greenland*
-#       -1:00       EGT EGST      Eastern Greenland*
-#        0:00       GMT BST  BDST Greenwich, British Summer
-#        0:00       GMT IST       Greenwich, Irish Summer
-#        0:00       WET WEST WEMT Western Europe
-#        0:19:32.13 AMT NST       Amsterdam, Netherlands Summer (1835-1937)*
-#        0:20       NET NEST      Netherlands (1937-1940)*
-#        1:00       CET CEST CEMT Central Europe
-#        1:00:14    SET           Swedish (1879-1899)*
-#        2:00       EET EEST      Eastern Europe
-#        3:00       MSK MSD       Moscow
-#
-# A reliable and entertaining source about time zones, especially in Britain,
-# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
-
-# From Peter Ilieve (1994-12-04),
-# The original six [EU members]: Belgium, France, (West) Germany, Italy,
-# Luxembourg, the Netherlands.
-# Plus, from 1 Jan 73: Denmark, Ireland, United Kingdom.
-# Plus, from 1 Jan 81: Greece.
-# Plus, from 1 Jan 86: Spain, Portugal.
-# Plus, from 1 Jan 95: Austria, Finland, Sweden. (Norway negotiated terms for
-# entry but in a referendum on 28 Nov 94 the people voted No by 52.2% to 47.8%
-# on a turnout of 88.6%. This was almost the same result as Norway's previous
-# referendum in 1972, they are the only country to have said No twice.
-# Referendums in the other three countries voted Yes.)
-# ...
-# Estonia ... uses EU dates but not at 01:00 GMT, they use midnight GMT.
-# I don't think they know yet what they will do from 1996 onwards.
-# ...
-# There shouldn't be any [current members who are not using EU rules].
-# A Directive has the force of law, member states are obliged to enact
-# national law to implement it. The only contentious issue was the
-# different end date for the UK and Ireland, and this was always allowed
-# in the Directive.
-
-
-###############################################################################
-
-# Britain (United Kingdom) and Ireland (Eire)
-
-# From Peter Ilieve (1994-07-06):
-#
-# On 17 Jan 1994 the Independent, a UK quality newspaper, had a piece about
-# historical vistas along the Thames in west London. There was a photo
-# and a sketch map showing some of the sightlines involved. One paragraph
-# of the text said:
-#
-# `An old stone obelisk marking a forgotten terrestrial meridian stands
-# beside the river at Kew. In the 18th century, before time and longitude
-# was standardised by the Royal Observatory in Greenwich, scholars observed
-# this stone and the movement of stars from Kew Observatory nearby. They
-# made their calculations and set the time for the Horse Guards and Parliament,
-# but now the stone is obscured by scrubwood and can only be seen by walking
-# along the towpath within a few yards of it.'
-#
-# I have a one inch to one mile map of London and my estimate of the stone's
-# position is 51 deg. 28' 30" N, 0 deg. 18' 45" W. The longitude should
-# be within about +-2". The Ordnance Survey grid reference is TQ172761.
-#
-# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.]
-
-# From Paul Eggert (1993-11-18):
-#
-# Howse writes that Britain was the first country to use standard time.
-# The railways cared most about the inconsistencies of local mean time,
-# and it was they who forced a uniform time on the country.
-# The original idea was credited to Dr. William Hyde Wollaston (1766-1828)
-# and was popularized by Abraham Follett Osler (1808-1903).
-# The first railway to adopt London time was the Great Western Railway
-# in November 1840; other railways followed suit, and by 1847 most
-# (though not all) railways used London time.  On 1847-09-22 the
-# Railway Clearing House, an industry standards body, recommended that GMT be
-# adopted at all stations as soon as the General Post Office permitted it.
-# The transition occurred on 12-01 for the L&NW, the Caledonian,
-# and presumably other railways; the January 1848 Bradshaw's lists many
-# railways as using GMT.  By 1855 the vast majority of public
-# clocks in Britain were set to GMT (though some, like the great clock
-# on Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
-# one for local time and one for GMT).  The last major holdout was the legal
-# system, which stubbornly stuck to local time for many years, leading
-# to oddities like polls opening at 08:13 and closing at 16:13.
-# The legal system finally switched to GMT when the Statutes (Definition
-# of Time) Act took effect; it received the Royal Assent on 1880-08-02.
-#
-# In the tables below, we condense this complicated story into a single
-# transition date for London, namely 1847-12-01.  We don't know as much
-# about Dublin, so we use 1880-08-02, the legal transition time.
-
-# From Paul Eggert (2003-09-27):
-# Summer Time was first seriously proposed by William Willett (1857-1915),
-# a London builder and member of the Royal Astronomical Society
-# who circulated a pamphlet ``The Waste of Daylight'' (1907)
-# that proposed advancing clocks 20 minutes on each of four Sundays in April,
-# and retarding them by the same amount on four Sundays in September.
-# A bill was drafted in 1909 and introduced in Parliament several times,
-# but it met with ridicule and opposition, especially from farming interests.
-# Later editions of the pamphlet proposed one-hour summer time, and
-# it was eventually adopted as a wartime measure in 1916.
-# See: Summer Time Arrives Early, The Times (2000-05-18).
-# A monument to Willett was unveiled on 1927-05-21, in an open space in
-# a 45-acre wood near Chislehurst, Kent that was purchased by popular
-# subscription and open to the public.  On the south face of the monolith,
-# designed by G. W. Miller, is the the William Willett Memorial Sundial,
-# which is permanently set to Summer Time.
-
-# From Winston Churchill (1934-04-28):
-# It is one of the paradoxes of history that we should owe the boon of
-# summer time, which gives every year to the people of this country
-# between 160 and 170 hours more daylight leisure, to a war which
-# plunged Europe into darkness for four years, and shook the
-# foundations of civilization throughout the world.
-#	-- <a href="http://www.winstonchurchill.org/fh114willett.htm">
-#	"A Silent Toast to William Willett", Pictorial Weekly
-#	</a>
-
-# From Paul Eggert (1996-09-03):
-# The OED Supplement says that the English originally said ``Daylight Saving''
-# when they were debating the adoption of DST in 1908; but by 1916 this
-# term appears only in quotes taken from DST's opponents, whereas the
-# proponents (who eventually won the argument) are quoted as using ``Summer''.
-
-# From Arthur David Olson (1989-01-19):
-#
-# A source at the British Information Office in New York avers that it's
-# known as "British" Summer Time in all parts of the United Kingdom.
-
-# Date: 4 Jan 89 08:57:25 GMT (Wed)
-# From: Jonathan Leffler
-# [British Summer Time] is fixed annually by Act of Parliament.
-# If you can predict what Parliament will do, you should be in
-# politics making a fortune, not computing.
-
-# From Chris Carrier (1996-06-14):
-# I remember reading in various wartime issues of the London Times the
-# acronym BDST for British Double Summer Time.  Look for the published
-# time of sunrise and sunset in The Times, when BDST was in effect, and
-# if you find a zone reference it will say, "All times B.D.S.T."
-
-# From Joseph S. Myers (1999-09-02):
-# ... some military cables (WO 219/4100 - this is a copy from the
-# main SHAEF archives held in the US National Archives, SHAEF/5252/8/516)
-# agree that the usage is BDST (this appears in a message dated 17 Feb 1945).
-
-# From Joseph S. Myers (2000-10-03):
-# On 18th April 1941, Sir Stephen Tallents of the BBC wrote to Sir
-# Alexander Maxwell of the Home Office asking whether there was any
-# official designation; the reply of the 21st was that there wasn't
-# but he couldn't think of anything better than the "Double British
-# Summer Time" that the BBC had been using informally.
-# http://student.cusu.cam.ac.uk/~jsm28/british-time/bbc-19410418.png
-# http://student.cusu.cam.ac.uk/~jsm28/british-time/ho-19410421.png
-
-# From Sir Alexander Maxwell in the above-mentioned letter (1941-04-21):
-# [N]o official designation has as far as I know been adopted for the time
-# which is to be introduced in May....
-# I cannot think of anything better than "Double British Summer Time"
-# which could not be said to run counter to any official description.
-
-# From Paul Eggert (2000-10-02):
-# Howse writes (p 157) `DBST' too, but `BDST' seems to have been common
-# and follows the more usual convention of putting the location name first,
-# so we use `BDST'.
-
-# Peter Ilieve (1998-04-19) described at length
-# the history of summer time legislation in the United Kingdom.
-# Since 1998 Joseph S. Myers has been updating
-# and extending this list, which can be found in
-# <a href="http://student.cusu.cam.ac.uk/~jsm28/british-time/">
-# History of legal time in Britain
-# </a>
-
-# From Joseph S. Myers (1998-01-06):
-#
-# The legal time in the UK outside of summer time is definitely GMT, not UTC;
-# see Lord Tanlaw's speech
-# <a href="http://www.parliament.the-stationery-office.co.uk/pa/ld199697/ldhansrd/pdvn/lds97/text/70611-20.htm#70611-20_head0">
-# (Lords Hansard 11 June 1997 columns 964 to 976)
-# </a>.
-
-# From Paul Eggert (2006-03-22):
-#
-# For lack of other data, follow Shanks & Pottenger for Eire in 1940-1948.
-#
-# Given Ilieve and Myers's data, the following claims by Shanks & Pottenger
-# are incorrect:
-#     * Wales did not switch from GMT to daylight saving time until
-#	1921 Apr 3, when they began to conform with the rest of Great Britain.
-# Actually, Wales was identical after 1880.
-#     * Eire had two transitions on 1916 Oct 1.
-# It actually just had one transition.
-#     * Northern Ireland used single daylight saving time throughout WW II.
-# Actually, it conformed to Britain.
-#     * GB-Eire changed standard time to 1 hour ahead of GMT on 1968-02-18.
-# Actually, that date saw the usual switch to summer time.
-# Standard time was not changed until 1968-10-27 (the clocks didn't change).
-#
-# Here is another incorrect claim by Shanks & Pottenger:
-#     * Jersey, Guernsey, and the Isle of Man did not switch from GMT
-#	to daylight saving time until 1921 Apr 3, when they began to
-#	conform with Great Britain.
-# S.R.&O. 1916, No. 382 and HO 45/10811/312364 (quoted above) say otherwise.
-#
-# The following claim by Shanks & Pottenger is possible though doubtful;
-# we'll ignore it for now.
-#     * Dublin's 1971-10-31 switch was at 02:00, even though London's was 03:00.
-#
-#
-# Whitman says Dublin Mean Time was -0:25:21, which is more precise than
-# Shanks & Pottenger.
-# Perhaps this was Dunsink Observatory Time, as Dunsink Observatory
-# (8 km NW of Dublin's center) seemingly was to Dublin as Greenwich was
-# to London.  For example:
-#
-#   "Timeball on the ballast office is down.  Dunsink time."
-#   -- James Joyce, Ulysses
-
-# From Joseph S. Myers (2005-01-26):
-# Irish laws are available online at www.irishstatutebook.ie.  These include
-# various relating to legal time, for example:
-#
-# ZZA13Y1923.html ZZA12Y1924.html ZZA8Y1925.html ZZSIV20PG1267.html
-#
-# ZZSI71Y1947.html ZZSI128Y1948.html ZZSI23Y1949.html ZZSI41Y1950.html
-# ZZSI27Y1951.html ZZSI73Y1952.html
-#
-# ZZSI11Y1961.html ZZSI232Y1961.html ZZSI182Y1962.html
-# ZZSI167Y1963.html ZZSI257Y1964.html ZZSI198Y1967.html
-# ZZA23Y1968.html ZZA17Y1971.html
-#
-# ZZSI67Y1981.html ZZSI212Y1982.html ZZSI45Y1986.html
-# ZZSI264Y1988.html ZZSI52Y1990.html ZZSI371Y1992.html
-# ZZSI395Y1994.html ZZSI484Y1997.html ZZSI506Y2001.html
-#
-# [These are all relative to the root, e.g., the first is
-# <http://www.irishstatutebook.ie/ZZA13Y1923.html>.]
-#
-# (These are those I found, but there could be more.  In any case these
-# should allow various updates to the comments in the europe file to cover
-# the laws applicable in Ireland.)
-#
-# (Note that the time in the Republic of Ireland since 1968 has been defined
-# in terms of standard time being GMT+1 with a period of winter time when it
-# is GMT, rather than standard time being GMT with a period of summer time
-# being GMT+1.)
-
-# From Paul Eggert (1999-03-28):
-# Clive Feather (<news:859845706.26043.0@office.demon.net>, 1997-03-31)
-# reports that Folkestone (Cheriton) Shuttle Terminal uses Concession Time
-# (CT), equivalent to French civil time.
-# Julian Hill (<news:36118128.5A14@virgin.net>, 1998-09-30) reports that
-# trains between Dollands Moor (the freight facility next door)
-# and Frethun run in CT.
-# My admittedly uninformed guess is that the terminal has two authorities,
-# the French concession operators and the British civil authorities,
-# and that the time depends on who you're talking to.
-# If, say, the British police were called to the station for some reason,
-# I would expect the official police report to use GMT/BST and not CET/CEST.
-# This is a borderline case, but for now let's stick to GMT/BST.
-
-# From an anonymous contributor (1996-06-02):
-# The law governing time in Ireland is under Statutory Instrument SI 395/94,
-# which gives force to European Union 7th Council Directive # 94/21/EC.
-# Under this directive, the Minister for Justice in Ireland makes appropriate
-# regulations. I spoke this morning with the Secretary of the Department of
-# Justice (tel +353 1 678 9711) who confirmed to me that the correct name is
-# "Irish Summer Time", abbreviated to "IST".
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Summer Time Act, 1916
-Rule	GB-Eire	1916	only	-	May	21	2:00s	1:00	BST
-Rule	GB-Eire	1916	only	-	Oct	 1	2:00s	0	GMT
-# S.R.&O. 1917, No. 358
-Rule	GB-Eire	1917	only	-	Apr	 8	2:00s	1:00	BST
-Rule	GB-Eire	1917	only	-	Sep	17	2:00s	0	GMT
-# S.R.&O. 1918, No. 274
-Rule	GB-Eire	1918	only	-	Mar	24	2:00s	1:00	BST
-Rule	GB-Eire	1918	only	-	Sep	30	2:00s	0	GMT
-# S.R.&O. 1919, No. 297
-Rule	GB-Eire	1919	only	-	Mar	30	2:00s	1:00	BST
-Rule	GB-Eire	1919	only	-	Sep	29	2:00s	0	GMT
-# S.R.&O. 1920, No. 458
-Rule	GB-Eire	1920	only	-	Mar	28	2:00s	1:00	BST
-# S.R.&O. 1920, No. 1844
-Rule	GB-Eire	1920	only	-	Oct	25	2:00s	0	GMT
-# S.R.&O. 1921, No. 363
-Rule	GB-Eire	1921	only	-	Apr	 3	2:00s	1:00	BST
-Rule	GB-Eire	1921	only	-	Oct	 3	2:00s	0	GMT
-# S.R.&O. 1922, No. 264
-Rule	GB-Eire	1922	only	-	Mar	26	2:00s	1:00	BST
-Rule	GB-Eire	1922	only	-	Oct	 8	2:00s	0	GMT
-# The Summer Time Act, 1922
-Rule	GB-Eire	1923	only	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1923	1924	-	Sep	Sun>=16	2:00s	0	GMT
-Rule	GB-Eire	1924	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1925	1926	-	Apr	Sun>=16	2:00s	1:00	BST
-# The Summer Time Act, 1925
-Rule	GB-Eire	1925	1938	-	Oct	Sun>=2	2:00s	0	GMT
-Rule	GB-Eire	1927	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1928	1929	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1930	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1931	1932	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1933	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1934	only	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1935	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1936	1937	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1938	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1939	only	-	Apr	Sun>=16	2:00s	1:00	BST
-# S.R.&O. 1939, No. 1379
-Rule	GB-Eire	1939	only	-	Nov	Sun>=16	2:00s	0	GMT
-# S.R.&O. 1940, No. 172 and No. 1883
-Rule	GB-Eire	1940	only	-	Feb	Sun>=23	2:00s	1:00	BST
-# S.R.&O. 1941, No. 476
-Rule	GB-Eire	1941	only	-	May	Sun>=2	1:00s	2:00	BDST
-Rule	GB-Eire	1941	1943	-	Aug	Sun>=9	1:00s	1:00	BST
-# S.R.&O. 1942, No. 506
-Rule	GB-Eire	1942	1944	-	Apr	Sun>=2	1:00s	2:00	BDST
-# S.R.&O. 1944, No. 932
-Rule	GB-Eire	1944	only	-	Sep	Sun>=16	1:00s	1:00	BST
-# S.R.&O. 1945, No. 312
-Rule	GB-Eire	1945	only	-	Apr	Mon>=2	1:00s	2:00	BDST
-Rule	GB-Eire	1945	only	-	Jul	Sun>=9	1:00s	1:00	BST
-# S.R.&O. 1945, No. 1208
-Rule	GB-Eire	1945	1946	-	Oct	Sun>=2	2:00s	0	GMT
-Rule	GB-Eire	1946	only	-	Apr	Sun>=9	2:00s	1:00	BST
-# The Summer Time Act, 1947
-Rule	GB-Eire	1947	only	-	Mar	16	2:00s	1:00	BST
-Rule	GB-Eire	1947	only	-	Apr	13	1:00s	2:00	BDST
-Rule	GB-Eire	1947	only	-	Aug	10	1:00s	1:00	BST
-Rule	GB-Eire	1947	only	-	Nov	 2	2:00s	0	GMT
-# Summer Time Order, 1948 (S.I. 1948/495)
-Rule	GB-Eire	1948	only	-	Mar	14	2:00s	1:00	BST
-Rule	GB-Eire	1948	only	-	Oct	31	2:00s	0	GMT
-# Summer Time Order, 1949 (S.I. 1949/373)
-Rule	GB-Eire	1949	only	-	Apr	 3	2:00s	1:00	BST
-Rule	GB-Eire	1949	only	-	Oct	30	2:00s	0	GMT
-# Summer Time Order, 1950 (S.I. 1950/518)
-# Summer Time Order, 1951 (S.I. 1951/430)
-# Summer Time Order, 1952 (S.I. 1952/451)
-Rule	GB-Eire	1950	1952	-	Apr	Sun>=14	2:00s	1:00	BST
-Rule	GB-Eire	1950	1952	-	Oct	Sun>=21	2:00s	0	GMT
-# revert to the rules of the Summer Time Act, 1925
-Rule	GB-Eire	1953	only	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1953	1960	-	Oct	Sun>=2	2:00s	0	GMT
-Rule	GB-Eire	1954	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1955	1956	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1957	only	-	Apr	Sun>=9	2:00s	1:00	BST
-Rule	GB-Eire	1958	1959	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1960	only	-	Apr	Sun>=9	2:00s	1:00	BST
-# Summer Time Order, 1961 (S.I. 1961/71)
-# Summer Time (1962) Order, 1961 (S.I. 1961/2465)
-# Summer Time Order, 1963 (S.I. 1963/81)
-Rule	GB-Eire	1961	1963	-	Mar	lastSun	2:00s	1:00	BST
-Rule	GB-Eire	1961	1968	-	Oct	Sun>=23	2:00s	0	GMT
-# Summer Time (1964) Order, 1963 (S.I. 1963/2101)
-# Summer Time Order, 1964 (S.I. 1964/1201)
-# Summer Time Order, 1967 (S.I. 1967/1148)
-Rule	GB-Eire	1964	1967	-	Mar	Sun>=19	2:00s	1:00	BST
-# Summer Time Order, 1968 (S.I. 1968/117)
-Rule	GB-Eire	1968	only	-	Feb	18	2:00s	1:00	BST
-# The British Standard Time Act, 1968
-#	(no summer time)
-# The Summer Time Act, 1972
-Rule	GB-Eire	1972	1980	-	Mar	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1972	1980	-	Oct	Sun>=23	2:00s	0	GMT
-# Summer Time Order, 1980 (S.I. 1980/1089)
-# Summer Time Order, 1982 (S.I. 1982/1673)
-# Summer Time Order, 1986 (S.I. 1986/223)
-# Summer Time Order, 1988 (S.I. 1988/931)
-Rule	GB-Eire	1981	1995	-	Mar	lastSun	1:00u	1:00	BST
-Rule	GB-Eire 1981	1989	-	Oct	Sun>=23	1:00u	0	GMT
-# Summer Time Order, 1989 (S.I. 1989/985)
-# Summer Time Order, 1992 (S.I. 1992/1729)
-# Summer Time Order 1994 (S.I. 1994/2798)
-Rule	GB-Eire 1990	1995	-	Oct	Sun>=22	1:00u	0	GMT
-# Summer Time Order 1997 (S.I. 1997/2982)
-# See EU for rules starting in 1996.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/London	-0:01:15 -	LMT	1847 Dec  1 0:00s
-			 0:00	GB-Eire	%s	1968 Oct 27
-			 1:00	-	BST	1971 Oct 31 2:00u
-			 0:00	GB-Eire	%s	1996
-			 0:00	EU	GMT/BST
-Link	Europe/London	Europe/Jersey
-Link	Europe/London	Europe/Guernsey
-Link	Europe/London	Europe/Isle_of_Man
-Zone	Europe/Dublin	-0:25:00 -	LMT	1880 Aug  2
-			-0:25:21 -	DMT	1916 May 21 2:00
-			-0:25:21 1:00	IST	1916 Oct  1 2:00s
-			 0:00	GB-Eire	%s	1921 Dec  6 # independence
-			 0:00	GB-Eire	GMT/IST	1940 Feb 25 2:00
-			 0:00	1:00	IST	1946 Oct  6 2:00
-			 0:00	-	GMT	1947 Mar 16 2:00
-			 0:00	1:00	IST	1947 Nov  2 2:00
-			 0:00	-	GMT	1948 Apr 18 2:00
-			 0:00	GB-Eire	GMT/IST	1968 Oct 27
-			 1:00	-	IST	1971 Oct 31 2:00u
-			 0:00	GB-Eire	GMT/IST	1996
-			 0:00	EU	GMT/IST
-
-###############################################################################
-
-# Europe
-
-# EU rules are for the European Union, previously known as the EC, EEC,
-# Common Market, etc.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	EU	1977	1980	-	Apr	Sun>=1	 1:00u	1:00	S
-Rule	EU	1977	only	-	Sep	lastSun	 1:00u	0	-
-Rule	EU	1978	only	-	Oct	 1	 1:00u	0	-
-Rule	EU	1979	1995	-	Sep	lastSun	 1:00u	0	-
-Rule	EU	1981	max	-	Mar	lastSun	 1:00u	1:00	S
-Rule	EU	1996	max	-	Oct	lastSun	 1:00u	0	-
-# The most recent directive covers the years starting in 2002.  See:
-# <a="http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=CELEX:32000L0084:EN:NOT">
-# Directive 2000/84/EC of the European Parliament and of the Council
-# of 19 January 2001 on summer-time arrangements.
-# </a>
-
-# W-Eur differs from EU only in that W-Eur uses standard time.
-Rule	W-Eur	1977	1980	-	Apr	Sun>=1	 1:00s	1:00	S
-Rule	W-Eur	1977	only	-	Sep	lastSun	 1:00s	0	-
-Rule	W-Eur	1978	only	-	Oct	 1	 1:00s	0	-
-Rule	W-Eur	1979	1995	-	Sep	lastSun	 1:00s	0	-
-Rule	W-Eur	1981	max	-	Mar	lastSun	 1:00s	1:00	S
-Rule	W-Eur	1996	max	-	Oct	lastSun	 1:00s	0	-
-
-# Older C-Eur rules are for convenience in the tables.
-# From 1977 on, C-Eur differs from EU only in that C-Eur uses standard time.
-Rule	C-Eur	1916	only	-	Apr	30	23:00	1:00	S
-Rule	C-Eur	1916	only	-	Oct	 1	 1:00	0	-
-Rule	C-Eur	1917	1918	-	Apr	Mon>=15	 2:00s	1:00	S
-Rule	C-Eur	1917	1918	-	Sep	Mon>=15	 2:00s	0	-
-Rule	C-Eur	1940	only	-	Apr	 1	 2:00s	1:00	S
-Rule	C-Eur	1942	only	-	Nov	 2	 2:00s	0	-
-Rule	C-Eur	1943	only	-	Mar	29	 2:00s	1:00	S
-Rule	C-Eur	1943	only	-	Oct	 4	 2:00s	0	-
-Rule	C-Eur	1944	1945	-	Apr	Mon>=1	 2:00s	1:00	S
-# Whitman gives 1944 Oct 7; go with Shanks & Pottenger.
-Rule	C-Eur	1944	only	-	Oct	 2	 2:00s	0	-
-# From Jesper Norgaard Welen (2008-07-13):
-#
-# I found what is probably a typo of 2:00 which should perhaps be 2:00s
-# in the C-Eur rule from tz database version 2008d (this part was
-# corrected in version 2008d). The circumstancial evidence is simply the
-# tz database itself, as seen below:
-#
-# Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15  0:01
-#    0:00 France WE%sT 1945 Sep 16  3:00
-#
-# Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
-#    0:00 France WE%sT 1945 Sep 16 3:00
-#
-# Zone Europe/Belgrade 1:22:00 - LMT 1884
-#    1:00 1:00 CEST 1945 Sep 16  2:00s
-#
-# Rule France 1945 only - Sep 16  3:00 0 -
-# Rule Belgium 1945 only - Sep 16  2:00s 0 -
-# Rule Neth 1945 only - Sep 16 2:00s 0 -
-#
-# The rule line to be changed is:
-#
-# Rule C-Eur 1945 only - Sep 16  2:00 0 -
-#
-# It seems that Paris, Monaco, Rule France, Rule Belgium all agree on
-# 2:00 standard time, e.g. 3:00 local time.  However there are no
-# countries that use C-Eur rules in September 1945, so the only items
-# affected are apparently these ficticious zones that translates acronyms
-# CET and MET:
-#
-# Zone CET  1:00 C-Eur CE%sT
-# Zone MET  1:00 C-Eur ME%sT
-#
-# It this is right then the corrected version would look like:
-#
-# Rule C-Eur 1945 only - Sep 16  2:00s 0 -
-#
-# A small step for mankind though 8-)
-Rule	C-Eur	1945	only	-	Sep	16	 2:00s	0	-
-Rule	C-Eur	1977	1980	-	Apr	Sun>=1	 2:00s	1:00	S
-Rule	C-Eur	1977	only	-	Sep	lastSun	 2:00s	0	-
-Rule	C-Eur	1978	only	-	Oct	 1	 2:00s	0	-
-Rule	C-Eur	1979	1995	-	Sep	lastSun	 2:00s	0	-
-Rule	C-Eur	1981	max	-	Mar	lastSun	 2:00s	1:00	S
-Rule	C-Eur	1996	max	-	Oct	lastSun	 2:00s	0	-
-
-# E-Eur differs from EU only in that E-Eur switches at midnight local time.
-Rule	E-Eur	1977	1980	-	Apr	Sun>=1	 0:00	1:00	S
-Rule	E-Eur	1977	only	-	Sep	lastSun	 0:00	0	-
-Rule	E-Eur	1978	only	-	Oct	 1	 0:00	0	-
-Rule	E-Eur	1979	1995	-	Sep	lastSun	 0:00	0	-
-Rule	E-Eur	1981	max	-	Mar	lastSun	 0:00	1:00	S
-Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Russia	1917	only	-	Jul	 1	23:00	1:00	MST	# Moscow Summer Time
-Rule	Russia	1917	only	-	Dec	28	 0:00	0	MMT	# Moscow Mean Time
-Rule	Russia	1918	only	-	May	31	22:00	2:00	MDST	# Moscow Double Summer Time
-Rule	Russia	1918	only	-	Sep	16	 1:00	1:00	MST
-Rule	Russia	1919	only	-	May	31	23:00	2:00	MDST
-Rule	Russia	1919	only	-	Jul	 1	 2:00	1:00	S
-Rule	Russia	1919	only	-	Aug	16	 0:00	0	-
-Rule	Russia	1921	only	-	Feb	14	23:00	1:00	S
-Rule	Russia	1921	only	-	Mar	20	23:00	2:00	M # Midsummer
-Rule	Russia	1921	only	-	Sep	 1	 0:00	1:00	S
-Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
-# Act No.925 of the Council of Ministers of the USSR (1980-10-24):
-Rule	Russia	1981	1984	-	Apr	 1	 0:00	1:00	S
-Rule	Russia	1981	1983	-	Oct	 1	 0:00	0	-
-# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in
-# Act No.227 of the Council of Ministers of the USSR (1989-03-14):
-Rule	Russia	1984	1991	-	Sep	lastSun	 2:00s	0	-
-Rule	Russia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
-#
-Rule	Russia	1992	only	-	Mar	lastSat	 23:00	1:00	S
-Rule	Russia	1992	only	-	Sep	lastSat	 23:00	0	-
-Rule	Russia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
-Rule	Russia	1993	1995	-	Sep	lastSun	 2:00s	0	-
-Rule	Russia	1996	max	-	Oct	lastSun	 2:00s	0	-
-
-# These are for backward compatibility with older versions.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	WET		0:00	EU	WE%sT
-Zone	CET		1:00	C-Eur	CE%sT
-Zone	MET		1:00	C-Eur	ME%sT
-Zone	EET		2:00	EU	EE%sT
-
-# Previous editions of this database used abbreviations like MET DST
-# for Central European Summer Time, but this didn't agree with common usage.
-
-# From Markus Kuhn (1996-07-12):
-# The official German names ... are
-#
-#	Mitteleuropaeische Zeit (MEZ)         = UTC+01:00
-#	Mitteleuropaeische Sommerzeit (MESZ)  = UTC+02:00
-#
-# as defined in the German Time Act (Gesetz ueber die Zeitbestimmung (ZeitG),
-# 1978-07-25, Bundesgesetzblatt, Jahrgang 1978, Teil I, S. 1110-1111)....
-# I wrote ... to the German Federal Physical-Technical Institution
-#
-#	Physikalisch-Technische Bundesanstalt (PTB)
-#	Laboratorium 4.41 "Zeiteinheit"
-#	Postfach 3345
-#	D-38023 Braunschweig
-#	phone: +49 531 592-0
-#
-# ... I received today an answer letter from Dr. Peter Hetzel, head of the PTB
-# department for time and frequency transmission.  He explained that the
-# PTB translates MEZ and MESZ into English as
-#
-#	Central European Time (CET)         = UTC+01:00
-#	Central European Summer Time (CEST) = UTC+02:00
-
-
-# Albania
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Albania	1940	only	-	Jun	16	0:00	1:00	S
-Rule	Albania	1942	only	-	Nov	 2	3:00	0	-
-Rule	Albania	1943	only	-	Mar	29	2:00	1:00	S
-Rule	Albania	1943	only	-	Apr	10	3:00	0	-
-Rule	Albania	1974	only	-	May	 4	0:00	1:00	S
-Rule	Albania	1974	only	-	Oct	 2	0:00	0	-
-Rule	Albania	1975	only	-	May	 1	0:00	1:00	S
-Rule	Albania	1975	only	-	Oct	 2	0:00	0	-
-Rule	Albania	1976	only	-	May	 2	0:00	1:00	S
-Rule	Albania	1976	only	-	Oct	 3	0:00	0	-
-Rule	Albania	1977	only	-	May	 8	0:00	1:00	S
-Rule	Albania	1977	only	-	Oct	 2	0:00	0	-
-Rule	Albania	1978	only	-	May	 6	0:00	1:00	S
-Rule	Albania	1978	only	-	Oct	 1	0:00	0	-
-Rule	Albania	1979	only	-	May	 5	0:00	1:00	S
-Rule	Albania	1979	only	-	Sep	30	0:00	0	-
-Rule	Albania	1980	only	-	May	 3	0:00	1:00	S
-Rule	Albania	1980	only	-	Oct	 4	0:00	0	-
-Rule	Albania	1981	only	-	Apr	26	0:00	1:00	S
-Rule	Albania	1981	only	-	Sep	27	0:00	0	-
-Rule	Albania	1982	only	-	May	 2	0:00	1:00	S
-Rule	Albania	1982	only	-	Oct	 3	0:00	0	-
-Rule	Albania	1983	only	-	Apr	18	0:00	1:00	S
-Rule	Albania	1983	only	-	Oct	 1	0:00	0	-
-Rule	Albania	1984	only	-	Apr	 1	0:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Tirane	1:19:20 -	LMT	1914
-			1:00	-	CET	1940 Jun 16
-			1:00	Albania	CE%sT	1984 Jul
-			1:00	EU	CE%sT
-
-# Andorra
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Andorra	0:06:04 -	LMT	1901
-			0:00	-	WET	1946 Sep 30
-			1:00	-	CET	1985 Mar 31 2:00
-			1:00	EU	CE%sT
-
-# Austria
-
-# From Paul Eggert (2006-03-22): Shanks & Pottenger give 1918-06-16 and
-# 1945-11-18, but the Austrian Federal Office of Metrology and
-# Surveying (BEV) gives 1918-09-16 and for Vienna gives the "alleged"
-# date of 1945-04-12 with no time.  For the 1980-04-06 transition
-# Shanks & Pottenger give 02:00, the BEV 00:00.  Go with the BEV,
-# and guess 02:00 for 1945-04-12.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Austria	1920	only	-	Apr	 5	2:00s	1:00	S
-Rule	Austria	1920	only	-	Sep	13	2:00s	0	-
-Rule	Austria	1946	only	-	Apr	14	2:00s	1:00	S
-Rule	Austria	1946	1948	-	Oct	Sun>=1	2:00s	0	-
-Rule	Austria	1947	only	-	Apr	 6	2:00s	1:00	S
-Rule	Austria	1948	only	-	Apr	18	2:00s	1:00	S
-Rule	Austria	1980	only	-	Apr	 6	0:00	1:00	S
-Rule	Austria	1980	only	-	Sep	28	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
-			1:00	C-Eur	CE%sT	1920
-			1:00	Austria	CE%sT	1940 Apr  1 2:00s
-			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
-			1:00	1:00	CEST	1945 Apr 12 2:00s
-			1:00	-	CET	1946
-			1:00	Austria	CE%sT	1981
-			1:00	EU	CE%sT
-
-# Belarus
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Minsk	1:50:16 -	LMT	1880
-			1:50	-	MMT	1924 May 2 # Minsk Mean Time
-			2:00	-	EET	1930 Jun 21
-			3:00	-	MSK	1941 Jun 28
-			1:00	C-Eur	CE%sT	1944 Jul  3
-			3:00	Russia	MSK/MSD	1990
-			3:00	-	MSK	1991 Mar 31 2:00s
-			2:00	1:00	EEST	1991 Sep 29 2:00s
-			2:00	-	EET	1992 Mar 29 0:00s
-			2:00	1:00	EEST	1992 Sep 27 0:00s
-			2:00	Russia	EE%sT
-
-# Belgium
-#
-# From Paul Eggert (1997-07-02):
-# Entries from 1918 through 1991 are taken from:
-#	Annuaire de L'Observatoire Royal de Belgique,
-#	Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe annee, 1991
-#	(Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC),
-#	pp 8-9.
-# LMT before 1892 was 0:17:30, according to the official journal of Belgium:
-#	Moniteur Belge, Samedi 30 Avril 1892, N.121.
-# Thanks to Pascal Delmoitie for these references.
-# The 1918 rules are listed for completeness; they apply to unoccupied Belgium.
-# Assume Brussels switched to WET in 1918 when the armistice took effect.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Belgium	1918	only	-	Mar	 9	 0:00s	1:00	S
-Rule	Belgium	1918	1919	-	Oct	Sat>=1	23:00s	0	-
-Rule	Belgium	1919	only	-	Mar	 1	23:00s	1:00	S
-Rule	Belgium	1920	only	-	Feb	14	23:00s	1:00	S
-Rule	Belgium	1920	only	-	Oct	23	23:00s	0	-
-Rule	Belgium	1921	only	-	Mar	14	23:00s	1:00	S
-Rule	Belgium	1921	only	-	Oct	25	23:00s	0	-
-Rule	Belgium	1922	only	-	Mar	25	23:00s	1:00	S
-Rule	Belgium	1922	1927	-	Oct	Sat>=1	23:00s	0	-
-Rule	Belgium	1923	only	-	Apr	21	23:00s	1:00	S
-Rule	Belgium	1924	only	-	Mar	29	23:00s	1:00	S
-Rule	Belgium	1925	only	-	Apr	 4	23:00s	1:00	S
-# DSH writes that a royal decree of 1926-02-22 specified the Sun following 3rd
-# Sat in Apr (except if it's Easter, in which case it's one Sunday earlier),
-# to Sun following 1st Sat in Oct, and that a royal decree of 1928-09-15
-# changed the transition times to 02:00 GMT.
-Rule	Belgium	1926	only	-	Apr	17	23:00s	1:00	S
-Rule	Belgium	1927	only	-	Apr	 9	23:00s	1:00	S
-Rule	Belgium	1928	only	-	Apr	14	23:00s	1:00	S
-Rule	Belgium	1928	1938	-	Oct	Sun>=2	 2:00s	0	-
-Rule	Belgium	1929	only	-	Apr	21	 2:00s	1:00	S
-Rule	Belgium	1930	only	-	Apr	13	 2:00s	1:00	S
-Rule	Belgium	1931	only	-	Apr	19	 2:00s	1:00	S
-Rule	Belgium	1932	only	-	Apr	 3	 2:00s	1:00	S
-Rule	Belgium	1933	only	-	Mar	26	 2:00s	1:00	S
-Rule	Belgium	1934	only	-	Apr	 8	 2:00s	1:00	S
-Rule	Belgium	1935	only	-	Mar	31	 2:00s	1:00	S
-Rule	Belgium	1936	only	-	Apr	19	 2:00s	1:00	S
-Rule	Belgium	1937	only	-	Apr	 4	 2:00s	1:00	S
-Rule	Belgium	1938	only	-	Mar	27	 2:00s	1:00	S
-Rule	Belgium	1939	only	-	Apr	16	 2:00s	1:00	S
-Rule	Belgium	1939	only	-	Nov	19	 2:00s	0	-
-Rule	Belgium	1940	only	-	Feb	25	 2:00s	1:00	S
-Rule	Belgium	1944	only	-	Sep	17	 2:00s	0	-
-Rule	Belgium	1945	only	-	Apr	 2	 2:00s	1:00	S
-Rule	Belgium	1945	only	-	Sep	16	 2:00s	0	-
-Rule	Belgium	1946	only	-	May	19	 2:00s	1:00	S
-Rule	Belgium	1946	only	-	Oct	 7	 2:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Brussels	0:17:30 -	LMT	1880
-			0:17:30	-	BMT	1892 May  1 12:00 # Brussels MT
-			0:00	-	WET	1914 Nov  8
-			1:00	-	CET	1916 May  1  0:00
-			1:00	C-Eur	CE%sT	1918 Nov 11 11:00u
-			0:00	Belgium	WE%sT	1940 May 20  2:00s
-			1:00	C-Eur	CE%sT	1944 Sep  3
-			1:00	Belgium	CE%sT	1977
-			1:00	EU	CE%sT
-
-# Bosnia and Herzegovina
-# see Serbia
-
-# Bulgaria
-#
-# From Plamen Simenov via Steffen Thorsen (1999-09-09):
-# A document of Government of Bulgaria (No.94/1997) says:
-# EET --> EETDST is in 03:00 Local time in last Sunday of March ...
-# EETDST --> EET is in 04:00 Local time in last Sunday of October
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Bulg	1979	only	-	Mar	31	23:00	1:00	S
-Rule	Bulg	1979	only	-	Oct	 1	 1:00	0	-
-Rule	Bulg	1980	1982	-	Apr	Sat>=1	23:00	1:00	S
-Rule	Bulg	1980	only	-	Sep	29	 1:00	0	-
-Rule	Bulg	1981	only	-	Sep	27	 2:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Sofia	1:33:16 -	LMT	1880
-			1:56:56	-	IMT	1894 Nov 30 # Istanbul MT?
-			2:00	-	EET	1942 Nov  2  3:00
-			1:00	C-Eur	CE%sT	1945
-			1:00	-	CET	1945 Apr 2 3:00
-			2:00	-	EET	1979 Mar 31 23:00
-			2:00	Bulg	EE%sT	1982 Sep 26  2:00
-			2:00	C-Eur	EE%sT	1991
-			2:00	E-Eur	EE%sT	1997
-			2:00	EU	EE%sT
-
-# Croatia
-# see Serbia
-
-# Cyprus
-# Please see the `asia' file for Asia/Nicosia.
-
-# Czech Republic
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Czech	1945	only	-	Apr	 8	2:00s	1:00	S
-Rule	Czech	1945	only	-	Nov	18	2:00s	0	-
-Rule	Czech	1946	only	-	May	 6	2:00s	1:00	S
-Rule	Czech	1946	1949	-	Oct	Sun>=1	2:00s	0	-
-Rule	Czech	1947	only	-	Apr	20	2:00s	1:00	S
-Rule	Czech	1948	only	-	Apr	18	2:00s	1:00	S
-Rule	Czech	1949	only	-	Apr	 9	2:00s	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Prague	0:57:44 -	LMT	1850
-			0:57:44	-	PMT	1891 Oct     # Prague Mean Time
-			1:00	C-Eur	CE%sT	1944 Sep 17 2:00s
-			1:00	Czech	CE%sT	1979
-			1:00	EU	CE%sT
-
-# Denmark, Faroe Islands, and Greenland
-
-# From Jesper Norgaard Welen (2005-04-26):
-# http://www.hum.aau.dk/~poe/tid/tine/DanskTid.htm says that the law
-# [introducing standard time] was in effect from 1894-01-01....
-# The page http://www.retsinfo.dk/_GETDOCI_/ACCN/A18930008330-REGL
-# confirms this, and states that the law was put forth 1893-03-29.
-#
-# The EU treaty with effect from 1973:
-# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19722110030-REGL
-#
-# This provoked a new law from 1974 to make possible summer time changes
-# in subsequenet decrees with the law
-# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19740022330-REGL
-#
-# It seems however that no decree was set forward until 1980.  I have
-# not found any decree, but in another related law, the effecting DST
-# changes are stated explicitly to be from 1980-04-06 at 02:00 to
-# 1980-09-28 at 02:00.  If this is true, this differs slightly from
-# the EU rule in that DST runs to 02:00, not 03:00.  We don't know
-# when Denmark began using the EU rule correctly, but we have only
-# confirmation of the 1980-time, so I presume it was correct in 1981:
-# The law is about the management of the extra hour, concerning
-# working hours reported and effect on obligatory-rest rules (which
-# was suspended on that night):
-# http://www.retsinfo.dk/_GETDOCI_/ACCN/C19801120554-REGL
-
-# From Jesper Norgaard Welen (2005-06-11):
-# The Herning Folkeblad (1980-09-26) reported that the night between
-# Saturday and Sunday the clock is set back from three to two.
-
-# From Paul Eggert (2005-06-11):
-# Hence the "02:00" of the 1980 law refers to standard time, not
-# wall-clock time, and so the EU rules were in effect in 1980.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Denmark	1916	only	-	May	14	23:00	1:00	S
-Rule	Denmark	1916	only	-	Sep	30	23:00	0	-
-Rule	Denmark	1940	only	-	May	15	 0:00	1:00	S
-Rule	Denmark	1945	only	-	Apr	 2	 2:00s	1:00	S
-Rule	Denmark	1945	only	-	Aug	15	 2:00s	0	-
-Rule	Denmark	1946	only	-	May	 1	 2:00s	1:00	S
-Rule	Denmark	1946	only	-	Sep	 1	 2:00s	0	-
-Rule	Denmark	1947	only	-	May	 4	 2:00s	1:00	S
-Rule	Denmark	1947	only	-	Aug	10	 2:00s	0	-
-Rule	Denmark	1948	only	-	May	 9	 2:00s	1:00	S
-Rule	Denmark	1948	only	-	Aug	 8	 2:00s	0	-
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Europe/Copenhagen	 0:50:20 -	LMT	1890
-			 0:50:20 -	CMT	1894 Jan  1 # Copenhagen MT
-			 1:00	Denmark	CE%sT	1942 Nov  2 2:00s
-			 1:00	C-Eur	CE%sT	1945 Apr  2 2:00
-			 1:00	Denmark	CE%sT	1980
-			 1:00	EU	CE%sT
-Zone Atlantic/Faroe	-0:27:04 -	LMT	1908 Jan 11	# Torshavn
-			 0:00	-	WET	1981
-			 0:00	EU	WE%sT
-#
-# From Paul Eggert (2004-10-31):
-# During World War II, Germany maintained secret manned weather stations in
-# East Greenland and Franz Josef Land, but we don't know their time zones.
-# My source for this is Wilhelm Dege's book mentioned under Svalbard.
-#
-# From Paul Eggert (2006-03-22):
-# Greenland joined the EU as part of Denmark, obtained home rule on 1979-05-01,
-# and left the EU on 1985-02-01.  It therefore should have been using EU
-# rules at least through 1984.  Shanks & Pottenger say Scoresbysund and Godthab
-# used C-Eur rules after 1980, but IATA SSIM (1991/1996) says they use EU
-# rules since at least 1991.  Assume EU rules since 1980.
-
-# From Gwillin Law (2001-06-06), citing
-# <http://www.statkart.no/efs/efshefter/2001/efs5-2001.pdf> (2001-03-15),
-# and with translations corrected by Steffen Thorsen:
-#
-# Greenland has four local times, and the relation to UTC
-# is according to the following time line:
-#
-# The military zone near Thule	UTC-4
-# Standard Greenland time	UTC-3
-# Scoresbysund			UTC-1
-# Danmarkshavn			UTC
-#
-# In the military area near Thule and in Danmarkshavn DST will not be
-# introduced.
-
-# From Rives McDow (2001-11-01):
-#
-# I correspond regularly with the Dansk Polarcenter, and wrote them at
-# the time to clarify the situation in Thule.  Unfortunately, I have
-# not heard back from them regarding my recent letter.  [But I have
-# info from earlier correspondence.]
-#
-# According to the center, a very small local time zone around Thule
-# Air Base keeps the time according to UTC-4, implementing daylight
-# savings using North America rules, changing the time at 02:00 local time....
-#
-# The east coast of Greenland north of the community of Scoresbysund
-# uses UTC in the same way as in Iceland, year round, with no dst.
-# There are just a few stations on this coast, including the
-# Danmarkshavn ICAO weather station mentioned in your September 29th
-# email.  The other stations are two sledge patrol stations in
-# Mestersvig and Daneborg, the air force base at Station Nord, and the
-# DPC research station at Zackenberg.
-#
-# Scoresbysund and two small villages nearby keep time UTC-1 and use
-# the same daylight savings time period as in West Greenland (Godthab).
-#
-# The rest of Greenland, including Godthab (this area, although it
-# includes central Greenland, is known as west Greenland), keeps time
-# UTC-3, with daylight savings methods according to European rules.
-#
-# It is common procedure to use UTC 0 in the wilderness of East and
-# North Greenland, because it is mainly Icelandic aircraft operators
-# maintaining traffic in these areas.  However, the official status of
-# this area is that it sticks with Godthab time.  This area might be
-# considered a dual time zone in some respects because of this.
-
-# From Rives McDow (2001-11-19):
-# I heard back from someone stationed at Thule; the time change took place
-# there at 2:00 AM.
-
-# From Paul Eggert (2006-03-22):
-# From 1997 on the CIA map shows Danmarkshavn on GMT;
-# the 1995 map as like Godthab.
-# For lack of better info, assume they were like Godthab before 1996.
-# startkart.no says Thule does not observe DST, but this is clearly an error,
-# so go with Shanks & Pottenger for Thule transitions until this year.
-# For 2007 on assume Thule will stay in sync with US DST rules.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Thule	1991	1992	-	Mar	lastSun	2:00	1:00	D
-Rule	Thule	1991	1992	-	Sep	lastSun	2:00	0	S
-Rule	Thule	1993	2006	-	Apr	Sun>=1	2:00	1:00	D
-Rule	Thule	1993	2006	-	Oct	lastSun	2:00	0	S
-Rule	Thule	2007	max	-	Mar	Sun>=8	2:00	1:00	D
-Rule	Thule	2007	max	-	Nov	Sun>=1	2:00	0	S
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Danmarkshavn -1:14:40 -	LMT	1916 Jul 28
-			-3:00	-	WGT	1980 Apr  6 2:00
-			-3:00	EU	WG%sT	1996
-			0:00	-	GMT
-Zone America/Scoresbysund -1:27:52 -	LMT	1916 Jul 28 # Ittoqqortoormiit
-			-2:00	-	CGT	1980 Apr  6 2:00
-			-2:00	C-Eur	CG%sT	1981 Mar 29
-			-1:00	EU	EG%sT
-Zone America/Godthab	-3:26:56 -	LMT	1916 Jul 28 # Nuuk
-			-3:00	-	WGT	1980 Apr  6 2:00
-			-3:00	EU	WG%sT
-Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik air base
-			-4:00	Thule	A%sT
-
-# Estonia
-# From Peter Ilieve (1994-10-15):
-# A relative in Tallinn confirms the accuracy of the data for 1989 onwards
-# [through 1994] and gives the legal authority for it,
-# a regulation of the Government of Estonia, No. 111 of 1989....
-#
-# From Peter Ilieve (1996-10-28):
-# [IATA SSIM (1992/1996) claims that the Baltic republics switch at 01:00s,
-# but a relative confirms that Estonia still switches at 02:00s, writing:]
-# ``I do not [know] exactly but there are some little different
-# (confusing) rules for International Air and Railway Transport Schedules
-# conversion in Sunday connected with end of summer time in Estonia....
-# A discussion is running about the summer time efficiency and effect on
-# human physiology.  It seems that Estonia maybe will not change to
-# summer time next spring.''
-
-# From Peter Ilieve (1998-11-04), heavily edited:
-# <a href="http://trip.rk.ee/cgi-bin/thw?${BASE}=akt&${OOHTML}=rtd&TA=1998&TO=1&AN=1390">
-# The 1998-09-22 Estonian time law
-# </a>
-# refers to the Eighth Directive and cites the association agreement between
-# the EU and Estonia, ratified by the Estonian law (RT II 1995, 22--27, 120).
-#
-# I also asked [my relative] whether they use any standard abbreviation
-# for their standard and summer times. He says no, they use "suveaeg"
-# (summer time) and "talveaeg" (winter time).
-
-# From <a href="http://www.baltictimes.com/">The Baltic Times</a> (1999-09-09)
-# via Steffen Thorsen:
-# This year will mark the last time Estonia shifts to summer time,
-# a council of the ruling coalition announced Sept. 6....
-# But what this could mean for Estonia's chances of joining the European
-# Union are still unclear.  In 1994, the EU declared summer time compulsory
-# for all member states until 2001.  Brussels has yet to decide what to do
-# after that.
-
-# From Mart Oruaas (2000-01-29):
-# Regulation no. 301 (1999-10-12) obsoletes previous regulation
-# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all
-# the year round.  The regulation is effective 1999-11-01.
-
-# From Toomas Soome (2002-02-21):
-# The Estonian government has changed once again timezone politics.
-# Now we are using again EU rules.
-#
-# From Urmet Jaanes (2002-03-28):
-# The legislative reference is Government decree No. 84 on 2002-02-21.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Tallinn	1:39:00	-	LMT	1880
-			1:39:00	-	TMT	1918 Feb # Tallinn Mean Time
-			1:00	C-Eur	CE%sT	1919 Jul
-			1:39:00	-	TMT	1921 May
-			2:00	-	EET	1940 Aug  6
-			3:00	-	MSK	1941 Sep 15
-			1:00	C-Eur	CE%sT	1944 Sep 22
-			3:00	Russia	MSK/MSD	1989 Mar 26 2:00s
-			2:00	1:00	EEST	1989 Sep 24 2:00s
-			2:00	C-Eur	EE%sT	1998 Sep 22
-			2:00	EU	EE%sT	1999 Nov  1
-			2:00	-	EET	2002 Feb 21
-			2:00	EU	EE%sT
-
-# Finland
-
-# From Hannu Strang (1994-09-25 06:03:37 UTC):
-# Well, here in Helsinki we're just changing from summer time to regular one,
-# and it's supposed to change at 4am...
-
-# From Janne Snabb (2010-0715):
-#
-# I noticed that the Finland data is not accurate for years 1981 and 1982.
-# During these two first trial years the DST adjustment was made one hour
-# earlier than in forthcoming years. Starting 1983 the adjustment was made
-# according to the central European standards.
-#
-# This is documented in Heikki Oja: Aikakirja 2007, published by The Almanac
-# Office of University of Helsinki, ISBN 952-10-3221-9, available online (in
-# Finnish) at
-#
-# <a href="http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf">
-# http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf
-# </a>
-#
-# Page 105 (56 in PDF version) has a handy table of all past daylight savings
-# transitions. It is easy enough to interpret without Finnish skills.
-#
-# This is also confirmed by Finnish Broadcasting Company's archive at:
-#
-# <a href="http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401">
-# http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401
-# </a>
-#
-# The news clip from 1981 says that "the time between 2 and 3 o'clock does not
-# exist tonight."
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Finland	1942	only	-	Apr	3	0:00	1:00	S
-Rule	Finland	1942	only	-	Oct	3	0:00	0	-
-Rule	Finland	1981	1982	-	Mar	lastSun	2:00	1:00	S
-Rule	Finland	1981	1982	-	Sep	lastSun	3:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Helsinki	1:39:52 -	LMT	1878 May 31
-			1:39:52	-	HMT	1921 May    # Helsinki Mean Time
-			2:00	Finland	EE%sT	1983
-			2:00	EU	EE%sT
-
-# Aaland Is
-Link	Europe/Helsinki	Europe/Mariehamn
-
-
-# France
-
-# From Ciro Discepolo (2000-12-20):
-#
-# Henri Le Corre, Regimes Horaires pour le monde entier, Editions
-# Traditionnelles - Paris 2 books, 1993
-#
-# Gabriel, Traite de l'heure dans le monde, Guy Tredaniel editeur,
-# Paris, 1991
-#
-# Francoise Gauquelin, Problemes de l'heure resolus en astrologie,
-# Guy tredaniel, Paris 1987
-
-
-#
-# Shank & Pottenger seem to use `24:00' ambiguously; resolve it with Whitman.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	France	1916	only	-	Jun	14	23:00s	1:00	S
-Rule	France	1916	1919	-	Oct	Sun>=1	23:00s	0	-
-Rule	France	1917	only	-	Mar	24	23:00s	1:00	S
-Rule	France	1918	only	-	Mar	 9	23:00s	1:00	S
-Rule	France	1919	only	-	Mar	 1	23:00s	1:00	S
-Rule	France	1920	only	-	Feb	14	23:00s	1:00	S
-Rule	France	1920	only	-	Oct	23	23:00s	0	-
-Rule	France	1921	only	-	Mar	14	23:00s	1:00	S
-Rule	France	1921	only	-	Oct	25	23:00s	0	-
-Rule	France	1922	only	-	Mar	25	23:00s	1:00	S
-# DSH writes that a law of 1923-05-24 specified 3rd Sat in Apr at 23:00 to 1st
-# Sat in Oct at 24:00; and that in 1930, because of Easter, the transitions
-# were Apr 12 and Oct 5.  Go with Shanks & Pottenger.
-Rule	France	1922	1938	-	Oct	Sat>=1	23:00s	0	-
-Rule	France	1923	only	-	May	26	23:00s	1:00	S
-Rule	France	1924	only	-	Mar	29	23:00s	1:00	S
-Rule	France	1925	only	-	Apr	 4	23:00s	1:00	S
-Rule	France	1926	only	-	Apr	17	23:00s	1:00	S
-Rule	France	1927	only	-	Apr	 9	23:00s	1:00	S
-Rule	France	1928	only	-	Apr	14	23:00s	1:00	S
-Rule	France	1929	only	-	Apr	20	23:00s	1:00	S
-Rule	France	1930	only	-	Apr	12	23:00s	1:00	S
-Rule	France	1931	only	-	Apr	18	23:00s	1:00	S
-Rule	France	1932	only	-	Apr	 2	23:00s	1:00	S
-Rule	France	1933	only	-	Mar	25	23:00s	1:00	S
-Rule	France	1934	only	-	Apr	 7	23:00s	1:00	S
-Rule	France	1935	only	-	Mar	30	23:00s	1:00	S
-Rule	France	1936	only	-	Apr	18	23:00s	1:00	S
-Rule	France	1937	only	-	Apr	 3	23:00s	1:00	S
-Rule	France	1938	only	-	Mar	26	23:00s	1:00	S
-Rule	France	1939	only	-	Apr	15	23:00s	1:00	S
-Rule	France	1939	only	-	Nov	18	23:00s	0	-
-Rule	France	1940	only	-	Feb	25	 2:00	1:00	S
-# The French rules for 1941-1944 were not used in Paris, but Shanks & Pottenger
-# write that they were used in Monaco and in many French locations.
-# Le Corre writes that the upper limit of the free zone was Arneguy, Orthez,
-# Mont-de-Marsan, Bazas, Langon, Lamotte-Montravel, Marouil, La
-# Rochefoucault, Champagne-Mouton, La Roche-Posay, La Haye-Decartes,
-# Loches, Montrichard, Vierzon, Bourges, Moulins, Digoin,
-# Paray-le-Monial, Montceau-les-Mines, Chalons-sur-Saone, Arbois,
-# Dole, Morez, St-Claude, and Collognes (Haute-Savioe).
-Rule	France	1941	only	-	May	 5	 0:00	2:00	M # Midsummer
-# Shanks & Pottenger say this transition occurred at Oct 6 1:00,
-# but go with Denis Excoffier (1997-12-12),
-# who quotes the Ephemerides Astronomiques for 1998 from Bureau des Longitudes
-# as saying 5/10/41 22hUT.
-Rule	France	1941	only	-	Oct	 6	 0:00	1:00	S
-Rule	France	1942	only	-	Mar	 9	 0:00	2:00	M
-Rule	France	1942	only	-	Nov	 2	 3:00	1:00	S
-Rule	France	1943	only	-	Mar	29	 2:00	2:00	M
-Rule	France	1943	only	-	Oct	 4	 3:00	1:00	S
-Rule	France	1944	only	-	Apr	 3	 2:00	2:00	M
-Rule	France	1944	only	-	Oct	 8	 1:00	1:00	S
-Rule	France	1945	only	-	Apr	 2	 2:00	2:00	M
-Rule	France	1945	only	-	Sep	16	 3:00	0	-
-# Shanks & Pottenger give Mar 28 2:00 and Sep 26 3:00;
-# go with Excoffier's 28/3/76 0hUT and 25/9/76 23hUT.
-Rule	France	1976	only	-	Mar	28	 1:00	1:00	S
-Rule	France	1976	only	-	Sep	26	 1:00	0	-
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time, and Whitman 0:09:05,
-# but Howse quotes the actual French legislation as saying 0:09:21.
-# Go with Howse.  Howse writes that the time in France was officially based
-# on PMT-0:09:21 until 1978-08-09, when the time base finally switched to UTC.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Paris	0:09:21 -	LMT	1891 Mar 15  0:01
-			0:09:21	-	PMT	1911 Mar 11  0:01  # Paris MT
-# Shanks & Pottenger give 1940 Jun 14 0:00; go with Excoffier and Le Corre.
-			0:00	France	WE%sT	1940 Jun 14 23:00
-# Le Corre says Paris stuck with occupied-France time after the liberation;
-# go with Shanks & Pottenger.
-			1:00	C-Eur	CE%sT	1944 Aug 25
-			0:00	France	WE%sT	1945 Sep 16  3:00
-			1:00	France	CE%sT	1977
-			1:00	EU	CE%sT
-
-# Germany
-
-# From Markus Kuhn (1998-09-29):
-# The German time zone web site by the Physikalisch-Technische
-# Bundesanstalt contains DST information back to 1916.
-# [See tz-link.htm for the URL.]
-
-# From Joerg Schilling (2002-10-23):
-# In 1945, Berlin was switched to Moscow Summer time (GMT+4) by
-# <a href="http://www.dhm.de/lemo/html/biografien/BersarinNikolai/">
-# General [Nikolai] Bersarin</a>.
-
-# From Paul Eggert (2003-03-08):
-# <a href="http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf">
-# http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf
-# </a>
-# says that Bersarin issued an order to use Moscow time on May 20.
-# However, Moscow did not observe daylight saving in 1945, so
-# this was equivalent to CEMT (GMT+3), not GMT+4.
-
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Germany	1946	only	-	Apr	14	2:00s	1:00	S
-Rule	Germany	1946	only	-	Oct	 7	2:00s	0	-
-Rule	Germany	1947	1949	-	Oct	Sun>=1	2:00s	0	-
-# http://www.ptb.de/de/org/4/44/441/salt.htm says the following transition
-# occurred at 3:00 MEZ, not the 2:00 MEZ given in Shanks & Pottenger.
-# Go with the PTB.
-Rule	Germany	1947	only	-	Apr	 6	3:00s	1:00	S
-Rule	Germany	1947	only	-	May	11	2:00s	2:00	M
-Rule	Germany	1947	only	-	Jun	29	3:00	1:00	S
-Rule	Germany	1948	only	-	Apr	18	2:00s	1:00	S
-Rule	Germany	1949	only	-	Apr	10	2:00s	1:00	S
-
-Rule SovietZone	1945	only	-	May	24	2:00	2:00	M # Midsummer
-Rule SovietZone	1945	only	-	Sep	24	3:00	1:00	S
-Rule SovietZone	1945	only	-	Nov	18	2:00s	0	-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Berlin	0:53:28 -	LMT	1893 Apr
-			1:00	C-Eur	CE%sT	1945 May 24 2:00
-			1:00 SovietZone	CE%sT	1946
-			1:00	Germany	CE%sT	1980
-			1:00	EU	CE%sT
-
-# Georgia
-# Please see the "asia" file for Asia/Tbilisi.
-# Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
-# is in Europe.  Our reference location Tbilisi is in the Asian part.
-
-# Gibraltar
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Europe/Gibraltar	-0:21:24 -	LMT	1880 Aug  2 0:00s
-			0:00	GB-Eire	%s	1957 Apr 14 2:00
-			1:00	-	CET	1982
-			1:00	EU	CE%sT
-
-# Greece
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks & Pottenger.
-Rule	Greece	1932	only	-	Jul	 7	0:00	1:00	S
-Rule	Greece	1932	only	-	Sep	 1	0:00	0	-
-# Whitman gives 1941 Apr 25 - ?; go with Shanks & Pottenger.
-Rule	Greece	1941	only	-	Apr	 7	0:00	1:00	S
-# Whitman gives 1942 Feb 2 - ?; go with Shanks & Pottenger.
-Rule	Greece	1942	only	-	Nov	 2	3:00	0	-
-Rule	Greece	1943	only	-	Mar	30	0:00	1:00	S
-Rule	Greece	1943	only	-	Oct	 4	0:00	0	-
-# Whitman gives 1944 Oct 3 - Oct 31; go with Shanks & Pottenger.
-Rule	Greece	1952	only	-	Jul	 1	0:00	1:00	S
-Rule	Greece	1952	only	-	Nov	 2	0:00	0	-
-Rule	Greece	1975	only	-	Apr	12	0:00s	1:00	S
-Rule	Greece	1975	only	-	Nov	26	0:00s	0	-
-Rule	Greece	1976	only	-	Apr	11	2:00s	1:00	S
-Rule	Greece	1976	only	-	Oct	10	2:00s	0	-
-Rule	Greece	1977	1978	-	Apr	Sun>=1	2:00s	1:00	S
-Rule	Greece	1977	only	-	Sep	26	2:00s	0	-
-Rule	Greece	1978	only	-	Sep	24	4:00	0	-
-Rule	Greece	1979	only	-	Apr	 1	9:00	1:00	S
-Rule	Greece	1979	only	-	Sep	29	2:00	0	-
-Rule	Greece	1980	only	-	Apr	 1	0:00	1:00	S
-Rule	Greece	1980	only	-	Sep	28	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Athens	1:34:52 -	LMT	1895 Sep 14
-			1:34:52	-	AMT	1916 Jul 28 0:01     # Athens MT
-			2:00	Greece	EE%sT	1941 Apr 30
-			1:00	Greece	CE%sT	1944 Apr  4
-			2:00	Greece	EE%sT	1981
-			# Shanks & Pottenger say it switched to C-Eur in 1981;
-			# go with EU instead, since Greece joined it on Jan 1.
-			2:00	EU	EE%sT
-
-# Hungary
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Hungary	1918	only	-	Apr	 1	 3:00	1:00	S
-Rule	Hungary	1918	only	-	Sep	29	 3:00	0	-
-Rule	Hungary	1919	only	-	Apr	15	 3:00	1:00	S
-Rule	Hungary	1919	only	-	Sep	15	 3:00	0	-
-Rule	Hungary	1920	only	-	Apr	 5	 3:00	1:00	S
-Rule	Hungary	1920	only	-	Sep	30	 3:00	0	-
-Rule	Hungary	1945	only	-	May	 1	23:00	1:00	S
-Rule	Hungary	1945	only	-	Nov	 3	 0:00	0	-
-Rule	Hungary	1946	only	-	Mar	31	 2:00s	1:00	S
-Rule	Hungary	1946	1949	-	Oct	Sun>=1	 2:00s	0	-
-Rule	Hungary	1947	1949	-	Apr	Sun>=4	 2:00s	1:00	S
-Rule	Hungary	1950	only	-	Apr	17	 2:00s	1:00	S
-Rule	Hungary	1950	only	-	Oct	23	 2:00s	0	-
-Rule	Hungary	1954	1955	-	May	23	 0:00	1:00	S
-Rule	Hungary	1954	1955	-	Oct	 3	 0:00	0	-
-Rule	Hungary	1956	only	-	Jun	Sun>=1	 0:00	1:00	S
-Rule	Hungary	1956	only	-	Sep	lastSun	 0:00	0	-
-Rule	Hungary	1957	only	-	Jun	Sun>=1	 1:00	1:00	S
-Rule	Hungary	1957	only	-	Sep	lastSun	 3:00	0	-
-Rule	Hungary	1980	only	-	Apr	 6	 1:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Budapest	1:16:20 -	LMT	1890 Oct
-			1:00	C-Eur	CE%sT	1918
-			1:00	Hungary	CE%sT	1941 Apr  6  2:00
-			1:00	C-Eur	CE%sT	1945
-			1:00	Hungary	CE%sT	1980 Sep 28  2:00s
-			1:00	EU	CE%sT
-
-# Iceland
-#
-# From Adam David (1993-11-06):
-# The name of the timezone in Iceland for system / mail / news purposes is GMT.
-#
-# (1993-12-05):
-# This material is paraphrased from the 1988 edition of the University of
-# Iceland Almanak.
-#
-# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
-# behind GMT. Previously, local mean solar time was used in different parts
-# of Iceland, the almanak had been based on Reykjavik mean solar time which
-# was 1 hour and 28 minutes behind GMT.
-#
-# "first day of winter" referred to [below] means the first day of the 26 weeks
-# of winter, according to the old icelandic calendar that dates back to the
-# time the norsemen first settled Iceland.  The first day of winter is always
-# Saturday, but is not dependent on the Julian or Gregorian calendars.
-#
-# (1993-12-10):
-# I have a reference from the Oxford Icelandic-English dictionary for the
-# beginning of winter, which ties it to the ecclesiastical calendar (and thus
-# to the julian/gregorian calendar) over the period in question.
-#	the winter begins on the Saturday next before St. Luke's day
-#	(old style), or on St. Luke's day, if a Saturday.
-# St. Luke's day ought to be traceable from ecclesiastical sources. "old style"
-# might be a reference to the Julian calendar as opposed to Gregorian, or it
-# might mean something else (???).
-#
-# From Paul Eggert (2006-03-22):
-# The Iceland Almanak, Shanks & Pottenger, and Whitman disagree on many points.
-# We go with the Almanak, except for one claim from Shanks & Pottenger, namely
-# that Reykavik was 21W57 from 1837 to 1908, local mean time before that.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Iceland	1917	1918	-	Feb	19	23:00	1:00	S
-Rule	Iceland	1917	only	-	Oct	21	 1:00	0	-
-Rule	Iceland	1918	only	-	Nov	16	 1:00	0	-
-Rule	Iceland	1939	only	-	Apr	29	23:00	1:00	S
-Rule	Iceland	1939	only	-	Nov	29	 2:00	0	-
-Rule	Iceland	1940	only	-	Feb	25	 2:00	1:00	S
-Rule	Iceland	1940	only	-	Nov	 3	 2:00	0	-
-Rule	Iceland	1941	only	-	Mar	 2	 1:00s	1:00	S
-Rule	Iceland	1941	only	-	Nov	 2	 1:00s	0	-
-Rule	Iceland	1942	only	-	Mar	 8	 1:00s	1:00	S
-Rule	Iceland	1942	only	-	Oct	25	 1:00s	0	-
-# 1943-1946 - first Sunday in March until first Sunday in winter
-Rule	Iceland	1943	1946	-	Mar	Sun>=1	 1:00s	1:00	S
-Rule	Iceland	1943	1948	-	Oct	Sun>=22	 1:00s	0	-
-# 1947-1967 - first Sunday in April until first Sunday in winter
-Rule	Iceland	1947	1967	-	Apr	Sun>=1	 1:00s	1:00	S
-# 1949 Oct transition delayed by 1 week
-Rule	Iceland	1949	only	-	Oct	30	 1:00s	0	-
-Rule	Iceland	1950	1966	-	Oct	Sun>=22	 1:00s	0	-
-Rule	Iceland	1967	only	-	Oct	29	 1:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/Reykjavik	-1:27:24 -	LMT	1837
-			-1:27:48 -	RMT	1908 # Reykjavik Mean Time?
-			-1:00	Iceland	IS%sT	1968 Apr 7 1:00s
-			 0:00	-	GMT
-
-# Italy
-#
-# From Paul Eggert (2001-03-06):
-# Sicily and Sardinia each had their own time zones from 1866 to 1893,
-# called Palermo Time (+00:53:28) and Cagliari Time (+00:36:32).
-# During World War II, German-controlled Italy used German time.
-# But these events all occurred before the 1970 cutoff,
-# so record only the time in Rome.
-#
-# From Paul Eggert (2006-03-22):
-# For Italian DST we have three sources: Shanks & Pottenger, Whitman, and
-# F. Pollastri
-# <a href="http://toi.iriti.cnr.it/uk/ienitlt.html">
-# Day-light Saving Time in Italy (2006-02-03)
-# </a>
-# (`FP' below), taken from an Italian National Electrotechnical Institute
-# publication. When the three sources disagree, guess who's right, as follows:
-#
-# year	FP	Shanks&P. (S)	Whitman (W)	Go with:
-# 1916	06-03	06-03 24:00	06-03 00:00	FP & W
-#	09-30	09-30 24:00	09-30 01:00	FP; guess 24:00s
-# 1917	04-01	03-31 24:00	03-31 00:00	FP & S
-#	09-30	09-29 24:00	09-30 01:00	FP & W
-# 1918	03-09	03-09 24:00	03-09 00:00	FP & S
-#	10-06	10-05 24:00	10-06 01:00	FP & W
-# 1919	03-01	03-01 24:00	03-01 00:00	FP & S
-#	10-04	10-04 24:00	10-04 01:00	FP; guess 24:00s
-# 1920	03-20	03-20 24:00	03-20 00:00	FP & S
-#	09-18	09-18 24:00	10-01 01:00	FP; guess 24:00s
-# 1944	04-02	04-03 02:00			S (see C-Eur)
-#	09-16	10-02 03:00			FP; guess 24:00s
-# 1945	09-14	09-16 24:00			FP; guess 24:00s
-# 1970	05-21	05-31 00:00			S
-#	09-20	09-27 00:00			S
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Italy	1916	only	-	Jun	 3	0:00s	1:00	S
-Rule	Italy	1916	only	-	Oct	 1	0:00s	0	-
-Rule	Italy	1917	only	-	Apr	 1	0:00s	1:00	S
-Rule	Italy	1917	only	-	Sep	30	0:00s	0	-
-Rule	Italy	1918	only	-	Mar	10	0:00s	1:00	S
-Rule	Italy	1918	1919	-	Oct	Sun>=1	0:00s	0	-
-Rule	Italy	1919	only	-	Mar	 2	0:00s	1:00	S
-Rule	Italy	1920	only	-	Mar	21	0:00s	1:00	S
-Rule	Italy	1920	only	-	Sep	19	0:00s	0	-
-Rule	Italy	1940	only	-	Jun	15	0:00s	1:00	S
-Rule	Italy	1944	only	-	Sep	17	0:00s	0	-
-Rule	Italy	1945	only	-	Apr	 2	2:00	1:00	S
-Rule	Italy	1945	only	-	Sep	15	0:00s	0	-
-Rule	Italy	1946	only	-	Mar	17	2:00s	1:00	S
-Rule	Italy	1946	only	-	Oct	 6	2:00s	0	-
-Rule	Italy	1947	only	-	Mar	16	0:00s	1:00	S
-Rule	Italy	1947	only	-	Oct	 5	0:00s	0	-
-Rule	Italy	1948	only	-	Feb	29	2:00s	1:00	S
-Rule	Italy	1948	only	-	Oct	 3	2:00s	0	-
-Rule	Italy	1966	1968	-	May	Sun>=22	0:00	1:00	S
-Rule	Italy	1966	1969	-	Sep	Sun>=22	0:00	0	-
-Rule	Italy	1969	only	-	Jun	 1	0:00	1:00	S
-Rule	Italy	1970	only	-	May	31	0:00	1:00	S
-Rule	Italy	1970	only	-	Sep	lastSun	0:00	0	-
-Rule	Italy	1971	1972	-	May	Sun>=22	0:00	1:00	S
-Rule	Italy	1971	only	-	Sep	lastSun	1:00	0	-
-Rule	Italy	1972	only	-	Oct	 1	0:00	0	-
-Rule	Italy	1973	only	-	Jun	 3	0:00	1:00	S
-Rule	Italy	1973	1974	-	Sep	lastSun	0:00	0	-
-Rule	Italy	1974	only	-	May	26	0:00	1:00	S
-Rule	Italy	1975	only	-	Jun	 1	0:00s	1:00	S
-Rule	Italy	1975	1977	-	Sep	lastSun	0:00s	0	-
-Rule	Italy	1976	only	-	May	30	0:00s	1:00	S
-Rule	Italy	1977	1979	-	May	Sun>=22	0:00s	1:00	S
-Rule	Italy	1978	only	-	Oct	 1	0:00s	0	-
-Rule	Italy	1979	only	-	Sep	30	0:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Rome	0:49:56 -	LMT	1866 Sep 22
-			0:49:56	-	RMT	1893 Nov  1 0:00s # Rome Mean
-			1:00	Italy	CE%sT	1942 Nov  2 2:00s
-			1:00	C-Eur	CE%sT	1944 Jul
-			1:00	Italy	CE%sT	1980
-			1:00	EU	CE%sT
-
-Link	Europe/Rome	Europe/Vatican
-Link	Europe/Rome	Europe/San_Marino
-
-# Latvia
-
-# From Liene Kanepe (1998-09-17):
-
-# I asked about this matter Scientific Secretary of the Institute of Astronomy
-# of The University of Latvia Dr. paed Mr. Ilgonis Vilks. I also searched the
-# correct data in juridical acts and I found some juridical documents about
-# changes in the counting of time in Latvia from 1981....
-#
-# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ...
-# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24
-# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
-# the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00)
-# and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00).
-#
-# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ...
-# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13
-# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
-# the hands of the clock 1 hour forward on the last Sunday of March at 02:00
-# (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of
-# September at 03:00 (GMT 23:00 on the previous day).
-#
-# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ...
-# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14
-# ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR,
-# Estonian SSR and Kaliningrad region of Russian Federation all year round the
-# time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia
-# transition to summer time is performed on the last Sunday of March at 02:00
-# (GMT 00:00), turning the hands of the clock 1 hour forward.  The end of
-# daylight saving time is performed on the last Sunday of September at 03:00
-# (GMT 00:00), turning the hands of the clock 1 hour backward. Exception is
-# 1989-03-26, when we must not turn the hands of the clock....
-#
-# The Regulations of the Cabinet of Ministers of the Republic of Latvia of
-# 1997-01-21 on transition to Summer time ... established the same order of
-# daylight savings time settings as in the States of the European Union.
-
-# From Andrei Ivanov (2000-03-06):
-# This year Latvia will not switch to Daylight Savings Time (as specified in
-# <a href="http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm">
-# The Regulations of the Cabinet of Ministers of the Rep. of Latvia of
-# 29-Feb-2000 (#79)</a>, in Latvian for subscribers only).
-
-# <a href="http://www.rferl.org/newsline/2001/01/3-CEE/cee-030101.html">
-# From RFE/RL Newsline (2001-01-03), noted after a heads-up by Rives McDow:
-# </a>
-# The Latvian government on 2 January decided that the country will
-# institute daylight-saving time this spring, LETA reported.
-# Last February the three Baltic states decided not to turn back their
-# clocks one hour in the spring....
-# Minister of Economy Aigars Kalvitis noted that Latvia had too few
-# daylight hours and thus decided to comply with a draft European
-# Commission directive that provides for instituting daylight-saving
-# time in EU countries between 2002 and 2006. The Latvian government
-# urged Lithuania and Estonia to adopt a similar time policy, but it
-# appears that they will not do so....
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Latvia	1989	1996	-	Mar	lastSun	 2:00s	1:00	S
-Rule	Latvia	1989	1996	-	Sep	lastSun	 2:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Riga	1:36:24	-	LMT	1880
-			1:36:24	-	RMT	1918 Apr 15 2:00 #Riga Mean Time
-			1:36:24	1:00	LST	1918 Sep 16 3:00 #Latvian Summer
-			1:36:24	-	RMT	1919 Apr  1 2:00
-			1:36:24	1:00	LST	1919 May 22 3:00
-			1:36:24	-	RMT	1926 May 11
-			2:00	-	EET	1940 Aug  5
-			3:00	-	MSK	1941 Jul
-			1:00	C-Eur	CE%sT	1944 Oct 13
-			3:00	Russia	MSK/MSD	1989 Mar lastSun 2:00s
-			2:00	1:00	EEST	1989 Sep lastSun 2:00s
-			2:00	Latvia	EE%sT	1997 Jan 21
-			2:00	EU	EE%sT	2000 Feb 29
-			2:00	-	EET	2001 Jan  2
-			2:00	EU	EE%sT
-
-# Liechtenstein
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Vaduz	0:38:04 -	LMT	1894 Jun
-			1:00	-	CET	1981
-			1:00	EU	CE%sT
-
-# Lithuania
-
-# From Paul Eggert (1996-11-22):
-# IATA SSIM (1992/1996) says Lithuania uses W-Eur rules, but since it is
-# known to be wrong about Estonia and Latvia, assume it's wrong here too.
-
-# From Marius Gedminas (1998-08-07):
-# I would like to inform that in this year Lithuanian time zone
-# (Europe/Vilnius) was changed.
-
-# From <a href="http://www.elta.lt/">ELTA</a> No. 972 (2582) (1999-09-29),
-# via Steffen Thorsen:
-# Lithuania has shifted back to the second time zone (GMT plus two hours)
-# to be valid here starting from October 31,
-# as decided by the national government on Wednesday....
-# The Lithuanian government also announced plans to consider a
-# motion to give up shifting to summer time in spring, as it was
-# already done by Estonia.
-
-# From the <a href="http://www.tourism.lt/informa/ff.htm">
-# Fact File, Lithuanian State Department of Tourism
-# </a> (2000-03-27): Local time is GMT+2 hours ..., no daylight saving.
-
-# From a user via Klaus Marten (2003-02-07):
-# As a candidate for membership of the European Union, Lithuania will
-# observe Summer Time in 2003, changing its clocks at the times laid
-# down in EU Directive 2000/84 of 19.I.01 (i.e. at the same times as its
-# neighbour Latvia). The text of the Lithuanian government Order of
-# 7.XI.02 to this effect can be found at
-# http://www.lrvk.lt/nut/11/n1749.htm
-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Vilnius	1:41:16	-	LMT	1880
-			1:24:00	-	WMT	1917	    # Warsaw Mean Time
-			1:35:36	-	KMT	1919 Oct 10 # Kaunas Mean Time
-			1:00	-	CET	1920 Jul 12
-			2:00	-	EET	1920 Oct  9
-			1:00	-	CET	1940 Aug  3
-			3:00	-	MSK	1941 Jun 24
-			1:00	C-Eur	CE%sT	1944 Aug
-			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			2:00	1:00	EEST	1991 Sep 29 2:00s
-			2:00	C-Eur	EE%sT	1998
-			2:00	-	EET	1998 Mar 29 1:00u
-			1:00	EU	CE%sT	1999 Oct 31 1:00u
-			2:00	-	EET	2003 Jan  1
-			2:00	EU	EE%sT
-
-# Luxembourg
-# Whitman disagrees with most of these dates in minor ways;
-# go with Shanks & Pottenger.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Lux	1916	only	-	May	14	23:00	1:00	S
-Rule	Lux	1916	only	-	Oct	 1	 1:00	0	-
-Rule	Lux	1917	only	-	Apr	28	23:00	1:00	S
-Rule	Lux	1917	only	-	Sep	17	 1:00	0	-
-Rule	Lux	1918	only	-	Apr	Mon>=15	 2:00s	1:00	S
-Rule	Lux	1918	only	-	Sep	Mon>=15	 2:00s	0	-
-Rule	Lux	1919	only	-	Mar	 1	23:00	1:00	S
-Rule	Lux	1919	only	-	Oct	 5	 3:00	0	-
-Rule	Lux	1920	only	-	Feb	14	23:00	1:00	S
-Rule	Lux	1920	only	-	Oct	24	 2:00	0	-
-Rule	Lux	1921	only	-	Mar	14	23:00	1:00	S
-Rule	Lux	1921	only	-	Oct	26	 2:00	0	-
-Rule	Lux	1922	only	-	Mar	25	23:00	1:00	S
-Rule	Lux	1922	only	-	Oct	Sun>=2	 1:00	0	-
-Rule	Lux	1923	only	-	Apr	21	23:00	1:00	S
-Rule	Lux	1923	only	-	Oct	Sun>=2	 2:00	0	-
-Rule	Lux	1924	only	-	Mar	29	23:00	1:00	S
-Rule	Lux	1924	1928	-	Oct	Sun>=2	 1:00	0	-
-Rule	Lux	1925	only	-	Apr	 5	23:00	1:00	S
-Rule	Lux	1926	only	-	Apr	17	23:00	1:00	S
-Rule	Lux	1927	only	-	Apr	 9	23:00	1:00	S
-Rule	Lux	1928	only	-	Apr	14	23:00	1:00	S
-Rule	Lux	1929	only	-	Apr	20	23:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Europe/Luxembourg	0:24:36 -	LMT	1904 Jun
-			1:00	Lux	CE%sT	1918 Nov 25
-			0:00	Lux	WE%sT	1929 Oct  6 2:00s
-			0:00	Belgium	WE%sT	1940 May 14 3:00
-			1:00	C-Eur	WE%sT	1944 Sep 18 3:00
-			1:00	Belgium	CE%sT	1977
-			1:00	EU	CE%sT
-
-# Macedonia
-# see Serbia
-
-# Malta
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Malta	1973	only	-	Mar	31	0:00s	1:00	S
-Rule	Malta	1973	only	-	Sep	29	0:00s	0	-
-Rule	Malta	1974	only	-	Apr	21	0:00s	1:00	S
-Rule	Malta	1974	only	-	Sep	16	0:00s	0	-
-Rule	Malta	1975	1979	-	Apr	Sun>=15	2:00	1:00	S
-Rule	Malta	1975	1980	-	Sep	Sun>=15	2:00	0	-
-Rule	Malta	1980	only	-	Mar	31	2:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Malta	0:58:04 -	LMT	1893 Nov  2 0:00s # Valletta
-			1:00	Italy	CE%sT	1942 Nov  2 2:00s
-			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
-			1:00	Italy	CE%sT	1973 Mar 31
-			1:00	Malta	CE%sT	1981
-			1:00	EU	CE%sT
-
-# Moldova
-
-# From Paul Eggert (2006-03-22):
-# A previous version of this database followed Shanks & Pottenger, who write
-# that Tiraspol switched to Moscow time on 1992-01-19 at 02:00.
-# However, this is most likely an error, as Moldova declared independence
-# on 1991-08-27 (the 1992-01-19 date is that of a Russian decree).
-# In early 1992 there was large-scale interethnic violence in the area
-# and it's possible that some Russophones continued to observe Moscow time.
-# But [two people] separately reported via
-# Jesper Norgaard that as of 2001-01-24 Tiraspol was like Chisinau.
-# The Tiraspol entry has therefore been removed for now.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Chisinau	1:55:20 -	LMT	1880
-			1:55	-	CMT	1918 Feb 15 # Chisinau MT
-			1:44:24	-	BMT	1931 Jul 24 # Bucharest MT
-			2:00	Romania	EE%sT	1940 Aug 15
-			2:00	1:00	EEST	1941 Jul 17
-			1:00	C-Eur	CE%sT	1944 Aug 24
-			3:00	Russia	MSK/MSD	1990
-			3:00	-	MSK	1990 May 6
-			2:00	-	EET	1991
-			2:00	Russia	EE%sT	1992
-			2:00	E-Eur	EE%sT	1997
-# See Romania commentary for the guessed 1997 transition to EU rules.
-			2:00	EU	EE%sT
-
-# Monaco
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
-# more precise 0:09:21.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Monaco	0:29:32 -	LMT	1891 Mar 15
-			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
-			0:00	France	WE%sT	1945 Sep 16 3:00
-			1:00	France	CE%sT	1977
-			1:00	EU	CE%sT
-
-# Montenegro
-# see Serbia
-
-# Netherlands
-
-# Howse writes that the Netherlands' railways used GMT between 1892 and 1940,
-# but for other purposes the Netherlands used Amsterdam mean time.
-
-# However, Robert H. van Gent writes (2001-04-01):
-# Howse's statement is only correct up to 1909. From 1909-05-01 (00:00:00
-# Amsterdam mean time) onwards, the whole of the Netherlands (including
-# the Dutch railways) was required by law to observe Amsterdam mean time
-# (19 minutes 32.13 seconds ahead of GMT). This had already been the
-# common practice (except for the railways) for many decades but it was
-# not until 1909 when the Dutch government finally defined this by law.
-# On 1937-07-01 this was changed to 20 minutes (exactly) ahead of GMT and
-# was generally known as Dutch Time ("Nederlandse Tijd").
-#
-# (2001-04-08):
-# 1892-05-01 was the date when the Dutch railways were by law required to
-# observe GMT while the remainder of the Netherlands adhered to the common
-# practice of following Amsterdam mean time.
-#
-# (2001-04-09):
-# In 1835 the authorities of the province of North Holland requested the
-# municipal authorities of the towns and cities in the province to observe
-# Amsterdam mean time but I do not know in how many cases this request was
-# actually followed.
-#
-# From 1852 onwards the Dutch telegraph offices were by law required to
-# observe Amsterdam mean time. As the time signals from the observatory of
-# Leiden were also distributed by the telegraph system, I assume that most
-# places linked up with the telegraph (and railway) system automatically
-# adopted Amsterdam mean time.
-#
-# Although the early Dutch railway companies initially observed a variety
-# of times, most of them had adopted Amsterdam mean time by 1858 but it
-# was not until 1866 when they were all required by law to observe
-# Amsterdam mean time.
-
-# The data before 1945 are taken from
-# <http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm>.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Neth	1916	only	-	May	 1	0:00	1:00	NST	# Netherlands Summer Time
-Rule	Neth	1916	only	-	Oct	 1	0:00	0	AMT	# Amsterdam Mean Time
-Rule	Neth	1917	only	-	Apr	16	2:00s	1:00	NST
-Rule	Neth	1917	only	-	Sep	17	2:00s	0	AMT
-Rule	Neth	1918	1921	-	Apr	Mon>=1	2:00s	1:00	NST
-Rule	Neth	1918	1921	-	Sep	lastMon	2:00s	0	AMT
-Rule	Neth	1922	only	-	Mar	lastSun	2:00s	1:00	NST
-Rule	Neth	1922	1936	-	Oct	Sun>=2	2:00s	0	AMT
-Rule	Neth	1923	only	-	Jun	Fri>=1	2:00s	1:00	NST
-Rule	Neth	1924	only	-	Mar	lastSun	2:00s	1:00	NST
-Rule	Neth	1925	only	-	Jun	Fri>=1	2:00s	1:00	NST
-# From 1926 through 1939 DST began 05-15, except that it was delayed by a week
-# in years when 05-15 fell in the Pentecost weekend.
-Rule	Neth	1926	1931	-	May	15	2:00s	1:00	NST
-Rule	Neth	1932	only	-	May	22	2:00s	1:00	NST
-Rule	Neth	1933	1936	-	May	15	2:00s	1:00	NST
-Rule	Neth	1937	only	-	May	22	2:00s	1:00	NST
-Rule	Neth	1937	only	-	Jul	 1	0:00	1:00	S
-Rule	Neth	1937	1939	-	Oct	Sun>=2	2:00s	0	-
-Rule	Neth	1938	1939	-	May	15	2:00s	1:00	S
-Rule	Neth	1945	only	-	Apr	 2	2:00s	1:00	S
-Rule	Neth	1945	only	-	Sep	16	2:00s	0	-
-#
-# Amsterdam Mean Time was +00:19:32.13 exactly, but the .13 is omitted
-# below because the current format requires GMTOFF to be an integer.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Europe/Amsterdam	0:19:32 -	LMT	1835
-			0:19:32	Neth	%s	1937 Jul  1
-			0:20	Neth	NE%sT	1940 May 16 0:00 # Dutch Time
-			1:00	C-Eur	CE%sT	1945 Apr  2 2:00
-			1:00	Neth	CE%sT	1977
-			1:00	EU	CE%sT
-
-# Norway
-# http://met.no/met/met_lex/q_u/sommertid.html (2004-01) agrees with Shanks &
-# Pottenger.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Norway	1916	only	-	May	22	1:00	1:00	S
-Rule	Norway	1916	only	-	Sep	30	0:00	0	-
-Rule	Norway	1945	only	-	Apr	 2	2:00s	1:00	S
-Rule	Norway	1945	only	-	Oct	 1	2:00s	0	-
-Rule	Norway	1959	1964	-	Mar	Sun>=15	2:00s	1:00	S
-Rule	Norway	1959	1965	-	Sep	Sun>=15	2:00s	0	-
-Rule	Norway	1965	only	-	Apr	25	2:00s	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Oslo	0:43:00 -	LMT	1895 Jan  1
-			1:00	Norway	CE%sT	1940 Aug 10 23:00
-			1:00	C-Eur	CE%sT	1945 Apr  2  2:00
-			1:00	Norway	CE%sT	1980
-			1:00	EU	CE%sT
-
-# Svalbard & Jan Mayen
-
-# From Steffen Thorsen (2001-05-01):
-# Although I could not find it explicitly, it seems that Jan Mayen and
-# Svalbard have been using the same time as Norway at least since the
-# time they were declared as parts of Norway.  Svalbard was declared
-# as a part of Norway by law of 1925-07-17 no 11, section 4 and Jan
-# Mayen by law of 1930-02-27 no 2, section 2. (From
-# http://www.lovdata.no/all/nl-19250717-011.html and
-# http://www.lovdata.no/all/nl-19300227-002.html).  The law/regulation
-# for normal/standard time in Norway is from 1894-06-29 no 1 (came
-# into operation on 1895-01-01) and Svalbard/Jan Mayen seem to be a
-# part of this law since 1925/1930. (From
-# http://www.lovdata.no/all/nl-18940629-001.html ) I have not been
-# able to find if Jan Mayen used a different time zone (e.g. -0100)
-# before 1930. Jan Mayen has only been "inhabitated" since 1921 by
-# Norwegian meteorologists and maybe used the same time as Norway ever
-# since 1921.  Svalbard (Arctic/Longyearbyen) has been inhabited since
-# before 1895, and therefore probably changed the local time somewhere
-# between 1895 and 1925 (inclusive).
-
-# From Paul Eggert (2001-05-01):
-#
-# Actually, Jan Mayen was never occupied by Germany during World War II,
-# so it must have diverged from Oslo time during the war, as Oslo was
-# keeping Berlin time.
-#
-# <http://home.no.net/janmayen/history.htm> says that the meteorologists
-# burned down their station in 1940 and left the island, but returned in
-# 1941 with a small Norwegian garrison and continued operations despite
-# frequent air ttacks from Germans.  In 1943 the Americans established a
-# radiolocating station on the island, called "Atlantic City".  Possibly
-# the UTC offset changed during the war, but I think it unlikely that
-# Jan Mayen used German daylight-saving rules.
-#
-# Svalbard is more complicated, as it was raided in August 1941 by an
-# Allied party that evacuated the civilian population to England (says
-# <http://www.bartleby.com/65/sv/Svalbard.html>).  The Svalbard FAQ
-# <http://www.svalbard.com/SvalbardFAQ.html> says that the Germans were
-# expelled on 1942-05-14.  However, small parties of Germans did return,
-# and according to Wilhelm Dege's book "War North of 80" (1954)
-# <http://www.ucalgary.ca/UofC/departments/UP/1-55238/1-55238-110-2.html>
-# the German armed forces at the Svalbard weather station code-named
-# Haudegen did not surrender to the Allies until September 1945.
-#
-# All these events predate our cutoff date of 1970.  Unless we can
-# come up with more definitive info about the timekeeping during the
-# war years it's probably best just do do the following for now:
-Link	Europe/Oslo	Arctic/Longyearbyen
-
-# Poland
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Poland	1918	1919	-	Sep	16	2:00s	0	-
-Rule	Poland	1919	only	-	Apr	15	2:00s	1:00	S
-Rule	Poland	1944	only	-	Apr	 3	2:00s	1:00	S
-# Whitman gives 1944 Nov 30; go with Shanks & Pottenger.
-Rule	Poland	1944	only	-	Oct	 4	2:00	0	-
-# For 1944-1948 Whitman gives the previous day; go with Shanks & Pottenger.
-Rule	Poland	1945	only	-	Apr	29	0:00	1:00	S
-Rule	Poland	1945	only	-	Nov	 1	0:00	0	-
-# For 1946 on the source is Kazimierz Borkowski,
-# Torun Center for Astronomy, Dept. of Radio Astronomy, Nicolaus Copernicus U.,
-# <http://www.astro.uni.torun.pl/~kb/Artykuly/U-PA/Czas2.htm#tth_tAb1>
-# Thanks to Przemyslaw Augustyniak (2005-05-28) for this reference.
-# He also gives these further references:
-# Mon Pol nr 13, poz 162 (1995) <http://www.abc.com.pl/serwis/mp/1995/0162.htm>
-# Druk nr 2180 (2003) <http://www.senat.gov.pl/k5/dok/sejm/053/2180.pdf>
-Rule	Poland	1946	only	-	Apr	14	0:00s	1:00	S
-Rule	Poland	1946	only	-	Oct	 7	2:00s	0	-
-Rule	Poland	1947	only	-	May	 4	2:00s	1:00	S
-Rule	Poland	1947	1949	-	Oct	Sun>=1	2:00s	0	-
-Rule	Poland	1948	only	-	Apr	18	2:00s	1:00	S
-Rule	Poland	1949	only	-	Apr	10	2:00s	1:00	S
-Rule	Poland	1957	only	-	Jun	 2	1:00s	1:00	S
-Rule	Poland	1957	1958	-	Sep	lastSun	1:00s	0	-
-Rule	Poland	1958	only	-	Mar	30	1:00s	1:00	S
-Rule	Poland	1959	only	-	May	31	1:00s	1:00	S
-Rule	Poland	1959	1961	-	Oct	Sun>=1	1:00s	0	-
-Rule	Poland	1960	only	-	Apr	 3	1:00s	1:00	S
-Rule	Poland	1961	1964	-	May	lastSun	1:00s	1:00	S
-Rule	Poland	1962	1964	-	Sep	lastSun	1:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Warsaw	1:24:00 -	LMT	1880
-			1:24:00	-	WMT	1915 Aug  5   # Warsaw Mean Time
-			1:00	C-Eur	CE%sT	1918 Sep 16 3:00
-			2:00	Poland	EE%sT	1922 Jun
-			1:00	Poland	CE%sT	1940 Jun 23 2:00
-			1:00	C-Eur	CE%sT	1944 Oct
-			1:00	Poland	CE%sT	1977
-			1:00	W-Eur	CE%sT	1988
-			1:00	EU	CE%sT
-
-# Portugal
-#
-# From Rui Pedro Salgueiro (1992-11-12):
-# Portugal has recently (September, 27) changed timezone
-# (from WET to MET or CET) to harmonize with EEC.
-#
-# Martin Bruckmann (1996-02-29) reports via Peter Ilieve
-# that Portugal is reverting to 0:00 by not moving its clocks this spring.
-# The new Prime Minister was fed up with getting up in the dark in the winter.
-#
-# From Paul Eggert (1996-11-12):
-# IATA SSIM (1991-09) reports several 1991-09 and 1992-09 transitions
-# at 02:00u, not 01:00u.  Assume that these are typos.
-# IATA SSIM (1991/1992) reports that the Azores were at -1:00.
-# IATA SSIM (1993-02) says +0:00; later issues (through 1996-09) say -1:00.
-# Guess that the Azores changed to EU rules in 1992 (since that's when Portugal
-# harmonized with the EU), and that they stayed +0:00 that winter.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# DSH writes that despite Decree 1,469 (1915), the change to the clocks was not
-# done every year, depending on what Spain did, because of railroad schedules.
-# Go with Shanks & Pottenger.
-Rule	Port	1916	only	-	Jun	17	23:00	1:00	S
-# Whitman gives 1916 Oct 31; go with Shanks & Pottenger.
-Rule	Port	1916	only	-	Nov	 1	 1:00	0	-
-Rule	Port	1917	only	-	Feb	28	23:00s	1:00	S
-Rule	Port	1917	1921	-	Oct	14	23:00s	0	-
-Rule	Port	1918	only	-	Mar	 1	23:00s	1:00	S
-Rule	Port	1919	only	-	Feb	28	23:00s	1:00	S
-Rule	Port	1920	only	-	Feb	29	23:00s	1:00	S
-Rule	Port	1921	only	-	Feb	28	23:00s	1:00	S
-Rule	Port	1924	only	-	Apr	16	23:00s	1:00	S
-Rule	Port	1924	only	-	Oct	14	23:00s	0	-
-Rule	Port	1926	only	-	Apr	17	23:00s	1:00	S
-Rule	Port	1926	1929	-	Oct	Sat>=1	23:00s	0	-
-Rule	Port	1927	only	-	Apr	 9	23:00s	1:00	S
-Rule	Port	1928	only	-	Apr	14	23:00s	1:00	S
-Rule	Port	1929	only	-	Apr	20	23:00s	1:00	S
-Rule	Port	1931	only	-	Apr	18	23:00s	1:00	S
-# Whitman gives 1931 Oct 8; go with Shanks & Pottenger.
-Rule	Port	1931	1932	-	Oct	Sat>=1	23:00s	0	-
-Rule	Port	1932	only	-	Apr	 2	23:00s	1:00	S
-Rule	Port	1934	only	-	Apr	 7	23:00s	1:00	S
-# Whitman gives 1934 Oct 5; go with Shanks & Pottenger.
-Rule	Port	1934	1938	-	Oct	Sat>=1	23:00s	0	-
-# Shanks & Pottenger give 1935 Apr 30; go with Whitman.
-Rule	Port	1935	only	-	Mar	30	23:00s	1:00	S
-Rule	Port	1936	only	-	Apr	18	23:00s	1:00	S
-# Whitman gives 1937 Apr 2; go with Shanks & Pottenger.
-Rule	Port	1937	only	-	Apr	 3	23:00s	1:00	S
-Rule	Port	1938	only	-	Mar	26	23:00s	1:00	S
-Rule	Port	1939	only	-	Apr	15	23:00s	1:00	S
-# Whitman gives 1939 Oct 7; go with Shanks & Pottenger.
-Rule	Port	1939	only	-	Nov	18	23:00s	0	-
-Rule	Port	1940	only	-	Feb	24	23:00s	1:00	S
-# Shanks & Pottenger give 1940 Oct 7; go with Whitman.
-Rule	Port	1940	1941	-	Oct	 5	23:00s	0	-
-Rule	Port	1941	only	-	Apr	 5	23:00s	1:00	S
-Rule	Port	1942	1945	-	Mar	Sat>=8	23:00s	1:00	S
-Rule	Port	1942	only	-	Apr	25	22:00s	2:00	M # Midsummer
-Rule	Port	1942	only	-	Aug	15	22:00s	1:00	S
-Rule	Port	1942	1945	-	Oct	Sat>=24	23:00s	0	-
-Rule	Port	1943	only	-	Apr	17	22:00s	2:00	M
-Rule	Port	1943	1945	-	Aug	Sat>=25	22:00s	1:00	S
-Rule	Port	1944	1945	-	Apr	Sat>=21	22:00s	2:00	M
-Rule	Port	1946	only	-	Apr	Sat>=1	23:00s	1:00	S
-Rule	Port	1946	only	-	Oct	Sat>=1	23:00s	0	-
-Rule	Port	1947	1949	-	Apr	Sun>=1	 2:00s	1:00	S
-Rule	Port	1947	1949	-	Oct	Sun>=1	 2:00s	0	-
-# Shanks & Pottenger say DST was observed in 1950; go with Whitman.
-# Whitman gives Oct lastSun for 1952 on; go with Shanks & Pottenger.
-Rule	Port	1951	1965	-	Apr	Sun>=1	 2:00s	1:00	S
-Rule	Port	1951	1965	-	Oct	Sun>=1	 2:00s	0	-
-Rule	Port	1977	only	-	Mar	27	 0:00s	1:00	S
-Rule	Port	1977	only	-	Sep	25	 0:00s	0	-
-Rule	Port	1978	1979	-	Apr	Sun>=1	 0:00s	1:00	S
-Rule	Port	1978	only	-	Oct	 1	 0:00s	0	-
-Rule	Port	1979	1982	-	Sep	lastSun	 1:00s	0	-
-Rule	Port	1980	only	-	Mar	lastSun	 0:00s	1:00	S
-Rule	Port	1981	1982	-	Mar	lastSun	 1:00s	1:00	S
-Rule	Port	1983	only	-	Mar	lastSun	 2:00s	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# Shanks & Pottenger say the transition from LMT to WET occurred 1911-05-24;
-# Willett says 1912-01-01.  Go with Willett.
-Zone	Europe/Lisbon	-0:36:32 -	LMT	1884
-			-0:36:32 -	LMT	1912 Jan  1  # Lisbon Mean Time
-			 0:00	Port	WE%sT	1966 Apr  3 2:00
-			 1:00	-	CET	1976 Sep 26 1:00
-			 0:00	Port	WE%sT	1983 Sep 25 1:00s
-			 0:00	W-Eur	WE%sT	1992 Sep 27 1:00s
-			 1:00	EU	CE%sT	1996 Mar 31 1:00u
-			 0:00	EU	WE%sT
-Zone Atlantic/Azores	-1:42:40 -	LMT	1884		# Ponta Delgada
-			-1:54:32 -	HMT	1911 May 24  # Horta Mean Time
-			-2:00	Port	AZO%sT	1966 Apr  3 2:00 # Azores Time
-			-1:00	Port	AZO%sT	1983 Sep 25 1:00s
-			-1:00	W-Eur	AZO%sT	1992 Sep 27 1:00s
-			 0:00	EU	WE%sT	1993 Mar 28 1:00u
-			-1:00	EU	AZO%sT
-Zone Atlantic/Madeira	-1:07:36 -	LMT	1884		# Funchal
-			-1:07:36 -	FMT	1911 May 24  # Funchal Mean Time
-			-1:00	Port	MAD%sT	1966 Apr  3 2:00 # Madeira Time
-			 0:00	Port	WE%sT	1983 Sep 25 1:00s
-			 0:00	EU	WE%sT
-
-# Romania
-#
-# From Paul Eggert (1999-10-07):
-# <a href="http://www.nineoclock.ro/POL/1778pol.html">
-# Nine O'clock</a> (1998-10-23) reports that the switch occurred at
-# 04:00 local time in fall 1998.  For lack of better info,
-# assume that Romania and Moldova switched to EU rules in 1997,
-# the same year as Bulgaria.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Romania	1932	only	-	May	21	 0:00s	1:00	S
-Rule	Romania	1932	1939	-	Oct	Sun>=1	 0:00s	0	-
-Rule	Romania	1933	1939	-	Apr	Sun>=2	 0:00s	1:00	S
-Rule	Romania	1979	only	-	May	27	 0:00	1:00	S
-Rule	Romania	1979	only	-	Sep	lastSun	 0:00	0	-
-Rule	Romania	1980	only	-	Apr	 5	23:00	1:00	S
-Rule	Romania	1980	only	-	Sep	lastSun	 1:00	0	-
-Rule	Romania	1991	1993	-	Mar	lastSun	 0:00s	1:00	S
-Rule	Romania	1991	1993	-	Sep	lastSun	 0:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Europe/Bucharest	1:44:24 -	LMT	1891 Oct
-			1:44:24	-	BMT	1931 Jul 24	# Bucharest MT
-			2:00	Romania	EE%sT	1981 Mar 29 2:00s
-			2:00	C-Eur	EE%sT	1991
-			2:00	Romania	EE%sT	1994
-			2:00	E-Eur	EE%sT	1997
-			2:00	EU	EE%sT
-
-# Russia
-
-# From Paul Eggert (2006-03-22):
-# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
-# Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
-# are from Andrey A. Chernov.  The rest is from Shanks & Pottenger,
-# except we follow Chernov's report that 1992 DST transitions were Sat
-# 23:00, not Sun 02:00s.
-#
-# From Stanislaw A. Kuzikowski (1994-06-29):
-# But now it is some months since Novosibirsk is 3 hours ahead of Moscow!
-# I do not know why they have decided to make this change;
-# as far as I remember it was done exactly during winter->summer switching
-# so we (Novosibirsk) simply did not switch.
-#
-# From Andrey A. Chernov (1996-10-04):
-# `MSK' and `MSD' were born and used initially on Moscow computers with
-# UNIX-like OSes by several developer groups (e.g. Demos group, Kiae group)....
-# The next step was the UUCP network, the Relcom predecessor
-# (used mainly for mail), and MSK/MSD was actively used there.
-#
-# From Chris Carrier (1996-10-30):
-# According to a friend of mine who rode the Trans-Siberian Railroad from
-# Moscow to Irkutsk in 1995, public air and rail transport in Russia ...
-# still follows Moscow time, no matter where in Russia it is located.
-#
-# For Grozny, Chechnya, we have the following story from
-# John Daniszewski, "Scavengers in the Rubble", Los Angeles Times (2001-02-07):
-# News--often false--is spread by word of mouth.  A rumor that it was
-# time to move the clocks back put this whole city out of sync with
-# the rest of Russia for two weeks--even soldiers stationed here began
-# enforcing curfew at the wrong time.
-#
-# From Gwillim Law (2001-06-05):
-# There's considerable evidence that Sakhalin Island used to be in
-# UTC+11, and has changed to UTC+10, in this decade.  I start with the
-# SSIM, which listed Yuzhno-Sakhalinsk in zone RU10 along with Magadan
-# until February 1997, and then in RU9 with Khabarovsk and Vladivostok
-# since September 1997....  Although the Kuril Islands are
-# administratively part of Sakhalin oblast', they appear to have
-# remained on UTC+11 along with Magadan.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-#
-# Kaliningradskaya oblast'.
-Zone Europe/Kaliningrad	 1:22:00 -	LMT	1893 Apr
-			 1:00	C-Eur	CE%sT	1945
-			 2:00	Poland	CE%sT	1946
-			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			 2:00	Russia	EE%sT
-#
-# From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Respublika Adygeya, Arkhangel'skaya oblast',
-# Belgorodskaya oblast', Bryanskaya oblast', Vladimirskaya oblast',
-# Vologodskaya oblast', Voronezhskaya oblast',
-# Respublika Dagestan, Ivanovskaya oblast', Respublika Ingushetiya,
-# Kabarbino-Balkarskaya Respublika, Respublika Kalmykiya,
-# Kalyzhskaya oblast', Respublika Karachaevo-Cherkessiya,
-# Respublika Kareliya, Respublika Komi,
-# Kostromskaya oblast', Krasnodarskij kraj, Kurskaya oblast',
-# Leningradskaya oblast', Lipetskaya oblast', Respublika Marij El,
-# Respublika Mordoviya, Moskva, Moskovskaya oblast',
-# Murmanskaya oblast', Nenetskij avtonomnyj okrug,
-# Nizhegorodskaya oblast', Novgorodskaya oblast', Orlovskaya oblast',
-# Penzenskaya oblast', Pskovskaya oblast', Rostovskaya oblast',
-# Ryazanskaya oblast', Sankt-Peterburg,
-# Respublika Severnaya Osetiya, Smolenskaya oblast',
-# Stavropol'skij kraj, Tambovskaya oblast', Respublika Tatarstan,
-# Tverskaya oblast', Tyl'skaya oblast', Ul'yanovskaya oblast',
-# Chechenskaya Respublika, Chuvashskaya oblast',
-# Yaroslavskaya oblast'
-Zone Europe/Moscow	 2:30:20 -	LMT	1880
-			 2:30	-	MMT	1916 Jul  3 # Moscow Mean Time
-			 2:30:48 Russia	%s	1919 Jul  1 2:00
-			 3:00	Russia	MSK/MSD	1922 Oct
-			 2:00	-	EET	1930 Jun 21
-			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			 2:00	Russia	EE%sT	1992 Jan 19 2:00s
-			 3:00	Russia	MSK/MSD
-#
-# Astrakhanskaya oblast', Kirovskaya oblast', Saratovskaya oblast',
-# Volgogradskaya oblast'.  Shanks & Pottenger say Kirov is still at +0400
-# but Wikipedia (2006-05-09) says +0300.  Perhaps it switched after the
-# others?  But we have no data.
-Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
-			 3:00	-	TSAT	1925 Apr  6 # Tsaritsyn Time
-			 3:00	-	STAT	1930 Jun 21 # Stalingrad Time
-			 4:00	-	STAT	1961 Nov 11
-			 4:00	Russia	VOL%sT	1989 Mar 26 2:00s # Volgograd T
-			 3:00	Russia	VOL%sT	1991 Mar 31 2:00s
-			 4:00	-	VOLT	1992 Mar 29 2:00s
-			 3:00	Russia	VOL%sT
-#
-# From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Samarskaya oblast', Udmyrtskaya respublika
-Zone Europe/Samara	 3:20:36 -	LMT	1919 Jul  1 2:00
-			 3:00	-	SAMT	1930 Jun 21
-			 4:00	-	SAMT	1935 Jan 27
-			 4:00	Russia	KUY%sT	1989 Mar 26 2:00s # Kuybyshev
-			 3:00	Russia	KUY%sT	1991 Mar 31 2:00s
-			 2:00	Russia	KUY%sT	1991 Sep 29 2:00s
-			 3:00	-	KUYT	1991 Oct 20 3:00
-			 4:00	Russia	SAM%sT	2010 Mar 28 2:00s # Samara Time
-			 3:00	Russia	SAM%sT
-
-#
-# From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Respublika Bashkortostan, Komi-Permyatskij avtonomnyj okrug,
-# Kurganskaya oblast', Orenburgskaya oblast', Permskaya oblast',
-# Sverdlovskaya oblast', Tyumenskaya oblast',
-# Khanty-Manskijskij avtonomnyj okrug, Chelyabinskaya oblast',
-# Yamalo-Nenetskij avtonomnyj okrug.
-Zone Asia/Yekaterinburg	 4:02:24 -	LMT	1919 Jul 15 4:00
-			 4:00	-	SVET	1930 Jun 21 # Sverdlovsk Time
-			 5:00	Russia	SVE%sT	1991 Mar 31 2:00s
-			 4:00	Russia	SVE%sT	1992 Jan 19 2:00s
-			 5:00	Russia	YEK%sT	# Yekaterinburg Time
-#
-# From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Respublika Altaj, Altajskij kraj, Omskaya oblast'.
-Zone Asia/Omsk		 4:53:36 -	LMT	1919 Nov 14
-			 5:00	-	OMST	1930 Jun 21 # Omsk TIme
-			 6:00	Russia	OMS%sT	1991 Mar 31 2:00s
-			 5:00	Russia	OMS%sT	1992 Jan 19 2:00s
-			 6:00	Russia	OMS%sT
-#
-# From Paul Eggert (2006-08-19): I'm guessing about Tomsk here; it's
-# not clear when it switched from +7 to +6.
-# Novosibirskaya oblast', Tomskaya oblast'.
-Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14 6:00
-			 6:00	-	NOVT	1930 Jun 21 # Novosibirsk Time
-			 7:00	Russia	NOV%sT	1991 Mar 31 2:00s
-			 6:00	Russia	NOV%sT	1992 Jan 19 2:00s
-			 7:00	Russia	NOV%sT	1993 May 23 # say Shanks & P.
-			 6:00	Russia	NOV%sT
-
-# From Alexander Krivenyshev (2009-10-13):
-# Kemerovo oblast' (Kemerovo region) in Russia will change current time zone on
-# March 28, 2010:
-# from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700
-# to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600
-#
-# This is according to Government of Russia decree # 740, on September
-# 14, 2009 "Application in the territory of the Kemerovo region the Fifth
-# time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600)
-#
-# Russian Government web site (Russian language)
-# <a href="http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archiv">
-# http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archive/2009/09/14/991633.htm
-# </a>
-# or Russian-English translation by WorldTimeZone.com with reference
-# map to local region and new Russia Time Zone map after March 28, 2010
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_russia03.html">
-# http://www.worldtimezone.com/dst_news/dst_news_russia03.html
-# </a>
-#
-# Thus, when Russia will switch to DST on the night of March 28, 2010
-# Kemerovo region (Kemerovo oblast') will not change the clock.
-#
-# As a result, Kemerovo oblast' will be in the same time zone as
-# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic.
-
-Zone Asia/Novokuznetsk	 5:48:48 -	NMT	1920 Jan  6
-			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
-			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
-			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
-			 7:00	Russia	KRA%sT	2010 Mar 28 2:00s
-			 6:00	Russia	NOV%sT # Novosibirsk/Novokuznetsk Time
-
-#
-# From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Krasnoyarskij kraj,
-# Tajmyrskij (Dolgano-Nenetskij) avtonomnyj okrug,
-# Respublika Tuva, Respublika Khakasiya, Evenkijskij avtonomnyj okrug.
-Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
-			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
-			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
-			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
-			 7:00	Russia	KRA%sT
-#
-# From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Respublika Buryatiya, Irkutskaya oblast',
-# Ust'-Ordynskij Buryatskij avtonomnyj okrug.
-Zone Asia/Irkutsk	 6:57:20 -	LMT	1880
-			 6:57:20 -	IMT	1920 Jan 25 # Irkutsk Mean Time
-			 7:00	-	IRKT	1930 Jun 21 # Irkutsk Time
-			 8:00	Russia	IRK%sT	1991 Mar 31 2:00s
-			 7:00	Russia	IRK%sT	1992 Jan 19 2:00s
-			 8:00	Russia	IRK%sT
-#
-# From Oscar van Vlijmen (2003-10-18): [This region consists of]
-# Aginskij Buryatskij avtonomnyj okrug, Amurskaya oblast',
-# [parts of] Respublika Sakha (Yakutiya), Chitinskaya oblast'.
-
-# From Oscar van Vlijmen (2009-11-29):
-# ...some regions of RUssia were merged with others since 2005...
-# Some names were changed, no big deal, except for one instance: a new name.
-# YAK/YAKST: UTC+9 Zabajkal'skij kraj.
-
-# From Oscar van Vlijmen (2009-11-29):
-# The Sakha districts are: Aldanskij, Amginskij, Anabarskij,
-# Verkhnevilyujskij, Vilyujskij, Gornyj,
-# Zhiganskij, Kobyajskij, Lenskij, Megino-Kangalasskij, Mirninskij,
-# Namskij, Nyurbinskij, Olenyokskij, Olyokminskij,
-# Suntarskij, Tattinskij, Ust'-Aldanskij, Khangalasskij,
-# Churapchinskij, Eveno-Bytantajskij Natsional'nij.
-
-Zone Asia/Yakutsk	 8:38:40 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
-			 8:00	Russia	YAK%sT	1992 Jan 19 2:00s
-			 9:00	Russia	YAK%sT
-#
-# From Oscar van Vlijmen (2003-10-18): [This region consists of]
-# Evrejskaya avtonomnaya oblast', Khabarovskij kraj, Primorskij kraj,
-# [parts of] Respublika Sakha (Yakutiya).
-
-# From Oscar van Vlijmen (2009-11-29):
-# The Sakha districts are: Bulunskij, Verkhoyanskij, Tomponskij, Ust'-Majskij,
-# Ust'-Yanskij.
-Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
-			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
-			10:00	Russia	VLA%sT	1991 Mar 31 2:00s
-			 9:00	Russia	VLA%sST	1992 Jan 19 2:00s
-			10:00	Russia	VLA%sT
-#
-# Sakhalinskaya oblast'.
-# The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
-Zone Asia/Sakhalin	 9:30:48 -	LMT	1905 Aug 23
-			 9:00	-	CJT	1938
-			 9:00	-	JST	1945 Aug 25
-			11:00	Russia	SAK%sT	1991 Mar 31 2:00s # Sakhalin T.
-			10:00	Russia	SAK%sT	1992 Jan 19 2:00s
-			11:00	Russia	SAK%sT	1997 Mar lastSun 2:00s
-			10:00	Russia	SAK%sT
-#
-# From Oscar van Vlijmen (2003-10-18): [This region consists of]
-# Magadanskaya oblast', Respublika Sakha (Yakutiya).
-# Probably also: Kuril Islands.
-
-# From Oscar van Vlijmen (2009-11-29):
-# The Sakha districts are: Abyjskij, Allaikhovskij, Verkhhhnekolymskij, Momskij,
-# Nizhnekolymskij, Ojmyakonskij, Srednekolymskij.
-Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
-			10:00	-	MAGT	1930 Jun 21 # Magadan Time
-			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
-			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
-			11:00	Russia	MAG%sT
-#
-# From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
-#
-# The Zone name should be Asia/Petropavlovsk-Kamchatski, but that's too long.
-Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
-			11:00	-	PETT	1930 Jun 21 # P-K Time
-			12:00	Russia	PET%sT	1991 Mar 31 2:00s
-			11:00	Russia	PET%sT	1992 Jan 19 2:00s
-			12:00	Russia	PET%sT	2010 Mar 28 2:00s
-			11:00	Russia	PET%sT
-#
-# Chukotskij avtonomnyj okrug
-Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
-			12:00	-	ANAT	1930 Jun 21 # Anadyr Time
-			13:00	Russia	ANA%sT	1982 Apr  1 0:00s
-			12:00	Russia	ANA%sT	1991 Mar 31 2:00s
-			11:00	Russia	ANA%sT	1992 Jan 19 2:00s
-			12:00	Russia	ANA%sT	2010 Mar 28 2:00s
-			11:00	Russia	ANA%sT
-
-# Serbia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Belgrade	1:22:00	-	LMT	1884
-			1:00	-	CET	1941 Apr 18 23:00
-			1:00	C-Eur	CE%sT	1945
-			1:00	-	CET	1945 May 8 2:00s
-			1:00	1:00	CEST	1945 Sep 16  2:00s
-# Metod Kozelj reports that the legal date of
-# transition to EU rules was 1982-11-27, for all of Yugoslavia at the time.
-# Shanks & Pottenger don't give as much detail, so go with Kozelj.
-			1:00	-	CET	1982 Nov 27
-			1:00	EU	CE%sT
-Link Europe/Belgrade Europe/Ljubljana	# Slovenia
-Link Europe/Belgrade Europe/Podgorica	# Montenegro
-Link Europe/Belgrade Europe/Sarajevo	# Bosnia and Herzegovina
-Link Europe/Belgrade Europe/Skopje	# Macedonia
-Link Europe/Belgrade Europe/Zagreb	# Croatia
-
-# Slovakia
-Link Europe/Prague Europe/Bratislava
-
-# Slovenia
-# see Serbia
-
-# Spain
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1;
-# go with Shanks & Pottenger.
-Rule	Spain	1917	only	-	May	 5	23:00s	1:00	S
-Rule	Spain	1917	1919	-	Oct	 6	23:00s	0	-
-Rule	Spain	1918	only	-	Apr	15	23:00s	1:00	S
-Rule	Spain	1919	only	-	Apr	 5	23:00s	1:00	S
-# Whitman gives 1921 Feb 28 - Oct 14; go with Shanks & Pottenger.
-Rule	Spain	1924	only	-	Apr	16	23:00s	1:00	S
-# Whitman gives 1924 Oct 14; go with Shanks & Pottenger.
-Rule	Spain	1924	only	-	Oct	 4	23:00s	0	-
-Rule	Spain	1926	only	-	Apr	17	23:00s	1:00	S
-# Whitman says no DST in 1929; go with Shanks & Pottenger.
-Rule	Spain	1926	1929	-	Oct	Sat>=1	23:00s	0	-
-Rule	Spain	1927	only	-	Apr	 9	23:00s	1:00	S
-Rule	Spain	1928	only	-	Apr	14	23:00s	1:00	S
-Rule	Spain	1929	only	-	Apr	20	23:00s	1:00	S
-# Whitman gives 1937 Jun 16, 1938 Apr 16, 1940 Apr 13;
-# go with Shanks & Pottenger.
-Rule	Spain	1937	only	-	May	22	23:00s	1:00	S
-Rule	Spain	1937	1939	-	Oct	Sat>=1	23:00s	0	-
-Rule	Spain	1938	only	-	Mar	22	23:00s	1:00	S
-Rule	Spain	1939	only	-	Apr	15	23:00s	1:00	S
-Rule	Spain	1940	only	-	Mar	16	23:00s	1:00	S
-# Whitman says no DST 1942-1945; go with Shanks & Pottenger.
-Rule	Spain	1942	only	-	May	 2	22:00s	2:00	M # Midsummer
-Rule	Spain	1942	only	-	Sep	 1	22:00s	1:00	S
-Rule	Spain	1943	1946	-	Apr	Sat>=13	22:00s	2:00	M
-Rule	Spain	1943	only	-	Oct	 3	22:00s	1:00	S
-Rule	Spain	1944	only	-	Oct	10	22:00s	1:00	S
-Rule	Spain	1945	only	-	Sep	30	 1:00	1:00	S
-Rule	Spain	1946	only	-	Sep	30	 0:00	0	-
-Rule	Spain	1949	only	-	Apr	30	23:00	1:00	S
-Rule	Spain	1949	only	-	Sep	30	 1:00	0	-
-Rule	Spain	1974	1975	-	Apr	Sat>=13	23:00	1:00	S
-Rule	Spain	1974	1975	-	Oct	Sun>=1	 1:00	0	-
-Rule	Spain	1976	only	-	Mar	27	23:00	1:00	S
-Rule	Spain	1976	1977	-	Sep	lastSun	 1:00	0	-
-Rule	Spain	1977	1978	-	Apr	 2	23:00	1:00	S
-Rule	Spain	1978	only	-	Oct	 1	 1:00	0	-
-# The following rules are copied from Morocco from 1967 through 1978.
-Rule SpainAfrica 1967	only	-	Jun	 3	12:00	1:00	S
-Rule SpainAfrica 1967	only	-	Oct	 1	 0:00	0	-
-Rule SpainAfrica 1974	only	-	Jun	24	 0:00	1:00	S
-Rule SpainAfrica 1974	only	-	Sep	 1	 0:00	0	-
-Rule SpainAfrica 1976	1977	-	May	 1	 0:00	1:00	S
-Rule SpainAfrica 1976	only	-	Aug	 1	 0:00	0	-
-Rule SpainAfrica 1977	only	-	Sep	28	 0:00	0	-
-Rule SpainAfrica 1978	only	-	Jun	 1	 0:00	1:00	S
-Rule SpainAfrica 1978	only	-	Aug	 4	 0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Madrid	-0:14:44 -	LMT	1901 Jan  1  0:00s
-			 0:00	Spain	WE%sT	1946 Sep 30
-			 1:00	Spain	CE%sT	1979
-			 1:00	EU	CE%sT
-Zone	Africa/Ceuta	-0:21:16 -	LMT	1901
-			 0:00	-	WET	1918 May  6 23:00
-			 0:00	1:00	WEST	1918 Oct  7 23:00
-			 0:00	-	WET	1924
-			 0:00	Spain	WE%sT	1929
-			 0:00 SpainAfrica WE%sT 1984 Mar 16
-			 1:00	-	CET	1986
-			 1:00	EU	CE%sT
-Zone	Atlantic/Canary	-1:01:36 -	LMT	1922 Mar # Las Palmas de Gran C.
-			-1:00	-	CANT	1946 Sep 30 1:00 # Canaries Time
-			 0:00	-	WET	1980 Apr  6 0:00s
-			 0:00	1:00	WEST	1980 Sep 28 0:00s
-			 0:00	EU	WE%sT
-# IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u.
-# Ignore this for now, as the Canaries are part of the EU.
-
-# Sweden
-
-# From Ivan Nilsson (2001-04-13), superseding Shanks & Pottenger:
-#
-# The law "Svensk forfattningssamling 1878, no 14" about standard time in 1879:
-# From the beginning of 1879 (that is 01-01 00:00) the time for all
-# places in the country is "the mean solar time for the meridian at
-# three degrees, or twelve minutes of time, to the west of the
-# meridian of the Observatory of Stockholm".  The law is dated 1878-05-31.
-#
-# The observatory at that time had the meridian 18 degrees 03' 30"
-# eastern longitude = 01:12:14 in time.  Less 12 minutes gives the
-# national standard time as 01:00:14 ahead of GMT....
-#
-# About the beginning of CET in Sweden. The lawtext ("Svensk
-# forfattningssamling 1899, no 44") states, that "from the beginning
-# of 1900... ... the same as the mean solar time for the meridian at
-# the distance of one hour of time from the meridian of the English
-# observatory at Greenwich, or at 12 minutes 14 seconds to the west
-# from the meridian of the Observatory of Stockholm". The law is dated
-# 1899-06-16.  In short: At 1900-01-01 00:00:00 the new standard time
-# in Sweden is 01:00:00 ahead of GMT.
-#
-# 1916: The lawtext ("Svensk forfattningssamling 1916, no 124") states
-# that "1916-05-15 is considered to begin one hour earlier". It is
-# pretty obvious that at 05-14 23:00 the clocks are set to 05-15 00:00....
-# Further the law says, that "1916-09-30 is considered to end one hour later".
-#
-# The laws regulating [DST] are available on the site of the Swedish
-# Parliament beginning with 1985 - the laws regulating 1980/1984 are
-# not available on the site (to my knowledge they are only available
-# in Swedish): <http://www.riksdagen.se/english/work/sfst.asp> (type
-# "sommartid" without the quotes in the field "Fritext" and then click
-# the Sok-button).
-#
-# (2001-05-13):
-#
-# I have now found a newspaper stating that at 1916-10-01 01:00
-# summertime the church-clocks etc were set back one hour to show
-# 1916-10-01 00:00 standard time.  The article also reports that some
-# people thought the switch to standard time would take place already
-# at 1916-10-01 00:00 summer time, but they had to wait for another
-# hour before the event took place.
-#
-# Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Europe/Stockholm	1:12:12 -	LMT	1879 Jan  1
-			1:00:14	-	SET	1900 Jan  1	# Swedish Time
-			1:00	-	CET	1916 May 14 23:00
-			1:00	1:00	CEST	1916 Oct  1 01:00
-			1:00	-	CET	1980
-			1:00	EU	CE%sT
-
-# Switzerland
-# From Howse:
-# By the end of the 18th century clocks and watches became commonplace
-# and their performance improved enormously.  Communities began to keep
-# mean time in preference to apparent time -- Geneva from 1780 ....
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# From Whitman (who writes ``Midnight?''):
-# Rule	Swiss	1940	only	-	Nov	 2	0:00	1:00	S
-# Rule	Swiss	1940	only	-	Dec	31	0:00	0	-
-# From Shanks & Pottenger:
-# Rule	Swiss	1941	1942	-	May	Sun>=1	2:00	1:00	S
-# Rule	Swiss	1941	1942	-	Oct	Sun>=1	0:00	0	-
-
-# From Alois Treindl (2008-12-17):
-# I have researched the DST usage in Switzerland during the 1940ies.
-#
-# As I wrote in an earlier message, I suspected the current tzdata values
-# to be wrong. This is now verified.
-#
-# I have found copies of the original ruling by the Swiss Federal
-# government, in 'Eidgen[o]ssische Gesetzessammlung 1941 and 1942' (Swiss
-# federal law collection)...
-#
-# DST began on Monday 5 May 1941, 1:00 am by shifting the clocks to 2:00 am
-# DST ended on Monday 6 Oct 1941, 2:00 am by shifting the clocks to 1:00 am.
-#
-# DST began on Monday, 4 May 1942 at 01:00 am
-# DST ended on Monday, 5 Oct 1942 at 02:00 am
-#
-# There was no DST in 1940, I have checked the law collection carefully.
-# It is also indicated by the fact that the 1942 entry in the law
-# collection points back to 1941 as a reference, but no reference to any
-# other years are made.
-#
-# Newspaper articles I have read in the archives on 6 May 1941 reported
-# about the introduction of DST (Sommerzeit in German) during the previous
-# night as an absolute novelty, because this was the first time that such
-# a thing had happened in Switzerland.
-#
-# I have also checked 1916, because one book source (Gabriel, Traite de
-# l'heure dans le monde) claims that Switzerland had DST in 1916. This is
-# false, no official document could be found. Probably Gabriel got misled
-# by references to Germany, which introduced DST in 1916 for the first time.
-#
-# The tzdata rules for Switzerland must be changed to:
-# Rule  Swiss   1941    1942    -       May     Mon>=1  1:00    1:00    S
-# Rule  Swiss   1941    1942    -       Oct     Mon>=1  2:00    0       -
-#
-# The 1940 rules must be deleted.
-#
-# One further detail for Switzerland, which is probably out of scope for
-# most users of tzdata:
-# The zone file
-# Zone    Europe/Zurich   0:34:08 -       LMT     1848 Sep 12
-#                          0:29:44 -       BMT     1894 Jun #Bern Mean Time
-#                          1:00    Swiss   CE%sT   1981
-#                          1:00    EU      CE%sT
-# describes all of Switzerland correctly, with the exception of
-# the Cantone Geneve (Geneva, Genf). Between 1848 and 1894 Geneve did not
-# follow Bern Mean Time but kept its own local mean time.
-# To represent this, an extra zone would be needed.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Swiss	1941	1942	-	May	Mon>=1	1:00	1:00	S
-Rule	Swiss	1941	1942	-	Oct	Mon>=1	2:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Zurich	0:34:08 -	LMT	1848 Sep 12
-			0:29:44	-	BMT	1894 Jun # Bern Mean Time
-			1:00	Swiss	CE%sT	1981
-			1:00	EU	CE%sT
-
-# Turkey
-
-# From Amar Devegowda (2007-01-03):
-# The time zone rules for Istanbul, Turkey have not been changed for years now.
-# ... The latest rules are available at -
-# http://www.timeanddate.com/worldclock/timezone.html?n=107
-# From Steffen Thorsen (2007-01-03):
-# I have been able to find press records back to 1996 which all say that
-# DST started 01:00 local time and end at 02:00 local time.  I am not sure
-# what happened before that.  One example for each year from 1996 to 2001:
-# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027
-# From Paul Eggert (2007-01-03):
-# Prefer the above source to Shanks & Pottenger for time stamps after 1990.
-
-# From Steffen Thorsen (2007-03-09):
-# Starting 2007 though, it seems that they are adopting EU's 1:00 UTC
-# start/end time, according to the following page (2007-03-07):
-# http://www.ntvmsnbc.com/news/402029.asp
-# The official document is located here - it is in Turkish...:
-# http://rega.basbakanlik.gov.tr/eskiler/2007/03/20070307-7.htm
-# I was able to locate the following seemingly official document
-# (on a non-government server though) describing dates between 2002 and 2006:
-# http://www.alomaliye.com/bkk_2002_3769.htm
-
-# From Sue Williams (2008-08-11):
-# I spotted this news article about a potential change in Turkey.
-#
-# <a href="http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1">
-# http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1
-# </a>
-
-# From Sue Williams (2008-08-20):
-# This article says that around the end of March 2011, Turkey wants to
-# adjust the clocks forward by 1/2 hour and stay that way permanently.
-# The article indicates that this is a change in timezone offset in addition
-# to stopping observance of DST.
-# This proposal has not yet been approved.
-#
-# Read more here...
-#
-# Turkey to abandon daylight saving time in 2011
-# <a href="http://www.turkishdailynews.com.tr/article.php?enewsid=112989">
-# http://www.turkishdailynews.com.tr/article.php?enewsid=112989
-# </a>
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Turkey	1916	only	-	May	 1	0:00	1:00	S
-Rule	Turkey	1916	only	-	Oct	 1	0:00	0	-
-Rule	Turkey	1920	only	-	Mar	28	0:00	1:00	S
-Rule	Turkey	1920	only	-	Oct	25	0:00	0	-
-Rule	Turkey	1921	only	-	Apr	 3	0:00	1:00	S
-Rule	Turkey	1921	only	-	Oct	 3	0:00	0	-
-Rule	Turkey	1922	only	-	Mar	26	0:00	1:00	S
-Rule	Turkey	1922	only	-	Oct	 8	0:00	0	-
-# Whitman gives 1923 Apr 28 - Sep 16 and no DST in 1924-1925;
-# go with Shanks & Pottenger.
-Rule	Turkey	1924	only	-	May	13	0:00	1:00	S
-Rule	Turkey	1924	1925	-	Oct	 1	0:00	0	-
-Rule	Turkey	1925	only	-	May	 1	0:00	1:00	S
-Rule	Turkey	1940	only	-	Jun	30	0:00	1:00	S
-Rule	Turkey	1940	only	-	Oct	 5	0:00	0	-
-Rule	Turkey	1940	only	-	Dec	 1	0:00	1:00	S
-Rule	Turkey	1941	only	-	Sep	21	0:00	0	-
-Rule	Turkey	1942	only	-	Apr	 1	0:00	1:00	S
-# Whitman omits the next two transition and gives 1945 Oct 1;
-# go with Shanks & Pottenger.
-Rule	Turkey	1942	only	-	Nov	 1	0:00	0	-
-Rule	Turkey	1945	only	-	Apr	 2	0:00	1:00	S
-Rule	Turkey	1945	only	-	Oct	 8	0:00	0	-
-Rule	Turkey	1946	only	-	Jun	 1	0:00	1:00	S
-Rule	Turkey	1946	only	-	Oct	 1	0:00	0	-
-Rule	Turkey	1947	1948	-	Apr	Sun>=16	0:00	1:00	S
-Rule	Turkey	1947	1950	-	Oct	Sun>=2	0:00	0	-
-Rule	Turkey	1949	only	-	Apr	10	0:00	1:00	S
-Rule	Turkey	1950	only	-	Apr	19	0:00	1:00	S
-Rule	Turkey	1951	only	-	Apr	22	0:00	1:00	S
-Rule	Turkey	1951	only	-	Oct	 8	0:00	0	-
-Rule	Turkey	1962	only	-	Jul	15	0:00	1:00	S
-Rule	Turkey	1962	only	-	Oct	 8	0:00	0	-
-Rule	Turkey	1964	only	-	May	15	0:00	1:00	S
-Rule	Turkey	1964	only	-	Oct	 1	0:00	0	-
-Rule	Turkey	1970	1972	-	May	Sun>=2	0:00	1:00	S
-Rule	Turkey	1970	1972	-	Oct	Sun>=2	0:00	0	-
-Rule	Turkey	1973	only	-	Jun	 3	1:00	1:00	S
-Rule	Turkey	1973	only	-	Nov	 4	3:00	0	-
-Rule	Turkey	1974	only	-	Mar	31	2:00	1:00	S
-Rule	Turkey	1974	only	-	Nov	 3	5:00	0	-
-Rule	Turkey	1975	only	-	Mar	30	0:00	1:00	S
-Rule	Turkey	1975	1976	-	Oct	lastSun	0:00	0	-
-Rule	Turkey	1976	only	-	Jun	 1	0:00	1:00	S
-Rule	Turkey	1977	1978	-	Apr	Sun>=1	0:00	1:00	S
-Rule	Turkey	1977	only	-	Oct	16	0:00	0	-
-Rule	Turkey	1979	1980	-	Apr	Sun>=1	3:00	1:00	S
-Rule	Turkey	1979	1982	-	Oct	Mon>=11	0:00	0	-
-Rule	Turkey	1981	1982	-	Mar	lastSun	3:00	1:00	S
-Rule	Turkey	1983	only	-	Jul	31	0:00	1:00	S
-Rule	Turkey	1983	only	-	Oct	 2	0:00	0	-
-Rule	Turkey	1985	only	-	Apr	20	0:00	1:00	S
-Rule	Turkey	1985	only	-	Sep	28	0:00	0	-
-Rule	Turkey	1986	1990	-	Mar	lastSun	2:00s	1:00	S
-Rule	Turkey	1986	1990	-	Sep	lastSun	2:00s	0	-
-Rule	Turkey	1991	2006	-	Mar	lastSun	1:00s	1:00	S
-Rule	Turkey	1991	1995	-	Sep	lastSun	1:00s	0	-
-Rule	Turkey	1996	2006	-	Oct	lastSun	1:00s	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Istanbul	1:55:52 -	LMT	1880
-			1:56:56	-	IMT	1910 Oct # Istanbul Mean Time?
-			2:00	Turkey	EE%sT	1978 Oct 15
-			3:00	Turkey	TR%sT	1985 Apr 20 # Turkey Time
-			2:00	Turkey	EE%sT	2007
-			2:00	EU	EE%sT
-Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
-
-# Ukraine
-#
-# From Igor Karpov, who works for the Ukranian Ministry of Justice,
-# via Garrett Wollman (2003-01-27):
-# BTW, I've found the official document on this matter. It's goverment
-# regulations number 509, May 13, 1996. In my poor translation it says:
-# "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday
-# of March at 3am the time is changing to 4am and each last Sunday of
-# October the time at 4am is changing to 3am"
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# Most of Ukraine since 1970 has been like Kiev.
-# "Kyiv" is the transliteration of the Ukrainian name, but
-# "Kiev" is more common in English.
-Zone Europe/Kiev	2:02:04 -	LMT	1880
-			2:02:04	-	KMT	1924 May  2 # Kiev Mean Time
-			2:00	-	EET	1930 Jun 21
-			3:00	-	MSK	1941 Sep 20
-			1:00	C-Eur	CE%sT	1943 Nov  6
-			3:00	Russia	MSK/MSD	1990
-			3:00	-	MSK	1990 Jul  1 2:00
-			2:00	-	EET	1992
-			2:00	E-Eur	EE%sT	1995
-			2:00	EU	EE%sT
-# Ruthenia used CET 1990/1991.
-# "Uzhhorod" is the transliteration of the Ukrainian name, but
-# "Uzhgorod" is more common in English.
-Zone Europe/Uzhgorod	1:29:12 -	LMT	1890 Oct
-			1:00	-	CET	1940
-			1:00	C-Eur	CE%sT	1944 Oct
-			1:00	1:00	CEST	1944 Oct 26
-			1:00	-	CET	1945 Jun 29
-			3:00	Russia	MSK/MSD	1990
-			3:00	-	MSK	1990 Jul  1 2:00
-			1:00	-	CET	1991 Mar 31 3:00
-			2:00	-	EET	1992
-			2:00	E-Eur	EE%sT	1995
-			2:00	EU	EE%sT
-# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
-# "Zaporizhia" is the transliteration of the Ukrainian name, but
-# "Zaporozh'ye" is more common in English.  Use the common English
-# spelling, except omit the apostrophe as it is not allowed in
-# portable Posix file names.
-Zone Europe/Zaporozhye	2:20:40 -	LMT	1880
-			2:20	-	CUT	1924 May  2 # Central Ukraine T
-			2:00	-	EET	1930 Jun 21
-			3:00	-	MSK	1941 Aug 25
-			1:00	C-Eur	CE%sT	1943 Oct 25
-			3:00	Russia	MSK/MSD	1991 Mar 31 2:00
-			2:00	E-Eur	EE%sT	1995
-			2:00	EU	EE%sT
-# Central Crimea used Moscow time 1994/1997.
-Zone Europe/Simferopol	2:16:24 -	LMT	1880
-			2:16	-	SMT	1924 May  2 # Simferopol Mean T
-			2:00	-	EET	1930 Jun 21
-			3:00	-	MSK	1941 Nov
-			1:00	C-Eur	CE%sT	1944 Apr 13
-			3:00	Russia	MSK/MSD	1990
-			3:00	-	MSK	1990 Jul  1 2:00
-			2:00	-	EET	1992
-# From Paul Eggert (2006-03-22):
-# The _Economist_ (1994-05-28, p 45) reports that central Crimea switched
-# from Kiev to Moscow time sometime after the January 1994 elections.
-# Shanks (1999) says ``date of change uncertain'', but implies that it happened
-# sometime between the 1994 DST switches.  Shanks & Pottenger simply say
-# 1994-09-25 03:00, but that can't be right.  For now, guess it
-# changed in May.
-			2:00	E-Eur	EE%sT	1994 May
-# From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev.
-			3:00	E-Eur	MSK/MSD	1996 Mar 31 3:00s
-			3:00	1:00	MSD	1996 Oct 27 3:00s
-# IATA SSIM (1997-09) says Crimea switched to EET/EEST.
-# Assume it happened in March by not changing the clocks.
-			3:00	Russia	MSK/MSD	1997
-			3:00	-	MSK	1997 Mar lastSun 1:00u
-			2:00	EU	EE%sT
-
-###############################################################################
-
-# One source shows that Bulgaria, Cyprus, Finland, and Greece observe DST from
-# the last Sunday in March to the last Sunday in September in 1986.
-# The source shows Romania changing a day later than everybody else.
-#
-# According to Bernard Sieloff's source, Poland is in the MET time zone but
-# uses the WE DST rules.  The Western USSR uses EET+1 and ME DST rules.
-# Bernard Sieloff's source claims Romania switches on the same day, but at
-# 00:00 standard time (i.e., 01:00 DST).  It also claims that Turkey
-# switches on the same day, but switches on at 01:00 standard time
-# and off at 00:00 standard time (i.e., 01:00 DST)
-
-# ...
-# Date: Wed, 28 Jan 87 16:56:27 -0100
-# From: Tom Hofmann
-# ...
-#
-# ...the European time rules are...standardized since 1981, when
-# most European coun[tr]ies started DST.  Before that year, only
-# a few countries (UK, France, Italy) had DST, each according
-# to own national rules.  In 1981, however, DST started on
-# 'Apr firstSun', and not on 'Mar lastSun' as in the following
-# years...
-# But also since 1981 there are some more national exceptions
-# than listed in 'europe': Switzerland, for example, joined DST
-# one year later, Denmark ended DST on 'Oct 1' instead of 'Sep
-# lastSun' in 1981---I don't know how they handle now.
-#
-# Finally, DST ist always from 'Apr 1' to 'Oct 1' in the
-# Soviet Union (as far as I know).
-#
-# Tom Hofmann, Scientific Computer Center, CIBA-GEIGY AG,
-# 4002 Basle, Switzerland
-# ...
-
-# ...
-# Date: Wed, 4 Feb 87 22:35:22 +0100
-# From: Dik T. Winter
-# ...
-#
-# The information from Tom Hofmann is (as far as I know) not entirely correct.
-# After a request from chongo at amdahl I tried to retrieve all information
-# about DST in Europe.  I was able to find all from about 1969.
-#
-# ...standardization on DST in Europe started in about 1977 with switches on
-# first Sunday in April and last Sunday in September...
-# In 1981 UK joined Europe insofar that
-# the starting day for both shifted to last Sunday in March.  And from 1982
-# the whole of Europe used DST, with switch dates April 1 and October 1 in
-# the Sov[i]et Union.  In 1985 the SU reverted to standard Europe[a]n switch
-# dates...
-#
-# It should also be remembered that time-zones are not constants; e.g.
-# Portugal switched in 1976 from MET (or CET) to WET with DST...
-# Note also that though there were rules for switch dates not
-# all countries abided to these dates, and many individual deviations
-# occurred, though not since 1982 I believe.  Another note: it is always
-# assumed that DST is 1 hour ahead of normal time, this need not be the
-# case; at least in the Netherlands there have been times when DST was 2 hours
-# in advance of normal time.
-#
-# ...
-# dik t. winter, cwi, amsterdam, nederland
-# ...
-
-# From Bob Devine (1988-01-28):
-# ...
-# Greece: Last Sunday in April to last Sunday in September (iffy on dates).
-# Since 1978.  Change at midnight.
-# ...
-# Monaco: has same DST as France.
-# ...
diff --git a/tools/zoneinfo/tzdata2010k/factory b/tools/zoneinfo/tzdata2010k/factory
deleted file mode 100644
index 624ccc0..0000000
--- a/tools/zoneinfo/tzdata2010k/factory
+++ /dev/null
@@ -1,11 +0,0 @@
-# <pre>
-# @(#)factory	8.2
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# For companies who don't want to put time zone specification in
-# their installation procedures.  When users run date, they'll get the message.
-# Also useful for the "comp.sources" version.
-
-# Zone	NAME	GMTOFF	RULES	FORMAT
-Zone	Factory	0	- "Local time zone must be set--see zic manual page"
diff --git a/tools/zoneinfo/tzdata2010k/iso3166.tab b/tools/zoneinfo/tzdata2010k/iso3166.tab
deleted file mode 100644
index b8a2592..0000000
--- a/tools/zoneinfo/tzdata2010k/iso3166.tab
+++ /dev/null
@@ -1,271 +0,0 @@
-# <pre>
-# @(#)iso3166.tab	8.6
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-# ISO 3166 alpha-2 country codes
-#
-# From Paul Eggert (2006-09-27):
-#
-# This file contains a table with the following columns:
-# 1.  ISO 3166-1 alpha-2 country code, current as of
-#     ISO 3166-1 Newsletter VI-1 (2007-09-21).  See:
-#     <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
-#     ISO 3166 Maintenance agency (ISO 3166/MA)
-#     </a>.
-# 2.  The usual English name for the country,
-#     chosen so that alphabetic sorting of subsets produces helpful lists.
-#     This is not the same as the English name in the ISO 3166 tables.
-#
-# Columns are separated by a single tab.
-# The table is sorted by country code.
-#
-# Lines beginning with `#' are comments.
-#
-#country-
-#code	country name
-AD	Andorra
-AE	United Arab Emirates
-AF	Afghanistan
-AG	Antigua & Barbuda
-AI	Anguilla
-AL	Albania
-AM	Armenia
-AN	Netherlands Antilles
-AO	Angola
-AQ	Antarctica
-AR	Argentina
-AS	Samoa (American)
-AT	Austria
-AU	Australia
-AW	Aruba
-AX	Aaland Islands
-AZ	Azerbaijan
-BA	Bosnia & Herzegovina
-BB	Barbados
-BD	Bangladesh
-BE	Belgium
-BF	Burkina Faso
-BG	Bulgaria
-BH	Bahrain
-BI	Burundi
-BJ	Benin
-BL	St Barthelemy
-BM	Bermuda
-BN	Brunei
-BO	Bolivia
-BR	Brazil
-BS	Bahamas
-BT	Bhutan
-BV	Bouvet Island
-BW	Botswana
-BY	Belarus
-BZ	Belize
-CA	Canada
-CC	Cocos (Keeling) Islands
-CD	Congo (Dem. Rep.)
-CF	Central African Rep.
-CG	Congo (Rep.)
-CH	Switzerland
-CI	Cote d'Ivoire
-CK	Cook Islands
-CL	Chile
-CM	Cameroon
-CN	China
-CO	Colombia
-CR	Costa Rica
-CU	Cuba
-CV	Cape Verde
-CX	Christmas Island
-CY	Cyprus
-CZ	Czech Republic
-DE	Germany
-DJ	Djibouti
-DK	Denmark
-DM	Dominica
-DO	Dominican Republic
-DZ	Algeria
-EC	Ecuador
-EE	Estonia
-EG	Egypt
-EH	Western Sahara
-ER	Eritrea
-ES	Spain
-ET	Ethiopia
-FI	Finland
-FJ	Fiji
-FK	Falkland Islands
-FM	Micronesia
-FO	Faroe Islands
-FR	France
-GA	Gabon
-GB	Britain (UK)
-GD	Grenada
-GE	Georgia
-GF	French Guiana
-GG	Guernsey
-GH	Ghana
-GI	Gibraltar
-GL	Greenland
-GM	Gambia
-GN	Guinea
-GP	Guadeloupe
-GQ	Equatorial Guinea
-GR	Greece
-GS	South Georgia & the South Sandwich Islands
-GT	Guatemala
-GU	Guam
-GW	Guinea-Bissau
-GY	Guyana
-HK	Hong Kong
-HM	Heard Island & McDonald Islands
-HN	Honduras
-HR	Croatia
-HT	Haiti
-HU	Hungary
-ID	Indonesia
-IE	Ireland
-IL	Israel
-IM	Isle of Man
-IN	India
-IO	British Indian Ocean Territory
-IQ	Iraq
-IR	Iran
-IS	Iceland
-IT	Italy
-JE	Jersey
-JM	Jamaica
-JO	Jordan
-JP	Japan
-KE	Kenya
-KG	Kyrgyzstan
-KH	Cambodia
-KI	Kiribati
-KM	Comoros
-KN	St Kitts & Nevis
-KP	Korea (North)
-KR	Korea (South)
-KW	Kuwait
-KY	Cayman Islands
-KZ	Kazakhstan
-LA	Laos
-LB	Lebanon
-LC	St Lucia
-LI	Liechtenstein
-LK	Sri Lanka
-LR	Liberia
-LS	Lesotho
-LT	Lithuania
-LU	Luxembourg
-LV	Latvia
-LY	Libya
-MA	Morocco
-MC	Monaco
-MD	Moldova
-ME	Montenegro
-MF	St Martin (French part)
-MG	Madagascar
-MH	Marshall Islands
-MK	Macedonia
-ML	Mali
-MM	Myanmar (Burma)
-MN	Mongolia
-MO	Macau
-MP	Northern Mariana Islands
-MQ	Martinique
-MR	Mauritania
-MS	Montserrat
-MT	Malta
-MU	Mauritius
-MV	Maldives
-MW	Malawi
-MX	Mexico
-MY	Malaysia
-MZ	Mozambique
-NA	Namibia
-NC	New Caledonia
-NE	Niger
-NF	Norfolk Island
-NG	Nigeria
-NI	Nicaragua
-NL	Netherlands
-NO	Norway
-NP	Nepal
-NR	Nauru
-NU	Niue
-NZ	New Zealand
-OM	Oman
-PA	Panama
-PE	Peru
-PF	French Polynesia
-PG	Papua New Guinea
-PH	Philippines
-PK	Pakistan
-PL	Poland
-PM	St Pierre & Miquelon
-PN	Pitcairn
-PR	Puerto Rico
-PS	Palestine
-PT	Portugal
-PW	Palau
-PY	Paraguay
-QA	Qatar
-RE	Reunion
-RO	Romania
-RS	Serbia
-RU	Russia
-RW	Rwanda
-SA	Saudi Arabia
-SB	Solomon Islands
-SC	Seychelles
-SD	Sudan
-SE	Sweden
-SG	Singapore
-SH	St Helena
-SI	Slovenia
-SJ	Svalbard & Jan Mayen
-SK	Slovakia
-SL	Sierra Leone
-SM	San Marino
-SN	Senegal
-SO	Somalia
-SR	Suriname
-ST	Sao Tome & Principe
-SV	El Salvador
-SY	Syria
-SZ	Swaziland
-TC	Turks & Caicos Is
-TD	Chad
-TF	French Southern & Antarctic Lands
-TG	Togo
-TH	Thailand
-TJ	Tajikistan
-TK	Tokelau
-TL	East Timor
-TM	Turkmenistan
-TN	Tunisia
-TO	Tonga
-TR	Turkey
-TT	Trinidad & Tobago
-TV	Tuvalu
-TW	Taiwan
-TZ	Tanzania
-UA	Ukraine
-UG	Uganda
-UM	US minor outlying islands
-US	United States
-UY	Uruguay
-UZ	Uzbekistan
-VA	Vatican City
-VC	St Vincent
-VE	Venezuela
-VG	Virgin Islands (UK)
-VI	Virgin Islands (US)
-VN	Vietnam
-VU	Vanuatu
-WF	Wallis & Futuna
-WS	Samoa (western)
-YE	Yemen
-YT	Mayotte
-ZA	South Africa
-ZM	Zambia
-ZW	Zimbabwe
diff --git a/tools/zoneinfo/tzdata2010k/leapseconds b/tools/zoneinfo/tzdata2010k/leapseconds
deleted file mode 100644
index d70185c..0000000
--- a/tools/zoneinfo/tzdata2010k/leapseconds
+++ /dev/null
@@ -1,87 +0,0 @@
-# <pre>
-# @(#)leapseconds	8.10
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# Allowance for leapseconds added to each timezone file.
-
-# The International Earth Rotation Service periodically uses leap seconds
-# to keep UTC to within 0.9 s of UT1
-# (which measures the true angular orientation of the earth in space); see
-# Terry J Quinn, The BIPM and the accurate measure of time,
-# Proc IEEE 79, 7 (July 1991), 894-905.
-# There were no leap seconds before 1972, because the official mechanism
-# accounting for the discrepancy between atomic time and the earth's rotation
-# did not exist until the early 1970s.
-
-# The correction (+ or -) is made at the given time, so lines
-# will typically look like:
-#	Leap	YEAR	MON	DAY	23:59:60	+	R/S
-# or
-#	Leap	YEAR	MON	DAY	23:59:59	-	R/S
-
-# If the leapsecond is Rolling (R) the given time is local time
-# If the leapsecond is Stationary (S) the given time is UTC
-
-# Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S
-Leap	1972	Jun	30	23:59:60	+	S
-Leap	1972	Dec	31	23:59:60	+	S
-Leap	1973	Dec	31	23:59:60	+	S
-Leap	1974	Dec	31	23:59:60	+	S
-Leap	1975	Dec	31	23:59:60	+	S
-Leap	1976	Dec	31	23:59:60	+	S
-Leap	1977	Dec	31	23:59:60	+	S
-Leap	1978	Dec	31	23:59:60	+	S
-Leap	1979	Dec	31	23:59:60	+	S
-Leap	1981	Jun	30	23:59:60	+	S
-Leap	1982	Jun	30	23:59:60	+	S
-Leap	1983	Jun	30	23:59:60	+	S
-Leap	1985	Jun	30	23:59:60	+	S
-Leap	1987	Dec	31	23:59:60	+	S
-Leap	1989	Dec	31	23:59:60	+	S
-Leap	1990	Dec	31	23:59:60	+	S
-Leap	1992	Jun	30	23:59:60	+	S
-Leap	1993	Jun	30	23:59:60	+	S
-Leap	1994	Jun	30	23:59:60	+	S
-Leap	1995	Dec	31	23:59:60	+	S
-Leap	1997	Jun	30	23:59:60	+	S
-Leap	1998	Dec	31	23:59:60	+	S
-Leap	2005	Dec	31	23:59:60	+	S
-Leap	2008	Dec	31	23:59:60	+	S
-
-# INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS)
-#
-# SERVICE INTERNATIONAL DE LA ROTATION TERRESTRE ET DES SYSTEMES DE REFERENCE
-#
-# SERVICE DE LA ROTATION TERRESTRE
-# OBSERVATOIRE DE PARIS
-# 61, Av. de l'Observatoire 75014 PARIS (France)
-# Tel.      : 33 (0) 1 40 51 22 26
-# FAX       : 33 (0) 1 40 51 22 91
-# Internet  : services.iers@obspm.fr
-#
-# Paris, 14 July 2010
-#
-# Bulletin C 40
-#
-# To authorities responsible
-# for the measurement and
-# distribution of time
-#
-# INFORMATION ON UTC - TAI
-#
-# NO positive leap second will be introduced at the end of December 2010.
-# The difference between Coordinated Universal Time UTC and the
-# International Atomic Time TAI is :
-#
-# from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s
-#
-# Leap seconds can be introduced in UTC at the end of the months of December
-# or June,  depending on the evolution of UT1-TAI. Bulletin C is mailed every
-# six months, either to announce a time step in UTC, or to confirm that there
-# will be no time step at the next possible date.
-#
-# Daniel GAMBIS
-# Director
-# Earth Orientation Center of IERS
-# Observatoire de Paris, France
diff --git a/tools/zoneinfo/tzdata2010k/northamerica b/tools/zoneinfo/tzdata2010k/northamerica
deleted file mode 100644
index 7dfd064..0000000
--- a/tools/zoneinfo/tzdata2010k/northamerica
+++ /dev/null
@@ -1,2897 +0,0 @@
-# <pre>
-# @(#)northamerica	8.34
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# also includes Central America and the Caribbean
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert (1999-03-22):
-# A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
-
-###############################################################################
-
-# United States
-
-# From Paul Eggert (1999-03-31):
-# Howse writes (pp 121-125) that time zones were invented by
-# Professor Charles Ferdinand Dowd (1825-1904),
-# Principal of Temple Grove Ladies' Seminary (Saratoga Springs, NY).
-# His pamphlet ``A System of National Time for Railroads'' (1870)
-# was the result of his proposals at the Convention of Railroad Trunk Lines
-# in New York City (1869-10).  His 1870 proposal was based on Washington, DC,
-# but in 1872-05 he moved the proposed origin to Greenwich.
-# His proposal was adopted by the railroads on 1883-11-18 at 12:00,
-# and the most of the country soon followed suit.
-
-# From Paul Eggert (2005-04-16):
-# That 1883 transition occurred at 12:00 new time, not at 12:00 old time.
-# See p 46 of David Prerau, Seize the daylight, Thunder's Mouth Press (2005).
-
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data in the US is
-# Thomas G. Shanks, The American Atlas (5th edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Make sure you have the errata sheet; the book is somewhat useless without it.
-# It is the source for most of the pre-1991 US entries below.
-
-# From Paul Eggert (2001-03-06):
-# Daylight Saving Time was first suggested as a joke by Benjamin Franklin
-# in his whimsical essay ``An Economical Project for Diminishing the Cost
-# of Light'' published in the Journal de Paris (1784-04-26).
-# Not everyone is happy with the results:
-#
-#	I don't really care how time is reckoned so long as there is some
-#	agreement about it, but I object to being told that I am saving
-#	daylight when my reason tells me that I am doing nothing of the kind.
-#	I even object to the implication that I am wasting something
-#	valuable if I stay in bed after the sun has risen.  As an admirer
-#	of moonlight I resent the bossy insistence of those who want to
-#	reduce my time for enjoying it.  At the back of the Daylight Saving
-#	scheme I detect the bony, blue-fingered hand of Puritanism, eager
-#	to push people into bed earlier, and get them up earlier, to make
-#	them healthy, wealthy and wise in spite of themselves.
-#
-#	-- Robertson Davies, The diary of Samuel Marchbanks,
-#	   Clarke, Irwin (1947), XIX, Sunday
-#
-# For more about the first ten years of DST in the United States, see
-# Robert Garland's <a href="http://www.clpgh.org/exhibit/dst.html">
-# Ten years of daylight saving from the Pittsburgh standpoint
-# (Carnegie Library of Pittsburgh, 1927)</a>.
-#
-# Shanks says that DST was called "War Time" in the US in 1918 and 1919.
-# However, DST was imposed by the Standard Time Act of 1918, which
-# was the first nationwide legal time standard, and apparently
-# time was just called "Standard Time" or "Daylight Saving Time".
-
-# From Arthur David Olson:
-# US Daylight Saving Time ended on the last Sunday of *October* in 1974.
-# See, for example, the front page of the Saturday, 1974-10-26
-# and Sunday, 1974-10-27 editions of the Washington Post.
-
-# From Arthur David Olson:
-# Before the Uniform Time Act of 1966 took effect in 1967, observance of
-# Daylight Saving Time in the US was by local option, except during wartime.
-
-# From Arthur David Olson (2000-09-25):
-# Last night I heard part of a rebroadcast of a 1945 Arch Oboler radio drama.
-# In the introduction, Oboler spoke of "Eastern Peace Time."
-# An AltaVista search turned up
-# <a href="http://rowayton.org/rhs/hstaug45.html">:
-# "When the time is announced over the radio now, it is 'Eastern Peace
-# Time' instead of the old familiar 'Eastern War Time.'  Peace is wonderful."
-# </a> (August 1945) by way of confirmation.
-
-# From Joseph Gallant citing
-# George H. Douglas, _The Early Days of Radio Broadcasting_ (1987):
-# At 7 P.M. (Eastern War Time) [on 1945-08-14], the networks were set
-# to switch to London for Attlee's address, but the American people
-# never got to hear his speech live. According to one press account,
-# CBS' Bob Trout was first to announce the word of Japan's surrender,
-# but a few seconds later, NBC, ABC and Mutual also flashed the word
-# of surrender, all of whom interrupting the bells of Big Ben in
-# London which were to precede Mr. Attlee's speech.
-
-# From Paul Eggert (2003-02-09): It was Robert St John, not Bob Trout.  From
-# Myrna Oliver's obituary of St John on page B16 of today's Los Angeles Times:
-#
-# ... a war-weary U.S. clung to radios, awaiting word of Japan's surrender.
-# Any announcement from Asia would reach St. John's New York newsroom on a
-# wire service teletype machine, which had prescribed signals for major news.
-# Associated Press, for example, would ring five bells before spewing out
-# typed copy of an important story, and 10 bells for news "of transcendental
-# importance."
-#
-# On Aug. 14, stalling while talking steadily into the NBC networks' open
-# microphone, St. John heard five bells and waited only to hear a sixth bell,
-# before announcing confidently: "Ladies and gentlemen, World War II is over.
-# The Japanese have agreed to our surrender terms."
-#
-# He had scored a 20-second scoop on other broadcasters.
-
-# From Arthur David Olson (2005-08-22):
-# Paul has been careful to use the "US" rules only in those locations
-# that are part of the United States; this reflects the real scope of
-# U.S. government action.  So even though the "US" rules have changed
-# in the latest release, other countries won't be affected.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	US	1918	1919	-	Mar	lastSun	2:00	1:00	D
-Rule	US	1918	1919	-	Oct	lastSun	2:00	0	S
-Rule	US	1942	only	-	Feb	9	2:00	1:00	W # War
-Rule	US	1945	only	-	Aug	14	23:00u	1:00	P # Peace
-Rule	US	1945	only	-	Sep	30	2:00	0	S
-Rule	US	1967	2006	-	Oct	lastSun	2:00	0	S
-Rule	US	1967	1973	-	Apr	lastSun	2:00	1:00	D
-Rule	US	1974	only	-	Jan	6	2:00	1:00	D
-Rule	US	1975	only	-	Feb	23	2:00	1:00	D
-Rule	US	1976	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	US	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
-Rule	US	2007	max	-	Mar	Sun>=8	2:00	1:00	D
-Rule	US	2007	max	-	Nov	Sun>=1	2:00	0	S
-
-# From Arthur David Olson, 2005-12-19
-# We generate the files specified below to guard against old files with
-# obsolete information being left in the time zone binary directory.
-# We limit the list to names that have appeared in previous versions of
-# this time zone package.
-# We do these as separate Zones rather than as Links to avoid problems if
-# a particular place changes whether it observes DST.
-# We put these specifications here in the northamerica file both to
-# increase the chances that they'll actually get compiled and to
-# avoid the need to duplicate the US rules in another file.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	EST		 -5:00	-	EST
-Zone	MST		 -7:00	-	MST
-Zone	HST		-10:00	-	HST
-Zone	EST5EDT		 -5:00	US	E%sT
-Zone	CST6CDT		 -6:00	US	C%sT
-Zone	MST7MDT		 -7:00	US	M%sT
-Zone	PST8PDT		 -8:00	US	P%sT
-
-# From Bob Devine (1988-01-28):
-# ...Alaska (and Hawaii) had the timezone names changed in 1967.
-#    old			 new
-#    Pacific Standard Time(PST)  -same-
-#    Yukon Standard Time(YST)    -same-
-#    Central Alaska S.T. (CAT)   Alaska-Hawaii St[an]dard Time (AHST)
-#    Nome Standard Time (NT)     Bering Standard Time (BST)
-#
-# ...Alaska's timezone lines were redrawn in 1983 to give only 2 tz.
-#    The YST zone now covers nearly all of the state, AHST just part
-#    of the Aleutian islands.   No DST.
-
-# From Paul Eggert (1995-12-19):
-# The tables below use `NST', not `NT', for Nome Standard Time.
-# I invented `CAWT' for Central Alaska War Time.
-
-# From U. S. Naval Observatory (1989-01-19):
-# USA  EASTERN       5 H  BEHIND UTC    NEW YORK, WASHINGTON
-# USA  EASTERN       4 H  BEHIND UTC    APR 3 - OCT 30
-# USA  CENTRAL       6 H  BEHIND UTC    CHICAGO, HOUSTON
-# USA  CENTRAL       5 H  BEHIND UTC    APR 3 - OCT 30
-# USA  MOUNTAIN      7 H  BEHIND UTC    DENVER
-# USA  MOUNTAIN      6 H  BEHIND UTC    APR 3 - OCT 30
-# USA  PACIFIC       8 H  BEHIND UTC    L.A., SAN FRANCISCO
-# USA  PACIFIC       7 H  BEHIND UTC    APR 3 - OCT 30
-# USA  ALASKA STD    9 H  BEHIND UTC    MOST OF ALASKA     (AKST)
-# USA  ALASKA STD    8 H  BEHIND UTC    APR 3 - OCT 30 (AKDT)
-# USA  ALEUTIAN     10 H  BEHIND UTC    ISLANDS WEST OF 170W
-# USA  - " -         9 H  BEHIND UTC    APR 3 - OCT 30
-# USA  HAWAII       10 H  BEHIND UTC
-# USA  BERING       11 H  BEHIND UTC    SAMOA, MIDWAY
-
-# From Arthur David Olson (1989-01-21):
-# The above dates are for 1988.
-# Note the "AKST" and "AKDT" abbreviations, the claim that there's
-# no DST in Samoa, and the claim that there is DST in Alaska and the
-# Aleutians.
-
-# From Arthur David Olson (1988-02-13):
-# Legal standard time zone names, from United States Code (1982 Edition and
-# Supplement III), Title 15, Chapter 6, Section 260 and forward.  First, names
-# up to 1967-04-01 (when most provisions of the Uniform Time Act of 1966
-# took effect), as explained in sections 263 and 261:
-#	(none)
-#	United States standard eastern time
-#	United States standard mountain time
-#	United States standard central time
-#	United States standard Pacific time
-#	(none)
-#	United States standard Alaska time
-#	(none)
-# Next, names from 1967-04-01 until 1983-11-30 (the date for
-# public law 98-181):
-#	Atlantic standard time
-#	eastern standard time
-#	central standard time
-#	mountain standard time
-#	Pacific standard time
-#	Yukon standard time
-#	Alaska-Hawaii standard time
-#	Bering standard time
-# And after 1983-11-30:
-#	Atlantic standard time
-#	eastern standard time
-#	central standard time
-#	mountain standard time
-#	Pacific standard time
-#	Alaska standard time
-#	Hawaii-Aleutian standard time
-#	Samoa standard time
-# The law doesn't give abbreviations.
-#
-# From Paul Eggert (2000-01-08), following a heads-up from Rives McDow:
-# Public law 106-564 (2000-12-23) introduced the abbreviation
-# "Chamorro Standard Time" for time in Guam and the Northern Marianas.
-# See the file "australasia".
-
-# From Arthur David Olson, 2005-08-09
-# The following was signed into law on 2005-08-08.
-#
-# H.R. 6, Energy Policy Act of 2005, SEC. 110. DAYLIGHT SAVINGS.
-#   (a) Amendment- Section 3(a) of the Uniform Time Act of 1966 (15
-#   U.S.C. 260a(a)) is amended--
-#     (1) by striking `first Sunday of April' and inserting `second
-#     Sunday of March'; and
-#     (2) by striking `last Sunday of October' and inserting `first
-#     Sunday of November'.
-#   (b) Effective Date- Subsection (a) shall take effect 1 year after the
-#   date of enactment of this Act or March 1, 2007, whichever is later.
-#   (c) Report to Congress- Not later than 9 months after the effective
-#   date stated in subsection (b), the Secretary shall report to Congress
-#   on the impact of this section on energy consumption in the United
-#   States.
-#   (d) Right to Revert- Congress retains the right to revert the
-#   Daylight Saving Time back to the 2005 time schedules once the
-#   Department study is complete.
-
-# US eastern time, represented by New York
-
-# Connecticut, Delaware, District of Columbia, most of Florida,
-# Georgia, southeast Indiana (Dearborn and Ohio counties), eastern Kentucky
-# (except America/Kentucky/Louisville below), Maine, Maryland, Massachusetts,
-# New Hampshire, New Jersey, New York, North Carolina, Ohio,
-# Pennsylvania, Rhode Island, South Carolina, eastern Tennessee,
-# Vermont, Virginia, West Virginia
-
-# From Dave Cantor (2004-11-02):
-# Early this summer I had the occasion to visit the Mount Washington
-# Observatory weather station atop (of course!) Mount Washington [, NH]....
-# One of the staff members said that the station was on Eastern Standard Time
-# and didn't change their clocks for Daylight Saving ... so that their
-# reports will always have times which are 5 hours behind UTC.
-
-# From Paul Eggert (2005-08-26):
-# According to today's Huntsville Times
-# <http://www.al.com/news/huntsvilletimes/index.ssf?/base/news/1125047783228320.xml&coll=1>
-# a few towns on Alabama's "eastern border with Georgia, such as Phenix City
-# in Russell County, Lanett in Chambers County and some towns in Lee County,
-# set their watches and clocks on Eastern time."  It quotes H.H. "Bubba"
-# Roberts, city administrator in Phenix City. as saying "We are in the Central
-# time zone, but we do go by the Eastern time zone because so many people work
-# in Columbus."
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	NYC	1920	only	-	Mar	lastSun	2:00	1:00	D
-Rule	NYC	1920	only	-	Oct	lastSun	2:00	0	S
-Rule	NYC	1921	1966	-	Apr	lastSun	2:00	1:00	D
-Rule	NYC	1921	1954	-	Sep	lastSun	2:00	0	S
-Rule	NYC	1955	1966	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/New_York	-4:56:02 -	LMT	1883 Nov 18 12:03:58
-			-5:00	US	E%sT	1920
-			-5:00	NYC	E%sT	1942
-			-5:00	US	E%sT	1946
-			-5:00	NYC	E%sT	1967
-			-5:00	US	E%sT
-
-# US central time, represented by Chicago
-
-# Alabama, Arkansas, Florida panhandle (Bay, Calhoun, Escambia,
-# Gulf, Holmes, Jackson, Okaloosa, Santa Rosa, Walton, and
-# Washington counties), Illinois, western Indiana
-# (Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
-# Vanderburgh, and Warrick counties), Iowa, most of Kansas, western
-# Kentucky, Louisiana, Minnesota, Mississippi, Missouri, eastern
-# Nebraska, eastern North Dakota, Oklahoma, eastern South Dakota,
-# western Tennessee, most of Texas, Wisconsin
-
-# From Larry M. Smith (2006-04-26) re Wisconsin:
-# http://www.legis.state.wi.us/statutes/Stat0175.pdf ...
-# is currently enforced at the 01:00 time of change.  Because the local
-# "bar time" in the state corresponds to 02:00, a number of citations
-# are issued for the "sale of class 'B' alcohol after prohibited
-# hours" within the deviated hour of this change every year....
-#
-# From Douglas R. Bomberg (2007-03-12):
-# Wisconsin has enacted (nearly eleventh-hour) legislation to get WI
-# Statue 175 closer in synch with the US Congress' intent....
-# http://www.legis.state.wi.us/2007/data/acts/07Act3.pdf
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	Chicago	1920	only	-	Jun	13	2:00	1:00	D
-Rule	Chicago	1920	1921	-	Oct	lastSun	2:00	0	S
-Rule	Chicago	1921	only	-	Mar	lastSun	2:00	1:00	D
-Rule	Chicago	1922	1966	-	Apr	lastSun	2:00	1:00	D
-Rule	Chicago	1922	1954	-	Sep	lastSun	2:00	0	S
-Rule	Chicago	1955	1966	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Chicago	-5:50:36 -	LMT	1883 Nov 18 12:09:24
-			-6:00	US	C%sT	1920
-			-6:00	Chicago	C%sT	1936 Mar  1 2:00
-			-5:00	-	EST	1936 Nov 15 2:00
-			-6:00	Chicago	C%sT	1942
-			-6:00	US	C%sT	1946
-			-6:00	Chicago	C%sT	1967
-			-6:00	US	C%sT
-# Oliver County, ND switched from mountain to central time on 1992-10-25.
-Zone America/North_Dakota/Center -6:45:12 - LMT	1883 Nov 18 12:14:48
-			-7:00	US	M%sT	1992 Oct 25 02:00
-			-6:00	US	C%sT
-# Morton County, ND, switched from mountain to central time on
-# 2003-10-26, except for the area around Mandan which was already central time.
-# See <http://dmses.dot.gov/docimages/p63/135818.pdf>.
-# Officially this switch also included part of Sioux County, and
-# Jones, Mellette, and Todd Counties in South Dakota;
-# but in practice these other counties were already observing central time.
-# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
-Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
-			-7:00	US	M%sT	2003 Oct 26 02:00
-			-6:00	US	C%sT
-
-# US mountain time, represented by Denver
-#
-# Colorado, far western Kansas, Montana, western
-# Nebraska, Nevada border (Jackpot, Owyhee, and Mountain City),
-# New Mexico, southwestern North Dakota,
-# western South Dakota, far western Texas (El Paso County, Hudspeth County,
-# and Pine Springs and Nickel Creek in Culberson County), Utah, Wyoming
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	Denver	1920	1921	-	Mar	lastSun	2:00	1:00	D
-Rule	Denver	1920	only	-	Oct	lastSun	2:00	0	S
-Rule	Denver	1921	only	-	May	22	2:00	0	S
-Rule	Denver	1965	1966	-	Apr	lastSun	2:00	1:00	D
-Rule	Denver	1965	1966	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Denver	-6:59:56 -	LMT	1883 Nov 18 12:00:04
-			-7:00	US	M%sT	1920
-			-7:00	Denver	M%sT	1942
-			-7:00	US	M%sT	1946
-			-7:00	Denver	M%sT	1967
-			-7:00	US	M%sT
-
-# US Pacific time, represented by Los Angeles
-#
-# California, northern Idaho (Benewah, Bonner, Boundary, Clearwater,
-# Idaho, Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties,
-# and the northern three-quarters of Idaho county),
-# most of Nevada, most of Oregon, and Washington
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	CA	1948	only	-	Mar	14	2:00	1:00	D
-Rule	CA	1949	only	-	Jan	 1	2:00	0	S
-Rule	CA	1950	1966	-	Apr	lastSun	2:00	1:00	D
-Rule	CA	1950	1961	-	Sep	lastSun	2:00	0	S
-Rule	CA	1962	1966	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Los_Angeles -7:52:58 -	LMT	1883 Nov 18 12:07:02
-			-8:00	US	P%sT	1946
-			-8:00	CA	P%sT	1967
-			-8:00	US	P%sT
-
-# Alaska
-# AK%sT is the modern abbreviation for -9:00 per USNO.
-#
-# From Paul Eggert (2001-05-30):
-# Howse writes that Alaska switched from the Julian to the Gregorian calendar,
-# and from east-of-GMT to west-of-GMT days, when the US bought it from Russia.
-# This was on 1867-10-18, a Friday; the previous day was 1867-10-06 Julian,
-# also a Friday.  Include only the time zone part of this transition,
-# ignoring the switch from Julian to Gregorian, since we can't represent
-# the Julian calendar.
-#
-# As far as we know, none of the exact locations mentioned below were
-# permanently inhabited in 1867 by anyone using either calendar.
-# (Yakutat was colonized by the Russians in 1799, but the settlement
-# was destroyed in 1805 by a Yakutat-kon war party.)  However, there
-# were nearby inhabitants in some cases and for our purposes perhaps
-# it's best to simply use the official transition.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Juneau	 15:02:19 -	LMT	1867 Oct 18
-			 -8:57:41 -	LMT	1900 Aug 20 12:00
-			 -8:00	-	PST	1942
-			 -8:00	US	P%sT	1946
-			 -8:00	-	PST	1969
-			 -8:00	US	P%sT	1983 Oct 30 2:00
-			 -9:00	US	Y%sT	1983 Nov 30
-			 -9:00	US	AK%sT
-Zone America/Yakutat	 14:41:05 -	LMT	1867 Oct 18
-			 -9:18:55 -	LMT	1900 Aug 20 12:00
-			 -9:00	-	YST	1942
-			 -9:00	US	Y%sT	1946
-			 -9:00	-	YST	1969
-			 -9:00	US	Y%sT	1983 Nov 30
-			 -9:00	US	AK%sT
-Zone America/Anchorage	 14:00:24 -	LMT	1867 Oct 18
-			 -9:59:36 -	LMT	1900 Aug 20 12:00
-			-10:00	-	CAT	1942
-			-10:00	US	CAT/CAWT 1945 Aug 14 23:00u
-			-10:00	US	CAT/CAPT 1946 # Peace
-			-10:00	-	CAT	1967 Apr
-			-10:00	-	AHST	1969
-			-10:00	US	AH%sT	1983 Oct 30 2:00
-			 -9:00	US	Y%sT	1983 Nov 30
-			 -9:00	US	AK%sT
-Zone America/Nome	 12:58:21 -	LMT	1867 Oct 18
-			-11:01:38 -	LMT	1900 Aug 20 12:00
-			-11:00	-	NST	1942
-			-11:00	US	N%sT	1946
-			-11:00	-	NST	1967 Apr
-			-11:00	-	BST	1969
-			-11:00	US	B%sT	1983 Oct 30 2:00
-			 -9:00	US	Y%sT	1983 Nov 30
-			 -9:00	US	AK%sT
-Zone America/Adak	 12:13:21 -	LMT	1867 Oct 18
-			-11:46:38 -	LMT	1900 Aug 20 12:00
-			-11:00	-	NST	1942
-			-11:00	US	N%sT	1946
-			-11:00	-	NST	1967 Apr
-			-11:00	-	BST	1969
-			-11:00	US	B%sT	1983 Oct 30 2:00
-			-10:00	US	AH%sT	1983 Nov 30
-			-10:00	US	HA%sT
-# The following switches don't quite make our 1970 cutoff.
-#
-# Shanks writes that part of southwest Alaska (e.g. Aniak)
-# switched from -11:00 to -10:00 on 1968-09-22 at 02:00,
-# and another part (e.g. Akiak) made the same switch five weeks later.
-#
-# From David Flater (2004-11-09):
-# In e-mail, 2004-11-02, Ray Hudson, historian/liaison to the Unalaska
-# Historic Preservation Commission, provided this information, which
-# suggests that Unalaska deviated from statutory time from early 1967
-# possibly until 1983:
-#
-#  Minutes of the Unalaska City Council Meeting, January 10, 1967:
-#  "Except for St. Paul and Akutan, Unalaska is the only important
-#  location not on Alaska Standard Time.  The following resolution was
-#  made by William Robinson and seconded by Henry Swanson:  Be it
-#  resolved that the City of Unalaska hereby goes to Alaska Standard
-#  Time as of midnight Friday, January 13, 1967 (1 A.M. Saturday,
-#  January 14, Alaska Standard Time.)  This resolution was passed with
-#  three votes for and one against."
-
-# Hawaii
-#
-# From Arthur David Olson:
-# And then there's Hawaii.
-# DST was observed for one day in 1933;
-# standard time was changed by half an hour in 1947;
-# it's always standard as of 1986.
-#
-# From Paul Eggert:
-# Shanks says the 1933 experiment lasted for three weeks.  Go with Shanks.
-#
-Zone Pacific/Honolulu	-10:31:26 -	LMT	1900 Jan  1 12:00
-			-10:30	-	HST	1933 Apr 30 2:00
-			-10:30	1:00	HDT	1933 May 21 2:00
-			-10:30	US	H%sT	1947 Jun  8 2:00
-			-10:00	-	HST
-
-# Now we turn to US areas that have diverged from the consensus since 1970.
-
-# Arizona mostly uses MST.
-
-# From Paul Eggert (2002-10-20):
-#
-# The information in the rest of this paragraph is derived from the
-# <a href="http://www.dlapr.lib.az.us/links/daylight.htm">
-# Daylight Saving Time web page (2002-01-23)</a> maintained by the
-# Arizona State Library, Archives and Public Records.
-# Between 1944-01-01 and 1944-04-01 the State of Arizona used standard
-# time, but by federal law railroads, airlines, bus lines, military
-# personnel, and some engaged in interstate commerce continued to
-# observe war (i.e., daylight saving) time.  The 1944-03-17 Phoenix
-# Gazette says that was the date the law changed, and that 04-01 was
-# the date the state's clocks would change.  In 1945 the State of
-# Arizona used standard time all year, again with exceptions only as
-# mandated by federal law.  Arizona observed DST in 1967, but Arizona
-# Laws 1968, ch. 183 (effective 1968-03-21) repealed DST.
-#
-# Shanks says the 1944 experiment came to an end on 1944-03-17.
-# Go with the Arizona State Library instead.
-
-Zone America/Phoenix	-7:28:18 -	LMT	1883 Nov 18 11:31:42
-			-7:00	US	M%sT	1944 Jan  1 00:01
-			-7:00	-	MST	1944 Apr  1 00:01
-			-7:00	US	M%sT	1944 Oct  1 00:01
-			-7:00	-	MST	1967
-			-7:00	US	M%sT	1968 Mar 21
-			-7:00	-	MST
-# From Arthur David Olson (1988-02-13):
-# A writer from the Inter Tribal Council of Arizona, Inc.,
-# notes in private correspondence dated 1987-12-28 that "Presently, only the
-# Navajo Nation participates in the Daylight Saving Time policy, due to its
-# large size and location in three states."  (The "only" means that other
-# tribal nations don't use DST.)
-
-Link America/Denver America/Shiprock
-
-# Southern Idaho (Ada, Adams, Bannock, Bear Lake, Bingham, Blaine,
-# Boise, Bonneville, Butte, Camas, Canyon, Caribou, Cassia, Clark,
-# Custer, Elmore, Franklin, Fremont, Gem, Gooding, Jefferson, Jerome,
-# Lemhi, Lincoln, Madison, Minidoka, Oneida, Owyhee, Payette, Power,
-# Teton, Twin Falls, Valley, Washington counties, and the southern
-# quarter of Idaho county) and eastern Oregon (most of Malheur County)
-# switched four weeks late in 1974.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Boise	-7:44:49 -	LMT	1883 Nov 18 12:15:11
-			-8:00	US	P%sT	1923 May 13 2:00
-			-7:00	US	M%sT	1974
-			-7:00	-	MST	1974 Feb  3 2:00
-			-7:00	US	M%sT
-
-# Indiana
-#
-# For a map of Indiana's time zone regions, see:
-# <a href="http://www.mccsc.edu/time.html">
-# What time is it in Indiana?
-# </a> (2006-03-01)
-#
-# From Paul Eggert (2007-08-17):
-# Since 1970, most of Indiana has been like America/Indiana/Indianapolis,
-# with the following exceptions:
-#
-# - Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
-#   Vandenburgh, and Warrick counties have been like America/Chicago.
-#
-# - Dearborn and Ohio counties have been like America/New_York.
-#
-# - Clark, Floyd, and Harrison counties have been like
-#   America/Kentucky/Louisville.
-#
-# - Crawford, Daviess, Dubois, Knox, Martin, Perry, Pike, Pulaski, Starke,
-#   and Switzerland counties have their own time zone histories as noted below.
-#
-# Shanks partitioned Indiana into 345 regions, each with its own time history,
-# and wrote ``Even newspaper reports present contradictory information.''
-# Those Hoosiers!  Such a flighty and changeable people!
-# Fortunately, most of the complexity occurred before our cutoff date of 1970.
-#
-# Other than Indianapolis, the Indiana place names are so nondescript
-# that they would be ambiguous if we left them at the `America' level.
-# So we reluctantly put them all in a subdirectory `America/Indiana'.
-
-# From Paul Eggert (2005-08-16):
-# http://www.mccsc.edu/time.html says that Indiana will use DST starting 2006.
-
-# From Nathan Stratton Treadway (2006-03-30):
-# http://www.dot.gov/affairs/dot0406.htm [3705 B]
-# From Deborah Goldsmith (2006-01-18):
-# http://dmses.dot.gov/docimages/pdf95/382329_web.pdf [2.9 MB]
-# From Paul Eggert (2006-01-20):
-# It says "DOT is relocating the time zone boundary in Indiana to move Starke,
-# Pulaski, Knox, Daviess, Martin, Pike, Dubois, and Perry Counties from the
-# Eastern Time Zone to the Central Time Zone.... The effective date of
-# this rule is 2:OO a.m. EST Sunday, April 2, 2006, which is the
-# changeover date from standard time to Daylight Saving Time."
-# Strictly speaking, this means the affected counties will change their
-# clocks twice that night, but this obviously is in error.  The intent
-# is that 01:59:59 EST be followed by 02:00:00 CDT.
-
-# From Gwillim Law (2007-02-10):
-# The Associated Press has been reporting that Pulaski County, Indiana is
-# going to switch from Central to Eastern Time on March 11, 2007....
-# http://www.indystar.com/apps/pbcs.dll/article?AID=/20070207/LOCAL190108/702070524/0/LOCAL
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule Indianapolis 1941	only	-	Jun	22	2:00	1:00	D
-Rule Indianapolis 1941	1954	-	Sep	lastSun	2:00	0	S
-Rule Indianapolis 1946	1954	-	Apr	lastSun	2:00	1:00	D
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
-			-6:00	US	C%sT	1920
-			-6:00 Indianapolis C%sT	1942
-			-6:00	US	C%sT	1946
-			-6:00 Indianapolis C%sT	1955 Apr 24 2:00
-			-5:00	-	EST	1957 Sep 29 2:00
-			-6:00	-	CST	1958 Apr 27 2:00
-			-5:00	-	EST	1969
-			-5:00	US	E%sT	1971
-			-5:00	-	EST	2006
-			-5:00	US	E%sT
-#
-# Eastern Crawford County, Indiana, left its clocks alone in 1974,
-# as well as from 1976 through 2005.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	Marengo	1951	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Marengo	1951	only	-	Sep	lastSun	2:00	0	S
-Rule	Marengo	1954	1960	-	Apr	lastSun	2:00	1:00	D
-Rule	Marengo	1954	1960	-	Sep	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Marengo -5:45:23 -	LMT	1883 Nov 18 12:14:37
-			-6:00	US	C%sT	1951
-			-6:00	Marengo	C%sT	1961 Apr 30 2:00
-			-5:00	-	EST	1969
-			-5:00	US	E%sT	1974 Jan  6 2:00
-			-6:00	1:00	CDT	1974 Oct 27 2:00
-			-5:00	US	E%sT	1976
-			-5:00	-	EST	2006
-			-5:00	US	E%sT
-#
-# Daviess, Dubois, Knox, and Martin Counties, Indiana,
-# switched from eastern to central time in April 2006, then switched back
-# in November 2007.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule Vincennes	1946	only	-	Apr	lastSun	2:00	1:00	D
-Rule Vincennes	1946	only	-	Sep	lastSun	2:00	0	S
-Rule Vincennes	1953	1954	-	Apr	lastSun	2:00	1:00	D
-Rule Vincennes	1953	1959	-	Sep	lastSun	2:00	0	S
-Rule Vincennes	1955	only	-	May	 1	0:00	1:00	D
-Rule Vincennes	1956	1963	-	Apr	lastSun	2:00	1:00	D
-Rule Vincennes	1960	only	-	Oct	lastSun	2:00	0	S
-Rule Vincennes	1961	only	-	Sep	lastSun	2:00	0	S
-Rule Vincennes	1962	1963	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Vincennes -5:50:07 - LMT	1883 Nov 18 12:09:53
-			-6:00	US	C%sT	1946
-			-6:00 Vincennes	C%sT	1964 Apr 26 2:00
-			-5:00	-	EST	1969
-			-5:00	US	E%sT	1971
-			-5:00	-	EST	2006 Apr  2 2:00
-			-6:00	US	C%sT	2007 Nov  4 2:00
-			-5:00	US	E%sT
-#
-# Perry County, Indiana, switched from eastern to central time in April 2006.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule Perry	1946	only	-	Apr	lastSun	2:00	1:00	D
-Rule Perry	1946	only	-	Sep	lastSun	2:00	0	S
-Rule Perry	1953	1954	-	Apr	lastSun	2:00	1:00	D
-Rule Perry	1953	1959	-	Sep	lastSun	2:00	0	S
-Rule Perry	1955	only	-	May	 1	0:00	1:00	D
-Rule Perry	1956	1963	-	Apr	lastSun	2:00	1:00	D
-Rule Perry	1960	only	-	Oct	lastSun	2:00	0	S
-Rule Perry	1961	only	-	Sep	lastSun	2:00	0	S
-Rule Perry	1962	1963	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Tell_City -5:47:03 - LMT	1883 Nov 18 12:12:57
-			-6:00	US	C%sT	1946
-			-6:00 Perry	C%sT	1964 Apr 26 2:00
-			-5:00	-	EST	1969
-			-5:00	US	E%sT	1971
-			-5:00	-	EST	2006 Apr  2 2:00
-			-6:00	US	C%sT
-#
-# Pike County, Indiana moved from central to eastern time in 1977,
-# then switched back in 2006, then switched back again in 2007.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	Pike	1955	only	-	May	 1	0:00	1:00	D
-Rule	Pike	1955	1960	-	Sep	lastSun	2:00	0	S
-Rule	Pike	1956	1964	-	Apr	lastSun	2:00	1:00	D
-Rule	Pike	1961	1964	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Petersburg -5:49:07 - LMT	1883 Nov 18 12:10:53
-			-6:00	US	C%sT	1955
-			-6:00	Pike	C%sT	1965 Apr 25 2:00
-			-5:00	-	EST	1966 Oct 30 2:00
-			-6:00	US	C%sT	1977 Oct 30 2:00
-			-5:00	-	EST	2006 Apr  2 2:00
-			-6:00	US	C%sT	2007 Nov  4 2:00
-			-5:00	US	E%sT
-#
-# Starke County, Indiana moved from central to eastern time in 1991,
-# then switched back in 2006.
-# From Arthur David Olson (1991-10-28):
-# An article on page A3 of the Sunday, 1991-10-27 Washington Post
-# notes that Starke County switched from Central time to Eastern time as of
-# 1991-10-27.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	Starke	1947	1961	-	Apr	lastSun	2:00	1:00	D
-Rule	Starke	1947	1954	-	Sep	lastSun	2:00	0	S
-Rule	Starke	1955	1956	-	Oct	lastSun	2:00	0	S
-Rule	Starke	1957	1958	-	Sep	lastSun	2:00	0	S
-Rule	Starke	1959	1961	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Knox -5:46:30 -	LMT	1883 Nov 18 12:13:30
-			-6:00	US	C%sT	1947
-			-6:00	Starke	C%sT	1962 Apr 29 2:00
-			-5:00	-	EST	1963 Oct 27 2:00
-			-6:00	US	C%sT	1991 Oct 27 2:00
-			-5:00	-	EST	2006 Apr  2 2:00
-			-6:00	US	C%sT
-#
-# Pulaski County, Indiana, switched from eastern to central time in
-# April 2006 and then switched back in March 2007.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	Pulaski	1946	1960	-	Apr	lastSun	2:00	1:00	D
-Rule	Pulaski	1946	1954	-	Sep	lastSun	2:00	0	S
-Rule	Pulaski	1955	1956	-	Oct	lastSun	2:00	0	S
-Rule	Pulaski	1957	1960	-	Sep	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Winamac -5:46:25 - LMT	1883 Nov 18 12:13:35
-			-6:00	US	C%sT	1946
-			-6:00	Pulaski	C%sT	1961 Apr 30 2:00
-			-5:00	-	EST	1969
-			-5:00	US	E%sT	1971
-			-5:00	-	EST	2006 Apr  2 2:00
-			-6:00	US	C%sT	2007 Mar 11 2:00
-			-5:00	US	E%sT
-#
-# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Indiana/Vevay -5:40:16 -	LMT	1883 Nov 18 12:19:44
-			-6:00	US	C%sT	1954 Apr 25 2:00
-			-5:00	-	EST	1969
-			-5:00	US	E%sT	1973
-			-5:00	-	EST	2006
-			-5:00	US	E%sT
-
-# Part of Kentucky left its clocks alone in 1974.
-# This also includes Clark, Floyd, and Harrison counties in Indiana.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule Louisville	1921	only	-	May	1	2:00	1:00	D
-Rule Louisville	1921	only	-	Sep	1	2:00	0	S
-Rule Louisville	1941	1961	-	Apr	lastSun	2:00	1:00	D
-Rule Louisville	1941	only	-	Sep	lastSun	2:00	0	S
-Rule Louisville	1946	only	-	Jun	2	2:00	0	S
-Rule Louisville	1950	1955	-	Sep	lastSun	2:00	0	S
-Rule Louisville	1956	1960	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Kentucky/Louisville -5:43:02 -	LMT	1883 Nov 18 12:16:58
-			-6:00	US	C%sT	1921
-			-6:00 Louisville C%sT	1942
-			-6:00	US	C%sT	1946
-			-6:00 Louisville C%sT	1961 Jul 23 2:00
-			-5:00	-	EST	1968
-			-5:00	US	E%sT	1974 Jan  6 2:00
-			-6:00	1:00	CDT	1974 Oct 27 2:00
-			-5:00	US	E%sT
-#
-# Wayne County, Kentucky
-#
-# From
-# <a href="http://www.lake-cumberland.com/life/archive/news990129time.shtml">
-# Lake Cumberland LIFE
-# </a> (1999-01-29) via WKYM-101.7:
-# Clinton County has joined Wayne County in asking the DoT to change from
-# the Central to the Eastern time zone....  The Wayne County government made
-# the same request in December.  And while Russell County officials have not
-# taken action, the majority of respondents to a poll conducted there in
-# August indicated they would like to change to "fast time" also.
-# The three Lake Cumberland counties are the farthest east of any U.S.
-# location in the Central time zone.
-#
-# From Rich Wales (2000-08-29):
-# After prolonged debate, and despite continuing deep differences of opinion,
-# Wayne County (central Kentucky) is switching from Central (-0600) to Eastern
-# (-0500) time.  They won't "fall back" this year.  See Sara Shipley,
-# The difference an hour makes, Nando Times (2000-08-29 15:33 -0400).
-#
-# From Paul Eggert (2001-07-16):
-# The final rule was published in the
-# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=2000_register&docid=fr17au00-22">
-# Federal Register 65, 160 (2000-08-17), page 50154-50158.
-# </a>
-#
-Zone America/Kentucky/Monticello -5:39:24 - LMT	1883 Nov 18 12:20:36
-			-6:00	US	C%sT	1946
-			-6:00	-	CST	1968
-			-6:00	US	C%sT	2000 Oct 29  2:00
-			-5:00	US	E%sT
-
-
-# From Rives McDow (2000-08-30):
-# Here ... are all the changes in the US since 1985.
-# Kearny County, KS (put all of county on central;
-#	previously split between MST and CST) ... 1990-10
-# Starke County, IN (from CST to EST) ... 1991-10
-# Oliver County, ND (from MST to CST) ... 1992-10
-# West Wendover, NV (from PST TO MST) ... 1999-10
-# Wayne County, KY (from CST to EST) ... 2000-10
-#
-# From Paul Eggert (2001-07-17):
-# We don't know where the line used to be within Kearny County, KS,
-# so omit that change for now.
-# See America/Indiana/Knox for the Starke County, IN change.
-# See America/North_Dakota/Center for the Oliver County, ND change.
-# West Wendover, NV officially switched from Pacific to mountain time on
-# 1999-10-31.  See the
-# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=1999_register&docid=fr21oc99-15">
-# Federal Register 64, 203 (1999-10-21), page 56705-56707.
-# </a>
-# However, the Federal Register says that West Wendover already operated
-# on mountain time, and the rule merely made this official;
-# hence a separate tz entry is not needed.
-
-# Michigan
-#
-# From Bob Devine (1988-01-28):
-# Michigan didn't observe DST from 1968 to 1973.
-#
-# From Paul Eggert (1999-03-31):
-# Shanks writes that Michigan started using standard time on 1885-09-18,
-# but Howse writes (pp 124-125, referring to Popular Astronomy, 1901-01)
-# that Detroit kept
-#
-#	local time until 1900 when the City Council decreed that clocks should
-#	be put back twenty-eight minutes to Central Standard Time.  Half the
-#	city obeyed, half refused.  After considerable debate, the decision
-#	was rescinded and the city reverted to Sun time.  A derisive offer to
-#	erect a sundial in front of the city hall was referred to the
-#	Committee on Sewers.  Then, in 1905, Central time was adopted
-#	by city vote.
-#
-# This story is too entertaining to be false, so go with Howse over Shanks.
-#
-# From Paul Eggert (2001-03-06):
-# Garland (1927) writes ``Cleveland and Detroit advanced their clocks
-# one hour in 1914.''  This change is not in Shanks.  We have no more
-# info, so omit this for now.
-#
-# Most of Michigan observed DST from 1973 on, but was a bit late in 1975.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	Detroit	1948	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Detroit	1948	only	-	Sep	lastSun	2:00	0	S
-Rule	Detroit	1967	only	-	Jun	14	2:00	1:00	D
-Rule	Detroit	1967	only	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Detroit	-5:32:11 -	LMT	1905
-			-6:00	-	CST	1915 May 15 2:00
-			-5:00	-	EST	1942
-			-5:00	US	E%sT	1946
-			-5:00	Detroit	E%sT	1973
-			-5:00	US	E%sT	1975
-			-5:00	-	EST	1975 Apr 27 2:00
-			-5:00	US	E%sT
-#
-# Dickinson, Gogebic, Iron, and Menominee Counties, Michigan,
-# switched from EST to CST/CDT in 1973.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule Menominee	1946	only	-	Apr	lastSun	2:00	1:00	D
-Rule Menominee	1946	only	-	Sep	lastSun	2:00	0	S
-Rule Menominee	1966	only	-	Apr	lastSun	2:00	1:00	D
-Rule Menominee	1966	only	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Menominee	-5:50:27 -	LMT	1885 Sep 18 12:00
-			-6:00	US	C%sT	1946
-			-6:00 Menominee	C%sT	1969 Apr 27 2:00
-			-5:00	-	EST	1973 Apr 29 2:00
-			-6:00	US	C%sT
-
-# Navassa
-# administered by the US Fish and Wildlife Service
-# claimed by US under the provisions of the 1856 Guano Islands Act
-# also claimed by Haiti
-# occupied 1857/1900 by the Navassa Phosphate Co
-# US lighthouse 1917/1996-09
-# currently uninhabited
-# see Mark Fineman, ``An Isle Rich in Guano and Discord'',
-# _Los Angeles Times_ (1998-11-10), A1, A10; it cites
-# Jimmy Skaggs, _The Great Guano Rush_ (1994).
-
-################################################################################
-
-
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
-# San Diego: ACS Publications, Inc. (2003).
-#
-# Gwillim Law writes that a good source
-# for recent time zone data is the International Air Transport
-# Association's Standard Schedules Information Manual (IATA SSIM),
-# published semiannually.  Law sent in several helpful summaries
-# of the IATA's data after 1990.
-#
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1990, and IATA SSIM is the source for entries afterwards.
-#
-# Other sources occasionally used include:
-#
-#	Edward W. Whitman, World Time Differences,
-#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
-#	which I found in the UCLA library.
-#
-#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
-#	William Willett, The Waste of Daylight, 19th edition
-#	</a> (1914-03)
-#
-# See the `europe' file for Greenland.
-
-# Canada
-
-# From Alain LaBont<e'> (1994-11-14):
-# I post here the time zone abbreviations standardized in Canada
-# for both English and French in the CAN/CSA-Z234.4-89 standard....
-#
-#	UTC	Standard time	Daylight savings time
-#	offset	French	English	French	English
-#	-2:30	-	-	HAT	NDT
-#	-3	-	-	HAA	ADT
-#	-3:30	HNT	NST	-	-
-#	-4	HNA	AST	HAE	EDT
-#	-5	HNE	EST	HAC	CDT
-#	-6	HNC	CST	HAR	MDT
-#	-7	HNR	MST	HAP	PDT
-#	-8	HNP	PST	HAY	YDT
-#	-9	HNY	YST	-	-
-#
-#	HN: Heure Normale	ST: Standard Time
-#	HA: Heure Avanc<e'>e	DT: Daylight saving Time
-#
-#	A: de l'Atlantique	Atlantic
-#	C: du Centre		Central
-#	E: de l'Est		Eastern
-#	M:			Mountain
-#	N:			Newfoundland
-#	P: du Pacifique		Pacific
-#	R: des Rocheuses
-#	T: de Terre-Neuve
-#	Y: du Yukon		Yukon
-#
-# From Paul Eggert (1994-11-22):
-# Alas, this sort of thing must be handled by localization software.
-
-# Unless otherwise specified, the data for Canada are all from Shanks
-# & Pottenger.
-
-# From Chris Walton (2006-04-01, 2006-04-25, 2006-06-26, 2007-01-31,
-# 2007-03-01):
-# The British Columbia government announced yesterday that it will
-# adjust daylight savings next year to align with changes in the
-# U.S. and the rest of Canada....
-# http://www2.news.gov.bc.ca/news_releases_2005-2009/2006AG0014-000330.htm
-# ...
-# Nova Scotia
-# Daylight saving time will be extended by four weeks starting in 2007....
-# http://www.gov.ns.ca/just/regulations/rg2/2006/ma1206.pdf
-#
-# [For New Brunswick] the new legislation dictates that the time change is to
-# be done at 02:00 instead of 00:01.
-# http://www.gnb.ca/0062/acts/BBA-2006/Chap-19.pdf
-# ...
-# Manitoba has traditionally changed the clock every fall at 03:00.
-# As of 2006, the transition is to take place one hour earlier at 02:00.
-# http://web2.gov.mb.ca/laws/statutes/ccsm/o030e.php
-# ...
-# [Alberta, Ontario, Quebec] will follow US rules.
-# http://www.qp.gov.ab.ca/documents/spring/CH03_06.CFM
-# http://www.e-laws.gov.on.ca/DBLaws/Source/Regs/English/2006/R06111_e.htm
-# http://www2.publicationsduquebec.gouv.qc.ca/dynamicSearch/telecharge.php?type=5&file=2006C39A.PDF
-# ...
-# P.E.I. will follow US rules....
-# http://www.assembly.pe.ca/bills/pdf_chapter/62/3/chapter-41.pdf
-# ...
-# Province of Newfoundland and Labrador....
-# http://www.hoa.gov.nl.ca/hoa/bills/Bill0634.htm
-# ...
-# Yukon
-# http://www.gov.yk.ca/legislation/regs/oic2006_127.pdf
-# ...
-# N.W.T. will follow US rules.  Whoever maintains the government web site
-# does not seem to believe in bookmarks.  To see the news release, click the
-# following link and search for "Daylight Savings Time Change".  Press the
-# "Daylight Savings Time Change" link; it will fire off a popup using
-# JavaScript.
-# http://www.exec.gov.nt.ca/currentnews/currentPR.asp?mode=archive
-# ...
-# Nunavut
-# An amendment to the Interpretation Act was registered on February 19/2007....
-# http://action.attavik.ca/home/justice-gn/attach/2007/gaz02part2.pdf
-
-# From Paul Eggert (2006-04-25):
-# H. David Matthews and Mary Vincent's map
-# <a href="http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp">
-# "It's about TIME", _Canadian Geographic_ (September-October 1998)
-# </a> contains detailed boundaries for regions observing nonstandard
-# time and daylight saving time arrangements in Canada circa 1998.
-#
-# INMS, the Institute for National Measurement Standards in Ottawa, has <a
-# href="http://inms-ienm.nrc-cnrc.gc.ca/en/time_services/daylight_saving_e.php">
-# information about standard and daylight saving time zones in Canada.
-# </a> (updated periodically).
-# Its unofficial information is often taken from Matthews and Vincent.
-
-# From Paul Eggert (2006-06-27):
-# For now, assume all of DST-observing Canada will fall into line with the
-# new US DST rules,
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Canada	1918	only	-	Apr	14	2:00	1:00	D
-Rule	Canada	1918	only	-	Oct	31	2:00	0	S
-Rule	Canada	1942	only	-	Feb	 9	2:00	1:00	W # War
-Rule	Canada	1945	only	-	Aug	14	23:00u	1:00	P # Peace
-Rule	Canada	1945	only	-	Sep	30	2:00	0	S
-Rule	Canada	1974	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	Canada	1974	2006	-	Oct	lastSun	2:00	0	S
-Rule	Canada	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
-Rule	Canada	2007	max	-	Mar	Sun>=8	2:00	1:00	D
-Rule	Canada	2007	max	-	Nov	Sun>=1	2:00	0	S
-
-
-# Newfoundland and Labrador
-
-# From Paul Eggert (2000-10-02):
-# Matthews and Vincent (1998) write that Labrador should use NST/NDT,
-# but the only part of Labrador that follows the rules is the
-# southeast corner, including Port Hope Simpson and Mary's Harbour,
-# but excluding, say, Black Tickle.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	StJohns	1917	only	-	Apr	 8	2:00	1:00	D
-Rule	StJohns	1917	only	-	Sep	17	2:00	0	S
-# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks & Pottenger.
-Rule	StJohns	1919	only	-	May	 5	23:00	1:00	D
-Rule	StJohns	1919	only	-	Aug	12	23:00	0	S
-# For 1931-1935 Whitman gives Apr same date; go with Shanks & Pottenger.
-Rule	StJohns	1920	1935	-	May	Sun>=1	23:00	1:00	D
-Rule	StJohns	1920	1935	-	Oct	lastSun	23:00	0	S
-# For 1936-1941 Whitman gives May Sun>=8 and Oct Sun>=1; go with Shanks &
-# Pottenger.
-Rule	StJohns	1936	1941	-	May	Mon>=9	0:00	1:00	D
-Rule	StJohns	1936	1941	-	Oct	Mon>=2	0:00	0	S
-# Whitman gives the following transitions:
-# 1942 03-01/12-31, 1943 05-30/09-05, 1944 07-10/09-02, 1945 01-01/10-07
-# but go with Shanks & Pottenger and assume they used Canadian rules.
-# For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives
-# Apr 30 - Sep 24; go with Shanks & Pottenger.
-Rule	StJohns	1946	1950	-	May	Sun>=8	2:00	1:00	D
-Rule	StJohns	1946	1950	-	Oct	Sun>=2	2:00	0	S
-Rule	StJohns	1951	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	StJohns	1951	1959	-	Sep	lastSun	2:00	0	S
-Rule	StJohns	1960	1986	-	Oct	lastSun	2:00	0	S
-# From Paul Eggert (2000-10-02):
-# INMS (2000-09-12) says that, since 1988 at least, Newfoundland switches
-# at 00:01 local time.  For now, assume it started in 1987.
-Rule	StJohns	1987	only	-	Apr	Sun>=1	0:01	1:00	D
-Rule	StJohns	1987	2006	-	Oct	lastSun	0:01	0	S
-Rule	StJohns	1988	only	-	Apr	Sun>=1	0:01	2:00	DD
-Rule	StJohns	1989	2006	-	Apr	Sun>=1	0:01	1:00	D
-Rule	StJohns	2007	max	-	Mar	Sun>=8	0:01	1:00	D
-Rule	StJohns	2007	max	-	Nov	Sun>=1	0:01	0	S
-#
-# St John's has an apostrophe, but Posix file names can't have apostrophes.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/St_Johns	-3:30:52 -	LMT	1884
-			-3:30:52 StJohns N%sT	1918
-			-3:30:52 Canada	N%sT	1919
-			-3:30:52 StJohns N%sT	1935 Mar 30
-			-3:30	StJohns	N%sT	1942 May 11
-			-3:30	Canada	N%sT	1946
-			-3:30	StJohns	N%sT
-
-# most of east Labrador
-
-# The name `Happy Valley-Goose Bay' is too long; use `Goose Bay'.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Goose_Bay	-4:01:40 -	LMT	1884 # Happy Valley-Goose Bay
-			-3:30:52 -	NST	1918
-			-3:30:52 Canada N%sT	1919
-			-3:30:52 -	NST	1935 Mar 30
-			-3:30	-	NST	1936
-			-3:30	StJohns	N%sT	1942 May 11
-			-3:30	Canada	N%sT	1946
-			-3:30	StJohns	N%sT	1966 Mar 15 2:00
-			-4:00	StJohns	A%sT
-
-
-# west Labrador, Nova Scotia, Prince Edward I
-
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger write that since 1970 most of this region has been like
-# Halifax.  Many locales did not observe peacetime DST until 1972;
-# Glace Bay, NS is the largest that we know of.
-# Shanks & Pottenger also write that Liverpool, NS was the only town
-# in Canada to observe DST in 1971 but not 1970; for now we'll assume
-# this is a typo.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Halifax	1916	only	-	Apr	 1	0:00	1:00	D
-Rule	Halifax	1916	only	-	Oct	 1	0:00	0	S
-Rule	Halifax	1920	only	-	May	 9	0:00	1:00	D
-Rule	Halifax	1920	only	-	Aug	29	0:00	0	S
-Rule	Halifax	1921	only	-	May	 6	0:00	1:00	D
-Rule	Halifax	1921	1922	-	Sep	 5	0:00	0	S
-Rule	Halifax	1922	only	-	Apr	30	0:00	1:00	D
-Rule	Halifax	1923	1925	-	May	Sun>=1	0:00	1:00	D
-Rule	Halifax	1923	only	-	Sep	 4	0:00	0	S
-Rule	Halifax	1924	only	-	Sep	15	0:00	0	S
-Rule	Halifax	1925	only	-	Sep	28	0:00	0	S
-Rule	Halifax	1926	only	-	May	16	0:00	1:00	D
-Rule	Halifax	1926	only	-	Sep	13	0:00	0	S
-Rule	Halifax	1927	only	-	May	 1	0:00	1:00	D
-Rule	Halifax	1927	only	-	Sep	26	0:00	0	S
-Rule	Halifax	1928	1931	-	May	Sun>=8	0:00	1:00	D
-Rule	Halifax	1928	only	-	Sep	 9	0:00	0	S
-Rule	Halifax	1929	only	-	Sep	 3	0:00	0	S
-Rule	Halifax	1930	only	-	Sep	15	0:00	0	S
-Rule	Halifax	1931	1932	-	Sep	Mon>=24	0:00	0	S
-Rule	Halifax	1932	only	-	May	 1	0:00	1:00	D
-Rule	Halifax	1933	only	-	Apr	30	0:00	1:00	D
-Rule	Halifax	1933	only	-	Oct	 2	0:00	0	S
-Rule	Halifax	1934	only	-	May	20	0:00	1:00	D
-Rule	Halifax	1934	only	-	Sep	16	0:00	0	S
-Rule	Halifax	1935	only	-	Jun	 2	0:00	1:00	D
-Rule	Halifax	1935	only	-	Sep	30	0:00	0	S
-Rule	Halifax	1936	only	-	Jun	 1	0:00	1:00	D
-Rule	Halifax	1936	only	-	Sep	14	0:00	0	S
-Rule	Halifax	1937	1938	-	May	Sun>=1	0:00	1:00	D
-Rule	Halifax	1937	1941	-	Sep	Mon>=24	0:00	0	S
-Rule	Halifax	1939	only	-	May	28	0:00	1:00	D
-Rule	Halifax	1940	1941	-	May	Sun>=1	0:00	1:00	D
-Rule	Halifax	1946	1949	-	Apr	lastSun	2:00	1:00	D
-Rule	Halifax	1946	1949	-	Sep	lastSun	2:00	0	S
-Rule	Halifax	1951	1954	-	Apr	lastSun	2:00	1:00	D
-Rule	Halifax	1951	1954	-	Sep	lastSun	2:00	0	S
-Rule	Halifax	1956	1959	-	Apr	lastSun	2:00	1:00	D
-Rule	Halifax	1956	1959	-	Sep	lastSun	2:00	0	S
-Rule	Halifax	1962	1973	-	Apr	lastSun	2:00	1:00	D
-Rule	Halifax	1962	1973	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Halifax	-4:14:24 -	LMT	1902 Jun 15
-			-4:00	Halifax	A%sT	1918
-			-4:00	Canada	A%sT	1919
-			-4:00	Halifax	A%sT	1942 Feb  9 2:00s
-			-4:00	Canada	A%sT	1946
-			-4:00	Halifax	A%sT	1974
-			-4:00	Canada	A%sT
-Zone America/Glace_Bay	-3:59:48 -	LMT	1902 Jun 15
-			-4:00	Canada	A%sT	1953
-			-4:00	Halifax	A%sT	1954
-			-4:00	-	AST	1972
-			-4:00	Halifax	A%sT	1974
-			-4:00	Canada	A%sT
-
-# New Brunswick
-
-# From Paul Eggert (2007-01-31):
-# The Time Definition Act <http://www.gnb.ca/0062/PDF-acts/t-06.pdf>
-# says they changed at 00:01 through 2006, and
-# <http://www.canlii.org/nb/laws/sta/t-6/20030127/whole.html> makes it
-# clear that this was the case since at least 1993.
-# For now, assume it started in 1993.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Moncton	1933	1935	-	Jun	Sun>=8	1:00	1:00	D
-Rule	Moncton	1933	1935	-	Sep	Sun>=8	1:00	0	S
-Rule	Moncton	1936	1938	-	Jun	Sun>=1	1:00	1:00	D
-Rule	Moncton	1936	1938	-	Sep	Sun>=1	1:00	0	S
-Rule	Moncton	1939	only	-	May	27	1:00	1:00	D
-Rule	Moncton	1939	1941	-	Sep	Sat>=21	1:00	0	S
-Rule	Moncton	1940	only	-	May	19	1:00	1:00	D
-Rule	Moncton	1941	only	-	May	 4	1:00	1:00	D
-Rule	Moncton	1946	1972	-	Apr	lastSun	2:00	1:00	D
-Rule	Moncton	1946	1956	-	Sep	lastSun	2:00	0	S
-Rule	Moncton	1957	1972	-	Oct	lastSun	2:00	0	S
-Rule	Moncton	1993	2006	-	Apr	Sun>=1	0:01	1:00	D
-Rule	Moncton	1993	2006	-	Oct	lastSun	0:01	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Moncton	-4:19:08 -	LMT	1883 Dec  9
-			-5:00	-	EST	1902 Jun 15
-			-4:00	Canada	A%sT	1933
-			-4:00	Moncton	A%sT	1942
-			-4:00	Canada	A%sT	1946
-			-4:00	Moncton	A%sT	1973
-			-4:00	Canada	A%sT	1993
-			-4:00	Moncton	A%sT	2007
-			-4:00	Canada	A%sT
-
-# Quebec
-
-# From Paul Eggert (2006-07-09):
-# Shanks & Pottenger write that since 1970 most of Quebec has been
-# like Montreal.
-
-# From Paul Eggert (2006-06-27):
-# Matthews and Vincent (1998) also write that Quebec east of the -63
-# meridian is supposed to observe AST, but residents as far east as
-# Natashquan use EST/EDT, and residents east of Natashquan use AST.
-# In "Official time in Quebec" the Quebec department of justice writes in
-# http://www.justice.gouv.qc.ca/english/publications/generale/temps-regl-1-a.htm
-# that "The residents of the Municipality of the
-# Cote-Nord-du-Golfe-Saint-Laurent and the municipalities of Saint-Augustin,
-# Bonne-Esperance and Blanc-Sablon apply the Official Time Act as it is
-# written and use Atlantic standard time all year round. The same applies to
-# the residents of the Native facilities along the lower North Shore."
-# <http://www.assnat.qc.ca/eng/37legislature2/Projets-loi/Publics/06-a002.htm>
-# says this common practice was codified into law as of 2007.
-# For lack of better info, guess this practice began around 1970, contra to
-# Shanks & Pottenger who have this region observing AST/ADT.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Mont	1917	only	-	Mar	25	2:00	1:00	D
-Rule	Mont	1917	only	-	Apr	24	0:00	0	S
-Rule	Mont	1919	only	-	Mar	31	2:30	1:00	D
-Rule	Mont	1919	only	-	Oct	25	2:30	0	S
-Rule	Mont	1920	only	-	May	 2	2:30	1:00	D
-Rule	Mont	1920	1922	-	Oct	Sun>=1	2:30	0	S
-Rule	Mont	1921	only	-	May	 1	2:00	1:00	D
-Rule	Mont	1922	only	-	Apr	30	2:00	1:00	D
-Rule	Mont	1924	only	-	May	17	2:00	1:00	D
-Rule	Mont	1924	1926	-	Sep	lastSun	2:30	0	S
-Rule	Mont	1925	1926	-	May	Sun>=1	2:00	1:00	D
-# The 1927-to-1937 rules can be expressed more simply as
-# Rule	Mont	1927	1937	-	Apr	lastSat	24:00	1:00	D
-# Rule	Mont	1927	1937	-	Sep	lastSat	24:00	0	S
-# The rules below avoid use of 24:00
-# (which pre-1998 versions of zic cannot handle).
-Rule	Mont	1927	only	-	May	1	0:00	1:00	D
-Rule	Mont	1927	1932	-	Sep	lastSun	0:00	0	S
-Rule	Mont	1928	1931	-	Apr	lastSun	0:00	1:00	D
-Rule	Mont	1932	only	-	May	1	0:00	1:00	D
-Rule	Mont	1933	1940	-	Apr	lastSun	0:00	1:00	D
-Rule	Mont	1933	only	-	Oct	1	0:00	0	S
-Rule	Mont	1934	1939	-	Sep	lastSun	0:00	0	S
-Rule	Mont	1946	1973	-	Apr	lastSun	2:00	1:00	D
-Rule	Mont	1945	1948	-	Sep	lastSun	2:00	0	S
-Rule	Mont	1949	1950	-	Oct	lastSun	2:00	0	S
-Rule	Mont	1951	1956	-	Sep	lastSun	2:00	0	S
-Rule	Mont	1957	1973	-	Oct	lastSun	2:00	0	S
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Blanc-Sablon -3:48:28 -	LMT	1884
-			-4:00	Canada	A%sT	1970
-			-4:00	-	AST
-Zone America/Montreal	-4:54:16 -	LMT	1884
-			-5:00	Mont	E%sT	1918
-			-5:00	Canada	E%sT	1919
-			-5:00	Mont	E%sT	1942 Feb  9 2:00s
-			-5:00	Canada	E%sT	1946
-			-5:00	Mont	E%sT	1974
-			-5:00	Canada	E%sT
-
-
-# Ontario
-
-# From Paul Eggert (2006-07-09):
-# Shanks & Pottenger write that since 1970 most of Ontario has been like
-# Toronto.
-# Thunder Bay skipped DST in 1973.
-# Many smaller locales did not observe peacetime DST until 1974;
-# Nipigon (EST) and Rainy River (CST) are the largest that we know of.
-# Far west Ontario is like Winnipeg; far east Quebec is like Halifax.
-
-# From Mark Brader (2003-07-26):
-# [According to the Toronto Star] Orillia, Ontario, adopted DST
-# effective Saturday, 1912-06-22, 22:00; the article mentions that
-# Port Arthur (now part of Thunder Bay, Ontario) as well as Moose Jaw
-# have already done so.  In Orillia DST was to run until Saturday,
-# 1912-08-31 (no time mentioned), but it was met with considerable
-# hostility from certain segments of the public, and was revoked after
-# only two weeks -- I copied it as Saturday, 1912-07-07, 22:00, but
-# presumably that should be -07-06.  (1912-06-19, -07-12; also letters
-# earlier in June).
-#
-# Kenora, Ontario, was to abandon DST on 1914-06-01 (-05-21).
-
-# From Paul Eggert (1997-10-17):
-# Mark Brader writes that an article in the 1997-10-14 Toronto Star
-# says that Atikokan, Ontario currently does not observe DST,
-# but will vote on 11-10 whether to use EST/EDT.
-# He also writes that the
-# <a href="http://www.gov.on.ca/MBS/english/publications/statregs/conttext.html">
-# Ontario Time Act (1990, Chapter T.9)
-# </a>
-# says that Ontario east of 90W uses EST/EDT, and west of 90W uses CST/CDT.
-# Officially Atikokan is therefore on CST/CDT, and most likely this report
-# concerns a non-official time observed as a matter of local practice.
-#
-# From Paul Eggert (2000-10-02):
-# Matthews and Vincent (1998) write that Atikokan, Pickle Lake, and
-# New Osnaburgh observe CST all year, that Big Trout Lake observes
-# CST/CDT, and that Upsala and Shebandowan observe EST/EDT, all in
-# violation of the official Ontario rules.
-#
-# From Paul Eggert (2006-07-09):
-# Chris Walton (2006-07-06) mentioned an article by Stephanie MacLellan in the
-# 2005-07-21 Chronicle-Journal, which said:
-#
-#	The clocks in Atikokan stay set on standard time year-round.
-#	This means they spend about half the time on central time and
-#	the other half on eastern time.
-#
-#	For the most part, the system works, Mayor Dennis Brown said.
-#
-#	"The majority of businesses in Atikokan deal more with Eastern
-#	Canada, but there are some that deal with Western Canada," he
-#	said.  "I don't see any changes happening here."
-#
-# Walton also writes "Supposedly Pickle Lake and Mishkeegogamang
-# [New Osnaburgh] follow the same practice."
-
-# From Garry McKinnon (2006-07-14) via Chris Walton:
-# I chatted with a member of my board who has an outstanding memory
-# and a long history in Atikokan (and in the telecom industry) and he
-# can say for certain that Atikokan has been practicing the current
-# time keeping since 1952, at least.
-
-# From Paul Eggert (2006-07-17):
-# Shanks & Pottenger say that Atikokan has agreed with Rainy River
-# ever since standard time was introduced, but the information from
-# McKinnon sounds more authoritative.  For now, assume that Atikokan
-# switched to EST immediately after WWII era daylight saving time
-# ended.  This matches the old (less-populous) America/Coral_Harbour
-# entry since our cutoff date of 1970, so we can move
-# America/Coral_Harbour to the 'backward' file.
-
-# From Mark Brader (2010-03-06):
-#
-# Currently the database has:
-#
-# # Ontario
-#
-# # From Paul Eggert (2006-07-09):
-# # Shanks & Pottenger write that since 1970 most of Ontario has been like
-# # Toronto.
-# # Thunder Bay skipped DST in 1973.
-# # Many smaller locales did not observe peacetime DST until 1974;
-# # Nipigon (EST) and Rainy River (CST) are the largest that we know of.
-#
-# In the (Toronto) Globe and Mail for Saturday, 1955-09-24, in the bottom
-# right corner of page 1, it says that Toronto will return to standard
-# time at 2 am Sunday morning (which agrees with the database), and that:
-#
-#     The one-hour setback will go into effect throughout most of Ontario,
-#     except in areas like Windsor which remains on standard time all year.
-#
-# Windsor is, of course, a lot larger than Nipigon.
-#
-# I only came across this incidentally.  I don't know if Windsor began
-# observing DST when Detroit did, or in 1974, or on some other date.
-#
-# By the way, the article continues by noting that:
-#
-#     Some cities in the United States have pushed the deadline back
-#     three weeks and will change over from daylight saving in October.
-
-# From Arthur David Olson (2010-07-17):
-#
-# "Standard Time and Time Zones in Canada" appeared in
-# The Journal of The Royal Astronomical Society of Canada,
-# volume 26, number 2 (February 1932) and, as of 2010-07-17,
-# was available at
-# <a href="http://adsabs.harvard.edu/full/1932JRASC..26...49S">
-# http://adsabs.harvard.edu/full/1932JRASC..26...49S
-# </a>
-#
-# It includes the text below (starting on page 57):
-#
-#   A list of the places in Canada using daylight saving time would
-# require yearly revision. From information kindly furnished by
-# the provincial governments and by the postmasters in many cities
-# and towns, it is found that the following places used daylight sav-
-# ing in 1930. The information for the province of Quebec is definite,
-# for the other provinces only approximate:
-#
-# 	Province	Daylight saving time used
-# Prince Edward Island	Not used.
-# Nova Scotia		In Halifax only.
-# New Brunswick		In St. John only.
-# Quebec		In the following places:
-# 			Montreal	Lachine
-# 			Quebec		Mont-Royal
-# 			Levis		Iberville
-# 			St. Lambert	Cap de la Madeleine
-# 			Verdun		Loretteville
-# 			Westmount	Richmond
-# 			Outremont	St. Jerome
-# 			Longueuil	Greenfield Park
-# 			Arvida		Waterloo
-# 			Chambly-Canton	Beaulieu
-# 			Melbourne	La Tuque
-# 			St. Theophile	Buckingham
-# Ontario		Used generally in the cities and towns along
-# 			the southerly part of the province. Not
-# 			used in the northwesterlhy part.
-# Manitoba		Not used.
-# Saskatchewan		In Regina only.
-# Alberta		Not used.
-# British Columbia	Not used.
-#
-#   With some exceptions, the use of daylight saving may be said to be limited
-# to those cities and towns lying between Quebec city and Windsor, Ont.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Toronto	1919	only	-	Mar	30	23:30	1:00	D
-Rule	Toronto	1919	only	-	Oct	26	0:00	0	S
-Rule	Toronto	1920	only	-	May	 2	2:00	1:00	D
-Rule	Toronto	1920	only	-	Sep	26	0:00	0	S
-Rule	Toronto	1921	only	-	May	15	2:00	1:00	D
-Rule	Toronto	1921	only	-	Sep	15	2:00	0	S
-Rule	Toronto	1922	1923	-	May	Sun>=8	2:00	1:00	D
-# Shanks & Pottenger say 1923-09-19; assume it's a typo and that "-16"
-# was meant.
-Rule	Toronto	1922	1926	-	Sep	Sun>=15	2:00	0	S
-Rule	Toronto	1924	1927	-	May	Sun>=1	2:00	1:00	D
-# The 1927-to-1939 rules can be expressed more simply as
-# Rule	Toronto	1927	1937	-	Sep	Sun>=25	2:00	0	S
-# Rule	Toronto	1928	1937	-	Apr	Sun>=25	2:00	1:00	D
-# Rule	Toronto	1938	1940	-	Apr	lastSun	2:00	1:00	D
-# Rule	Toronto	1938	1939	-	Sep	lastSun	2:00	0	S
-# The rules below avoid use of Sun>=25
-# (which pre-2004 versions of zic cannot handle).
-Rule	Toronto	1927	1932	-	Sep	lastSun	2:00	0	S
-Rule	Toronto	1928	1931	-	Apr	lastSun	2:00	1:00	D
-Rule	Toronto	1932	only	-	May	1	2:00	1:00	D
-Rule	Toronto	1933	1940	-	Apr	lastSun	2:00	1:00	D
-Rule	Toronto	1933	only	-	Oct	1	2:00	0	S
-Rule	Toronto	1934	1939	-	Sep	lastSun	2:00	0	S
-Rule	Toronto	1945	1946	-	Sep	lastSun	2:00	0	S
-Rule	Toronto	1946	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Toronto	1947	1949	-	Apr	lastSun	0:00	1:00	D
-Rule	Toronto	1947	1948	-	Sep	lastSun	0:00	0	S
-Rule	Toronto	1949	only	-	Nov	lastSun	0:00	0	S
-Rule	Toronto	1950	1973	-	Apr	lastSun	2:00	1:00	D
-Rule	Toronto	1950	only	-	Nov	lastSun	2:00	0	S
-Rule	Toronto	1951	1956	-	Sep	lastSun	2:00	0	S
-# Shanks & Pottenger say Toronto ended DST a week early in 1971,
-# namely on 1971-10-24, but Mark Brader wrote (2003-05-31) that this
-# is wrong, and that he had confirmed it by checking the 1971-10-30
-# Toronto Star, which said that DST was ending 1971-10-31 as usual.
-Rule	Toronto	1957	1973	-	Oct	lastSun	2:00	0	S
-
-# From Paul Eggert (2003-07-27):
-# Willett (1914-03) writes (p. 17) "In the Cities of Fort William, and
-# Port Arthur, Ontario, the principle of the Bill has been in
-# operation for the past three years, and in the City of Moose Jaw,
-# Saskatchewan, for one year."
-
-# From David Bryan via Tory Tronrud, Director/Curator,
-# Thunder Bay Museum (2003-11-12):
-# There is some suggestion, however, that, by-law or not, daylight
-# savings time was being practiced in Fort William and Port Arthur
-# before 1909.... [I]n 1910, the line between the Eastern and Central
-# Time Zones was permanently moved about two hundred miles west to
-# include the Thunder Bay area....  When Canada adopted daylight
-# savings time in 1916, Fort William and Port Arthur, having done so
-# already, did not change their clocks....  During the Second World
-# War,... [t]he cities agreed to implement DST during the summer
-# months for the remainder of the war years.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Toronto	-5:17:32 -	LMT	1895
-			-5:00	Canada	E%sT	1919
-			-5:00	Toronto	E%sT	1942 Feb  9 2:00s
-			-5:00	Canada	E%sT	1946
-			-5:00	Toronto	E%sT	1974
-			-5:00	Canada	E%sT
-Zone America/Thunder_Bay -5:57:00 -	LMT	1895
-			-6:00	-	CST	1910
-			-5:00	-	EST	1942
-			-5:00	Canada	E%sT	1970
-			-5:00	Mont	E%sT	1973
-			-5:00	-	EST	1974
-			-5:00	Canada	E%sT
-Zone America/Nipigon	-5:53:04 -	LMT	1895
-			-5:00	Canada	E%sT	1940 Sep 29
-			-5:00	1:00	EDT	1942 Feb  9 2:00s
-			-5:00	Canada	E%sT
-Zone America/Rainy_River -6:18:16 -	LMT	1895
-			-6:00	Canada	C%sT	1940 Sep 29
-			-6:00	1:00	CDT	1942 Feb  9 2:00s
-			-6:00	Canada	C%sT
-Zone America/Atikokan	-6:06:28 -	LMT	1895
-			-6:00	Canada	C%sT	1940 Sep 29
-			-6:00	1:00	CDT	1942 Feb  9 2:00s
-			-6:00	Canada	C%sT	1945 Sep 30 2:00
-			-5:00	-	EST
-
-
-# Manitoba
-
-# From Rob Douglas (2006-04-06):
-# the old Manitoba Time Act - as amended by Bill 2, assented to
-# March 27, 1987 ... said ...
-# "between two o'clock Central Standard Time in the morning of
-# the first Sunday of April of each year and two o'clock Central
-# Standard Time in the morning of the last Sunday of October next
-# following, one hour in advance of Central Standard Time."...
-# I believe that the English legislation [of the old time act] had =
-# been assented to (March 22, 1967)....
-# Also, as far as I can tell, there was no order-in-council varying
-# the time of Daylight Saving Time for 2005 and so the provisions of
-# the 1987 version would apply - the changeover was at 2:00 Central
-# Standard Time (i.e. not until 3:00 Central Daylight Time).
-
-# From Paul Eggert (2006-04-10):
-# Shanks & Pottenger say Manitoba switched at 02:00 (not 02:00s)
-# starting 1966.  Since 02:00s is clearly correct for 1967 on, assume
-# it was also 02:00s in 1966.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Winn	1916	only	-	Apr	23	0:00	1:00	D
-Rule	Winn	1916	only	-	Sep	17	0:00	0	S
-Rule	Winn	1918	only	-	Apr	14	2:00	1:00	D
-Rule	Winn	1918	only	-	Oct	31	2:00	0	S
-Rule	Winn	1937	only	-	May	16	2:00	1:00	D
-Rule	Winn	1937	only	-	Sep	26	2:00	0	S
-Rule	Winn	1942	only	-	Feb	 9	2:00	1:00	W # War
-Rule	Winn	1945	only	-	Aug	14	23:00u	1:00	P # Peace
-Rule	Winn	1945	only	-	Sep	lastSun	2:00	0	S
-Rule	Winn	1946	only	-	May	12	2:00	1:00	D
-Rule	Winn	1946	only	-	Oct	13	2:00	0	S
-Rule	Winn	1947	1949	-	Apr	lastSun	2:00	1:00	D
-Rule	Winn	1947	1949	-	Sep	lastSun	2:00	0	S
-Rule	Winn	1950	only	-	May	 1	2:00	1:00	D
-Rule	Winn	1950	only	-	Sep	30	2:00	0	S
-Rule	Winn	1951	1960	-	Apr	lastSun	2:00	1:00	D
-Rule	Winn	1951	1958	-	Sep	lastSun	2:00	0	S
-Rule	Winn	1959	only	-	Oct	lastSun	2:00	0	S
-Rule	Winn	1960	only	-	Sep	lastSun	2:00	0	S
-Rule	Winn	1963	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Winn	1963	only	-	Sep	22	2:00	0	S
-Rule	Winn	1966	1986	-	Apr	lastSun	2:00s	1:00	D
-Rule	Winn	1966	2005	-	Oct	lastSun	2:00s	0	S
-Rule	Winn	1987	2005	-	Apr	Sun>=1	2:00s	1:00	D
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Winnipeg	-6:28:36 -	LMT	1887 Jul 16
-			-6:00	Winn	C%sT	2006
-			-6:00	Canada	C%sT
-
-
-# Saskatchewan
-
-# From Mark Brader (2003-07-26):
-# The first actual adoption of DST in Canada was at the municipal
-# level.  As the [Toronto] Star put it (1912-06-07), "While people
-# elsewhere have long been talking of legislation to save daylight,
-# the city of Moose Jaw [Saskatchewan] has acted on its own hook."
-# DST in Moose Jaw began on Saturday, 1912-06-01 (no time mentioned:
-# presumably late evening, as below), and would run until "the end of
-# the summer".  The discrepancy between municipal time and railroad
-# time was noted.
-
-# From Paul Eggert (2003-07-27):
-# Willett (1914-03) notes that DST "has been in operation ... in the
-# City of Moose Jaw, Saskatchewan, for one year."
-
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger say that since 1970 this region has mostly been as Regina.
-# Some western towns (e.g. Swift Current) switched from MST/MDT to CST in 1972.
-# Other western towns (e.g. Lloydminster) are like Edmonton.
-# Matthews and Vincent (1998) write that Denare Beach and Creighton
-# are like Winnipeg, in violation of Saskatchewan law.
-
-# From W. Jones (1992-11-06):
-# The. . .below is based on information I got from our law library, the
-# provincial archives, and the provincial Community Services department.
-# A precise history would require digging through newspaper archives, and
-# since you didn't say what you wanted, I didn't bother.
-#
-# Saskatchewan is split by a time zone meridian (105W) and over the years
-# the boundary became pretty ragged as communities near it reevaluated
-# their affiliations in one direction or the other.  In 1965 a provincial
-# referendum favoured legislating common time practices.
-#
-# On 15 April 1966 the Time Act (c. T-14, Revised Statutes of
-# Saskatchewan 1978) was proclaimed, and established that the eastern
-# part of Saskatchewan would use CST year round, that districts in
-# northwest Saskatchewan would by default follow CST but could opt to
-# follow Mountain Time rules (thus 1 hour difference in the winter and
-# zero in the summer), and that districts in southwest Saskatchewan would
-# by default follow MT but could opt to follow CST.
-#
-# It took a few years for the dust to settle (I know one story of a town
-# on one time zone having its school in another, such that a mom had to
-# serve her family lunch in two shifts), but presently it seems that only
-# a few towns on the border with Alberta (e.g. Lloydminster) follow MT
-# rules any more; all other districts appear to have used CST year round
-# since sometime in the 1960s.
-
-# From Chris Walton (2006-06-26):
-# The Saskatchewan time act which was last updated in 1996 is about 30 pages
-# long and rather painful to read.
-# http://www.qp.gov.sk.ca/documents/English/Statutes/Statutes/T14.pdf
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Regina	1918	only	-	Apr	14	2:00	1:00	D
-Rule	Regina	1918	only	-	Oct	31	2:00	0	S
-Rule	Regina	1930	1934	-	May	Sun>=1	0:00	1:00	D
-Rule	Regina	1930	1934	-	Oct	Sun>=1	0:00	0	S
-Rule	Regina	1937	1941	-	Apr	Sun>=8	0:00	1:00	D
-Rule	Regina	1937	only	-	Oct	Sun>=8	0:00	0	S
-Rule	Regina	1938	only	-	Oct	Sun>=1	0:00	0	S
-Rule	Regina	1939	1941	-	Oct	Sun>=8	0:00	0	S
-Rule	Regina	1942	only	-	Feb	 9	2:00	1:00	W # War
-Rule	Regina	1945	only	-	Aug	14	23:00u	1:00	P # Peace
-Rule	Regina	1945	only	-	Sep	lastSun	2:00	0	S
-Rule	Regina	1946	only	-	Apr	Sun>=8	2:00	1:00	D
-Rule	Regina	1946	only	-	Oct	Sun>=8	2:00	0	S
-Rule	Regina	1947	1957	-	Apr	lastSun	2:00	1:00	D
-Rule	Regina	1947	1957	-	Sep	lastSun	2:00	0	S
-Rule	Regina	1959	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Regina	1959	only	-	Oct	lastSun	2:00	0	S
-#
-Rule	Swift	1957	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Swift	1957	only	-	Oct	lastSun	2:00	0	S
-Rule	Swift	1959	1961	-	Apr	lastSun	2:00	1:00	D
-Rule	Swift	1959	only	-	Oct	lastSun	2:00	0	S
-Rule	Swift	1960	1961	-	Sep	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Regina	-6:58:36 -	LMT	1905 Sep
-			-7:00	Regina	M%sT	1960 Apr lastSun 2:00
-			-6:00	-	CST
-Zone America/Swift_Current -7:11:20 -	LMT	1905 Sep
-			-7:00	Canada	M%sT	1946 Apr lastSun 2:00
-			-7:00	Regina	M%sT	1950
-			-7:00	Swift	M%sT	1972 Apr lastSun 2:00
-			-6:00	-	CST
-
-
-# Alberta
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Edm	1918	1919	-	Apr	Sun>=8	2:00	1:00	D
-Rule	Edm	1918	only	-	Oct	31	2:00	0	S
-Rule	Edm	1919	only	-	May	27	2:00	0	S
-Rule	Edm	1920	1923	-	Apr	lastSun	2:00	1:00	D
-Rule	Edm	1920	only	-	Oct	lastSun	2:00	0	S
-Rule	Edm	1921	1923	-	Sep	lastSun	2:00	0	S
-Rule	Edm	1942	only	-	Feb	 9	2:00	1:00	W # War
-Rule	Edm	1945	only	-	Aug	14	23:00u	1:00	P # Peace
-Rule	Edm	1945	only	-	Sep	lastSun	2:00	0	S
-Rule	Edm	1947	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Edm	1947	only	-	Sep	lastSun	2:00	0	S
-Rule	Edm	1967	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Edm	1967	only	-	Oct	lastSun	2:00	0	S
-Rule	Edm	1969	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Edm	1969	only	-	Oct	lastSun	2:00	0	S
-Rule	Edm	1972	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	Edm	1972	2006	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Edmonton	-7:33:52 -	LMT	1906 Sep
-			-7:00	Edm	M%sT	1987
-			-7:00	Canada	M%sT
-
-
-# British Columbia
-
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger write that since 1970 most of this region has
-# been like Vancouver.
-# Dawson Creek uses MST.  Much of east BC is like Edmonton.
-# Matthews and Vincent (1998) write that Creston is like Dawson Creek.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Vanc	1918	only	-	Apr	14	2:00	1:00	D
-Rule	Vanc	1918	only	-	Oct	31	2:00	0	S
-Rule	Vanc	1942	only	-	Feb	 9	2:00	1:00	W # War
-Rule	Vanc	1945	only	-	Aug	14	23:00u	1:00	P # Peace
-Rule	Vanc	1945	only	-	Sep	30	2:00	0	S
-Rule	Vanc	1946	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	Vanc	1946	only	-	Oct	13	2:00	0	S
-Rule	Vanc	1947	1961	-	Sep	lastSun	2:00	0	S
-Rule	Vanc	1962	2006	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Vancouver	-8:12:28 -	LMT	1884
-			-8:00	Vanc	P%sT	1987
-			-8:00	Canada	P%sT
-Zone America/Dawson_Creek -8:00:56 -	LMT	1884
-			-8:00	Canada	P%sT	1947
-			-8:00	Vanc	P%sT	1972 Aug 30 2:00
-			-7:00	-	MST
-
-
-# Northwest Territories, Nunavut, Yukon
-
-# From Paul Eggert (2006-03-22):
-# Dawson switched to PST in 1973.  Inuvik switched to MST in 1979.
-# Mathew Englander (1996-10-07) gives the following refs:
-#	* 1967. Paragraph 28(34)(g) of the Interpretation Act, S.C. 1967-68,
-#	c. 7 defines Yukon standard time as UTC-9.  This is still valid;
-#	see Interpretation Act, R.S.C. 1985, c. I-21, s. 35(1).
-#	* C.O. 1973/214 switched Yukon to PST on 1973-10-28 00:00.
-#	* O.I.C. 1980/02 established DST.
-#	* O.I.C. 1987/056 changed DST to Apr firstSun 2:00 to Oct lastSun 2:00.
-# Shanks & Pottenger say Yukon's 1973-10-28 switch was at 2:00; go
-# with Englander.
-# From Chris Walton (2006-06-26):
-# Here is a link to the old daylight saving portion of the interpretation
-# act which was last updated in 1987:
-# http://www.gov.yk.ca/legislation/regs/oic1987_056.pdf
-
-# From Rives McDow (1999-09-04):
-# Nunavut ... moved ... to incorporate the whole territory into one time zone.
-# <a href="http://www.nunatsiaq.com/nunavut/nvt90903_13.html">
-# Nunavut moves to single time zone Oct. 31
-# </a>
-#
-# From Antoine Leca (1999-09-06):
-# We then need to create a new timezone for the Kitikmeot region of Nunavut
-# to differentiate it from the Yellowknife region.
-
-# From Paul Eggert (1999-09-20):
-# <a href="http://www.nunavut.com/basicfacts/english/basicfacts_1territory.html">
-# Basic Facts: The New Territory
-# </a> (1999) reports that Pangnirtung operates on eastern time,
-# and that Coral Harbour does not observe DST.  We don't know when
-# Pangnirtung switched to eastern time; we'll guess 1995.
-
-# From Rives McDow (1999-11-08):
-# On October 31, when the rest of Nunavut went to Central time,
-# Pangnirtung wobbled.  Here is the result of their wobble:
-#
-# The following businesses and organizations in Pangnirtung use Central Time:
-#
-#	First Air, Power Corp, Nunavut Construction, Health Center, RCMP,
-#	Eastern Arctic National Parks, A & D Specialist
-#
-# The following businesses and organizations in Pangnirtung use Eastern Time:
-#
-#	Hamlet office, All other businesses, Both schools, Airport operator
-#
-# This has made for an interesting situation there, which warranted the news.
-# No one there that I spoke with seems concerned, or has plans to
-# change the local methods of keeping time, as it evidently does not
-# really interfere with any activities or make things difficult locally.
-# They plan to celebrate New Year's turn-over twice, one hour apart,
-# so it appears that the situation will last at least that long.
-# The Nunavut Intergovernmental Affairs hopes that they will "come to
-# their senses", but the locals evidently don't see any problem with
-# the current state of affairs.
-
-# From Michaela Rodrigue, writing in the
-# <a href="http://www.nunatsiaq.com/archives/nunavut991130/nvt91119_17.html">
-# Nunatsiaq News (1999-11-19)</a>:
-# Clyde River, Pangnirtung and Sanikiluaq now operate with two time zones,
-# central - or Nunavut time - for government offices, and eastern time
-# for municipal offices and schools....  Igloolik [was similar but then]
-# made the switch to central time on Saturday, Nov. 6.
-
-# From Paul Eggert (2000-10-02):
-# Matthews and Vincent (1998) say the following, but we lack histories
-# for these potential new Zones.
-#
-# The Canadian Forces station at Alert uses Eastern Time while the
-# handful of residents at the Eureka weather station [in the Central
-# zone] skip daylight savings.  Baffin Island, which is crossed by the
-# Central, Eastern and Atlantic Time zones only uses Eastern Time.
-# Gjoa Haven, Taloyoak and Pelly Bay all use Mountain instead of
-# Central Time and Southampton Island [in the Central zone] is not
-# required to use daylight savings.
-
-# From
-# <a href="http://www.nunatsiaq.com/archives/nunavut001130/nvt21110_02.html">
-# Nunavut now has two time zones
-# </a> (2000-11-10):
-# The Nunavut government would allow its employees in Kugluktuk and
-# Cambridge Bay to operate on central time year-round, putting them
-# one hour behind the rest of Nunavut for six months during the winter.
-# At the end of October the two communities had rebelled against
-# Nunavut's unified time zone, refusing to shift to eastern time with
-# the rest of the territory for the winter.  Cambridge Bay remained on
-# central time, while Kugluktuk, even farther west, reverted to
-# mountain time, which they had used before the advent of Nunavut's
-# unified time zone in 1999.
-#
-# From Rives McDow (2001-01-20), quoting the Nunavut government:
-# The preceding decision came into effect at midnight, Saturday Nov 4, 2000.
-
-# From Paul Eggert (2000-12-04):
-# Let's just keep track of the official times for now.
-
-# From Rives McDow (2001-03-07):
-# The premier of Nunavut has issued a ministerial statement advising
-# that effective 2001-04-01, the territory of Nunavut will revert
-# back to three time zones (mountain, central, and eastern).  Of the
-# cities in Nunavut, Coral Harbor is the only one that I know of that
-# has said it will not observe dst, staying on EST year round.  I'm
-# checking for more info, and will get back to you if I come up with
-# more.
-# [Also see <http://www.nunatsiaq.com/nunavut/nvt10309_06.html> (2001-03-09).]
-
-# From Gwillim Law (2005-05-21):
-# According to maps at
-# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SWE.jpg
-# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SSE.jpg
-# (both dated 2003), and
-# http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp
-# (from a 1998 Canadian Geographic article), the de facto and de jure time
-# for Southampton Island (at the north end of Hudson Bay) is UTC-5 all year
-# round.  Using Google, it's easy to find other websites that confirm this.
-# I wasn't able to find how far back this time regimen goes, but since it
-# predates the creation of Nunavut, it probably goes back many years....
-# The Inuktitut name of Coral Harbour is Sallit, but it's rarely used.
-#
-# From Paul Eggert (2005-07-26):
-# For lack of better information, assume that Southampton Island observed
-# daylight saving only during wartime.
-
-# From Chris Walton (2007-03-01):
-# ... the community of Resolute (located on Cornwallis Island in
-# Nunavut) moved from Central Time to Eastern Time last November.
-# Basically the community did not change its clocks at the end of
-# daylight saving....
-# http://www.nnsl.com/frames/newspapers/2006-11/nov13_06none.html
-
-# From Chris Walton (2007-03-14):
-# Today I phoned the "hamlet office" to find out what Resolute was doing with
-# its clocks.
-#
-# The individual that answered the phone confirmed that the clocks did not
-# move at the end of daylight saving on October 29/2006.  He also told me that
-# the clocks did not move this past weekend (March 11/2007)....
-
-# From Chris Walton (2008-11-13):
-# ...the residents of Resolute believe that they are changing "time zones"
-# twice a year.  In winter months, local time is qualified with "Eastern
-# Time" which is really "Eastern Standard Time (UTC-5)".  In summer
-# months, local time is qualified with "Central Time" which is really
-# "Central Daylight Time (UTC-5)"...
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	NT_YK	1918	only	-	Apr	14	2:00	1:00	D
-Rule	NT_YK	1918	only	-	Oct	27	2:00	0	S
-Rule	NT_YK	1919	only	-	May	25	2:00	1:00	D
-Rule	NT_YK	1919	only	-	Nov	 1	0:00	0	S
-Rule	NT_YK	1942	only	-	Feb	 9	2:00	1:00	W # War
-Rule	NT_YK	1945	only	-	Aug	14	23:00u	1:00	P # Peace
-Rule	NT_YK	1945	only	-	Sep	30	2:00	0	S
-Rule	NT_YK	1965	only	-	Apr	lastSun	0:00	2:00	DD
-Rule	NT_YK	1965	only	-	Oct	lastSun	2:00	0	S
-Rule	NT_YK	1980	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	NT_YK	1980	2006	-	Oct	lastSun	2:00	0	S
-Rule	NT_YK	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# aka Panniqtuuq
-Zone America/Pangnirtung 0	-	zzz	1921 # trading post est.
-			-4:00	NT_YK	A%sT	1995 Apr Sun>=1 2:00
-			-5:00	Canada	E%sT	1999 Oct 31 2:00
-			-6:00	Canada	C%sT	2000 Oct 29 2:00
-			-5:00	Canada	E%sT
-# formerly Frobisher Bay
-Zone America/Iqaluit	0	-	zzz	1942 Aug # Frobisher Bay est.
-			-5:00	NT_YK	E%sT	1999 Oct 31 2:00
-			-6:00	Canada	C%sT	2000 Oct 29 2:00
-			-5:00	Canada	E%sT
-# aka Qausuittuq
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Resolute 2006	max	-	Nov	Sun>=1	2:00	0	ES
-Rule	Resolute 2007	max	-	Mar	Sun>=8	2:00	0	CD
-Zone America/Resolute	0	-	zzz	1947 Aug 31 # Resolute founded
-			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
-			-5:00	-	EST	2001 Apr  1 3:00
-			-6:00	Canada	C%sT	2006 Oct 29 2:00
-			-5:00	Resolute	%sT
-# aka Kangiqiniq
-Zone America/Rankin_Inlet 0	-	zzz	1957 # Rankin Inlet founded
-			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
-			-5:00	-	EST	2001 Apr  1 3:00
-			-6:00	Canada	C%sT
-# aka Iqaluktuuttiaq
-Zone America/Cambridge_Bay 0	-	zzz	1920 # trading post est.?
-			-7:00	NT_YK	M%sT	1999 Oct 31 2:00
-			-6:00	Canada	C%sT	2000 Oct 29 2:00
-			-5:00	-	EST	2000 Nov  5 0:00
-			-6:00	-	CST	2001 Apr  1 3:00
-			-7:00	Canada	M%sT
-Zone America/Yellowknife 0	-	zzz	1935 # Yellowknife founded?
-			-7:00	NT_YK	M%sT	1980
-			-7:00	Canada	M%sT
-Zone America/Inuvik	0	-	zzz	1953 # Inuvik founded
-			-8:00	NT_YK	P%sT	1979 Apr lastSun 2:00
-			-7:00	NT_YK	M%sT	1980
-			-7:00	Canada	M%sT
-Zone America/Whitehorse	-9:00:12 -	LMT	1900 Aug 20
-			-9:00	NT_YK	Y%sT	1966 Jul 1 2:00
-			-8:00	NT_YK	P%sT	1980
-			-8:00	Canada	P%sT
-Zone America/Dawson	-9:17:40 -	LMT	1900 Aug 20
-			-9:00	NT_YK	Y%sT	1973 Oct 28 0:00
-			-8:00	NT_YK	P%sT	1980
-			-8:00	Canada	P%sT
-
-
-###############################################################################
-
-# Mexico
-
-# From Paul Eggert (2001-03-05):
-# The Investigation and Analysis Service of the
-# Mexican Library of Congress (MLoC) has published a
-# <a href="http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/">
-# history of Mexican local time (in Spanish)
-# </a>.
-#
-# Here are the discrepancies between Shanks & Pottenger (S&P) and the MLoC.
-# (In all cases we go with the MLoC.)
-# S&P report that Baja was at -8:00 in 1922/1923.
-# S&P say the 1930 transition in Baja was 1930-11-16.
-# S&P report no DST during summer 1931.
-# S&P report a transition at 1932-03-30 23:00, not 1932-04-01.
-
-# From Gwillim Law (2001-02-20):
-# There are some other discrepancies between the Decrees page and the
-# tz database.  I think they can best be explained by supposing that
-# the researchers who prepared the Decrees page failed to find some of
-# the relevant documents.
-
-# From Alan Perry (1996-02-15):
-# A guy from our Mexico subsidiary finally found the Presidential Decree
-# outlining the timezone changes in Mexico.
-#
-# ------------- Begin Forwarded Message -------------
-#
-# I finally got my hands on the Official Presidential Decree that sets up the
-# rules for the DST changes. The rules are:
-#
-# 1. The country is divided in 3 timezones:
-#    - Baja California Norte (the Mexico/BajaNorte TZ)
-#    - Baja California Sur, Nayarit, Sinaloa and Sonora (the Mexico/BajaSur TZ)
-#    - The rest of the country (the Mexico/General TZ)
-#
-# 2. From the first Sunday in April at 2:00 AM to the last Sunday in October
-#    at 2:00 AM, the times in each zone are as follows:
-#    BajaNorte: GMT+7
-#    BajaSur:   GMT+6
-#    General:   GMT+5
-#
-# 3. The rest of the year, the times are as follows:
-#    BajaNorte: GMT+8
-#    BajaSur:   GMT+7
-#    General:   GMT+6
-#
-# The Decree was published in Mexico's Official Newspaper on January 4th.
-#
-# -------------- End Forwarded Message --------------
-# From Paul Eggert (1996-06-12):
-# For an English translation of the decree, see
-# <a href="http://mexico-travel.com/extra/timezone_eng.html">
-# ``Diario Oficial: Time Zone Changeover'' (1996-01-04).
-# </a>
-
-# From Rives McDow (1998-10-08):
-# The State of Quintana Roo has reverted back to central STD and DST times
-# (i.e. UTC -0600 and -0500 as of 1998-08-02).
-
-# From Rives McDow (2000-01-10):
-# Effective April 4, 1999 at 2:00 AM local time, Sonora changed to the time
-# zone 5 hours from the International Date Line, and will not observe daylight
-# savings time so as to stay on the same time zone as the southern part of
-# Arizona year round.
-
-# From Jesper Norgaard, translating
-# <http://www.reforma.com/nacional/articulo/064327/> (2001-01-17):
-# In Oaxaca, the 55.000 teachers from the Section 22 of the National
-# Syndicate of Education Workers, refuse to apply daylight saving each
-# year, so that the more than 10,000 schools work at normal hour the
-# whole year.
-
-# From Gwillim Law (2001-01-19):
-# <http://www.reforma.com/negocios_y_dinero/articulo/064481/> ... says
-# (translated):...
-# January 17, 2000 - The Energy Secretary, Ernesto Martens, announced
-# that Summer Time will be reduced from seven to five months, starting
-# this year....
-# <http://www.publico.com.mx/scripts/texto3.asp?action=pagina&pag=21&pos=p&secc=naci&date=01/17/2001>
-# [translated], says "summer time will ... take effect on the first Sunday
-# in May, and end on the last Sunday of September.
-
-# From Arthur David Olson (2001-01-25):
-# The 2001-01-24 traditional Washington Post contained the page one
-# story "Timely Issue Divides Mexicans."...
-# http://www.washingtonpost.com/wp-dyn/articles/A37383-2001Jan23.html
-# ... Mexico City Mayor Lopez Obrador "...is threatening to keep
-# Mexico City and its 20 million residents on a different time than
-# the rest of the country..." In particular, Lopez Obrador would abolish
-# observation of Daylight Saving Time.
-
-# <a href="http://www.conae.gob.mx/ahorro/decretohorver2001.html#decre">
-# Official statute published by the Energy Department
-# </a> (2001-02-01) shows Baja and Chihauhua as still using US DST rules,
-# and Sonora with no DST.  This was reported by Jesper Norgaard (2001-02-03).
-
-# From Paul Eggert (2001-03-03):
-#
-# <a href="http://www.latimes.com/news/nation/20010303/t000018766.html">
-# James F. Smith writes in today's LA Times
-# </a>
-# * Sonora will continue to observe standard time.
-# * Last week Mexico City's mayor Andres Manuel Lopez Obrador decreed that
-#   the Federal District will not adopt DST.
-# * 4 of 16 district leaders announced they'll ignore the decree.
-# * The decree does not affect federal-controlled facilities including
-#   the airport, banks, hospitals, and schools.
-#
-# For now we'll assume that the Federal District will bow to federal rules.
-
-# From Jesper Norgaard (2001-04-01):
-# I found some references to the Mexican application of daylight
-# saving, which modifies what I had already sent you, stating earlier
-# that a number of northern Mexican states would go on daylight
-# saving. The modification reverts this to only cover Baja California
-# (Norte), while all other states (except Sonora, who has no daylight
-# saving all year) will follow the original decree of president
-# Vicente Fox, starting daylight saving May 6, 2001 and ending
-# September 30, 2001.
-# References: "Diario de Monterrey" <www.diariodemonterrey.com/index.asp>
-# Palabra <http://palabra.infosel.com/010331/primera/ppri3101.pdf> (2001-03-31)
-
-# From Reuters (2001-09-04):
-# Mexico's Supreme Court on Tuesday declared that daylight savings was
-# unconstitutional in Mexico City, creating the possibility the
-# capital will be in a different time zone from the rest of the nation
-# next year....  The Supreme Court's ruling takes effect at 2:00
-# a.m. (0800 GMT) on Sept. 30, when Mexico is scheduled to revert to
-# standard time. "This is so residents of the Federal District are not
-# subject to unexpected time changes," a statement from the court said.
-
-# From Jesper Norgaard Welen (2002-03-12):
-# ... consulting my local grocery store(!) and my coworkers, they all insisted
-# that a new decision had been made to reinstate US style DST in Mexico....
-# http://www.conae.gob.mx/ahorro/horaver2001_m1_2002.html (2002-02-20)
-# confirms this.  Sonora as usual is the only state where DST is not applied.
-
-# From Steffen Thorsen (2009-12-28):
-#
-# Steffen Thorsen wrote:
-# > Mexico's House of Representatives has approved a proposal for northern
-# > Mexico's border cities to share the same daylight saving schedule as
-# > the United States.
-# Now this has passed both the Congress and the Senate, so starting from
-# 2010, some border regions will be the same:
-# <a href="http://www.signonsandiego.com/news/2009/dec/28/clocks-will-match-both-sides-border/">
-# http://www.signonsandiego.com/news/2009/dec/28/clocks-will-match-both-sides-border/
-# </a>
-# <a href="http://www.elmananarey.com/diario/noticia/nacional/noticias/empatan_horario_de_frontera_con_eu/621939">
-# http://www.elmananarey.com/diario/noticia/nacional/noticias/empatan_horario_de_frontera_con_eu/621939
-# </a>
-# (Spanish)
-#
-# Could not find the new law text, but the proposed law text changes are here:
-# <a href="http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/20091210-V.pdf">
-# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/20091210-V.pdf
-# </a>
-# (Gaceta Parlamentaria)
-#
-# There is also a list of the votes here:
-# <a href="http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html">
-# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html
-# </a>
-#
-# Our page:
-# <a href="http://www.timeanddate.com/news/time/north-mexico-dst-change.html">
-# http://www.timeanddate.com/news/time/north-mexico-dst-change.html
-# </a>
-
-# From Arthur David Olson (2010-01-20):
-# The page
-# <a href="http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010">
-# http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010
-# </a>
-# includes this text:
-# En los municipios fronterizos de Tijuana y Mexicali en Baja California;
-# Ju&aacute;rez y Ojinaga en Chihuahua; Acu&ntilde;a y Piedras Negras en Coahuila;
-# An&aacute;huac en Nuevo Le&oacute;n; y Nuevo Laredo, Reynosa y Matamoros en
-# Tamaulipas, la aplicaci&oacute;n de este horario estacional surtir&aacute; efecto
-# desde las dos horas del segundo domingo de marzo y concluir&aacute; a las dos
-# horas del primer domingo de noviembre.
-# En los municipios fronterizos que se encuentren ubicados en la franja
-# fronteriza norte en el territorio comprendido entre la l&iacute;nea
-# internacional y la l&iacute;nea paralela ubicada a una distancia de veinte
-# kil&oacute;metros, as&iacute; como la Ciudad de Ensenada, Baja California, hacia el
-# interior del pa&iacute;s, la aplicaci&oacute;n de este horario estacional surtir&aacute;
-# efecto desde las dos horas del segundo domingo de marzo y concluir&aacute; a
-# las dos horas del primer domingo de noviembre.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Mexico	1939	only	-	Feb	5	0:00	1:00	D
-Rule	Mexico	1939	only	-	Jun	25	0:00	0	S
-Rule	Mexico	1940	only	-	Dec	9	0:00	1:00	D
-Rule	Mexico	1941	only	-	Apr	1	0:00	0	S
-Rule	Mexico	1943	only	-	Dec	16	0:00	1:00	W # War
-Rule	Mexico	1944	only	-	May	1	0:00	0	S
-Rule	Mexico	1950	only	-	Feb	12	0:00	1:00	D
-Rule	Mexico	1950	only	-	Jul	30	0:00	0	S
-Rule	Mexico	1996	2000	-	Apr	Sun>=1	2:00	1:00	D
-Rule	Mexico	1996	2000	-	Oct	lastSun	2:00	0	S
-Rule	Mexico	2001	only	-	May	Sun>=1	2:00	1:00	D
-Rule	Mexico	2001	only	-	Sep	lastSun	2:00	0	S
-Rule	Mexico	2002	max	-	Apr	Sun>=1	2:00	1:00	D
-Rule	Mexico	2002	max	-	Oct	lastSun	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-# Quintana Roo
-Zone America/Cancun	-5:47:04 -	LMT	1922 Jan  1  0:12:56
-			-6:00	-	CST	1981 Dec 23
-			-5:00	Mexico	E%sT	1998 Aug  2  2:00
-			-6:00	Mexico	C%sT
-# Campeche, Yucatan
-Zone America/Merida	-5:58:28 -	LMT	1922 Jan  1  0:01:32
-			-6:00	-	CST	1981 Dec 23
-			-5:00	-	EST	1982 Dec  2
-			-6:00	Mexico	C%sT
-# Coahuila, Durango, Nuevo Leon, Tamaulipas (near US border)
-Zone America/Matamoros	-6:40:00 -	LMT	1921 Dec 31 23:20:00
-			-6:00	-	CST	1988
-			-6:00	US	C%sT	1989
-			-6:00	Mexico	C%sT	2010
-			-6:00	US	C%sT
-# Coahuila, Durango, Nuevo Leon, Tamaulipas (away from US border)
-Zone America/Monterrey	-6:41:16 -	LMT	1921 Dec 31 23:18:44
-			-6:00	-	CST	1988
-			-6:00	US	C%sT	1989
-			-6:00	Mexico	C%sT
-# Central Mexico
-Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1 0:23:24
-			-7:00	-	MST	1927 Jun 10 23:00
-			-6:00	-	CST	1930 Nov 15
-			-7:00	-	MST	1931 May  1 23:00
-			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Apr  1
-			-6:00	Mexico	C%sT	2001 Sep 30 02:00
-			-6:00	-	CST	2002 Feb 20
-			-6:00	Mexico	C%sT
-# Chihuahua (near US border)
-Zone America/Ojinaga	-6:57:40 -	LMT	1922 Jan 1 0:02:20
-			-7:00	-	MST	1927 Jun 10 23:00
-			-6:00	-	CST	1930 Nov 15
-			-7:00	-	MST	1931 May  1 23:00
-			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Apr  1
-			-6:00	-	CST	1996
-			-6:00	Mexico	C%sT	1998
-			-6:00	-	CST	1998 Apr Sun>=1 3:00
-			-7:00	Mexico	M%sT	2010
-			-7:00	US	M%sT
-# Chihuahua (away from US border)
-Zone America/Chihuahua	-7:04:20 -	LMT	1921 Dec 31 23:55:40
-			-7:00	-	MST	1927 Jun 10 23:00
-			-6:00	-	CST	1930 Nov 15
-			-7:00	-	MST	1931 May  1 23:00
-			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Apr  1
-			-6:00	-	CST	1996
-			-6:00	Mexico	C%sT	1998
-			-6:00	-	CST	1998 Apr Sun>=1 3:00
-			-7:00	Mexico	M%sT
-# Sonora
-Zone America/Hermosillo	-7:23:52 -	LMT	1921 Dec 31 23:36:08
-			-7:00	-	MST	1927 Jun 10 23:00
-			-6:00	-	CST	1930 Nov 15
-			-7:00	-	MST	1931 May  1 23:00
-			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Apr  1
-			-6:00	-	CST	1942 Apr 24
-			-7:00	-	MST	1949 Jan 14
-			-8:00	-	PST	1970
-			-7:00	Mexico	M%sT	1999
-			-7:00	-	MST
-
-# From Alexander Krivenyshev (2010-04-21):
-# According to news, Bah&iacute;a de Banderas (Mexican state of Nayarit)
-# changed time zone UTC-7 to new time zone UTC-6 on April 4, 2010 (to
-# share the same time zone as nearby city Puerto Vallarta, Jalisco).
-#
-# (Spanish)
-# Bah&iacute;a de Banderas homologa su horario al del centro del
-# pa&iacute;s, a partir de este domingo
-# <a href="http://www.nayarit.gob.mx/notes.asp?id=20748">
-# http://www.nayarit.gob.mx/notes.asp?id=20748
-# </a>
-#
-# Bah&iacute;a de Banderas homologa su horario con el del Centro del
-# Pa&iacute;s
-# <a href="http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50">
-# http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50"
-# </a>
-#
-# (English)
-# Puerto Vallarta and Bah&iacute;a de Banderas: One Time Zone
-# <a href="http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml">
-# http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml
-# </a>
-#
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_mexico08.html">
-# http://www.worldtimezone.com/dst_news/dst_news_mexico08.html
-# </a>
-#
-# "Mexico's Senate approved the amendments to the Mexican Schedule System that
-# will allow Bah&iacute;a de Banderas and Puerto Vallarta to share the same time
-# zone ..."
-# Baja California Sur, Nayarit, Sinaloa
-
-# From Arthur David Olson (2010-05-01):
-# Use "Bahia_Banderas" to keep the name to fourteen characters.
-
-Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
-			-7:00	-	MST	1927 Jun 10 23:00
-			-6:00	-	CST	1930 Nov 15
-			-7:00	-	MST	1931 May  1 23:00
-			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Apr  1
-			-6:00	-	CST	1942 Apr 24
-			-7:00	-	MST	1949 Jan 14
-			-8:00	-	PST	1970
-			-7:00	Mexico	M%sT
-
-Zone America/Bahia_Banderas	-7:01:00 -	LMT	1921 Dec 31 23:59:00
-			-7:00	-	MST	1927 Jun 10 23:00
-			-6:00	-	CST	1930 Nov 15
-			-7:00	-	MST	1931 May  1 23:00
-			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Apr  1
-			-6:00	-	CST	1942 Apr 24
-			-7:00	-	MST	1949 Jan 14
-			-8:00	-	PST	1970
-			-7:00	Mexico	M%sT	2010 Apr 4 2:00
-			-6:00	Mexico	C%sT
-
-# Baja California (near US border)
-Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
-			-7:00	-	MST	1924
-			-8:00	-	PST	1927 Jun 10 23:00
-			-7:00	-	MST	1930 Nov 15
-			-8:00	-	PST	1931 Apr  1
-			-8:00	1:00	PDT	1931 Sep 30
-			-8:00	-	PST	1942 Apr 24
-			-8:00	1:00	PWT	1945 Aug 14 23:00u
-			-8:00	1:00	PPT	1945 Nov 12 # Peace
-			-8:00	-	PST	1948 Apr  5
-			-8:00	1:00	PDT	1949 Jan 14
-			-8:00	-	PST	1954
-			-8:00	CA	P%sT	1961
-			-8:00	-	PST	1976
-			-8:00	US	P%sT	1996
-			-8:00	Mexico	P%sT	2001
-			-8:00	US	P%sT	2002 Feb 20
-			-8:00	Mexico	P%sT	2010
-			-8:00	US	P%sT
-# Baja California (away from US border)
-Zone America/Santa_Isabel	-7:39:28 -	LMT	1922 Jan  1  0:20:32
-			-7:00	-	MST	1924
-			-8:00	-	PST	1927 Jun 10 23:00
-			-7:00	-	MST	1930 Nov 15
-			-8:00	-	PST	1931 Apr  1
-			-8:00	1:00	PDT	1931 Sep 30
-			-8:00	-	PST	1942 Apr 24
-			-8:00	1:00	PWT	1945 Aug 14 23:00u
-			-8:00	1:00	PPT	1945 Nov 12 # Peace
-			-8:00	-	PST	1948 Apr  5
-			-8:00	1:00	PDT	1949 Jan 14
-			-8:00	-	PST	1954
-			-8:00	CA	P%sT	1961
-			-8:00	-	PST	1976
-			-8:00	US	P%sT	1996
-			-8:00	Mexico	P%sT	2001
-			-8:00	US	P%sT	2002 Feb 20
-			-8:00	Mexico	P%sT
-# From Paul Eggert (2006-03-22):
-# Formerly there was an America/Ensenada zone, which differed from
-# America/Tijuana only in that it did not observe DST from 1976
-# through 1995.  This was as per Shanks (1999).  But Shanks & Pottenger say
-# Ensenada did not observe DST from 1948 through 1975.  Guy Harris reports
-# that the 1987 OAG says "Only Ensenada, Mexicale, San Felipe and
-# Tijuana observe DST," which agrees with Shanks & Pottenger but implies that
-# DST-observance was a town-by-town matter back then.  This concerns
-# data after 1970 so most likely there should be at least one Zone
-# other than America/Tijuana for Baja, but it's not clear yet what its
-# name or contents should be.
-#
-# Revillagigedo Is
-# no information
-
-###############################################################################
-
-# Anguilla
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Anguilla	-4:12:16 -	LMT	1912 Mar 2
-			-4:00	-	AST
-
-# Antigua and Barbuda
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Antigua	-4:07:12 -	LMT	1912 Mar 2
-			-5:00	-	EST	1951
-			-4:00	-	AST
-
-# Bahamas
-#
-# From Sue Williams (2006-12-07):
-# The Bahamas announced about a month ago that they plan to change their DST
-# rules to sync with the U.S. starting in 2007....
-# http://www.jonesbahamas.com/?c=45&a=10412
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Bahamas	1964	1975	-	Oct	lastSun	2:00	0	S
-Rule	Bahamas	1964	1975	-	Apr	lastSun	2:00	1:00	D
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Nassau	-5:09:24 -	LMT	1912 Mar 2
-			-5:00	Bahamas	E%sT	1976
-			-5:00	US	E%sT
-
-# Barbados
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Barb	1977	only	-	Jun	12	2:00	1:00	D
-Rule	Barb	1977	1978	-	Oct	Sun>=1	2:00	0	S
-Rule	Barb	1978	1980	-	Apr	Sun>=15	2:00	1:00	D
-Rule	Barb	1979	only	-	Sep	30	2:00	0	S
-Rule	Barb	1980	only	-	Sep	25	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Barbados	-3:58:28 -	LMT	1924		# Bridgetown
-			-3:58:28 -	BMT	1932	  # Bridgetown Mean Time
-			-4:00	Barb	A%sT
-
-# Belize
-# Whitman entirely disagrees with Shanks; go with Shanks & Pottenger.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Belize	1918	1942	-	Oct	Sun>=2	0:00	0:30	HD
-Rule	Belize	1919	1943	-	Feb	Sun>=9	0:00	0	S
-Rule	Belize	1973	only	-	Dec	 5	0:00	1:00	D
-Rule	Belize	1974	only	-	Feb	 9	0:00	0	S
-Rule	Belize	1982	only	-	Dec	18	0:00	1:00	D
-Rule	Belize	1983	only	-	Feb	12	0:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Belize	-5:52:48 -	LMT	1912 Apr
-			-6:00	Belize	C%sT
-
-# Bermuda
-
-# From Dan Jones, reporting in The Royal Gazette (2006-06-26):
-
-# Next year, however, clocks in the US will go forward on the second Sunday
-# in March, until the first Sunday in November.  And, after the Time Zone
-# (Seasonal Variation) Bill 2006 was passed in the House of Assembly on
-# Friday, the same thing will happen in Bermuda.
-# http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/Bermuda	-4:19:04 -	LMT	1930 Jan  1 2:00    # Hamilton
-			-4:00	-	AST	1974 Apr 28 2:00
-			-4:00	Bahamas	A%sT	1976
-			-4:00	US	A%sT
-
-# Cayman Is
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Cayman	-5:25:32 -	LMT	1890		# Georgetown
-			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
-			-5:00	-	EST
-
-# Costa Rica
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	CR	1979	1980	-	Feb	lastSun	0:00	1:00	D
-Rule	CR	1979	1980	-	Jun	Sun>=1	0:00	0	S
-Rule	CR	1991	1992	-	Jan	Sat>=15	0:00	1:00	D
-# IATA SSIM (1991-09) says the following was at 1:00;
-# go with Shanks & Pottenger.
-Rule	CR	1991	only	-	Jul	 1	0:00	0	S
-Rule	CR	1992	only	-	Mar	15	0:00	0	S
-# There are too many San Joses elsewhere, so we'll use `Costa Rica'.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Costa_Rica	-5:36:20 -	LMT	1890		# San Jose
-			-5:36:20 -	SJMT	1921 Jan 15 # San Jose Mean Time
-			-6:00	CR	C%sT
-# Coco
-# no information; probably like America/Costa_Rica
-
-# Cuba
-
-# From Arthur David Olson (1999-03-29):
-# The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
-# the Cuban National Team and the Baltimore Orioles was carried live on
-# the Orioles Radio Network, including affiliate WTOP in Washington, DC.
-# During the game, play-by-play announcer Jim Hunter noted that
-# "We'll be losing two hours of sleep...Cuba switched to Daylight Saving
-# Time today."  (The "two hour" remark referred to losing one hour of
-# sleep on 1999-03-28--when the announcers were in Cuba as it switched
-# to DST--and one more hour on 1999-04-04--when the announcers will have
-# returned to Baltimore, which switches on that date.)
-
-# From Evert van der Veer via Steffen Thorsen (2004-10-28):
-# Cuba is not going back to standard time this year.
-# From Paul Eggert (2006-03-22):
-# http://www.granma.cu/ingles/2004/septiembre/juev30/41medid-i.html
-# says that it's due to a problem at the Antonio Guiteras
-# thermoelectric plant, and says "This October there will be no return
-# to normal hours (after daylight saving time)".
-# For now, let's assume that it's a temporary measure.
-
-# From Carlos A. Carnero Delgado (2005-11-12):
-# This year (just like in 2004-2005) there's no change in time zone
-# adjustment in Cuba.  We will stay in daylight saving time:
-# http://www.granma.cu/espanol/2005/noviembre/mier9/horario.html
-
-# From Jesper Norgaard Welen (2006-10-21):
-# An article in GRANMA INTERNACIONAL claims that Cuba will end
-# the 3 years of permanent DST next weekend, see
-# http://www.granma.cu/ingles/2006/octubre/lun16/43horario.html
-# "On Saturday night, October 28 going into Sunday, October 29, at 01:00,
-# watches should be set back one hour -- going back to 00:00 hours -- returning
-# to the normal schedule....
-
-# From Paul Eggert (2007-03-02):
-# http://www.granma.cubaweb.cu/english/news/art89.html, dated yesterday,
-# says Cuban clocks will advance at midnight on March 10.
-# For lack of better information, assume Cuba will use US rules,
-# except that it switches at midnight standard time as usual.
-#
-# From Steffen Thorsen (2007-10-25):
-# Carlos Alberto Fonseca Arauz informed me that Cuba will end DST one week 
-# earlier - on the last Sunday of October, just like in 2006.
-# 
-# He supplied these references:
-# 
-# http://www.prensalatina.com.mx/article.asp?ID=%7B4CC32C1B-A9F7-42FB-8A07-8631AFC923AF%7D&language=ES
-# http://actualidad.terra.es/sociedad/articulo/cuba_llama_ahorrar_energia_cambio_1957044.htm
-# 
-# From Alex Kryvenishev (2007-10-25):
-# Here is also article from Granma (Cuba):
-# 
-# [Regira] el Horario Normal desde el [proximo] domingo 28 de octubre
-# http://www.granma.cubaweb.cu/2007/10/24/nacional/artic07.html
-# 
-# http://www.worldtimezone.com/dst_news/dst_news_cuba03.html
-
-# From Arthur David Olson (2008-03-09):
-# I'm in Maryland which is now observing United States Eastern Daylight
-# Time. At 9:44 local time I used RealPlayer to listen to
-# <a href="http://media.enet.cu/radioreloj">
-# http://media.enet.cu/radioreloj
-# </a>, a Cuban information station, and heard
-# the time announced as "ocho cuarenta y cuatro" ("eight forty-four"),
-# indicating that Cuba is still on standard time.
-
-# From Steffen Thorsen (2008-03-12):
-# It seems that Cuba will start DST on Sunday, 2007-03-16...
-# It was announced yesterday, according to this source (in Spanish):
-# <a href="http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm">
-# http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm
-# </a>
-#
-# Some more background information is posted here:
-# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html">
-# http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html
-# </a>
-#
-# The article also says that Cuba has been observing DST since 1963,
-# while Shanks (and tzdata) has 1965 as the first date (except in the
-# 1940's). Many other web pages in Cuba also claim that it has been
-# observed since 1963, but with the exception of 1970 - an exception
-# which is not present in tzdata/Shanks. So there is a chance we need to
-# change some historic records as well.
-#
-# One example:
-# <a href="http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm">
-# http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm
-# </a>
-
-# From Jesper Norgaard Welen (2008-03-13):
-# The Cuban time change has just been confirmed on the most authoritative
-# web site, the Granma.  Please check out
-# <a href="http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html">
-# http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html
-# </a>
-#
-# Basically as expected after Steffen Thorsens information, the change
-# will take place midnight between Saturday and Sunday.
-
-# From Arthur David Olson (2008-03-12):
-# Assume Sun>=15 (third Sunday) going forward.
-
-# From Alexander Krivenyshev (2009-03-04)
-# According to the Radio Reloj - Cuba will start Daylight Saving Time on
-# midnight between Saturday, March 07, 2009 and Sunday, March 08, 2009-
-# not on midnight March 14 / March 15 as previously thought.
-#
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_cuba05.html">
-# http://www.worldtimezone.com/dst_news/dst_news_cuba05.html
-# (in Spanish)
-# </a>
-
-# From Arthur David Olson (2009-03-09)
-# I listened over the Internet to
-# <a href="http://media.enet.cu/readioreloj">
-# http://media.enet.cu/readioreloj
-# </a>
-# this morning; when it was 10:05 a. m. here in Bethesda, Maryland the
-# the time was announced as "diez cinco"--the same time as here, indicating
-# that has indeed switched to DST. Assume second Sunday from 2009 forward.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Cuba	1928	only	-	Jun	10	0:00	1:00	D
-Rule	Cuba	1928	only	-	Oct	10	0:00	0	S
-Rule	Cuba	1940	1942	-	Jun	Sun>=1	0:00	1:00	D
-Rule	Cuba	1940	1942	-	Sep	Sun>=1	0:00	0	S
-Rule	Cuba	1945	1946	-	Jun	Sun>=1	0:00	1:00	D
-Rule	Cuba	1945	1946	-	Sep	Sun>=1	0:00	0	S
-Rule	Cuba	1965	only	-	Jun	1	0:00	1:00	D
-Rule	Cuba	1965	only	-	Sep	30	0:00	0	S
-Rule	Cuba	1966	only	-	May	29	0:00	1:00	D
-Rule	Cuba	1966	only	-	Oct	2	0:00	0	S
-Rule	Cuba	1967	only	-	Apr	8	0:00	1:00	D
-Rule	Cuba	1967	1968	-	Sep	Sun>=8	0:00	0	S
-Rule	Cuba	1968	only	-	Apr	14	0:00	1:00	D
-Rule	Cuba	1969	1977	-	Apr	lastSun	0:00	1:00	D
-Rule	Cuba	1969	1971	-	Oct	lastSun	0:00	0	S
-Rule	Cuba	1972	1974	-	Oct	8	0:00	0	S
-Rule	Cuba	1975	1977	-	Oct	lastSun	0:00	0	S
-Rule	Cuba	1978	only	-	May	7	0:00	1:00	D
-Rule	Cuba	1978	1990	-	Oct	Sun>=8	0:00	0	S
-Rule	Cuba	1979	1980	-	Mar	Sun>=15	0:00	1:00	D
-Rule	Cuba	1981	1985	-	May	Sun>=5	0:00	1:00	D
-Rule	Cuba	1986	1989	-	Mar	Sun>=14	0:00	1:00	D
-Rule	Cuba	1990	1997	-	Apr	Sun>=1	0:00	1:00	D
-Rule	Cuba	1991	1995	-	Oct	Sun>=8	0:00s	0	S
-Rule	Cuba	1996	only	-	Oct	 6	0:00s	0	S
-Rule	Cuba	1997	only	-	Oct	12	0:00s	0	S
-Rule	Cuba	1998	1999	-	Mar	lastSun	0:00s	1:00	D
-Rule	Cuba	1998	2003	-	Oct	lastSun	0:00s	0	S
-Rule	Cuba	2000	2004	-	Apr	Sun>=1	0:00s	1:00	D
-Rule	Cuba	2006	max	-	Oct	lastSun	0:00s	0	S
-Rule	Cuba	2007	only	-	Mar	Sun>=8	0:00s	1:00	D
-Rule	Cuba	2008	only	-	Mar	Sun>=15	0:00s	1:00	D
-Rule	Cuba	2009	max	-	Mar	Sun>=8	0:00s	1:00	D
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Havana	-5:29:28 -	LMT	1890
-			-5:29:36 -	HMT	1925 Jul 19 12:00 # Havana MT
-			-5:00	Cuba	C%sT
-
-# Dominica
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Dominica	-4:05:36 -	LMT	1911 Jul 1 0:01		# Roseau
-			-4:00	-	AST
-
-# Dominican Republic
-
-# From Steffen Thorsen (2000-10-30):
-# Enrique Morales reported to me that the Dominican Republic has changed the
-# time zone to Eastern Standard Time as of Sunday 29 at 2 am....
-# http://www.listin.com.do/antes/261000/republica/princi.html
-
-# From Paul Eggert (2000-12-04):
-# That URL (2000-10-26, in Spanish) says they planned to use US-style DST.
-
-# From Rives McDow (2000-12-01):
-# Dominican Republic changed its mind and presidential decree on Tuesday,
-# November 28, 2000, with a new decree.  On Sunday, December 3 at 1:00 AM the
-# Dominican Republic will be reverting to 8 hours from the International Date
-# Line, and will not be using DST in the foreseeable future.  The reason they
-# decided to use DST was to be in synch with Puerto Rico, who was also going
-# to implement DST.  When Puerto Rico didn't implement DST, the president
-# decided to revert.
-
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	DR	1966	only	-	Oct	30	0:00	1:00	D
-Rule	DR	1967	only	-	Feb	28	0:00	0	S
-Rule	DR	1969	1973	-	Oct	lastSun	0:00	0:30	HD
-Rule	DR	1970	only	-	Feb	21	0:00	0	S
-Rule	DR	1971	only	-	Jan	20	0:00	0	S
-Rule	DR	1972	1974	-	Jan	21	0:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Santo_Domingo -4:39:36 -	LMT	1890
-			-4:40	-	SDMT	1933 Apr  1 12:00 # S. Dom. MT
-			-5:00	DR	E%sT	1974 Oct 27
-			-4:00	-	AST	2000 Oct 29 02:00
-			-5:00	US	E%sT	2000 Dec  3 01:00
-			-4:00	-	AST
-
-# El Salvador
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Salv	1987	1988	-	May	Sun>=1	0:00	1:00	D
-Rule	Salv	1987	1988	-	Sep	lastSun	0:00	0	S
-# There are too many San Salvadors elsewhere, so use America/El_Salvador
-# instead of America/San_Salvador.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/El_Salvador -5:56:48 -	LMT	1921		# San Salvador
-			-6:00	Salv	C%sT
-
-# Grenada
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Grenada	-4:07:00 -	LMT	1911 Jul	# St George's
-			-4:00	-	AST
-
-# Guadeloupe
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Guadeloupe	-4:06:08 -	LMT	1911 Jun 8	# Pointe a Pitre
-			-4:00	-	AST
-# St Barthelemy
-Link America/Guadeloupe	America/St_Barthelemy
-# St Martin (French part)
-Link America/Guadeloupe	America/Marigot
-
-# Guatemala
-#
-# From Gwillim Law (2006-04-22), after a heads-up from Oscar van Vlijmen:
-# Diario Co Latino, at
-# http://www.diariocolatino.com/internacionales/detalles.asp?NewsID=8079,
-# says in an article dated 2006-04-19 that the Guatemalan government had
-# decided on that date to advance official time by 60 minutes, to lessen the
-# impact of the elevated cost of oil....  Daylight saving time will last from
-# 2006-04-29 24:00 (Guatemalan standard time) to 2006-09-30 (time unspecified).
-# From Paul Eggert (2006-06-22):
-# The Ministry of Energy and Mines, press release CP-15/2006
-# (2006-04-19), says DST ends at 24:00.  See
-# <http://www.sieca.org.gt/Sitio_publico/Energeticos/Doc/Medidas/Cambio_Horario_Nac_190406.pdf>.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Guat	1973	only	-	Nov	25	0:00	1:00	D
-Rule	Guat	1974	only	-	Feb	24	0:00	0	S
-Rule	Guat	1983	only	-	May	21	0:00	1:00	D
-Rule	Guat	1983	only	-	Sep	22	0:00	0	S
-Rule	Guat	1991	only	-	Mar	23	0:00	1:00	D
-Rule	Guat	1991	only	-	Sep	 7	0:00	0	S
-Rule	Guat	2006	only	-	Apr	30	0:00	1:00	D
-Rule	Guat	2006	only	-	Oct	 1	0:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Guatemala	-6:02:04 -	LMT	1918 Oct 5
-			-6:00	Guat	C%sT
-
-# Haiti
-# From Gwillim Law (2005-04-15):
-# Risto O. Nykanen wrote me that Haiti is now on DST.
-# I searched for confirmation, and I found a
-# <a href="http://www.haitianconsulate.org/time.doc"> press release
-# on the Web page of the Haitian Consulate in Chicago (2005-03-31),
-# </a>.  Translated from French, it says:
-#
-#  "The Prime Minister's Communication Office notifies the public in general
-#   and the press in particular that, following a decision of the Interior
-#   Ministry and the Territorial Collectivities [I suppose that means the
-#   provinces], Haiti will move to Eastern Daylight Time in the night from next
-#   Saturday the 2nd to Sunday the 3rd.
-#
-#  "Consequently, the Prime Minister's Communication Office wishes to inform
-#   the population that the country's clocks will be set forward one hour
-#   starting at midnight.  This provision will hold until the last Saturday in
-#   October 2005.
-#
-#  "Port-au-Prince, March 31, 2005"
-#
-# From Steffen Thorsen (2006-04-04):
-# I have been informed by users that Haiti observes DST this year like
-# last year, so the current "only" rule for 2005 might be changed to a
-# "max" rule or to last until 2006. (Who knows if they will observe DST
-# next year or if they will extend their DST like US/Canada next year).
-#
-# I have found this article about it (in French):
-# http://www.haitipressnetwork.com/news.cfm?articleID=7612
-#
-# The reason seems to be an energy crisis.
-
-# From Stephen Colebourne (2007-02-22):
-# Some IATA info: Haiti won't be having DST in 2007.
-
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Haiti	1983	only	-	May	8	0:00	1:00	D
-Rule	Haiti	1984	1987	-	Apr	lastSun	0:00	1:00	D
-Rule	Haiti	1983	1987	-	Oct	lastSun	0:00	0	S
-# Shanks & Pottenger say AT is 2:00, but IATA SSIM (1991/1997) says 1:00s.
-# Go with IATA.
-Rule	Haiti	1988	1997	-	Apr	Sun>=1	1:00s	1:00	D
-Rule	Haiti	1988	1997	-	Oct	lastSun	1:00s	0	S
-Rule	Haiti	2005	2006	-	Apr	Sun>=1	0:00	1:00	D
-Rule	Haiti	2005	2006	-	Oct	lastSun	0:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Port-au-Prince -4:49:20 -	LMT	1890
-			-4:49	-	PPMT	1917 Jan 24 12:00 # P-a-P MT
-			-5:00	Haiti	E%sT
-
-# Honduras
-# Shanks & Pottenger say 1921 Jan 1; go with Whitman's more precise Apr 1.
-
-# From Paul Eggert (2006-05-05):
-# worldtimezone.com reports a 2006-05-02 Spanish-language AP article
-# saying Honduras will start using DST midnight Saturday, effective 4
-# months until September.  La Tribuna reported today
-# <http://www.latribuna.hn/99299.html> that Manuel Zelaya, the president
-# of Honduras, refused to back down on this.
-
-# From Jesper Norgaard Welen (2006-08-08):
-# It seems that Honduras has returned from DST to standard time this Monday at
-# 00:00 hours (prolonging Sunday to 25 hours duration).
-# http://www.worldtimezone.com/dst_news/dst_news_honduras04.html
-
-# From Paul Eggert (2006-08-08):
-# Also see Diario El Heraldo, The country returns to standard time (2006-08-08)
-# <http://www.elheraldo.hn/nota.php?nid=54941&sec=12>.
-# It mentions executive decree 18-2006.
-
-# From Steffen Thorsen (2006-08-17):
-# Honduras will observe DST from 2007 to 2009, exact dates are not
-# published, I have located this authoritative source:
-# http://www.presidencia.gob.hn/noticia.aspx?nId=47
-
-# From Steffen Thorsen (2007-03-30):
-# http://www.laprensahn.com/pais_nota.php?id04962=7386
-# So it seems that Honduras will not enter DST this year....
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Hond	1987	1988	-	May	Sun>=1	0:00	1:00	D
-Rule	Hond	1987	1988	-	Sep	lastSun	0:00	0	S
-Rule	Hond	2006	only	-	May	Sun>=1	0:00	1:00	D
-Rule	Hond	2006	only	-	Aug	Mon>=1	0:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Tegucigalpa -5:48:52 -	LMT	1921 Apr
-			-6:00	Hond	C%sT
-#
-# Great Swan I ceded by US to Honduras in 1972
-
-# Jamaica
-
-# From Bob Devine (1988-01-28):
-# Follows US rules.
-
-# From U. S. Naval Observatory (1989-01-19):
-# JAMAICA             5 H  BEHIND UTC
-
-# From Shanks & Pottenger:
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Jamaica	-5:07:12 -	LMT	1890		# Kingston
-			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
-			-5:00	-	EST	1974 Apr 28 2:00
-			-5:00	US	E%sT	1984
-			-5:00	-	EST
-
-# Martinique
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Martinique	-4:04:20 -      LMT	1890		# Fort-de-France
-			-4:04:20 -	FFMT	1911 May     # Fort-de-France MT
-			-4:00	-	AST	1980 Apr  6
-			-4:00	1:00	ADT	1980 Sep 28
-			-4:00	-	AST
-
-# Montserrat
-# From Paul Eggert (2006-03-22):
-# In 1995 volcanic eruptions forced evacuation of Plymouth, the capital.
-# world.gazetteer.com says Cork Hill is the most populous location now.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Montserrat	-4:08:52 -	LMT	1911 Jul 1 0:01   # Cork Hill
-			-4:00	-	AST
-
-# Nicaragua
-#
-# This uses Shanks & Pottenger for times before 2005.
-#
-# From Steffen Thorsen (2005-04-12):
-# I've got reports from 8 different people that Nicaragua just started
-# DST on Sunday 2005-04-10, in order to save energy because of
-# expensive petroleum.  The exact end date for DST is not yet
-# announced, only "September" but some sites also say "mid-September".
-# Some background information is available on the President's official site:
-# http://www.presidencia.gob.ni/Presidencia/Files_index/Secretaria/Notas%20de%20Prensa/Presidente/2005/ABRIL/Gobierno-de-nicaragua-adelanta-hora-oficial-06abril.htm
-# The Decree, no 23-2005 is available here:
-# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2005/Decreto%2023-2005%20Se%20adelanta%20en%20una%20hora%20en%20todo%20el%20territorio%20nacional%20apartir%20de%20las%2024horas%20del%2009%20de%20Abril.pdf
-#
-# From Paul Eggert (2005-05-01):
-# The decree doesn't say anything about daylight saving, but for now let's
-# assume that it is daylight saving....
-#
-# From Gwillim Law (2005-04-21):
-# The Associated Press story on the time change, which can be found at
-# http://www.lapalmainteractivo.com/guias/content/gen/ap/America_Latina/AMC_GEN_NICARAGUA_HORA.html
-# and elsewhere, says (fifth paragraph, translated from Spanish):  "The last
-# time that a change of clocks was applied to save energy was in the year 2000
-# during the Arnoldo Aleman administration."...
-# The northamerica file says that Nicaragua has been on UTC-6 continuously
-# since December 1998.  I wasn't able to find any details of Nicaraguan time
-# changes in 2000.  Perhaps a note could be added to the northamerica file, to
-# the effect that we have indirect evidence that DST was observed in 2000.
-#
-# From Jesper Norgaard Welen (2005-11-02):
-# Nicaragua left DST the 2005-10-02 at 00:00 (local time).
-# http://www.presidencia.gob.ni/presidencia/files_index/secretaria/comunicados/2005/septiembre/26septiembre-cambio-hora.htm
-# (2005-09-26)
-#
-# From Jesper Norgaard Welen (2006-05-05):
-# http://www.elnuevodiario.com.ni/2006/05/01/nacionales/18410
-# (my informal translation)
-# By order of the president of the republic, Enrique Bolanos, Nicaragua
-# advanced by sixty minutes their official time, yesterday at 2 in the
-# morning, and will stay that way until 30.th. of september.
-#
-# From Jesper Norgaard Welen (2006-09-30):
-# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2006/D-063-2006P-PRN-Cambio-Hora.pdf
-# My informal translation runs:
-# The natural sun time is restored in all the national territory, in that the
-# time is returned one hour at 01:00 am of October 1 of 2006.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Nic	1979	1980	-	Mar	Sun>=16	0:00	1:00	D
-Rule	Nic	1979	1980	-	Jun	Mon>=23	0:00	0	S
-Rule	Nic	2005	only	-	Apr	10	0:00	1:00	D
-Rule	Nic	2005	only	-	Oct	Sun>=1	0:00	0	S
-Rule	Nic	2006	only	-	Apr	30	2:00	1:00	D
-Rule	Nic	2006	only	-	Oct	Sun>=1	1:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Managua	-5:45:08 -	LMT	1890
-			-5:45:12 -	MMT	1934 Jun 23 # Managua Mean Time?
-			-6:00	-	CST	1973 May
-			-5:00	-	EST	1975 Feb 16
-			-6:00	Nic	C%sT	1992 Jan  1 4:00
-			-5:00	-	EST	1992 Sep 24
-			-6:00	-	CST	1993
-			-5:00	-	EST	1997
-			-6:00	Nic	C%sT
-
-# Panama
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Panama	-5:18:08 -	LMT	1890
-			-5:19:36 -	CMT	1908 Apr 22   # Colon Mean Time
-			-5:00	-	EST
-
-# Puerto Rico
-# There are too many San Juans elsewhere, so we'll use `Puerto_Rico'.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Puerto_Rico -4:24:25 -	LMT	1899 Mar 28 12:00    # San Juan
-			-4:00	-	AST	1942 May  3
-			-4:00	US	A%sT	1946
-			-4:00	-	AST
-
-# St Kitts-Nevis
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/St_Kitts	-4:10:52 -	LMT	1912 Mar 2	# Basseterre
-			-4:00	-	AST
-
-# St Lucia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/St_Lucia	-4:04:00 -	LMT	1890		# Castries
-			-4:04:00 -	CMT	1912	    # Castries Mean Time
-			-4:00	-	AST
-
-# St Pierre and Miquelon
-# There are too many St Pierres elsewhere, so we'll use `Miquelon'.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Miquelon	-3:44:40 -	LMT	1911 May 15	# St Pierre
-			-4:00	-	AST	1980 May
-			-3:00	-	PMST	1987 # Pierre & Miquelon Time
-			-3:00	Canada	PM%sT
-
-# St Vincent and the Grenadines
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/St_Vincent	-4:04:56 -	LMT	1890		# Kingstown
-			-4:04:56 -	KMT	1912	   # Kingstown Mean Time
-			-4:00	-	AST
-
-# Turks and Caicos
-#
-# From Chris Dunn in
-# <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=415007>
-# (2007-03-15): In the Turks & Caicos Islands (America/Grand_Turk) the
-# daylight saving dates for time changes have been adjusted to match
-# the recent U.S. change of dates.
-#
-# From Brian Inglis (2007-04-28):
-# http://www.turksandcaicos.tc/calendar/index.htm [2007-04-26]
-# there is an entry for Nov 4 "Daylight Savings Time Ends 2007" and three
-# rows before that there is an out of date entry for Oct:
-# "Eastern Standard Times Begins 2007
-# Clocks are set back one hour at 2:00 a.m. local Daylight Saving Time"
-# indicating that the normal ET rules are followed.
-#
-# From Paul Eggert (2006-05-01):
-# Shanks & Pottenger say they use US DST rules, but IATA SSIM (1991/1998)
-# says they switch at midnight.  Go with Shanks & Pottenger.
-#
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	TC	1979	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	TC	1979	2006	-	Oct	lastSun	2:00	0	S
-Rule	TC	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
-Rule	TC	2007	max	-	Mar	Sun>=8	2:00	1:00	D
-Rule	TC	2007	max	-	Nov	Sun>=1	2:00	0	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Grand_Turk	-4:44:32 -	LMT	1890
-			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
-			-5:00	TC	E%sT
-
-# British Virgin Is
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Tortola	-4:18:28 -	LMT	1911 Jul    # Road Town
-			-4:00	-	AST
-
-# Virgin Is
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/St_Thomas	-4:19:44 -	LMT	1911 Jul    # Charlotte Amalie
-			-4:00	-	AST
diff --git a/tools/zoneinfo/tzdata2010k/pacificnew b/tools/zoneinfo/tzdata2010k/pacificnew
deleted file mode 100644
index e2512c1..0000000
--- a/tools/zoneinfo/tzdata2010k/pacificnew
+++ /dev/null
@@ -1,29 +0,0 @@
-# <pre>
-# @(#)pacificnew	8.2
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# From Arthur David Olson (1989-04-05):
-# On 1989-04-05, the U. S. House of Representatives passed (238-154) a bill
-# establishing "Pacific Presidential Election Time"; it was not acted on
-# by the Senate or signed into law by the President.
-# You might want to change the "PE" (Presidential Election) below to
-# "Q" (Quadrennial) to maintain three-character zone abbreviations.
-# If you're really conservative, you might want to change it to "D".
-# Avoid "L" (Leap Year), which won't be true in 2100.
-
-# If Presidential Election Time is ever established, replace "XXXX" below
-# with the year the law takes effect and uncomment the "##" lines.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-## Rule	Twilite	XXXX	max	-	Apr	Sun>=1	2:00	1:00	D
-## Rule	Twilite	XXXX	max	uspres	Oct	lastSun	2:00	1:00	PE
-## Rule	Twilite	XXXX	max	uspres	Nov	Sun>=7	2:00	0	S
-## Rule	Twilite	XXXX	max	nonpres	Oct	lastSun	2:00	0	S
-
-# Zone	NAME			GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
-## Zone	America/Los_Angeles-PET	-8:00	US		P%sT	XXXX
-##				-8:00	Twilite		P%sT
-
-# For now...
-Link	America/Los_Angeles	US/Pacific-New	##
diff --git a/tools/zoneinfo/tzdata2010k/solar87 b/tools/zoneinfo/tzdata2010k/solar87
deleted file mode 100644
index 47ee7e7..0000000
--- a/tools/zoneinfo/tzdata2010k/solar87
+++ /dev/null
@@ -1,391 +0,0 @@
-# <pre>
-# @(#)solar87	8.2
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# So much for footnotes about Saudi Arabia.
-# Apparent noon times below are for Riyadh; your mileage will vary.
-# Times were computed using formulas in the U.S. Naval Observatory's
-# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of
-# [plus or minus two] seconds during the current year."
-#
-# Rounding to the nearest five seconds results in fewer than
-# 256 different "time types"--a limit that's faced because time types are
-# stored on disk as unsigned chars.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	sol87	1987	only	-	Jan	1	12:03:20s -0:03:20 -
-Rule	sol87	1987	only	-	Jan	2	12:03:50s -0:03:50 -
-Rule	sol87	1987	only	-	Jan	3	12:04:15s -0:04:15 -
-Rule	sol87	1987	only	-	Jan	4	12:04:45s -0:04:45 -
-Rule	sol87	1987	only	-	Jan	5	12:05:10s -0:05:10 -
-Rule	sol87	1987	only	-	Jan	6	12:05:40s -0:05:40 -
-Rule	sol87	1987	only	-	Jan	7	12:06:05s -0:06:05 -
-Rule	sol87	1987	only	-	Jan	8	12:06:30s -0:06:30 -
-Rule	sol87	1987	only	-	Jan	9	12:06:55s -0:06:55 -
-Rule	sol87	1987	only	-	Jan	10	12:07:20s -0:07:20 -
-Rule	sol87	1987	only	-	Jan	11	12:07:45s -0:07:45 -
-Rule	sol87	1987	only	-	Jan	12	12:08:10s -0:08:10 -
-Rule	sol87	1987	only	-	Jan	13	12:08:30s -0:08:30 -
-Rule	sol87	1987	only	-	Jan	14	12:08:55s -0:08:55 -
-Rule	sol87	1987	only	-	Jan	15	12:09:15s -0:09:15 -
-Rule	sol87	1987	only	-	Jan	16	12:09:35s -0:09:35 -
-Rule	sol87	1987	only	-	Jan	17	12:09:55s -0:09:55 -
-Rule	sol87	1987	only	-	Jan	18	12:10:15s -0:10:15 -
-Rule	sol87	1987	only	-	Jan	19	12:10:35s -0:10:35 -
-Rule	sol87	1987	only	-	Jan	20	12:10:55s -0:10:55 -
-Rule	sol87	1987	only	-	Jan	21	12:11:10s -0:11:10 -
-Rule	sol87	1987	only	-	Jan	22	12:11:30s -0:11:30 -
-Rule	sol87	1987	only	-	Jan	23	12:11:45s -0:11:45 -
-Rule	sol87	1987	only	-	Jan	24	12:12:00s -0:12:00 -
-Rule	sol87	1987	only	-	Jan	25	12:12:15s -0:12:15 -
-Rule	sol87	1987	only	-	Jan	26	12:12:30s -0:12:30 -
-Rule	sol87	1987	only	-	Jan	27	12:12:40s -0:12:40 -
-Rule	sol87	1987	only	-	Jan	28	12:12:55s -0:12:55 -
-Rule	sol87	1987	only	-	Jan	29	12:13:05s -0:13:05 -
-Rule	sol87	1987	only	-	Jan	30	12:13:15s -0:13:15 -
-Rule	sol87	1987	only	-	Jan	31	12:13:25s -0:13:25 -
-Rule	sol87	1987	only	-	Feb	1	12:13:35s -0:13:35 -
-Rule	sol87	1987	only	-	Feb	2	12:13:40s -0:13:40 -
-Rule	sol87	1987	only	-	Feb	3	12:13:50s -0:13:50 -
-Rule	sol87	1987	only	-	Feb	4	12:13:55s -0:13:55 -
-Rule	sol87	1987	only	-	Feb	5	12:14:00s -0:14:00 -
-Rule	sol87	1987	only	-	Feb	6	12:14:05s -0:14:05 -
-Rule	sol87	1987	only	-	Feb	7	12:14:10s -0:14:10 -
-Rule	sol87	1987	only	-	Feb	8	12:14:10s -0:14:10 -
-Rule	sol87	1987	only	-	Feb	9	12:14:15s -0:14:15 -
-Rule	sol87	1987	only	-	Feb	10	12:14:15s -0:14:15 -
-Rule	sol87	1987	only	-	Feb	11	12:14:15s -0:14:15 -
-Rule	sol87	1987	only	-	Feb	12	12:14:15s -0:14:15 -
-Rule	sol87	1987	only	-	Feb	13	12:14:15s -0:14:15 -
-Rule	sol87	1987	only	-	Feb	14	12:14:15s -0:14:15 -
-Rule	sol87	1987	only	-	Feb	15	12:14:10s -0:14:10 -
-Rule	sol87	1987	only	-	Feb	16	12:14:10s -0:14:10 -
-Rule	sol87	1987	only	-	Feb	17	12:14:05s -0:14:05 -
-Rule	sol87	1987	only	-	Feb	18	12:14:00s -0:14:00 -
-Rule	sol87	1987	only	-	Feb	19	12:13:55s -0:13:55 -
-Rule	sol87	1987	only	-	Feb	20	12:13:50s -0:13:50 -
-Rule	sol87	1987	only	-	Feb	21	12:13:45s -0:13:45 -
-Rule	sol87	1987	only	-	Feb	22	12:13:35s -0:13:35 -
-Rule	sol87	1987	only	-	Feb	23	12:13:30s -0:13:30 -
-Rule	sol87	1987	only	-	Feb	24	12:13:20s -0:13:20 -
-Rule	sol87	1987	only	-	Feb	25	12:13:10s -0:13:10 -
-Rule	sol87	1987	only	-	Feb	26	12:13:00s -0:13:00 -
-Rule	sol87	1987	only	-	Feb	27	12:12:50s -0:12:50 -
-Rule	sol87	1987	only	-	Feb	28	12:12:40s -0:12:40 -
-Rule	sol87	1987	only	-	Mar	1	12:12:30s -0:12:30 -
-Rule	sol87	1987	only	-	Mar	2	12:12:20s -0:12:20 -
-Rule	sol87	1987	only	-	Mar	3	12:12:05s -0:12:05 -
-Rule	sol87	1987	only	-	Mar	4	12:11:55s -0:11:55 -
-Rule	sol87	1987	only	-	Mar	5	12:11:40s -0:11:40 -
-Rule	sol87	1987	only	-	Mar	6	12:11:25s -0:11:25 -
-Rule	sol87	1987	only	-	Mar	7	12:11:15s -0:11:15 -
-Rule	sol87	1987	only	-	Mar	8	12:11:00s -0:11:00 -
-Rule	sol87	1987	only	-	Mar	9	12:10:45s -0:10:45 -
-Rule	sol87	1987	only	-	Mar	10	12:10:30s -0:10:30 -
-Rule	sol87	1987	only	-	Mar	11	12:10:15s -0:10:15 -
-Rule	sol87	1987	only	-	Mar	12	12:09:55s -0:09:55 -
-Rule	sol87	1987	only	-	Mar	13	12:09:40s -0:09:40 -
-Rule	sol87	1987	only	-	Mar	14	12:09:25s -0:09:25 -
-Rule	sol87	1987	only	-	Mar	15	12:09:10s -0:09:10 -
-Rule	sol87	1987	only	-	Mar	16	12:08:50s -0:08:50 -
-Rule	sol87	1987	only	-	Mar	17	12:08:35s -0:08:35 -
-Rule	sol87	1987	only	-	Mar	18	12:08:15s -0:08:15 -
-Rule	sol87	1987	only	-	Mar	19	12:08:00s -0:08:00 -
-Rule	sol87	1987	only	-	Mar	20	12:07:40s -0:07:40 -
-Rule	sol87	1987	only	-	Mar	21	12:07:25s -0:07:25 -
-Rule	sol87	1987	only	-	Mar	22	12:07:05s -0:07:05 -
-Rule	sol87	1987	only	-	Mar	23	12:06:50s -0:06:50 -
-Rule	sol87	1987	only	-	Mar	24	12:06:30s -0:06:30 -
-Rule	sol87	1987	only	-	Mar	25	12:06:10s -0:06:10 -
-Rule	sol87	1987	only	-	Mar	26	12:05:55s -0:05:55 -
-Rule	sol87	1987	only	-	Mar	27	12:05:35s -0:05:35 -
-Rule	sol87	1987	only	-	Mar	28	12:05:15s -0:05:15 -
-Rule	sol87	1987	only	-	Mar	29	12:05:00s -0:05:00 -
-Rule	sol87	1987	only	-	Mar	30	12:04:40s -0:04:40 -
-Rule	sol87	1987	only	-	Mar	31	12:04:25s -0:04:25 -
-Rule	sol87	1987	only	-	Apr	1	12:04:05s -0:04:05 -
-Rule	sol87	1987	only	-	Apr	2	12:03:45s -0:03:45 -
-Rule	sol87	1987	only	-	Apr	3	12:03:30s -0:03:30 -
-Rule	sol87	1987	only	-	Apr	4	12:03:10s -0:03:10 -
-Rule	sol87	1987	only	-	Apr	5	12:02:55s -0:02:55 -
-Rule	sol87	1987	only	-	Apr	6	12:02:35s -0:02:35 -
-Rule	sol87	1987	only	-	Apr	7	12:02:20s -0:02:20 -
-Rule	sol87	1987	only	-	Apr	8	12:02:05s -0:02:05 -
-Rule	sol87	1987	only	-	Apr	9	12:01:45s -0:01:45 -
-Rule	sol87	1987	only	-	Apr	10	12:01:30s -0:01:30 -
-Rule	sol87	1987	only	-	Apr	11	12:01:15s -0:01:15 -
-Rule	sol87	1987	only	-	Apr	12	12:00:55s -0:00:55 -
-Rule	sol87	1987	only	-	Apr	13	12:00:40s -0:00:40 -
-Rule	sol87	1987	only	-	Apr	14	12:00:25s -0:00:25 -
-Rule	sol87	1987	only	-	Apr	15	12:00:10s -0:00:10 -
-Rule	sol87	1987	only	-	Apr	16	11:59:55s 0:00:05 -
-Rule	sol87	1987	only	-	Apr	17	11:59:45s 0:00:15 -
-Rule	sol87	1987	only	-	Apr	18	11:59:30s 0:00:30 -
-Rule	sol87	1987	only	-	Apr	19	11:59:15s 0:00:45 -
-Rule	sol87	1987	only	-	Apr	20	11:59:05s 0:00:55 -
-Rule	sol87	1987	only	-	Apr	21	11:58:50s 0:01:10 -
-Rule	sol87	1987	only	-	Apr	22	11:58:40s 0:01:20 -
-Rule	sol87	1987	only	-	Apr	23	11:58:25s 0:01:35 -
-Rule	sol87	1987	only	-	Apr	24	11:58:15s 0:01:45 -
-Rule	sol87	1987	only	-	Apr	25	11:58:05s 0:01:55 -
-Rule	sol87	1987	only	-	Apr	26	11:57:55s 0:02:05 -
-Rule	sol87	1987	only	-	Apr	27	11:57:45s 0:02:15 -
-Rule	sol87	1987	only	-	Apr	28	11:57:35s 0:02:25 -
-Rule	sol87	1987	only	-	Apr	29	11:57:25s 0:02:35 -
-Rule	sol87	1987	only	-	Apr	30	11:57:15s 0:02:45 -
-Rule	sol87	1987	only	-	May	1	11:57:10s 0:02:50 -
-Rule	sol87	1987	only	-	May	2	11:57:00s 0:03:00 -
-Rule	sol87	1987	only	-	May	3	11:56:55s 0:03:05 -
-Rule	sol87	1987	only	-	May	4	11:56:50s 0:03:10 -
-Rule	sol87	1987	only	-	May	5	11:56:45s 0:03:15 -
-Rule	sol87	1987	only	-	May	6	11:56:40s 0:03:20 -
-Rule	sol87	1987	only	-	May	7	11:56:35s 0:03:25 -
-Rule	sol87	1987	only	-	May	8	11:56:30s 0:03:30 -
-Rule	sol87	1987	only	-	May	9	11:56:25s 0:03:35 -
-Rule	sol87	1987	only	-	May	10	11:56:25s 0:03:35 -
-Rule	sol87	1987	only	-	May	11	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	12	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	13	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	14	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	15	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	16	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	17	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	18	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	May	19	11:56:25s 0:03:35 -
-Rule	sol87	1987	only	-	May	20	11:56:25s 0:03:35 -
-Rule	sol87	1987	only	-	May	21	11:56:30s 0:03:30 -
-Rule	sol87	1987	only	-	May	22	11:56:35s 0:03:25 -
-Rule	sol87	1987	only	-	May	23	11:56:40s 0:03:20 -
-Rule	sol87	1987	only	-	May	24	11:56:45s 0:03:15 -
-Rule	sol87	1987	only	-	May	25	11:56:50s 0:03:10 -
-Rule	sol87	1987	only	-	May	26	11:56:55s 0:03:05 -
-Rule	sol87	1987	only	-	May	27	11:57:00s 0:03:00 -
-Rule	sol87	1987	only	-	May	28	11:57:10s 0:02:50 -
-Rule	sol87	1987	only	-	May	29	11:57:15s 0:02:45 -
-Rule	sol87	1987	only	-	May	30	11:57:25s 0:02:35 -
-Rule	sol87	1987	only	-	May	31	11:57:30s 0:02:30 -
-Rule	sol87	1987	only	-	Jun	1	11:57:40s 0:02:20 -
-Rule	sol87	1987	only	-	Jun	2	11:57:50s 0:02:10 -
-Rule	sol87	1987	only	-	Jun	3	11:58:00s 0:02:00 -
-Rule	sol87	1987	only	-	Jun	4	11:58:10s 0:01:50 -
-Rule	sol87	1987	only	-	Jun	5	11:58:20s 0:01:40 -
-Rule	sol87	1987	only	-	Jun	6	11:58:30s 0:01:30 -
-Rule	sol87	1987	only	-	Jun	7	11:58:40s 0:01:20 -
-Rule	sol87	1987	only	-	Jun	8	11:58:50s 0:01:10 -
-Rule	sol87	1987	only	-	Jun	9	11:59:05s 0:00:55 -
-Rule	sol87	1987	only	-	Jun	10	11:59:15s 0:00:45 -
-Rule	sol87	1987	only	-	Jun	11	11:59:30s 0:00:30 -
-Rule	sol87	1987	only	-	Jun	12	11:59:40s 0:00:20 -
-Rule	sol87	1987	only	-	Jun	13	11:59:50s 0:00:10 -
-Rule	sol87	1987	only	-	Jun	14	12:00:05s -0:00:05 -
-Rule	sol87	1987	only	-	Jun	15	12:00:15s -0:00:15 -
-Rule	sol87	1987	only	-	Jun	16	12:00:30s -0:00:30 -
-Rule	sol87	1987	only	-	Jun	17	12:00:45s -0:00:45 -
-Rule	sol87	1987	only	-	Jun	18	12:00:55s -0:00:55 -
-Rule	sol87	1987	only	-	Jun	19	12:01:10s -0:01:10 -
-Rule	sol87	1987	only	-	Jun	20	12:01:20s -0:01:20 -
-Rule	sol87	1987	only	-	Jun	21	12:01:35s -0:01:35 -
-Rule	sol87	1987	only	-	Jun	22	12:01:50s -0:01:50 -
-Rule	sol87	1987	only	-	Jun	23	12:02:00s -0:02:00 -
-Rule	sol87	1987	only	-	Jun	24	12:02:15s -0:02:15 -
-Rule	sol87	1987	only	-	Jun	25	12:02:25s -0:02:25 -
-Rule	sol87	1987	only	-	Jun	26	12:02:40s -0:02:40 -
-Rule	sol87	1987	only	-	Jun	27	12:02:50s -0:02:50 -
-Rule	sol87	1987	only	-	Jun	28	12:03:05s -0:03:05 -
-Rule	sol87	1987	only	-	Jun	29	12:03:15s -0:03:15 -
-Rule	sol87	1987	only	-	Jun	30	12:03:30s -0:03:30 -
-Rule	sol87	1987	only	-	Jul	1	12:03:40s -0:03:40 -
-Rule	sol87	1987	only	-	Jul	2	12:03:50s -0:03:50 -
-Rule	sol87	1987	only	-	Jul	3	12:04:05s -0:04:05 -
-Rule	sol87	1987	only	-	Jul	4	12:04:15s -0:04:15 -
-Rule	sol87	1987	only	-	Jul	5	12:04:25s -0:04:25 -
-Rule	sol87	1987	only	-	Jul	6	12:04:35s -0:04:35 -
-Rule	sol87	1987	only	-	Jul	7	12:04:45s -0:04:45 -
-Rule	sol87	1987	only	-	Jul	8	12:04:55s -0:04:55 -
-Rule	sol87	1987	only	-	Jul	9	12:05:05s -0:05:05 -
-Rule	sol87	1987	only	-	Jul	10	12:05:15s -0:05:15 -
-Rule	sol87	1987	only	-	Jul	11	12:05:20s -0:05:20 -
-Rule	sol87	1987	only	-	Jul	12	12:05:30s -0:05:30 -
-Rule	sol87	1987	only	-	Jul	13	12:05:40s -0:05:40 -
-Rule	sol87	1987	only	-	Jul	14	12:05:45s -0:05:45 -
-Rule	sol87	1987	only	-	Jul	15	12:05:50s -0:05:50 -
-Rule	sol87	1987	only	-	Jul	16	12:06:00s -0:06:00 -
-Rule	sol87	1987	only	-	Jul	17	12:06:05s -0:06:05 -
-Rule	sol87	1987	only	-	Jul	18	12:06:10s -0:06:10 -
-Rule	sol87	1987	only	-	Jul	19	12:06:15s -0:06:15 -
-Rule	sol87	1987	only	-	Jul	20	12:06:15s -0:06:15 -
-Rule	sol87	1987	only	-	Jul	21	12:06:20s -0:06:20 -
-Rule	sol87	1987	only	-	Jul	22	12:06:25s -0:06:25 -
-Rule	sol87	1987	only	-	Jul	23	12:06:25s -0:06:25 -
-Rule	sol87	1987	only	-	Jul	24	12:06:25s -0:06:25 -
-Rule	sol87	1987	only	-	Jul	25	12:06:30s -0:06:30 -
-Rule	sol87	1987	only	-	Jul	26	12:06:30s -0:06:30 -
-Rule	sol87	1987	only	-	Jul	27	12:06:30s -0:06:30 -
-Rule	sol87	1987	only	-	Jul	28	12:06:30s -0:06:30 -
-Rule	sol87	1987	only	-	Jul	29	12:06:25s -0:06:25 -
-Rule	sol87	1987	only	-	Jul	30	12:06:25s -0:06:25 -
-Rule	sol87	1987	only	-	Jul	31	12:06:25s -0:06:25 -
-Rule	sol87	1987	only	-	Aug	1	12:06:20s -0:06:20 -
-Rule	sol87	1987	only	-	Aug	2	12:06:15s -0:06:15 -
-Rule	sol87	1987	only	-	Aug	3	12:06:10s -0:06:10 -
-Rule	sol87	1987	only	-	Aug	4	12:06:05s -0:06:05 -
-Rule	sol87	1987	only	-	Aug	5	12:06:00s -0:06:00 -
-Rule	sol87	1987	only	-	Aug	6	12:05:55s -0:05:55 -
-Rule	sol87	1987	only	-	Aug	7	12:05:50s -0:05:50 -
-Rule	sol87	1987	only	-	Aug	8	12:05:40s -0:05:40 -
-Rule	sol87	1987	only	-	Aug	9	12:05:35s -0:05:35 -
-Rule	sol87	1987	only	-	Aug	10	12:05:25s -0:05:25 -
-Rule	sol87	1987	only	-	Aug	11	12:05:15s -0:05:15 -
-Rule	sol87	1987	only	-	Aug	12	12:05:05s -0:05:05 -
-Rule	sol87	1987	only	-	Aug	13	12:04:55s -0:04:55 -
-Rule	sol87	1987	only	-	Aug	14	12:04:45s -0:04:45 -
-Rule	sol87	1987	only	-	Aug	15	12:04:35s -0:04:35 -
-Rule	sol87	1987	only	-	Aug	16	12:04:25s -0:04:25 -
-Rule	sol87	1987	only	-	Aug	17	12:04:10s -0:04:10 -
-Rule	sol87	1987	only	-	Aug	18	12:04:00s -0:04:00 -
-Rule	sol87	1987	only	-	Aug	19	12:03:45s -0:03:45 -
-Rule	sol87	1987	only	-	Aug	20	12:03:30s -0:03:30 -
-Rule	sol87	1987	only	-	Aug	21	12:03:15s -0:03:15 -
-Rule	sol87	1987	only	-	Aug	22	12:03:00s -0:03:00 -
-Rule	sol87	1987	only	-	Aug	23	12:02:45s -0:02:45 -
-Rule	sol87	1987	only	-	Aug	24	12:02:30s -0:02:30 -
-Rule	sol87	1987	only	-	Aug	25	12:02:15s -0:02:15 -
-Rule	sol87	1987	only	-	Aug	26	12:02:00s -0:02:00 -
-Rule	sol87	1987	only	-	Aug	27	12:01:40s -0:01:40 -
-Rule	sol87	1987	only	-	Aug	28	12:01:25s -0:01:25 -
-Rule	sol87	1987	only	-	Aug	29	12:01:05s -0:01:05 -
-Rule	sol87	1987	only	-	Aug	30	12:00:50s -0:00:50 -
-Rule	sol87	1987	only	-	Aug	31	12:00:30s -0:00:30 -
-Rule	sol87	1987	only	-	Sep	1	12:00:10s -0:00:10 -
-Rule	sol87	1987	only	-	Sep	2	11:59:50s 0:00:10 -
-Rule	sol87	1987	only	-	Sep	3	11:59:35s 0:00:25 -
-Rule	sol87	1987	only	-	Sep	4	11:59:15s 0:00:45 -
-Rule	sol87	1987	only	-	Sep	5	11:58:55s 0:01:05 -
-Rule	sol87	1987	only	-	Sep	6	11:58:35s 0:01:25 -
-Rule	sol87	1987	only	-	Sep	7	11:58:15s 0:01:45 -
-Rule	sol87	1987	only	-	Sep	8	11:57:55s 0:02:05 -
-Rule	sol87	1987	only	-	Sep	9	11:57:30s 0:02:30 -
-Rule	sol87	1987	only	-	Sep	10	11:57:10s 0:02:50 -
-Rule	sol87	1987	only	-	Sep	11	11:56:50s 0:03:10 -
-Rule	sol87	1987	only	-	Sep	12	11:56:30s 0:03:30 -
-Rule	sol87	1987	only	-	Sep	13	11:56:10s 0:03:50 -
-Rule	sol87	1987	only	-	Sep	14	11:55:45s 0:04:15 -
-Rule	sol87	1987	only	-	Sep	15	11:55:25s 0:04:35 -
-Rule	sol87	1987	only	-	Sep	16	11:55:05s 0:04:55 -
-Rule	sol87	1987	only	-	Sep	17	11:54:45s 0:05:15 -
-Rule	sol87	1987	only	-	Sep	18	11:54:20s 0:05:40 -
-Rule	sol87	1987	only	-	Sep	19	11:54:00s 0:06:00 -
-Rule	sol87	1987	only	-	Sep	20	11:53:40s 0:06:20 -
-Rule	sol87	1987	only	-	Sep	21	11:53:15s 0:06:45 -
-Rule	sol87	1987	only	-	Sep	22	11:52:55s 0:07:05 -
-Rule	sol87	1987	only	-	Sep	23	11:52:35s 0:07:25 -
-Rule	sol87	1987	only	-	Sep	24	11:52:15s 0:07:45 -
-Rule	sol87	1987	only	-	Sep	25	11:51:55s 0:08:05 -
-Rule	sol87	1987	only	-	Sep	26	11:51:35s 0:08:25 -
-Rule	sol87	1987	only	-	Sep	27	11:51:10s 0:08:50 -
-Rule	sol87	1987	only	-	Sep	28	11:50:50s 0:09:10 -
-Rule	sol87	1987	only	-	Sep	29	11:50:30s 0:09:30 -
-Rule	sol87	1987	only	-	Sep	30	11:50:10s 0:09:50 -
-Rule	sol87	1987	only	-	Oct	1	11:49:50s 0:10:10 -
-Rule	sol87	1987	only	-	Oct	2	11:49:35s 0:10:25 -
-Rule	sol87	1987	only	-	Oct	3	11:49:15s 0:10:45 -
-Rule	sol87	1987	only	-	Oct	4	11:48:55s 0:11:05 -
-Rule	sol87	1987	only	-	Oct	5	11:48:35s 0:11:25 -
-Rule	sol87	1987	only	-	Oct	6	11:48:20s 0:11:40 -
-Rule	sol87	1987	only	-	Oct	7	11:48:00s 0:12:00 -
-Rule	sol87	1987	only	-	Oct	8	11:47:45s 0:12:15 -
-Rule	sol87	1987	only	-	Oct	9	11:47:25s 0:12:35 -
-Rule	sol87	1987	only	-	Oct	10	11:47:10s 0:12:50 -
-Rule	sol87	1987	only	-	Oct	11	11:46:55s 0:13:05 -
-Rule	sol87	1987	only	-	Oct	12	11:46:40s 0:13:20 -
-Rule	sol87	1987	only	-	Oct	13	11:46:25s 0:13:35 -
-Rule	sol87	1987	only	-	Oct	14	11:46:10s 0:13:50 -
-Rule	sol87	1987	only	-	Oct	15	11:45:55s 0:14:05 -
-Rule	sol87	1987	only	-	Oct	16	11:45:45s 0:14:15 -
-Rule	sol87	1987	only	-	Oct	17	11:45:30s 0:14:30 -
-Rule	sol87	1987	only	-	Oct	18	11:45:20s 0:14:40 -
-Rule	sol87	1987	only	-	Oct	19	11:45:05s 0:14:55 -
-Rule	sol87	1987	only	-	Oct	20	11:44:55s 0:15:05 -
-Rule	sol87	1987	only	-	Oct	21	11:44:45s 0:15:15 -
-Rule	sol87	1987	only	-	Oct	22	11:44:35s 0:15:25 -
-Rule	sol87	1987	only	-	Oct	23	11:44:25s 0:15:35 -
-Rule	sol87	1987	only	-	Oct	24	11:44:20s 0:15:40 -
-Rule	sol87	1987	only	-	Oct	25	11:44:10s 0:15:50 -
-Rule	sol87	1987	only	-	Oct	26	11:44:05s 0:15:55 -
-Rule	sol87	1987	only	-	Oct	27	11:43:55s 0:16:05 -
-Rule	sol87	1987	only	-	Oct	28	11:43:50s 0:16:10 -
-Rule	sol87	1987	only	-	Oct	29	11:43:45s 0:16:15 -
-Rule	sol87	1987	only	-	Oct	30	11:43:45s 0:16:15 -
-Rule	sol87	1987	only	-	Oct	31	11:43:40s 0:16:20 -
-Rule	sol87	1987	only	-	Nov	1	11:43:40s 0:16:20 -
-Rule	sol87	1987	only	-	Nov	2	11:43:35s 0:16:25 -
-Rule	sol87	1987	only	-	Nov	3	11:43:35s 0:16:25 -
-Rule	sol87	1987	only	-	Nov	4	11:43:35s 0:16:25 -
-Rule	sol87	1987	only	-	Nov	5	11:43:35s 0:16:25 -
-Rule	sol87	1987	only	-	Nov	6	11:43:40s 0:16:20 -
-Rule	sol87	1987	only	-	Nov	7	11:43:40s 0:16:20 -
-Rule	sol87	1987	only	-	Nov	8	11:43:45s 0:16:15 -
-Rule	sol87	1987	only	-	Nov	9	11:43:50s 0:16:10 -
-Rule	sol87	1987	only	-	Nov	10	11:43:55s 0:16:05 -
-Rule	sol87	1987	only	-	Nov	11	11:44:00s 0:16:00 -
-Rule	sol87	1987	only	-	Nov	12	11:44:05s 0:15:55 -
-Rule	sol87	1987	only	-	Nov	13	11:44:15s 0:15:45 -
-Rule	sol87	1987	only	-	Nov	14	11:44:20s 0:15:40 -
-Rule	sol87	1987	only	-	Nov	15	11:44:30s 0:15:30 -
-Rule	sol87	1987	only	-	Nov	16	11:44:40s 0:15:20 -
-Rule	sol87	1987	only	-	Nov	17	11:44:50s 0:15:10 -
-Rule	sol87	1987	only	-	Nov	18	11:45:05s 0:14:55 -
-Rule	sol87	1987	only	-	Nov	19	11:45:15s 0:14:45 -
-Rule	sol87	1987	only	-	Nov	20	11:45:30s 0:14:30 -
-Rule	sol87	1987	only	-	Nov	21	11:45:45s 0:14:15 -
-Rule	sol87	1987	only	-	Nov	22	11:46:00s 0:14:00 -
-Rule	sol87	1987	only	-	Nov	23	11:46:15s 0:13:45 -
-Rule	sol87	1987	only	-	Nov	24	11:46:30s 0:13:30 -
-Rule	sol87	1987	only	-	Nov	25	11:46:50s 0:13:10 -
-Rule	sol87	1987	only	-	Nov	26	11:47:10s 0:12:50 -
-Rule	sol87	1987	only	-	Nov	27	11:47:25s 0:12:35 -
-Rule	sol87	1987	only	-	Nov	28	11:47:45s 0:12:15 -
-Rule	sol87	1987	only	-	Nov	29	11:48:05s 0:11:55 -
-Rule	sol87	1987	only	-	Nov	30	11:48:30s 0:11:30 -
-Rule	sol87	1987	only	-	Dec	1	11:48:50s 0:11:10 -
-Rule	sol87	1987	only	-	Dec	2	11:49:10s 0:10:50 -
-Rule	sol87	1987	only	-	Dec	3	11:49:35s 0:10:25 -
-Rule	sol87	1987	only	-	Dec	4	11:50:00s 0:10:00 -
-Rule	sol87	1987	only	-	Dec	5	11:50:25s 0:09:35 -
-Rule	sol87	1987	only	-	Dec	6	11:50:50s 0:09:10 -
-Rule	sol87	1987	only	-	Dec	7	11:51:15s 0:08:45 -
-Rule	sol87	1987	only	-	Dec	8	11:51:40s 0:08:20 -
-Rule	sol87	1987	only	-	Dec	9	11:52:05s 0:07:55 -
-Rule	sol87	1987	only	-	Dec	10	11:52:30s 0:07:30 -
-Rule	sol87	1987	only	-	Dec	11	11:53:00s 0:07:00 -
-Rule	sol87	1987	only	-	Dec	12	11:53:25s 0:06:35 -
-Rule	sol87	1987	only	-	Dec	13	11:53:55s 0:06:05 -
-Rule	sol87	1987	only	-	Dec	14	11:54:25s 0:05:35 -
-Rule	sol87	1987	only	-	Dec	15	11:54:50s 0:05:10 -
-Rule	sol87	1987	only	-	Dec	16	11:55:20s 0:04:40 -
-Rule	sol87	1987	only	-	Dec	17	11:55:50s 0:04:10 -
-Rule	sol87	1987	only	-	Dec	18	11:56:20s 0:03:40 -
-Rule	sol87	1987	only	-	Dec	19	11:56:50s 0:03:10 -
-Rule	sol87	1987	only	-	Dec	20	11:57:20s 0:02:40 -
-Rule	sol87	1987	only	-	Dec	21	11:57:50s 0:02:10 -
-Rule	sol87	1987	only	-	Dec	22	11:58:20s 0:01:40 -
-Rule	sol87	1987	only	-	Dec	23	11:58:50s 0:01:10 -
-Rule	sol87	1987	only	-	Dec	24	11:59:20s 0:00:40 -
-Rule	sol87	1987	only	-	Dec	25	11:59:50s 0:00:10 -
-Rule	sol87	1987	only	-	Dec	26	12:00:20s -0:00:20 -
-Rule	sol87	1987	only	-	Dec	27	12:00:45s -0:00:45 -
-Rule	sol87	1987	only	-	Dec	28	12:01:15s -0:01:15 -
-Rule	sol87	1987	only	-	Dec	29	12:01:45s -0:01:45 -
-Rule	sol87	1987	only	-	Dec	30	12:02:15s -0:02:15 -
-Rule	sol87	1987	only	-	Dec	31	12:02:45s -0:02:45 -
-
-# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
-# Before and after 1987, we'll operate on local mean solar time.
-
-# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
-Zone	Asia/Riyadh87	3:07:04	-		zzz	1987
-			3:07:04	sol87		zzz	1988
-			3:07:04	-		zzz
-# For backward compatibility...
-Link	Asia/Riyadh87	Mideast/Riyadh87
diff --git a/tools/zoneinfo/tzdata2010k/solar88 b/tools/zoneinfo/tzdata2010k/solar88
deleted file mode 100644
index 8db590e..0000000
--- a/tools/zoneinfo/tzdata2010k/solar88
+++ /dev/null
@@ -1,391 +0,0 @@
-# <pre>
-# @(#)solar88	8.2
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# Apparent noon times below are for Riyadh; they're a bit off for other places.
-# Times were computed using formulas in the U.S. Naval Observatory's
-# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of
-# [plus or minus two] seconds during the current year."
-#
-# Rounding to the nearest five seconds results in fewer than
-# 256 different "time types"--a limit that's faced because time types are
-# stored on disk as unsigned chars.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	sol88	1988	only	-	Jan	1	12:03:15s -0:03:15 -
-Rule	sol88	1988	only	-	Jan	2	12:03:40s -0:03:40 -
-Rule	sol88	1988	only	-	Jan	3	12:04:10s -0:04:10 -
-Rule	sol88	1988	only	-	Jan	4	12:04:40s -0:04:40 -
-Rule	sol88	1988	only	-	Jan	5	12:05:05s -0:05:05 -
-Rule	sol88	1988	only	-	Jan	6	12:05:30s -0:05:30 -
-Rule	sol88	1988	only	-	Jan	7	12:06:00s -0:06:00 -
-Rule	sol88	1988	only	-	Jan	8	12:06:25s -0:06:25 -
-Rule	sol88	1988	only	-	Jan	9	12:06:50s -0:06:50 -
-Rule	sol88	1988	only	-	Jan	10	12:07:15s -0:07:15 -
-Rule	sol88	1988	only	-	Jan	11	12:07:40s -0:07:40 -
-Rule	sol88	1988	only	-	Jan	12	12:08:05s -0:08:05 -
-Rule	sol88	1988	only	-	Jan	13	12:08:25s -0:08:25 -
-Rule	sol88	1988	only	-	Jan	14	12:08:50s -0:08:50 -
-Rule	sol88	1988	only	-	Jan	15	12:09:10s -0:09:10 -
-Rule	sol88	1988	only	-	Jan	16	12:09:30s -0:09:30 -
-Rule	sol88	1988	only	-	Jan	17	12:09:50s -0:09:50 -
-Rule	sol88	1988	only	-	Jan	18	12:10:10s -0:10:10 -
-Rule	sol88	1988	only	-	Jan	19	12:10:30s -0:10:30 -
-Rule	sol88	1988	only	-	Jan	20	12:10:50s -0:10:50 -
-Rule	sol88	1988	only	-	Jan	21	12:11:05s -0:11:05 -
-Rule	sol88	1988	only	-	Jan	22	12:11:25s -0:11:25 -
-Rule	sol88	1988	only	-	Jan	23	12:11:40s -0:11:40 -
-Rule	sol88	1988	only	-	Jan	24	12:11:55s -0:11:55 -
-Rule	sol88	1988	only	-	Jan	25	12:12:10s -0:12:10 -
-Rule	sol88	1988	only	-	Jan	26	12:12:25s -0:12:25 -
-Rule	sol88	1988	only	-	Jan	27	12:12:40s -0:12:40 -
-Rule	sol88	1988	only	-	Jan	28	12:12:50s -0:12:50 -
-Rule	sol88	1988	only	-	Jan	29	12:13:00s -0:13:00 -
-Rule	sol88	1988	only	-	Jan	30	12:13:10s -0:13:10 -
-Rule	sol88	1988	only	-	Jan	31	12:13:20s -0:13:20 -
-Rule	sol88	1988	only	-	Feb	1	12:13:30s -0:13:30 -
-Rule	sol88	1988	only	-	Feb	2	12:13:40s -0:13:40 -
-Rule	sol88	1988	only	-	Feb	3	12:13:45s -0:13:45 -
-Rule	sol88	1988	only	-	Feb	4	12:13:55s -0:13:55 -
-Rule	sol88	1988	only	-	Feb	5	12:14:00s -0:14:00 -
-Rule	sol88	1988	only	-	Feb	6	12:14:05s -0:14:05 -
-Rule	sol88	1988	only	-	Feb	7	12:14:10s -0:14:10 -
-Rule	sol88	1988	only	-	Feb	8	12:14:10s -0:14:10 -
-Rule	sol88	1988	only	-	Feb	9	12:14:15s -0:14:15 -
-Rule	sol88	1988	only	-	Feb	10	12:14:15s -0:14:15 -
-Rule	sol88	1988	only	-	Feb	11	12:14:15s -0:14:15 -
-Rule	sol88	1988	only	-	Feb	12	12:14:15s -0:14:15 -
-Rule	sol88	1988	only	-	Feb	13	12:14:15s -0:14:15 -
-Rule	sol88	1988	only	-	Feb	14	12:14:15s -0:14:15 -
-Rule	sol88	1988	only	-	Feb	15	12:14:10s -0:14:10 -
-Rule	sol88	1988	only	-	Feb	16	12:14:10s -0:14:10 -
-Rule	sol88	1988	only	-	Feb	17	12:14:05s -0:14:05 -
-Rule	sol88	1988	only	-	Feb	18	12:14:00s -0:14:00 -
-Rule	sol88	1988	only	-	Feb	19	12:13:55s -0:13:55 -
-Rule	sol88	1988	only	-	Feb	20	12:13:50s -0:13:50 -
-Rule	sol88	1988	only	-	Feb	21	12:13:45s -0:13:45 -
-Rule	sol88	1988	only	-	Feb	22	12:13:40s -0:13:40 -
-Rule	sol88	1988	only	-	Feb	23	12:13:30s -0:13:30 -
-Rule	sol88	1988	only	-	Feb	24	12:13:20s -0:13:20 -
-Rule	sol88	1988	only	-	Feb	25	12:13:15s -0:13:15 -
-Rule	sol88	1988	only	-	Feb	26	12:13:05s -0:13:05 -
-Rule	sol88	1988	only	-	Feb	27	12:12:55s -0:12:55 -
-Rule	sol88	1988	only	-	Feb	28	12:12:45s -0:12:45 -
-Rule	sol88	1988	only	-	Feb	29	12:12:30s -0:12:30 -
-Rule	sol88	1988	only	-	Mar	1	12:12:20s -0:12:20 -
-Rule	sol88	1988	only	-	Mar	2	12:12:10s -0:12:10 -
-Rule	sol88	1988	only	-	Mar	3	12:11:55s -0:11:55 -
-Rule	sol88	1988	only	-	Mar	4	12:11:45s -0:11:45 -
-Rule	sol88	1988	only	-	Mar	5	12:11:30s -0:11:30 -
-Rule	sol88	1988	only	-	Mar	6	12:11:15s -0:11:15 -
-Rule	sol88	1988	only	-	Mar	7	12:11:00s -0:11:00 -
-Rule	sol88	1988	only	-	Mar	8	12:10:45s -0:10:45 -
-Rule	sol88	1988	only	-	Mar	9	12:10:30s -0:10:30 -
-Rule	sol88	1988	only	-	Mar	10	12:10:15s -0:10:15 -
-Rule	sol88	1988	only	-	Mar	11	12:10:00s -0:10:00 -
-Rule	sol88	1988	only	-	Mar	12	12:09:45s -0:09:45 -
-Rule	sol88	1988	only	-	Mar	13	12:09:30s -0:09:30 -
-Rule	sol88	1988	only	-	Mar	14	12:09:10s -0:09:10 -
-Rule	sol88	1988	only	-	Mar	15	12:08:55s -0:08:55 -
-Rule	sol88	1988	only	-	Mar	16	12:08:40s -0:08:40 -
-Rule	sol88	1988	only	-	Mar	17	12:08:20s -0:08:20 -
-Rule	sol88	1988	only	-	Mar	18	12:08:05s -0:08:05 -
-Rule	sol88	1988	only	-	Mar	19	12:07:45s -0:07:45 -
-Rule	sol88	1988	only	-	Mar	20	12:07:30s -0:07:30 -
-Rule	sol88	1988	only	-	Mar	21	12:07:10s -0:07:10 -
-Rule	sol88	1988	only	-	Mar	22	12:06:50s -0:06:50 -
-Rule	sol88	1988	only	-	Mar	23	12:06:35s -0:06:35 -
-Rule	sol88	1988	only	-	Mar	24	12:06:15s -0:06:15 -
-Rule	sol88	1988	only	-	Mar	25	12:06:00s -0:06:00 -
-Rule	sol88	1988	only	-	Mar	26	12:05:40s -0:05:40 -
-Rule	sol88	1988	only	-	Mar	27	12:05:20s -0:05:20 -
-Rule	sol88	1988	only	-	Mar	28	12:05:05s -0:05:05 -
-Rule	sol88	1988	only	-	Mar	29	12:04:45s -0:04:45 -
-Rule	sol88	1988	only	-	Mar	30	12:04:25s -0:04:25 -
-Rule	sol88	1988	only	-	Mar	31	12:04:10s -0:04:10 -
-Rule	sol88	1988	only	-	Apr	1	12:03:50s -0:03:50 -
-Rule	sol88	1988	only	-	Apr	2	12:03:35s -0:03:35 -
-Rule	sol88	1988	only	-	Apr	3	12:03:15s -0:03:15 -
-Rule	sol88	1988	only	-	Apr	4	12:03:00s -0:03:00 -
-Rule	sol88	1988	only	-	Apr	5	12:02:40s -0:02:40 -
-Rule	sol88	1988	only	-	Apr	6	12:02:25s -0:02:25 -
-Rule	sol88	1988	only	-	Apr	7	12:02:05s -0:02:05 -
-Rule	sol88	1988	only	-	Apr	8	12:01:50s -0:01:50 -
-Rule	sol88	1988	only	-	Apr	9	12:01:35s -0:01:35 -
-Rule	sol88	1988	only	-	Apr	10	12:01:15s -0:01:15 -
-Rule	sol88	1988	only	-	Apr	11	12:01:00s -0:01:00 -
-Rule	sol88	1988	only	-	Apr	12	12:00:45s -0:00:45 -
-Rule	sol88	1988	only	-	Apr	13	12:00:30s -0:00:30 -
-Rule	sol88	1988	only	-	Apr	14	12:00:15s -0:00:15 -
-Rule	sol88	1988	only	-	Apr	15	12:00:00s 0:00:00 -
-Rule	sol88	1988	only	-	Apr	16	11:59:45s 0:00:15 -
-Rule	sol88	1988	only	-	Apr	17	11:59:30s 0:00:30 -
-Rule	sol88	1988	only	-	Apr	18	11:59:20s 0:00:40 -
-Rule	sol88	1988	only	-	Apr	19	11:59:05s 0:00:55 -
-Rule	sol88	1988	only	-	Apr	20	11:58:55s 0:01:05 -
-Rule	sol88	1988	only	-	Apr	21	11:58:40s 0:01:20 -
-Rule	sol88	1988	only	-	Apr	22	11:58:30s 0:01:30 -
-Rule	sol88	1988	only	-	Apr	23	11:58:15s 0:01:45 -
-Rule	sol88	1988	only	-	Apr	24	11:58:05s 0:01:55 -
-Rule	sol88	1988	only	-	Apr	25	11:57:55s 0:02:05 -
-Rule	sol88	1988	only	-	Apr	26	11:57:45s 0:02:15 -
-Rule	sol88	1988	only	-	Apr	27	11:57:35s 0:02:25 -
-Rule	sol88	1988	only	-	Apr	28	11:57:30s 0:02:30 -
-Rule	sol88	1988	only	-	Apr	29	11:57:20s 0:02:40 -
-Rule	sol88	1988	only	-	Apr	30	11:57:10s 0:02:50 -
-Rule	sol88	1988	only	-	May	1	11:57:05s 0:02:55 -
-Rule	sol88	1988	only	-	May	2	11:56:55s 0:03:05 -
-Rule	sol88	1988	only	-	May	3	11:56:50s 0:03:10 -
-Rule	sol88	1988	only	-	May	4	11:56:45s 0:03:15 -
-Rule	sol88	1988	only	-	May	5	11:56:40s 0:03:20 -
-Rule	sol88	1988	only	-	May	6	11:56:35s 0:03:25 -
-Rule	sol88	1988	only	-	May	7	11:56:30s 0:03:30 -
-Rule	sol88	1988	only	-	May	8	11:56:25s 0:03:35 -
-Rule	sol88	1988	only	-	May	9	11:56:25s 0:03:35 -
-Rule	sol88	1988	only	-	May	10	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	11	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	12	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	13	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	14	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	15	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	16	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	17	11:56:20s 0:03:40 -
-Rule	sol88	1988	only	-	May	18	11:56:25s 0:03:35 -
-Rule	sol88	1988	only	-	May	19	11:56:25s 0:03:35 -
-Rule	sol88	1988	only	-	May	20	11:56:30s 0:03:30 -
-Rule	sol88	1988	only	-	May	21	11:56:35s 0:03:25 -
-Rule	sol88	1988	only	-	May	22	11:56:40s 0:03:20 -
-Rule	sol88	1988	only	-	May	23	11:56:45s 0:03:15 -
-Rule	sol88	1988	only	-	May	24	11:56:50s 0:03:10 -
-Rule	sol88	1988	only	-	May	25	11:56:55s 0:03:05 -
-Rule	sol88	1988	only	-	May	26	11:57:00s 0:03:00 -
-Rule	sol88	1988	only	-	May	27	11:57:05s 0:02:55 -
-Rule	sol88	1988	only	-	May	28	11:57:15s 0:02:45 -
-Rule	sol88	1988	only	-	May	29	11:57:20s 0:02:40 -
-Rule	sol88	1988	only	-	May	30	11:57:30s 0:02:30 -
-Rule	sol88	1988	only	-	May	31	11:57:40s 0:02:20 -
-Rule	sol88	1988	only	-	Jun	1	11:57:50s 0:02:10 -
-Rule	sol88	1988	only	-	Jun	2	11:57:55s 0:02:05 -
-Rule	sol88	1988	only	-	Jun	3	11:58:05s 0:01:55 -
-Rule	sol88	1988	only	-	Jun	4	11:58:15s 0:01:45 -
-Rule	sol88	1988	only	-	Jun	5	11:58:30s 0:01:30 -
-Rule	sol88	1988	only	-	Jun	6	11:58:40s 0:01:20 -
-Rule	sol88	1988	only	-	Jun	7	11:58:50s 0:01:10 -
-Rule	sol88	1988	only	-	Jun	8	11:59:00s 0:01:00 -
-Rule	sol88	1988	only	-	Jun	9	11:59:15s 0:00:45 -
-Rule	sol88	1988	only	-	Jun	10	11:59:25s 0:00:35 -
-Rule	sol88	1988	only	-	Jun	11	11:59:35s 0:00:25 -
-Rule	sol88	1988	only	-	Jun	12	11:59:50s 0:00:10 -
-Rule	sol88	1988	only	-	Jun	13	12:00:00s 0:00:00 -
-Rule	sol88	1988	only	-	Jun	14	12:00:15s -0:00:15 -
-Rule	sol88	1988	only	-	Jun	15	12:00:25s -0:00:25 -
-Rule	sol88	1988	only	-	Jun	16	12:00:40s -0:00:40 -
-Rule	sol88	1988	only	-	Jun	17	12:00:55s -0:00:55 -
-Rule	sol88	1988	only	-	Jun	18	12:01:05s -0:01:05 -
-Rule	sol88	1988	only	-	Jun	19	12:01:20s -0:01:20 -
-Rule	sol88	1988	only	-	Jun	20	12:01:30s -0:01:30 -
-Rule	sol88	1988	only	-	Jun	21	12:01:45s -0:01:45 -
-Rule	sol88	1988	only	-	Jun	22	12:02:00s -0:02:00 -
-Rule	sol88	1988	only	-	Jun	23	12:02:10s -0:02:10 -
-Rule	sol88	1988	only	-	Jun	24	12:02:25s -0:02:25 -
-Rule	sol88	1988	only	-	Jun	25	12:02:35s -0:02:35 -
-Rule	sol88	1988	only	-	Jun	26	12:02:50s -0:02:50 -
-Rule	sol88	1988	only	-	Jun	27	12:03:00s -0:03:00 -
-Rule	sol88	1988	only	-	Jun	28	12:03:15s -0:03:15 -
-Rule	sol88	1988	only	-	Jun	29	12:03:25s -0:03:25 -
-Rule	sol88	1988	only	-	Jun	30	12:03:40s -0:03:40 -
-Rule	sol88	1988	only	-	Jul	1	12:03:50s -0:03:50 -
-Rule	sol88	1988	only	-	Jul	2	12:04:00s -0:04:00 -
-Rule	sol88	1988	only	-	Jul	3	12:04:10s -0:04:10 -
-Rule	sol88	1988	only	-	Jul	4	12:04:25s -0:04:25 -
-Rule	sol88	1988	only	-	Jul	5	12:04:35s -0:04:35 -
-Rule	sol88	1988	only	-	Jul	6	12:04:45s -0:04:45 -
-Rule	sol88	1988	only	-	Jul	7	12:04:55s -0:04:55 -
-Rule	sol88	1988	only	-	Jul	8	12:05:05s -0:05:05 -
-Rule	sol88	1988	only	-	Jul	9	12:05:10s -0:05:10 -
-Rule	sol88	1988	only	-	Jul	10	12:05:20s -0:05:20 -
-Rule	sol88	1988	only	-	Jul	11	12:05:30s -0:05:30 -
-Rule	sol88	1988	only	-	Jul	12	12:05:35s -0:05:35 -
-Rule	sol88	1988	only	-	Jul	13	12:05:45s -0:05:45 -
-Rule	sol88	1988	only	-	Jul	14	12:05:50s -0:05:50 -
-Rule	sol88	1988	only	-	Jul	15	12:05:55s -0:05:55 -
-Rule	sol88	1988	only	-	Jul	16	12:06:00s -0:06:00 -
-Rule	sol88	1988	only	-	Jul	17	12:06:05s -0:06:05 -
-Rule	sol88	1988	only	-	Jul	18	12:06:10s -0:06:10 -
-Rule	sol88	1988	only	-	Jul	19	12:06:15s -0:06:15 -
-Rule	sol88	1988	only	-	Jul	20	12:06:20s -0:06:20 -
-Rule	sol88	1988	only	-	Jul	21	12:06:25s -0:06:25 -
-Rule	sol88	1988	only	-	Jul	22	12:06:25s -0:06:25 -
-Rule	sol88	1988	only	-	Jul	23	12:06:25s -0:06:25 -
-Rule	sol88	1988	only	-	Jul	24	12:06:30s -0:06:30 -
-Rule	sol88	1988	only	-	Jul	25	12:06:30s -0:06:30 -
-Rule	sol88	1988	only	-	Jul	26	12:06:30s -0:06:30 -
-Rule	sol88	1988	only	-	Jul	27	12:06:30s -0:06:30 -
-Rule	sol88	1988	only	-	Jul	28	12:06:30s -0:06:30 -
-Rule	sol88	1988	only	-	Jul	29	12:06:25s -0:06:25 -
-Rule	sol88	1988	only	-	Jul	30	12:06:25s -0:06:25 -
-Rule	sol88	1988	only	-	Jul	31	12:06:20s -0:06:20 -
-Rule	sol88	1988	only	-	Aug	1	12:06:15s -0:06:15 -
-Rule	sol88	1988	only	-	Aug	2	12:06:15s -0:06:15 -
-Rule	sol88	1988	only	-	Aug	3	12:06:10s -0:06:10 -
-Rule	sol88	1988	only	-	Aug	4	12:06:05s -0:06:05 -
-Rule	sol88	1988	only	-	Aug	5	12:05:55s -0:05:55 -
-Rule	sol88	1988	only	-	Aug	6	12:05:50s -0:05:50 -
-Rule	sol88	1988	only	-	Aug	7	12:05:45s -0:05:45 -
-Rule	sol88	1988	only	-	Aug	8	12:05:35s -0:05:35 -
-Rule	sol88	1988	only	-	Aug	9	12:05:25s -0:05:25 -
-Rule	sol88	1988	only	-	Aug	10	12:05:20s -0:05:20 -
-Rule	sol88	1988	only	-	Aug	11	12:05:10s -0:05:10 -
-Rule	sol88	1988	only	-	Aug	12	12:05:00s -0:05:00 -
-Rule	sol88	1988	only	-	Aug	13	12:04:50s -0:04:50 -
-Rule	sol88	1988	only	-	Aug	14	12:04:35s -0:04:35 -
-Rule	sol88	1988	only	-	Aug	15	12:04:25s -0:04:25 -
-Rule	sol88	1988	only	-	Aug	16	12:04:15s -0:04:15 -
-Rule	sol88	1988	only	-	Aug	17	12:04:00s -0:04:00 -
-Rule	sol88	1988	only	-	Aug	18	12:03:50s -0:03:50 -
-Rule	sol88	1988	only	-	Aug	19	12:03:35s -0:03:35 -
-Rule	sol88	1988	only	-	Aug	20	12:03:20s -0:03:20 -
-Rule	sol88	1988	only	-	Aug	21	12:03:05s -0:03:05 -
-Rule	sol88	1988	only	-	Aug	22	12:02:50s -0:02:50 -
-Rule	sol88	1988	only	-	Aug	23	12:02:35s -0:02:35 -
-Rule	sol88	1988	only	-	Aug	24	12:02:20s -0:02:20 -
-Rule	sol88	1988	only	-	Aug	25	12:02:00s -0:02:00 -
-Rule	sol88	1988	only	-	Aug	26	12:01:45s -0:01:45 -
-Rule	sol88	1988	only	-	Aug	27	12:01:30s -0:01:30 -
-Rule	sol88	1988	only	-	Aug	28	12:01:10s -0:01:10 -
-Rule	sol88	1988	only	-	Aug	29	12:00:50s -0:00:50 -
-Rule	sol88	1988	only	-	Aug	30	12:00:35s -0:00:35 -
-Rule	sol88	1988	only	-	Aug	31	12:00:15s -0:00:15 -
-Rule	sol88	1988	only	-	Sep	1	11:59:55s 0:00:05 -
-Rule	sol88	1988	only	-	Sep	2	11:59:35s 0:00:25 -
-Rule	sol88	1988	only	-	Sep	3	11:59:20s 0:00:40 -
-Rule	sol88	1988	only	-	Sep	4	11:59:00s 0:01:00 -
-Rule	sol88	1988	only	-	Sep	5	11:58:40s 0:01:20 -
-Rule	sol88	1988	only	-	Sep	6	11:58:20s 0:01:40 -
-Rule	sol88	1988	only	-	Sep	7	11:58:00s 0:02:00 -
-Rule	sol88	1988	only	-	Sep	8	11:57:35s 0:02:25 -
-Rule	sol88	1988	only	-	Sep	9	11:57:15s 0:02:45 -
-Rule	sol88	1988	only	-	Sep	10	11:56:55s 0:03:05 -
-Rule	sol88	1988	only	-	Sep	11	11:56:35s 0:03:25 -
-Rule	sol88	1988	only	-	Sep	12	11:56:15s 0:03:45 -
-Rule	sol88	1988	only	-	Sep	13	11:55:50s 0:04:10 -
-Rule	sol88	1988	only	-	Sep	14	11:55:30s 0:04:30 -
-Rule	sol88	1988	only	-	Sep	15	11:55:10s 0:04:50 -
-Rule	sol88	1988	only	-	Sep	16	11:54:50s 0:05:10 -
-Rule	sol88	1988	only	-	Sep	17	11:54:25s 0:05:35 -
-Rule	sol88	1988	only	-	Sep	18	11:54:05s 0:05:55 -
-Rule	sol88	1988	only	-	Sep	19	11:53:45s 0:06:15 -
-Rule	sol88	1988	only	-	Sep	20	11:53:25s 0:06:35 -
-Rule	sol88	1988	only	-	Sep	21	11:53:00s 0:07:00 -
-Rule	sol88	1988	only	-	Sep	22	11:52:40s 0:07:20 -
-Rule	sol88	1988	only	-	Sep	23	11:52:20s 0:07:40 -
-Rule	sol88	1988	only	-	Sep	24	11:52:00s 0:08:00 -
-Rule	sol88	1988	only	-	Sep	25	11:51:40s 0:08:20 -
-Rule	sol88	1988	only	-	Sep	26	11:51:15s 0:08:45 -
-Rule	sol88	1988	only	-	Sep	27	11:50:55s 0:09:05 -
-Rule	sol88	1988	only	-	Sep	28	11:50:35s 0:09:25 -
-Rule	sol88	1988	only	-	Sep	29	11:50:15s 0:09:45 -
-Rule	sol88	1988	only	-	Sep	30	11:49:55s 0:10:05 -
-Rule	sol88	1988	only	-	Oct	1	11:49:35s 0:10:25 -
-Rule	sol88	1988	only	-	Oct	2	11:49:20s 0:10:40 -
-Rule	sol88	1988	only	-	Oct	3	11:49:00s 0:11:00 -
-Rule	sol88	1988	only	-	Oct	4	11:48:40s 0:11:20 -
-Rule	sol88	1988	only	-	Oct	5	11:48:25s 0:11:35 -
-Rule	sol88	1988	only	-	Oct	6	11:48:05s 0:11:55 -
-Rule	sol88	1988	only	-	Oct	7	11:47:50s 0:12:10 -
-Rule	sol88	1988	only	-	Oct	8	11:47:30s 0:12:30 -
-Rule	sol88	1988	only	-	Oct	9	11:47:15s 0:12:45 -
-Rule	sol88	1988	only	-	Oct	10	11:47:00s 0:13:00 -
-Rule	sol88	1988	only	-	Oct	11	11:46:45s 0:13:15 -
-Rule	sol88	1988	only	-	Oct	12	11:46:30s 0:13:30 -
-Rule	sol88	1988	only	-	Oct	13	11:46:15s 0:13:45 -
-Rule	sol88	1988	only	-	Oct	14	11:46:00s 0:14:00 -
-Rule	sol88	1988	only	-	Oct	15	11:45:45s 0:14:15 -
-Rule	sol88	1988	only	-	Oct	16	11:45:35s 0:14:25 -
-Rule	sol88	1988	only	-	Oct	17	11:45:20s 0:14:40 -
-Rule	sol88	1988	only	-	Oct	18	11:45:10s 0:14:50 -
-Rule	sol88	1988	only	-	Oct	19	11:45:00s 0:15:00 -
-Rule	sol88	1988	only	-	Oct	20	11:44:45s 0:15:15 -
-Rule	sol88	1988	only	-	Oct	21	11:44:40s 0:15:20 -
-Rule	sol88	1988	only	-	Oct	22	11:44:30s 0:15:30 -
-Rule	sol88	1988	only	-	Oct	23	11:44:20s 0:15:40 -
-Rule	sol88	1988	only	-	Oct	24	11:44:10s 0:15:50 -
-Rule	sol88	1988	only	-	Oct	25	11:44:05s 0:15:55 -
-Rule	sol88	1988	only	-	Oct	26	11:44:00s 0:16:00 -
-Rule	sol88	1988	only	-	Oct	27	11:43:55s 0:16:05 -
-Rule	sol88	1988	only	-	Oct	28	11:43:50s 0:16:10 -
-Rule	sol88	1988	only	-	Oct	29	11:43:45s 0:16:15 -
-Rule	sol88	1988	only	-	Oct	30	11:43:40s 0:16:20 -
-Rule	sol88	1988	only	-	Oct	31	11:43:40s 0:16:20 -
-Rule	sol88	1988	only	-	Nov	1	11:43:35s 0:16:25 -
-Rule	sol88	1988	only	-	Nov	2	11:43:35s 0:16:25 -
-Rule	sol88	1988	only	-	Nov	3	11:43:35s 0:16:25 -
-Rule	sol88	1988	only	-	Nov	4	11:43:35s 0:16:25 -
-Rule	sol88	1988	only	-	Nov	5	11:43:40s 0:16:20 -
-Rule	sol88	1988	only	-	Nov	6	11:43:40s 0:16:20 -
-Rule	sol88	1988	only	-	Nov	7	11:43:45s 0:16:15 -
-Rule	sol88	1988	only	-	Nov	8	11:43:45s 0:16:15 -
-Rule	sol88	1988	only	-	Nov	9	11:43:50s 0:16:10 -
-Rule	sol88	1988	only	-	Nov	10	11:44:00s 0:16:00 -
-Rule	sol88	1988	only	-	Nov	11	11:44:05s 0:15:55 -
-Rule	sol88	1988	only	-	Nov	12	11:44:10s 0:15:50 -
-Rule	sol88	1988	only	-	Nov	13	11:44:20s 0:15:40 -
-Rule	sol88	1988	only	-	Nov	14	11:44:30s 0:15:30 -
-Rule	sol88	1988	only	-	Nov	15	11:44:40s 0:15:20 -
-Rule	sol88	1988	only	-	Nov	16	11:44:50s 0:15:10 -
-Rule	sol88	1988	only	-	Nov	17	11:45:00s 0:15:00 -
-Rule	sol88	1988	only	-	Nov	18	11:45:15s 0:14:45 -
-Rule	sol88	1988	only	-	Nov	19	11:45:25s 0:14:35 -
-Rule	sol88	1988	only	-	Nov	20	11:45:40s 0:14:20 -
-Rule	sol88	1988	only	-	Nov	21	11:45:55s 0:14:05 -
-Rule	sol88	1988	only	-	Nov	22	11:46:10s 0:13:50 -
-Rule	sol88	1988	only	-	Nov	23	11:46:30s 0:13:30 -
-Rule	sol88	1988	only	-	Nov	24	11:46:45s 0:13:15 -
-Rule	sol88	1988	only	-	Nov	25	11:47:05s 0:12:55 -
-Rule	sol88	1988	only	-	Nov	26	11:47:20s 0:12:40 -
-Rule	sol88	1988	only	-	Nov	27	11:47:40s 0:12:20 -
-Rule	sol88	1988	only	-	Nov	28	11:48:00s 0:12:00 -
-Rule	sol88	1988	only	-	Nov	29	11:48:25s 0:11:35 -
-Rule	sol88	1988	only	-	Nov	30	11:48:45s 0:11:15 -
-Rule	sol88	1988	only	-	Dec	1	11:49:05s 0:10:55 -
-Rule	sol88	1988	only	-	Dec	2	11:49:30s 0:10:30 -
-Rule	sol88	1988	only	-	Dec	3	11:49:55s 0:10:05 -
-Rule	sol88	1988	only	-	Dec	4	11:50:15s 0:09:45 -
-Rule	sol88	1988	only	-	Dec	5	11:50:40s 0:09:20 -
-Rule	sol88	1988	only	-	Dec	6	11:51:05s 0:08:55 -
-Rule	sol88	1988	only	-	Dec	7	11:51:35s 0:08:25 -
-Rule	sol88	1988	only	-	Dec	8	11:52:00s 0:08:00 -
-Rule	sol88	1988	only	-	Dec	9	11:52:25s 0:07:35 -
-Rule	sol88	1988	only	-	Dec	10	11:52:55s 0:07:05 -
-Rule	sol88	1988	only	-	Dec	11	11:53:20s 0:06:40 -
-Rule	sol88	1988	only	-	Dec	12	11:53:50s 0:06:10 -
-Rule	sol88	1988	only	-	Dec	13	11:54:15s 0:05:45 -
-Rule	sol88	1988	only	-	Dec	14	11:54:45s 0:05:15 -
-Rule	sol88	1988	only	-	Dec	15	11:55:15s 0:04:45 -
-Rule	sol88	1988	only	-	Dec	16	11:55:45s 0:04:15 -
-Rule	sol88	1988	only	-	Dec	17	11:56:15s 0:03:45 -
-Rule	sol88	1988	only	-	Dec	18	11:56:40s 0:03:20 -
-Rule	sol88	1988	only	-	Dec	19	11:57:10s 0:02:50 -
-Rule	sol88	1988	only	-	Dec	20	11:57:40s 0:02:20 -
-Rule	sol88	1988	only	-	Dec	21	11:58:10s 0:01:50 -
-Rule	sol88	1988	only	-	Dec	22	11:58:40s 0:01:20 -
-Rule	sol88	1988	only	-	Dec	23	11:59:10s 0:00:50 -
-Rule	sol88	1988	only	-	Dec	24	11:59:40s 0:00:20 -
-Rule	sol88	1988	only	-	Dec	25	12:00:10s -0:00:10 -
-Rule	sol88	1988	only	-	Dec	26	12:00:40s -0:00:40 -
-Rule	sol88	1988	only	-	Dec	27	12:01:10s -0:01:10 -
-Rule	sol88	1988	only	-	Dec	28	12:01:40s -0:01:40 -
-Rule	sol88	1988	only	-	Dec	29	12:02:10s -0:02:10 -
-Rule	sol88	1988	only	-	Dec	30	12:02:35s -0:02:35 -
-Rule	sol88	1988	only	-	Dec	31	12:03:05s -0:03:05 -
-
-# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
-# Before and after 1988, we'll operate on local mean solar time.
-
-# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
-Zone	Asia/Riyadh88	3:07:04	-		zzz	1988
-			3:07:04	sol88		zzz	1989
-			3:07:04	-		zzz
-# For backward compatibility...
-Link	Asia/Riyadh88	Mideast/Riyadh88
diff --git a/tools/zoneinfo/tzdata2010k/solar89 b/tools/zoneinfo/tzdata2010k/solar89
deleted file mode 100644
index d24de4a..0000000
--- a/tools/zoneinfo/tzdata2010k/solar89
+++ /dev/null
@@ -1,396 +0,0 @@
-# <pre>
-# @(#)solar89	8.2
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# Apparent noon times below are for Riyadh; they're a bit off for other places.
-# Times were computed using a formula provided by the U. S. Naval Observatory:
-#	eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l)
-#		-12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l)
-#		+ 19.3 * cos(3 * l);
-# where l is the "mean longitude of the Sun" given by
-#	l = 279.642 degrees + 0.985647 * d
-# and d is the interval in days from January 0, 0 hours Universal Time
-# (equaling the day of the year plus the fraction of a day from zero hours).
-# The accuracy of the formula is plus or minus three seconds.
-#
-# Rounding to the nearest five seconds results in fewer than
-# 256 different "time types"--a limit that's faced because time types are
-# stored on disk as unsigned chars.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	sol89	1989	only	-	Jan	1	12:03:35s -0:03:35 -
-Rule	sol89	1989	only	-	Jan	2	12:04:05s -0:04:05 -
-Rule	sol89	1989	only	-	Jan	3	12:04:30s -0:04:30 -
-Rule	sol89	1989	only	-	Jan	4	12:05:00s -0:05:00 -
-Rule	sol89	1989	only	-	Jan	5	12:05:25s -0:05:25 -
-Rule	sol89	1989	only	-	Jan	6	12:05:50s -0:05:50 -
-Rule	sol89	1989	only	-	Jan	7	12:06:15s -0:06:15 -
-Rule	sol89	1989	only	-	Jan	8	12:06:45s -0:06:45 -
-Rule	sol89	1989	only	-	Jan	9	12:07:10s -0:07:10 -
-Rule	sol89	1989	only	-	Jan	10	12:07:35s -0:07:35 -
-Rule	sol89	1989	only	-	Jan	11	12:07:55s -0:07:55 -
-Rule	sol89	1989	only	-	Jan	12	12:08:20s -0:08:20 -
-Rule	sol89	1989	only	-	Jan	13	12:08:45s -0:08:45 -
-Rule	sol89	1989	only	-	Jan	14	12:09:05s -0:09:05 -
-Rule	sol89	1989	only	-	Jan	15	12:09:25s -0:09:25 -
-Rule	sol89	1989	only	-	Jan	16	12:09:45s -0:09:45 -
-Rule	sol89	1989	only	-	Jan	17	12:10:05s -0:10:05 -
-Rule	sol89	1989	only	-	Jan	18	12:10:25s -0:10:25 -
-Rule	sol89	1989	only	-	Jan	19	12:10:45s -0:10:45 -
-Rule	sol89	1989	only	-	Jan	20	12:11:05s -0:11:05 -
-Rule	sol89	1989	only	-	Jan	21	12:11:20s -0:11:20 -
-Rule	sol89	1989	only	-	Jan	22	12:11:35s -0:11:35 -
-Rule	sol89	1989	only	-	Jan	23	12:11:55s -0:11:55 -
-Rule	sol89	1989	only	-	Jan	24	12:12:10s -0:12:10 -
-Rule	sol89	1989	only	-	Jan	25	12:12:20s -0:12:20 -
-Rule	sol89	1989	only	-	Jan	26	12:12:35s -0:12:35 -
-Rule	sol89	1989	only	-	Jan	27	12:12:50s -0:12:50 -
-Rule	sol89	1989	only	-	Jan	28	12:13:00s -0:13:00 -
-Rule	sol89	1989	only	-	Jan	29	12:13:10s -0:13:10 -
-Rule	sol89	1989	only	-	Jan	30	12:13:20s -0:13:20 -
-Rule	sol89	1989	only	-	Jan	31	12:13:30s -0:13:30 -
-Rule	sol89	1989	only	-	Feb	1	12:13:40s -0:13:40 -
-Rule	sol89	1989	only	-	Feb	2	12:13:45s -0:13:45 -
-Rule	sol89	1989	only	-	Feb	3	12:13:55s -0:13:55 -
-Rule	sol89	1989	only	-	Feb	4	12:14:00s -0:14:00 -
-Rule	sol89	1989	only	-	Feb	5	12:14:05s -0:14:05 -
-Rule	sol89	1989	only	-	Feb	6	12:14:10s -0:14:10 -
-Rule	sol89	1989	only	-	Feb	7	12:14:10s -0:14:10 -
-Rule	sol89	1989	only	-	Feb	8	12:14:15s -0:14:15 -
-Rule	sol89	1989	only	-	Feb	9	12:14:15s -0:14:15 -
-Rule	sol89	1989	only	-	Feb	10	12:14:20s -0:14:20 -
-Rule	sol89	1989	only	-	Feb	11	12:14:20s -0:14:20 -
-Rule	sol89	1989	only	-	Feb	12	12:14:20s -0:14:20 -
-Rule	sol89	1989	only	-	Feb	13	12:14:15s -0:14:15 -
-Rule	sol89	1989	only	-	Feb	14	12:14:15s -0:14:15 -
-Rule	sol89	1989	only	-	Feb	15	12:14:10s -0:14:10 -
-Rule	sol89	1989	only	-	Feb	16	12:14:10s -0:14:10 -
-Rule	sol89	1989	only	-	Feb	17	12:14:05s -0:14:05 -
-Rule	sol89	1989	only	-	Feb	18	12:14:00s -0:14:00 -
-Rule	sol89	1989	only	-	Feb	19	12:13:55s -0:13:55 -
-Rule	sol89	1989	only	-	Feb	20	12:13:50s -0:13:50 -
-Rule	sol89	1989	only	-	Feb	21	12:13:40s -0:13:40 -
-Rule	sol89	1989	only	-	Feb	22	12:13:35s -0:13:35 -
-Rule	sol89	1989	only	-	Feb	23	12:13:25s -0:13:25 -
-Rule	sol89	1989	only	-	Feb	24	12:13:15s -0:13:15 -
-Rule	sol89	1989	only	-	Feb	25	12:13:05s -0:13:05 -
-Rule	sol89	1989	only	-	Feb	26	12:12:55s -0:12:55 -
-Rule	sol89	1989	only	-	Feb	27	12:12:45s -0:12:45 -
-Rule	sol89	1989	only	-	Feb	28	12:12:35s -0:12:35 -
-Rule	sol89	1989	only	-	Mar	1	12:12:25s -0:12:25 -
-Rule	sol89	1989	only	-	Mar	2	12:12:10s -0:12:10 -
-Rule	sol89	1989	only	-	Mar	3	12:12:00s -0:12:00 -
-Rule	sol89	1989	only	-	Mar	4	12:11:45s -0:11:45 -
-Rule	sol89	1989	only	-	Mar	5	12:11:35s -0:11:35 -
-Rule	sol89	1989	only	-	Mar	6	12:11:20s -0:11:20 -
-Rule	sol89	1989	only	-	Mar	7	12:11:05s -0:11:05 -
-Rule	sol89	1989	only	-	Mar	8	12:10:50s -0:10:50 -
-Rule	sol89	1989	only	-	Mar	9	12:10:35s -0:10:35 -
-Rule	sol89	1989	only	-	Mar	10	12:10:20s -0:10:20 -
-Rule	sol89	1989	only	-	Mar	11	12:10:05s -0:10:05 -
-Rule	sol89	1989	only	-	Mar	12	12:09:50s -0:09:50 -
-Rule	sol89	1989	only	-	Mar	13	12:09:30s -0:09:30 -
-Rule	sol89	1989	only	-	Mar	14	12:09:15s -0:09:15 -
-Rule	sol89	1989	only	-	Mar	15	12:09:00s -0:09:00 -
-Rule	sol89	1989	only	-	Mar	16	12:08:40s -0:08:40 -
-Rule	sol89	1989	only	-	Mar	17	12:08:25s -0:08:25 -
-Rule	sol89	1989	only	-	Mar	18	12:08:05s -0:08:05 -
-Rule	sol89	1989	only	-	Mar	19	12:07:50s -0:07:50 -
-Rule	sol89	1989	only	-	Mar	20	12:07:30s -0:07:30 -
-Rule	sol89	1989	only	-	Mar	21	12:07:15s -0:07:15 -
-Rule	sol89	1989	only	-	Mar	22	12:06:55s -0:06:55 -
-Rule	sol89	1989	only	-	Mar	23	12:06:35s -0:06:35 -
-Rule	sol89	1989	only	-	Mar	24	12:06:20s -0:06:20 -
-Rule	sol89	1989	only	-	Mar	25	12:06:00s -0:06:00 -
-Rule	sol89	1989	only	-	Mar	26	12:05:40s -0:05:40 -
-Rule	sol89	1989	only	-	Mar	27	12:05:25s -0:05:25 -
-Rule	sol89	1989	only	-	Mar	28	12:05:05s -0:05:05 -
-Rule	sol89	1989	only	-	Mar	29	12:04:50s -0:04:50 -
-Rule	sol89	1989	only	-	Mar	30	12:04:30s -0:04:30 -
-Rule	sol89	1989	only	-	Mar	31	12:04:10s -0:04:10 -
-Rule	sol89	1989	only	-	Apr	1	12:03:55s -0:03:55 -
-Rule	sol89	1989	only	-	Apr	2	12:03:35s -0:03:35 -
-Rule	sol89	1989	only	-	Apr	3	12:03:20s -0:03:20 -
-Rule	sol89	1989	only	-	Apr	4	12:03:00s -0:03:00 -
-Rule	sol89	1989	only	-	Apr	5	12:02:45s -0:02:45 -
-Rule	sol89	1989	only	-	Apr	6	12:02:25s -0:02:25 -
-Rule	sol89	1989	only	-	Apr	7	12:02:10s -0:02:10 -
-Rule	sol89	1989	only	-	Apr	8	12:01:50s -0:01:50 -
-Rule	sol89	1989	only	-	Apr	9	12:01:35s -0:01:35 -
-Rule	sol89	1989	only	-	Apr	10	12:01:20s -0:01:20 -
-Rule	sol89	1989	only	-	Apr	11	12:01:05s -0:01:05 -
-Rule	sol89	1989	only	-	Apr	12	12:00:50s -0:00:50 -
-Rule	sol89	1989	only	-	Apr	13	12:00:35s -0:00:35 -
-Rule	sol89	1989	only	-	Apr	14	12:00:20s -0:00:20 -
-Rule	sol89	1989	only	-	Apr	15	12:00:05s -0:00:05 -
-Rule	sol89	1989	only	-	Apr	16	11:59:50s 0:00:10 -
-Rule	sol89	1989	only	-	Apr	17	11:59:35s 0:00:25 -
-Rule	sol89	1989	only	-	Apr	18	11:59:20s 0:00:40 -
-Rule	sol89	1989	only	-	Apr	19	11:59:10s 0:00:50 -
-Rule	sol89	1989	only	-	Apr	20	11:58:55s 0:01:05 -
-Rule	sol89	1989	only	-	Apr	21	11:58:45s 0:01:15 -
-Rule	sol89	1989	only	-	Apr	22	11:58:30s 0:01:30 -
-Rule	sol89	1989	only	-	Apr	23	11:58:20s 0:01:40 -
-Rule	sol89	1989	only	-	Apr	24	11:58:10s 0:01:50 -
-Rule	sol89	1989	only	-	Apr	25	11:58:00s 0:02:00 -
-Rule	sol89	1989	only	-	Apr	26	11:57:50s 0:02:10 -
-Rule	sol89	1989	only	-	Apr	27	11:57:40s 0:02:20 -
-Rule	sol89	1989	only	-	Apr	28	11:57:30s 0:02:30 -
-Rule	sol89	1989	only	-	Apr	29	11:57:20s 0:02:40 -
-Rule	sol89	1989	only	-	Apr	30	11:57:15s 0:02:45 -
-Rule	sol89	1989	only	-	May	1	11:57:05s 0:02:55 -
-Rule	sol89	1989	only	-	May	2	11:57:00s 0:03:00 -
-Rule	sol89	1989	only	-	May	3	11:56:50s 0:03:10 -
-Rule	sol89	1989	only	-	May	4	11:56:45s 0:03:15 -
-Rule	sol89	1989	only	-	May	5	11:56:40s 0:03:20 -
-Rule	sol89	1989	only	-	May	6	11:56:35s 0:03:25 -
-Rule	sol89	1989	only	-	May	7	11:56:30s 0:03:30 -
-Rule	sol89	1989	only	-	May	8	11:56:30s 0:03:30 -
-Rule	sol89	1989	only	-	May	9	11:56:25s 0:03:35 -
-Rule	sol89	1989	only	-	May	10	11:56:25s 0:03:35 -
-Rule	sol89	1989	only	-	May	11	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	May	12	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	May	13	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	May	14	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	May	15	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	May	16	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	May	17	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	May	18	11:56:25s 0:03:35 -
-Rule	sol89	1989	only	-	May	19	11:56:25s 0:03:35 -
-Rule	sol89	1989	only	-	May	20	11:56:30s 0:03:30 -
-Rule	sol89	1989	only	-	May	21	11:56:35s 0:03:25 -
-Rule	sol89	1989	only	-	May	22	11:56:35s 0:03:25 -
-Rule	sol89	1989	only	-	May	23	11:56:40s 0:03:20 -
-Rule	sol89	1989	only	-	May	24	11:56:45s 0:03:15 -
-Rule	sol89	1989	only	-	May	25	11:56:55s 0:03:05 -
-Rule	sol89	1989	only	-	May	26	11:57:00s 0:03:00 -
-Rule	sol89	1989	only	-	May	27	11:57:05s 0:02:55 -
-Rule	sol89	1989	only	-	May	28	11:57:15s 0:02:45 -
-Rule	sol89	1989	only	-	May	29	11:57:20s 0:02:40 -
-Rule	sol89	1989	only	-	May	30	11:57:30s 0:02:30 -
-Rule	sol89	1989	only	-	May	31	11:57:35s 0:02:25 -
-Rule	sol89	1989	only	-	Jun	1	11:57:45s 0:02:15 -
-Rule	sol89	1989	only	-	Jun	2	11:57:55s 0:02:05 -
-Rule	sol89	1989	only	-	Jun	3	11:58:05s 0:01:55 -
-Rule	sol89	1989	only	-	Jun	4	11:58:15s 0:01:45 -
-Rule	sol89	1989	only	-	Jun	5	11:58:25s 0:01:35 -
-Rule	sol89	1989	only	-	Jun	6	11:58:35s 0:01:25 -
-Rule	sol89	1989	only	-	Jun	7	11:58:45s 0:01:15 -
-Rule	sol89	1989	only	-	Jun	8	11:59:00s 0:01:00 -
-Rule	sol89	1989	only	-	Jun	9	11:59:10s 0:00:50 -
-Rule	sol89	1989	only	-	Jun	10	11:59:20s 0:00:40 -
-Rule	sol89	1989	only	-	Jun	11	11:59:35s 0:00:25 -
-Rule	sol89	1989	only	-	Jun	12	11:59:45s 0:00:15 -
-Rule	sol89	1989	only	-	Jun	13	12:00:00s 0:00:00 -
-Rule	sol89	1989	only	-	Jun	14	12:00:10s -0:00:10 -
-Rule	sol89	1989	only	-	Jun	15	12:00:25s -0:00:25 -
-Rule	sol89	1989	only	-	Jun	16	12:00:35s -0:00:35 -
-Rule	sol89	1989	only	-	Jun	17	12:00:50s -0:00:50 -
-Rule	sol89	1989	only	-	Jun	18	12:01:05s -0:01:05 -
-Rule	sol89	1989	only	-	Jun	19	12:01:15s -0:01:15 -
-Rule	sol89	1989	only	-	Jun	20	12:01:30s -0:01:30 -
-Rule	sol89	1989	only	-	Jun	21	12:01:40s -0:01:40 -
-Rule	sol89	1989	only	-	Jun	22	12:01:55s -0:01:55 -
-Rule	sol89	1989	only	-	Jun	23	12:02:10s -0:02:10 -
-Rule	sol89	1989	only	-	Jun	24	12:02:20s -0:02:20 -
-Rule	sol89	1989	only	-	Jun	25	12:02:35s -0:02:35 -
-Rule	sol89	1989	only	-	Jun	26	12:02:45s -0:02:45 -
-Rule	sol89	1989	only	-	Jun	27	12:03:00s -0:03:00 -
-Rule	sol89	1989	only	-	Jun	28	12:03:10s -0:03:10 -
-Rule	sol89	1989	only	-	Jun	29	12:03:25s -0:03:25 -
-Rule	sol89	1989	only	-	Jun	30	12:03:35s -0:03:35 -
-Rule	sol89	1989	only	-	Jul	1	12:03:45s -0:03:45 -
-Rule	sol89	1989	only	-	Jul	2	12:04:00s -0:04:00 -
-Rule	sol89	1989	only	-	Jul	3	12:04:10s -0:04:10 -
-Rule	sol89	1989	only	-	Jul	4	12:04:20s -0:04:20 -
-Rule	sol89	1989	only	-	Jul	5	12:04:30s -0:04:30 -
-Rule	sol89	1989	only	-	Jul	6	12:04:40s -0:04:40 -
-Rule	sol89	1989	only	-	Jul	7	12:04:50s -0:04:50 -
-Rule	sol89	1989	only	-	Jul	8	12:05:00s -0:05:00 -
-Rule	sol89	1989	only	-	Jul	9	12:05:10s -0:05:10 -
-Rule	sol89	1989	only	-	Jul	10	12:05:20s -0:05:20 -
-Rule	sol89	1989	only	-	Jul	11	12:05:25s -0:05:25 -
-Rule	sol89	1989	only	-	Jul	12	12:05:35s -0:05:35 -
-Rule	sol89	1989	only	-	Jul	13	12:05:40s -0:05:40 -
-Rule	sol89	1989	only	-	Jul	14	12:05:50s -0:05:50 -
-Rule	sol89	1989	only	-	Jul	15	12:05:55s -0:05:55 -
-Rule	sol89	1989	only	-	Jul	16	12:06:00s -0:06:00 -
-Rule	sol89	1989	only	-	Jul	17	12:06:05s -0:06:05 -
-Rule	sol89	1989	only	-	Jul	18	12:06:10s -0:06:10 -
-Rule	sol89	1989	only	-	Jul	19	12:06:15s -0:06:15 -
-Rule	sol89	1989	only	-	Jul	20	12:06:20s -0:06:20 -
-Rule	sol89	1989	only	-	Jul	21	12:06:20s -0:06:20 -
-Rule	sol89	1989	only	-	Jul	22	12:06:25s -0:06:25 -
-Rule	sol89	1989	only	-	Jul	23	12:06:25s -0:06:25 -
-Rule	sol89	1989	only	-	Jul	24	12:06:30s -0:06:30 -
-Rule	sol89	1989	only	-	Jul	25	12:06:30s -0:06:30 -
-Rule	sol89	1989	only	-	Jul	26	12:06:30s -0:06:30 -
-Rule	sol89	1989	only	-	Jul	27	12:06:30s -0:06:30 -
-Rule	sol89	1989	only	-	Jul	28	12:06:30s -0:06:30 -
-Rule	sol89	1989	only	-	Jul	29	12:06:25s -0:06:25 -
-Rule	sol89	1989	only	-	Jul	30	12:06:25s -0:06:25 -
-Rule	sol89	1989	only	-	Jul	31	12:06:20s -0:06:20 -
-Rule	sol89	1989	only	-	Aug	1	12:06:20s -0:06:20 -
-Rule	sol89	1989	only	-	Aug	2	12:06:15s -0:06:15 -
-Rule	sol89	1989	only	-	Aug	3	12:06:10s -0:06:10 -
-Rule	sol89	1989	only	-	Aug	4	12:06:05s -0:06:05 -
-Rule	sol89	1989	only	-	Aug	5	12:06:00s -0:06:00 -
-Rule	sol89	1989	only	-	Aug	6	12:05:50s -0:05:50 -
-Rule	sol89	1989	only	-	Aug	7	12:05:45s -0:05:45 -
-Rule	sol89	1989	only	-	Aug	8	12:05:35s -0:05:35 -
-Rule	sol89	1989	only	-	Aug	9	12:05:30s -0:05:30 -
-Rule	sol89	1989	only	-	Aug	10	12:05:20s -0:05:20 -
-Rule	sol89	1989	only	-	Aug	11	12:05:10s -0:05:10 -
-Rule	sol89	1989	only	-	Aug	12	12:05:00s -0:05:00 -
-Rule	sol89	1989	only	-	Aug	13	12:04:50s -0:04:50 -
-Rule	sol89	1989	only	-	Aug	14	12:04:40s -0:04:40 -
-Rule	sol89	1989	only	-	Aug	15	12:04:30s -0:04:30 -
-Rule	sol89	1989	only	-	Aug	16	12:04:15s -0:04:15 -
-Rule	sol89	1989	only	-	Aug	17	12:04:05s -0:04:05 -
-Rule	sol89	1989	only	-	Aug	18	12:03:50s -0:03:50 -
-Rule	sol89	1989	only	-	Aug	19	12:03:35s -0:03:35 -
-Rule	sol89	1989	only	-	Aug	20	12:03:25s -0:03:25 -
-Rule	sol89	1989	only	-	Aug	21	12:03:10s -0:03:10 -
-Rule	sol89	1989	only	-	Aug	22	12:02:55s -0:02:55 -
-Rule	sol89	1989	only	-	Aug	23	12:02:40s -0:02:40 -
-Rule	sol89	1989	only	-	Aug	24	12:02:20s -0:02:20 -
-Rule	sol89	1989	only	-	Aug	25	12:02:05s -0:02:05 -
-Rule	sol89	1989	only	-	Aug	26	12:01:50s -0:01:50 -
-Rule	sol89	1989	only	-	Aug	27	12:01:30s -0:01:30 -
-Rule	sol89	1989	only	-	Aug	28	12:01:15s -0:01:15 -
-Rule	sol89	1989	only	-	Aug	29	12:00:55s -0:00:55 -
-Rule	sol89	1989	only	-	Aug	30	12:00:40s -0:00:40 -
-Rule	sol89	1989	only	-	Aug	31	12:00:20s -0:00:20 -
-Rule	sol89	1989	only	-	Sep	1	12:00:00s 0:00:00 -
-Rule	sol89	1989	only	-	Sep	2	11:59:45s 0:00:15 -
-Rule	sol89	1989	only	-	Sep	3	11:59:25s 0:00:35 -
-Rule	sol89	1989	only	-	Sep	4	11:59:05s 0:00:55 -
-Rule	sol89	1989	only	-	Sep	5	11:58:45s 0:01:15 -
-Rule	sol89	1989	only	-	Sep	6	11:58:25s 0:01:35 -
-Rule	sol89	1989	only	-	Sep	7	11:58:05s 0:01:55 -
-Rule	sol89	1989	only	-	Sep	8	11:57:45s 0:02:15 -
-Rule	sol89	1989	only	-	Sep	9	11:57:20s 0:02:40 -
-Rule	sol89	1989	only	-	Sep	10	11:57:00s 0:03:00 -
-Rule	sol89	1989	only	-	Sep	11	11:56:40s 0:03:20 -
-Rule	sol89	1989	only	-	Sep	12	11:56:20s 0:03:40 -
-Rule	sol89	1989	only	-	Sep	13	11:56:00s 0:04:00 -
-Rule	sol89	1989	only	-	Sep	14	11:55:35s 0:04:25 -
-Rule	sol89	1989	only	-	Sep	15	11:55:15s 0:04:45 -
-Rule	sol89	1989	only	-	Sep	16	11:54:55s 0:05:05 -
-Rule	sol89	1989	only	-	Sep	17	11:54:35s 0:05:25 -
-Rule	sol89	1989	only	-	Sep	18	11:54:10s 0:05:50 -
-Rule	sol89	1989	only	-	Sep	19	11:53:50s 0:06:10 -
-Rule	sol89	1989	only	-	Sep	20	11:53:30s 0:06:30 -
-Rule	sol89	1989	only	-	Sep	21	11:53:10s 0:06:50 -
-Rule	sol89	1989	only	-	Sep	22	11:52:45s 0:07:15 -
-Rule	sol89	1989	only	-	Sep	23	11:52:25s 0:07:35 -
-Rule	sol89	1989	only	-	Sep	24	11:52:05s 0:07:55 -
-Rule	sol89	1989	only	-	Sep	25	11:51:45s 0:08:15 -
-Rule	sol89	1989	only	-	Sep	26	11:51:25s 0:08:35 -
-Rule	sol89	1989	only	-	Sep	27	11:51:05s 0:08:55 -
-Rule	sol89	1989	only	-	Sep	28	11:50:40s 0:09:20 -
-Rule	sol89	1989	only	-	Sep	29	11:50:20s 0:09:40 -
-Rule	sol89	1989	only	-	Sep	30	11:50:00s 0:10:00 -
-Rule	sol89	1989	only	-	Oct	1	11:49:45s 0:10:15 -
-Rule	sol89	1989	only	-	Oct	2	11:49:25s 0:10:35 -
-Rule	sol89	1989	only	-	Oct	3	11:49:05s 0:10:55 -
-Rule	sol89	1989	only	-	Oct	4	11:48:45s 0:11:15 -
-Rule	sol89	1989	only	-	Oct	5	11:48:30s 0:11:30 -
-Rule	sol89	1989	only	-	Oct	6	11:48:10s 0:11:50 -
-Rule	sol89	1989	only	-	Oct	7	11:47:50s 0:12:10 -
-Rule	sol89	1989	only	-	Oct	8	11:47:35s 0:12:25 -
-Rule	sol89	1989	only	-	Oct	9	11:47:20s 0:12:40 -
-Rule	sol89	1989	only	-	Oct	10	11:47:00s 0:13:00 -
-Rule	sol89	1989	only	-	Oct	11	11:46:45s 0:13:15 -
-Rule	sol89	1989	only	-	Oct	12	11:46:30s 0:13:30 -
-Rule	sol89	1989	only	-	Oct	13	11:46:15s 0:13:45 -
-Rule	sol89	1989	only	-	Oct	14	11:46:00s 0:14:00 -
-Rule	sol89	1989	only	-	Oct	15	11:45:50s 0:14:10 -
-Rule	sol89	1989	only	-	Oct	16	11:45:35s 0:14:25 -
-Rule	sol89	1989	only	-	Oct	17	11:45:20s 0:14:40 -
-Rule	sol89	1989	only	-	Oct	18	11:45:10s 0:14:50 -
-Rule	sol89	1989	only	-	Oct	19	11:45:00s 0:15:00 -
-Rule	sol89	1989	only	-	Oct	20	11:44:50s 0:15:10 -
-Rule	sol89	1989	only	-	Oct	21	11:44:40s 0:15:20 -
-Rule	sol89	1989	only	-	Oct	22	11:44:30s 0:15:30 -
-Rule	sol89	1989	only	-	Oct	23	11:44:20s 0:15:40 -
-Rule	sol89	1989	only	-	Oct	24	11:44:10s 0:15:50 -
-Rule	sol89	1989	only	-	Oct	25	11:44:05s 0:15:55 -
-Rule	sol89	1989	only	-	Oct	26	11:44:00s 0:16:00 -
-Rule	sol89	1989	only	-	Oct	27	11:43:50s 0:16:10 -
-Rule	sol89	1989	only	-	Oct	28	11:43:45s 0:16:15 -
-Rule	sol89	1989	only	-	Oct	29	11:43:40s 0:16:20 -
-Rule	sol89	1989	only	-	Oct	30	11:43:40s 0:16:20 -
-Rule	sol89	1989	only	-	Oct	31	11:43:35s 0:16:25 -
-Rule	sol89	1989	only	-	Nov	1	11:43:35s 0:16:25 -
-Rule	sol89	1989	only	-	Nov	2	11:43:35s 0:16:25 -
-Rule	sol89	1989	only	-	Nov	3	11:43:30s 0:16:30 -
-Rule	sol89	1989	only	-	Nov	4	11:43:35s 0:16:25 -
-Rule	sol89	1989	only	-	Nov	5	11:43:35s 0:16:25 -
-Rule	sol89	1989	only	-	Nov	6	11:43:35s 0:16:25 -
-Rule	sol89	1989	only	-	Nov	7	11:43:40s 0:16:20 -
-Rule	sol89	1989	only	-	Nov	8	11:43:45s 0:16:15 -
-Rule	sol89	1989	only	-	Nov	9	11:43:50s 0:16:10 -
-Rule	sol89	1989	only	-	Nov	10	11:43:55s 0:16:05 -
-Rule	sol89	1989	only	-	Nov	11	11:44:00s 0:16:00 -
-Rule	sol89	1989	only	-	Nov	12	11:44:05s 0:15:55 -
-Rule	sol89	1989	only	-	Nov	13	11:44:15s 0:15:45 -
-Rule	sol89	1989	only	-	Nov	14	11:44:25s 0:15:35 -
-Rule	sol89	1989	only	-	Nov	15	11:44:35s 0:15:25 -
-Rule	sol89	1989	only	-	Nov	16	11:44:45s 0:15:15 -
-Rule	sol89	1989	only	-	Nov	17	11:44:55s 0:15:05 -
-Rule	sol89	1989	only	-	Nov	18	11:45:10s 0:14:50 -
-Rule	sol89	1989	only	-	Nov	19	11:45:20s 0:14:40 -
-Rule	sol89	1989	only	-	Nov	20	11:45:35s 0:14:25 -
-Rule	sol89	1989	only	-	Nov	21	11:45:50s 0:14:10 -
-Rule	sol89	1989	only	-	Nov	22	11:46:05s 0:13:55 -
-Rule	sol89	1989	only	-	Nov	23	11:46:25s 0:13:35 -
-Rule	sol89	1989	only	-	Nov	24	11:46:40s 0:13:20 -
-Rule	sol89	1989	only	-	Nov	25	11:47:00s 0:13:00 -
-Rule	sol89	1989	only	-	Nov	26	11:47:20s 0:12:40 -
-Rule	sol89	1989	only	-	Nov	27	11:47:35s 0:12:25 -
-Rule	sol89	1989	only	-	Nov	28	11:47:55s 0:12:05 -
-Rule	sol89	1989	only	-	Nov	29	11:48:20s 0:11:40 -
-Rule	sol89	1989	only	-	Nov	30	11:48:40s 0:11:20 -
-Rule	sol89	1989	only	-	Dec	1	11:49:00s 0:11:00 -
-Rule	sol89	1989	only	-	Dec	2	11:49:25s 0:10:35 -
-Rule	sol89	1989	only	-	Dec	3	11:49:50s 0:10:10 -
-Rule	sol89	1989	only	-	Dec	4	11:50:15s 0:09:45 -
-Rule	sol89	1989	only	-	Dec	5	11:50:35s 0:09:25 -
-Rule	sol89	1989	only	-	Dec	6	11:51:00s 0:09:00 -
-Rule	sol89	1989	only	-	Dec	7	11:51:30s 0:08:30 -
-Rule	sol89	1989	only	-	Dec	8	11:51:55s 0:08:05 -
-Rule	sol89	1989	only	-	Dec	9	11:52:20s 0:07:40 -
-Rule	sol89	1989	only	-	Dec	10	11:52:50s 0:07:10 -
-Rule	sol89	1989	only	-	Dec	11	11:53:15s 0:06:45 -
-Rule	sol89	1989	only	-	Dec	12	11:53:45s 0:06:15 -
-Rule	sol89	1989	only	-	Dec	13	11:54:10s 0:05:50 -
-Rule	sol89	1989	only	-	Dec	14	11:54:40s 0:05:20 -
-Rule	sol89	1989	only	-	Dec	15	11:55:10s 0:04:50 -
-Rule	sol89	1989	only	-	Dec	16	11:55:40s 0:04:20 -
-Rule	sol89	1989	only	-	Dec	17	11:56:05s 0:03:55 -
-Rule	sol89	1989	only	-	Dec	18	11:56:35s 0:03:25 -
-Rule	sol89	1989	only	-	Dec	19	11:57:05s 0:02:55 -
-Rule	sol89	1989	only	-	Dec	20	11:57:35s 0:02:25 -
-Rule	sol89	1989	only	-	Dec	21	11:58:05s 0:01:55 -
-Rule	sol89	1989	only	-	Dec	22	11:58:35s 0:01:25 -
-Rule	sol89	1989	only	-	Dec	23	11:59:05s 0:00:55 -
-Rule	sol89	1989	only	-	Dec	24	11:59:35s 0:00:25 -
-Rule	sol89	1989	only	-	Dec	25	12:00:05s -0:00:05 -
-Rule	sol89	1989	only	-	Dec	26	12:00:35s -0:00:35 -
-Rule	sol89	1989	only	-	Dec	27	12:01:05s -0:01:05 -
-Rule	sol89	1989	only	-	Dec	28	12:01:35s -0:01:35 -
-Rule	sol89	1989	only	-	Dec	29	12:02:00s -0:02:00 -
-Rule	sol89	1989	only	-	Dec	30	12:02:30s -0:02:30 -
-Rule	sol89	1989	only	-	Dec	31	12:03:00s -0:03:00 -
-
-# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
-# Before and after 1989, we'll operate on local mean solar time.
-
-# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
-Zone	Asia/Riyadh89	3:07:04	-		zzz	1989
-			3:07:04	sol89		zzz	1990
-			3:07:04	-		zzz
-# For backward compatibility...
-Link	Asia/Riyadh89	Mideast/Riyadh89
diff --git a/tools/zoneinfo/tzdata2010k/southamerica b/tools/zoneinfo/tzdata2010k/southamerica
deleted file mode 100644
index 7355022..0000000
--- a/tools/zoneinfo/tzdata2010k/southamerica
+++ /dev/null
@@ -1,1568 +0,0 @@
-# <pre>
-# @(#)southamerica	8.44
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
-# San Diego: ACS Publications, Inc. (2003).
-#
-# Gwillim Law writes that a good source
-# for recent time zone data is the International Air Transport
-# Association's Standard Schedules Information Manual (IATA SSIM),
-# published semiannually.  Law sent in several helpful summaries
-# of the IATA's data after 1990.
-#
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1990, and IATA SSIM is the source for entries afterwards.
-#
-# Earlier editions of these tables used the North American style (e.g. ARST and
-# ARDT for Argentine Standard and Daylight Time), but the following quote
-# suggests that it's better to use European style (e.g. ART and ARST).
-#	I suggest the use of _Summer time_ instead of the more cumbersome
-#	_daylight-saving time_.  _Summer time_ seems to be in general use
-#	in Europe and South America.
-#	-- E O Cutler, _New York Times_ (1937-02-14), quoted in
-#	H L Mencken, _The American Language: Supplement I_ (1960), p 466
-#
-# Earlier editions of these tables also used the North American style
-# for time zones in Brazil, but this was incorrect, as Brazilians say
-# "summer time".  Reinaldo Goulart, a Sao Paulo businessman active in
-# the railroad sector, writes (1999-07-06):
-#	The subject of time zones is currently a matter of discussion/debate in
-#	Brazil.  Let's say that "the Brasilia time" is considered the
-#	"official time" because Brasilia is the capital city.
-#	The other three time zones are called "Brasilia time "minus one" or
-#	"plus one" or "plus two".  As far as I know there is no such
-#	name/designation as "Eastern Time" or "Central Time".
-# So I invented the following (English-language) abbreviations for now.
-# Corrections are welcome!
-#		std	dst
-#	-2:00	FNT	FNST	Fernando de Noronha
-#	-3:00	BRT	BRST	Brasilia
-#	-4:00	AMT	AMST	Amazon
-#	-5:00	ACT	ACST	Acre
-
-###############################################################################
-
-###############################################################################
-
-# Argentina
-
-# From Bob Devine (1988-01-28):
-# Argentina: first Sunday in October to first Sunday in April since 1976.
-# Double Summer time from 1969 to 1974.  Switches at midnight.
-
-# From U. S. Naval Observatory (1988-01-199):
-# ARGENTINA           3 H BEHIND   UTC
-
-# From Hernan G. Otero (1995-06-26):
-# I am sending modifications to the Argentine time zone table...
-# AR was chosen because they are the ISO letters that represent Argentina.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Arg	1930	only	-	Dec	 1	0:00	1:00	S
-Rule	Arg	1931	only	-	Apr	 1	0:00	0	-
-Rule	Arg	1931	only	-	Oct	15	0:00	1:00	S
-Rule	Arg	1932	1940	-	Mar	 1	0:00	0	-
-Rule	Arg	1932	1939	-	Nov	 1	0:00	1:00	S
-Rule	Arg	1940	only	-	Jul	 1	0:00	1:00	S
-Rule	Arg	1941	only	-	Jun	15	0:00	0	-
-Rule	Arg	1941	only	-	Oct	15	0:00	1:00	S
-Rule	Arg	1943	only	-	Aug	 1	0:00	0	-
-Rule	Arg	1943	only	-	Oct	15	0:00	1:00	S
-Rule	Arg	1946	only	-	Mar	 1	0:00	0	-
-Rule	Arg	1946	only	-	Oct	 1	0:00	1:00	S
-Rule	Arg	1963	only	-	Oct	 1	0:00	0	-
-Rule	Arg	1963	only	-	Dec	15	0:00	1:00	S
-Rule	Arg	1964	1966	-	Mar	 1	0:00	0	-
-Rule	Arg	1964	1966	-	Oct	15	0:00	1:00	S
-Rule	Arg	1967	only	-	Apr	 2	0:00	0	-
-Rule	Arg	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
-Rule	Arg	1968	1969	-	Apr	Sun>=1	0:00	0	-
-Rule	Arg	1974	only	-	Jan	23	0:00	1:00	S
-Rule	Arg	1974	only	-	May	 1	0:00	0	-
-Rule	Arg	1988	only	-	Dec	 1	0:00	1:00	S
-#
-# From Hernan G. Otero (1995-06-26):
-# These corrections were contributed by InterSoft Argentina S.A.,
-# obtaining the data from the:
-# Talleres de Hidrografia Naval Argentina
-# (Argentine Naval Hydrography Institute)
-Rule	Arg	1989	1993	-	Mar	Sun>=1	0:00	0	-
-Rule	Arg	1989	1992	-	Oct	Sun>=15	0:00	1:00	S
-#
-# From Hernan G. Otero (1995-06-26):
-# From this moment on, the law that mandated the daylight saving
-# time corrections was derogated and no more modifications
-# to the time zones (for daylight saving) are now made.
-#
-# From Rives McDow (2000-01-10):
-# On October 3, 1999, 0:00 local, Argentina implemented daylight savings time,
-# which did not result in the switch of a time zone, as they stayed 9 hours
-# from the International Date Line.
-Rule	Arg	1999	only	-	Oct	Sun>=1	0:00	1:00	S
-# From Paul Eggert (2007-12-28):
-# DST was set to expire on March 5, not March 3, but since it was converted
-# to standard time on March 3 it's more convenient for us to pretend that
-# it ended on March 3.
-Rule	Arg	2000	only	-	Mar	3	0:00	0	-
-#
-# From Peter Gradelski via Steffen Thorsen (2000-03-01):
-# We just checked with our Sao Paulo office and they say the government of
-# Argentina decided not to become one of the countries that go on or off DST.
-# So Buenos Aires should be -3 hours from GMT at all times.
-#
-# From Fabian L. Arce Jofre (2000-04-04):
-# The law that claimed DST for Argentina was derogated by President Fernando
-# de la Rua on March 2, 2000, because it would make people spend more energy
-# in the winter time, rather than less.  The change took effect on March 3.
-#
-# From Mariano Absatz (2001-06-06):
-# one of the major newspapers here in Argentina said that the 1999
-# Timezone Law (which never was effectively applied) will (would?) be
-# in effect.... The article is at
-# http://ar.clarin.com/diario/2001-06-06/e-01701.htm
-# ... The Law itself is "Ley No 25155", sanctioned on 1999-08-25, enacted
-# 1999-09-17, and published 1999-09-21.  The official publication is at:
-# http://www.boletin.jus.gov.ar/BON/Primera/1999/09-Septiembre/21/PDF/BO21-09-99LEG.PDF
-# Regretfully, you have to subscribe (and pay) for the on-line version....
-#
-# (2001-06-12):
-# the timezone for Argentina will not change next Sunday.
-# Apparently it will do so on Sunday 24th....
-# http://ar.clarin.com/diario/2001-06-12/s-03501.htm
-#
-# (2001-06-25):
-# Last Friday (yes, the last working day before the date of the change), the
-# Senate annulled the 1999 law that introduced the changes later postponed.
-# http://www.clarin.com.ar/diario/2001-06-22/s-03601.htm
-# It remains the vote of the Deputies..., but it will be the same....
-# This kind of things had always been done this way in Argentina.
-# We are still -03:00 all year round in all of the country.
-#
-# From Steffen Thorsen (2007-12-21):
-# A user (Leonardo Chaim) reported that Argentina will adopt DST....
-# all of the country (all Zone-entries) are affected.  News reports like
-# http://www.lanacion.com.ar/opinion/nota.asp?nota_id=973037 indicate
-# that Argentina will use DST next year as well, from October to
-# March, although exact rules are not given.
-#
-# From Jesper Norgaard Welen (2007-12-26)
-# The last hurdle of Argentina DST is over, the proposal was approved in
-# the lower chamber too (Deputados) with a vote 192 for and 2 against.
-# By the way thanks to Mariano Absatz and Daniel Mario Vega for the link to
-# the original scanned proposal, where the dates and the zero hours are
-# clear and unambiguous...This is the article about final approval:
-# <a href="http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996">
-# http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996
-# </a>
-#
-# From Paul Eggert (2007-12-22):
-# For dates after mid-2008, the following rules are my guesses and
-# are quite possibly wrong, but are more likely than no DST at all.
-
-# From Alexander Krivenyshev (2008-09-05):
-# As per message from Carlos Alberto Fonseca Arauz (Nicaragua),
-# Argentina will start DST on Sunday October 19, 2008.
-#
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina03.html">
-# http://www.worldtimezone.com/dst_news/dst_news_argentina03.html
-# </a>
-# OR
-# <a href="http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)">
-# http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)
-# </a>
-
-# From Rodrigo Severo (2008-10-06):
-# Here is some info available at a Gentoo bug related to TZ on Argentina's DST:
-# ...
-# ------- Comment #1 from [jmdocile]  2008-10-06 16:28 0000 -------
-# Hi, there is a problem with timezone-data-2008e and maybe with
-# timezone-data-2008f
-# Argentinian law [Number] 25.155 is no longer valid.
-# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm">
-# http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm
-# </a>
-# The new one is law [Number] 26.350
-# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm">
-# http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm
-# </a>
-# So there is no summer time in Argentina for now.
-
-# From Mariano Absatz (2008-10-20):
-# Decree 1693/2008 applies Law 26.350 for the summer 2008/2009 establishing DST in Argentina
-# From 2008-10-19 until 2009-03-15
-# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01">
-# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01
-# </a>
-#
-# Decree 1705/2008 excepting 12 Provinces from applying DST in the summer 2008/2009:
-# Catamarca, La Rioja, Mendoza, Salta, San Juan, San Luis, La Pampa, Neuquen, Rio Negro, Chubut, Santa Cruz
-# and Tierra del Fuego
-# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01">
-# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01
-# </a>
-#
-# Press release 235 dated Saturday October 18th, from the Government of the Province of Jujuy saying
-# it will not apply DST either (even when it was not included in Decree 1705/2008)
-# <a href="http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc">
-# http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc
-# </a>
-
-# From fullinet (2009-10-18):
-# As announced in
-# <a hef="http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356">
-# http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356
-# </a>
-# (an official .gob.ar) under title: "Sin Cambio de Hora" (english: "No hour change")
-#
-# "Por el momento, el Gobierno Nacional resolvio no modificar la hora
-# oficial, decision que estaba en estudio para su implementacion el
-# domingo 18 de octubre. Desde el Ministerio de Planificacion se anuncio
-# que la Argentina hoy, en estas condiciones meteorologicas, no necesita
-# la modificacion del huso horario, ya que 2009 nos encuentra con
-# crecimiento en la produccion y distribucion energetica."
-
-Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
-Rule	Arg	2008	2009	-	Mar	Sun>=15	0:00	0	-
-Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
- 
-# From Mariano Absatz (2004-05-21):
-# Today it was officially published that the Province of Mendoza is changing
-# its timezone this winter... starting tomorrow night....
-# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040521-27158-normas.pdf
-# From Paul Eggert (2004-05-24):
-# It's Law No. 7,210.  This change is due to a public power emergency, so for
-# now we'll assume it's for this year only.
-#
-# From Paul Eggert (2006-03-22):
-# <a href="http://www.spicasc.net/horvera.html">
-# Hora de verano para la Republica Argentina (2003-06-08)
-# </a> says that standard time in Argentina from 1894-10-31
-# to 1920-05-01 was -4:16:48.25.  Go with this more-precise value
-# over Shanks & Pottenger.
-#
-# From Mariano Absatz (2004-06-05):
-# These media articles from a major newspaper mostly cover the current state:
-# http://www.lanacion.com.ar/04/05/27/de_604825.asp
-# http://www.lanacion.com.ar/04/05/28/de_605203.asp
-#
-# The following eight (8) provinces pulled clocks back to UTC-04:00 at
-# midnight Monday May 31st. (that is, the night between 05/31 and 06/01).
-# Apparently, all nine provinces would go back to UTC-03:00 at the same
-# time in October 17th.
-#
-# Catamarca, Chubut, La Rioja, San Juan, San Luis, Santa Cruz,
-# Tierra del Fuego, Tucuman.
-#
-# From Mariano Absatz (2004-06-14):
-# ... this weekend, the Province of Tucuman decided it'd go back to UTC-03:00
-# yesterday midnight (that is, at 24:00 Saturday 12th), since the people's
-# annoyance with the change is much higher than the power savings obtained....
-#
-# From Gwillim Law (2004-06-14):
-# http://www.lanacion.com.ar/04/06/10/de_609078.asp ...
-#     "The time change in Tierra del Fuego was a conflicted decision from
-#   the start.  The government had decreed that the measure would take
-#   effect on June 1, but a normative error forced the new time to begin
-#   three days earlier, from a Saturday to a Sunday....
-# Our understanding was that the change was originally scheduled to take place
-# on June 1 at 00:00 in Chubut, Santa Cruz, Tierra del Fuego (and some other
-# provinces).  Sunday was May 30, only two days earlier.  So the article
-# contains a contradiction.  I would give more credence to the Saturday/Sunday
-# date than the "three days earlier" phrase, and conclude that Tierra del
-# Fuego set its clocks back at 2004-05-30 00:00.
-#
-# From Steffen Thorsen (2004-10-05):
-# The previous law 7210 which changed the province of Mendoza's time zone
-# back in May have been modified slightly in a new law 7277, which set the
-# new end date to 2004-09-26 (original date was 2004-10-17).
-# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040924-27244-normas.pdf
-#
-# From Mariano Absatz (2004-10-05):
-# San Juan changed from UTC-03:00 to UTC-04:00 at midnight between
-# Sunday, May 30th and Monday, May 31st.  It changed back to UTC-03:00
-# at midnight between Saturday, July 24th and Sunday, July 25th....
-# http://www.sanjuan.gov.ar/prensa/archivo/000329.html
-# http://www.sanjuan.gov.ar/prensa/archivo/000426.html
-# http://www.sanjuan.gov.ar/prensa/archivo/000441.html
-
-# From Alex Krivenyshev (2008-01-17):
-# Here are articles that Argentina Province San Luis is planning to end DST
-# as earlier as upcoming Monday January 21, 2008 or February 2008:
-#
-# Provincia argentina retrasa reloj y marca diferencia con resto del pais
-# (Argentine Province delayed clock and mark difference with the rest of the
-# country)
-# <a href="http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel">
-# http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel
-# </a>
-#
-# Es inminente que en San Luis atrasen una hora los relojes
-# (It is imminent in San Luis clocks one hour delay)
-# <a href="http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414">
-# http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414
-# </a>
-#
-# <a href="http://www.worldtimezone.net/dst_news/dst_news_argentina02.html">
-# http://www.worldtimezone.net/dst_news/dst_news_argentina02.html
-# </a>
-
-# From Jesper Norgaard Welen (2008-01-18):
-# The page of the San Luis provincial government
-# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812">
-# http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812
-# </a>
-# confirms what Alex Krivenyshev has earlier sent to the tz
-# emailing list about that San Luis plans to return to standard
-# time much earlier than the rest of the country. It also
-# confirms that upon request the provinces San Juan and Mendoza 
-# refused to follow San Luis in this change. 
-# 
-# The change is supposed to take place Monday the 21.st at 0:00
-# hours. As far as I understand it if this goes ahead, we need
-# a new timezone for San Luis (although there are also documented
-# independent changes in the southamerica file of San Luis in
-# 1990 and 1991 which has not been confirmed).
-
-# From Jesper Norgaard Welen (2008-01-25):
-# Unfortunately the below page has become defunct, about the San Luis
-# time change. Perhaps because it now is part of a group of pages "Most
-# important pages of 2008."
-#
-# You can use
-# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834">
-# http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834
-# </a>
-# instead it seems. Or use "Buscador" from the main page of the San Luis
-# government, and fill in "huso" and click OK, and you will get 3 pages
-# from which the first one is identical to the above.
-
-# From Mariano Absatz (2008-01-28):
-# I can confirm that the Province of San Luis (and so far only that
-# province) decided to go back to UTC-3 effective midnight Jan 20th 2008
-# (that is, Monday 21st at 0:00 is the time the clocks were delayed back
-# 1 hour), and they intend to keep UTC-3 as their timezone all year round
-# (that is, unless they change their mind any minute now).
-#
-# So we'll have to add yet another city to 'southamerica' (I think San
-# Luis city is the mos populated city in the Province, so it'd be
-# America/Argentina/San_Luis... of course I can't remember if San Luis's
-# history of particular changes goes along with Mendoza or San Juan :-(
-# (I only remember not being able to collect hard facts about San Luis
-# back in 2004, when these provinces changed to UTC-4 for a few days, I
-# mailed them personally and never got an answer).
-
-# From Paul Eggert (2008-06-30):
-# Unless otherwise specified, data are from Shanks & Pottenger through 1992,
-# from the IATA otherwise.  As noted below, Shanks & Pottenger say that
-# America/Cordoba split into 6 subregions during 1991/1992, one of which
-# was America/San_Luis, but we haven't verified this yet so for now we'll
-# keep America/Cordoba a single region rather than splitting it into the
-# other 5 subregions.
-
-# From Mariano Absatz (2009-03-13):
-# Yesterday (with our usual 2-day notice) the Province of San Luis
-# decided that next Sunday instead of "staying" @utc-03:00 they will go
-# to utc-04:00 until the second Saturday in October...
-#
-# The press release is at
-# <a href="http://www.sanluis.gov.ar/SL/Paginas/NoticiaDetalle.asp?TemaId=1&InfoPrensaId=3102">
-# http://www.sanluis.gov.ar/SL/Paginas/NoticiaDetalle.asp?TemaId=1&InfoPrensaId=3102
-# </a>
-# (I couldn't find the decree, but
-# <a href="http://www.sanluis.gov.ar">
-# www.sanluis.gov.ar
-# <a/>
-# is the official page for the Province Government).
-#
-# There's also a note in only one of the major national papers (La Nación) at
-# <a href="http://www.lanacion.com.ar/nota.asp?nota_id=1107912">
-# http://www.lanacion.com.ar/nota.asp?nota_id=1107912
-# </a>
-# 
-# The press release says:
-#  (...) anunció que el próximo domingo a las 00:00 los puntanos deberán
-# atrasar una hora sus relojes.
-#
-# A partir de entonces, San Luis establecerá el huso horario propio de
-# la Provincia. De esta manera, durante el periodo del calendario anual
-# 2009, el cambio horario quedará comprendido entre las 00:00 del tercer
-# domingo de marzo y las 24:00 del segundo sábado de octubre.
-# Quick&dirty translation
-# (...) announced that next Sunday, at 00:00, Puntanos (the San Luis
-# inhabitants) will have to turn back one hour their clocks
-#
-# Since then, San Luis will establish its own Province timezone. Thus,
-# during 2009, this timezone change will run from 00:00 the third Sunday
-# in March until 24:00 of the second Saturday in October.
-
-# From Mariano Absatz (2009-10-16):
-# ...the Province of San Luis is a case in itself.
-#
-# The Law at
-# <a href="http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276>"
-# http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276
-# </a>
-# is ambiguous because establishes a calendar from the 2nd Sunday in
-# October at 0:00 thru the 2nd Saturday in March at 24:00 and the
-# complement of that starting on the 2nd Sunday of March at 0:00 and
-# ending on the 2nd Saturday of March at 24:00.
-#
-# This clearly breaks every time the 1st of March or October is a Sunday.
-#
-# IMHO, the "spirit of the Law" is to make the changes at 0:00 on the 2nd
-# Sunday of October and March.
-#
-# The problem is that the changes in the rest of the Provinces that did
-# change in 2007/2008, were made according to the Federal Law and Decrees
-# that did so on the 3rd Sunday of October and March.
-#
-# In fact, San Luis actually switched from UTC-4 to UTC-3 last Sunday
-# (October 11th) at 0:00.
-#
-# So I guess a new set of rules, besides "Arg", must be made and the last
-# America/Argentina/San_Luis entries should change to use these...
-#
-# I'm enclosing a patch that does what I say... regretfully, the San Luis
-# timezone must be called "WART/WARST" even when most of the time (like,
-# right now) WARST == ART... that is, since last Sunday, all the country
-# is using UTC-3, but in my patch, San Luis calls it "WARST" and the rest
-# of the country calls it "ART".
-# ...
-
-# From Alexander Krivenyshev (2010-04-09):
-# According to news reports from El Diario de la Republica Province San
-# Luis, Argentina (standard time UTC-04) will keep Daylight Saving Time
-# after April 11, 2010--will continue to have same time as rest of
-# Argentina (UTC-3) (no DST).
-#
-# Confirmaron la pr&oacute;rroga del huso horario de verano (Spanish)
-# <a href="http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9">
-# http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9
-# </a>
-# or (some English translation):
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina08.html">
-# http://www.worldtimezone.com/dst_news/dst_news_argentina08.html
-# </a>
-
-# From Mariano Absatz (2010-04-12):
-# yes...I can confirm this...and given that San Luis keeps calling
-# UTC-03:00 "summer time", we should't just let San Luis go back to "Arg"
-# rules...San Luis is still using "Western ARgentina Time" and it got
-# stuck on Summer daylight savings time even though the summer is over.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-#
-# Buenos Aires (BA), Capital Federal (CF),
-Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
-			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	Arg	AR%sT
-#
-# Cordoba (CB), Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN),
-# Chaco (CC), Formosa (FM), Santiago del Estero (SE)
-#
-# Shanks & Pottenger also make the following claims, which we haven't verified:
-# - Formosa switched to -3:00 on 1991-01-07.
-# - Misiones switched to -3:00 on 1990-12-29.
-# - Chaco switched to -3:00 on 1991-01-04.
-# - Santiago del Estero switched to -4:00 on 1991-04-01,
-#   then to -3:00 on 1991-04-26.
-#
-Zone America/Argentina/Cordoba -4:16:48 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1991 Mar  3
-			-4:00	-	WART	1991 Oct 20
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	Arg	AR%sT
-#
-# Salta (SA), La Pampa (LP), Neuquen (NQ), Rio Negro (RN)
-Zone America/Argentina/Salta -4:21:40 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1991 Mar  3
-			-4:00	-	WART	1991 Oct 20
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-#
-# Tucuman (TM)
-Zone America/Argentina/Tucuman -4:20:52 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1991 Mar  3
-			-4:00	-	WART	1991 Oct 20
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	-	ART	2004 Jun  1
-			-4:00	-	WART	2004 Jun 13
-			-3:00	Arg	AR%sT
-#
-# La Rioja (LR)
-Zone America/Argentina/La_Rioja -4:27:24 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1991 Mar  1
-			-4:00	-	WART	1991 May  7
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	-	ART	2004 Jun  1
-			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-#
-# San Juan (SJ)
-Zone America/Argentina/San_Juan -4:34:04 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1991 Mar  1
-			-4:00	-	WART	1991 May  7
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	-	ART	2004 May 31
-			-4:00	-	WART	2004 Jul 25
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-#
-# Jujuy (JY)
-Zone America/Argentina/Jujuy -4:21:12 -	LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1990 Mar  4
-			-4:00	-	WART	1990 Oct 28
-			-4:00	1:00	WARST	1991 Mar 17
-			-4:00	-	WART	1991 Oct  6
-			-3:00	1:00	ARST	1992
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-#
-# Catamarca (CT), Chubut (CH)
-Zone America/Argentina/Catamarca -4:23:08 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1991 Mar  3
-			-4:00	-	WART	1991 Oct 20
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	-	ART	2004 Jun  1
-			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-#
-# Mendoza (MZ)
-Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1990 Mar  4
-			-4:00	-	WART	1990 Oct 15
-			-4:00	1:00	WARST	1991 Mar  1
-			-4:00	-	WART	1991 Oct 15
-			-4:00	1:00	WARST	1992 Mar  1
-			-4:00	-	WART	1992 Oct 18
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	-	ART	2004 May 23
-			-4:00	-	WART	2004 Sep 26
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-#
-# San Luis (SL)
-
-Rule	SanLuis	2008	2009	-	Mar	Sun>=8	0:00	0	-
-Rule	SanLuis	2007	2009	-	Oct	Sun>=8	0:00	1:00	S
-
-Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
-			-4:16:48 -	CMT	1920 May
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1990
-			-3:00	1:00	ARST	1990 Mar 14
-			-4:00	-	WART	1990 Oct 15
-			-4:00	1:00	WARST	1991 Mar  1
-			-4:00	-	WART	1991 Jun  1
-			-3:00	-	ART	1999 Oct  3
-			-4:00	1:00	WARST	2000 Mar  3
-			-3:00	-	ART	2004 May 31
-			-4:00	-	WART	2004 Jul 25
-			-3:00	Arg	AR%sT	2008 Jan 21
-			-4:00	SanLuis	WAR%sT
-#
-# Santa Cruz (SC)
-Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
-			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	-	ART	2004 Jun  1
-			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-#
-# Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
-Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31
-			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
-			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct  5
-			-3:00	Arg	AR%sT	1999 Oct  3
-			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	-	ART	2004 May 30
-			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT	2008 Oct 18
-			-3:00	-	ART
-
-# Aruba
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Aruba	-4:40:24 -	LMT	1912 Feb 12	# Oranjestad
-			-4:30	-	ANT	1965 # Netherlands Antilles Time
-			-4:00	-	AST
-
-# Bolivia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/La_Paz	-4:32:36 -	LMT	1890
-			-4:32:36 -	CMT	1931 Oct 15 # Calamarca MT
-			-4:32:36 1:00	BOST	1932 Mar 21 # Bolivia ST
-			-4:00	-	BOT	# Bolivia Time
-
-# Brazil
-
-# From Paul Eggert (1993-11-18):
-# The mayor of Rio recently attempted to change the time zone rules
-# just in his city, in order to leave more summer time for the tourist trade.
-# The rule change lasted only part of the day;
-# the federal government refused to follow the city's rules, and business
-# was in a chaos, so the mayor backed down that afternoon.
-
-# From IATA SSIM (1996-02):
-# _Only_ the following states in BR1 observe DST: Rio Grande do Sul (RS),
-# Santa Catarina (SC), Parana (PR), Sao Paulo (SP), Rio de Janeiro (RJ),
-# Espirito Santo (ES), Minas Gerais (MG), Bahia (BA), Goias (GO),
-# Distrito Federal (DF), Tocantins (TO), Sergipe [SE] and Alagoas [AL].
-# [The last three states are new to this issue of the IATA SSIM.]
-
-# From Gwillim Law (1996-10-07):
-# Geography, history (Tocantins was part of Goias until 1989), and other
-# sources of time zone information lead me to believe that AL, SE, and TO were
-# always in BR1, and so the only change was whether or not they observed DST....
-# The earliest issue of the SSIM I have is 2/91.  Each issue from then until
-# 9/95 says that DST is observed only in the ten states I quoted from 9/95,
-# along with Mato Grosso (MT) and Mato Grosso do Sul (MS), which are in BR2
-# (UTC-4)....  The other two time zones given for Brazil are BR3, which is
-# UTC-5, no DST, and applies only in the state of Acre (AC); and BR4, which is
-# UTC-2, and applies to Fernando de Noronha (formerly FN, but I believe it's
-# become part of the state of Pernambuco).  The boundary between BR1 and BR2
-# has never been clearly stated.  They've simply been called East and West.
-# However, some conclusions can be drawn from another IATA manual: the Airline
-# Coding Directory, which lists close to 400 airports in Brazil.  For each
-# airport it gives a time zone which is coded to the SSIM.  From that
-# information, I'm led to conclude that the states of Amapa (AP), Ceara (CE),
-# Maranhao (MA), Paraiba (PR), Pernambuco (PE), Piaui (PI), and Rio Grande do
-# Norte (RN), and the eastern part of Para (PA) are all in BR1 without DST.
-
-# From Marcos Tadeu (1998-09-27):
-# <a href="http://pcdsh01.on.br/verao1.html">
-# Brazilian official page
-# </a>
-
-# From Jesper Norgaard (2000-11-03):
-# [For an official list of which regions in Brazil use which time zones, see:]
-# http://pcdsh01.on.br/Fusbr.htm
-# http://pcdsh01.on.br/Fusbrhv.htm
-
-# From Celso Doria via David Madeo (2002-10-09):
-# The reason for the delay this year has to do with elections in Brazil.
-#
-# Unlike in the United States, elections in Brazil are 100% computerized and
-# the results are known almost immediately.  Yesterday, it was the first
-# round of the elections when 115 million Brazilians voted for President,
-# Governor, Senators, Federal Deputies, and State Deputies.  Nobody is
-# counting (or re-counting) votes anymore and we know there will be a second
-# round for the Presidency and also for some Governors.  The 2nd round will
-# take place on October 27th.
-#
-# The reason why the DST will only begin November 3rd is that the thousands
-# of electoral machines used cannot have their time changed, and since the
-# Constitution says the elections must begin at 8:00 AM and end at 5:00 PM,
-# the Government decided to postpone DST, instead of changing the Constitution
-# (maybe, for the next elections, it will be possible to change the clock)...
-
-# From Rodrigo Severo (2004-10-04):
-# It's just the biannual change made necessary by the much hyped, supposedly
-# modern Brazilian eletronic voting machines which, apparently, can't deal
-# with a time change between the first and the second rounds of the elections.
-
-# From Steffen Thorsen (2007-09-20):
-# Brazil will start DST on 2007-10-14 00:00 and end on 2008-02-17 00:00:
-# http://www.mme.gov.br/site/news/detail.do;jsessionid=BBA06811AFCAAC28F0285210913513DA?newsId=13975
-
-# From Paul Schulze (2008-06-24):
-# ...by law number 11.662 of April 24, 2008 (published in the "Diario
-# Oficial da Uniao"...) in Brazil there are changes in the timezones,
-# effective today (00:00am at June 24, 2008) as follows:
-#
-# a) The timezone UTC+5 is e[x]tinguished, with all the Acre state and the
-# part of the Amazonas state that had this timezone now being put to the
-# timezone UTC+4
-# b) The whole Para state now is put at timezone UTC+3, instead of just
-# part of it, as was before.
-#
-# This change follows a proposal of senator Tiao Viana of Acre state, that
-# proposed it due to concerns about open television channels displaying
-# programs inappropriate to youths in the states that had the timezone
-# UTC+5 too early in the night. In the occasion, some more corrections
-# were proposed, trying to unify the timezones of any given state. This
-# change modifies timezone rules defined in decree 2.784 of 18 June,
-# 1913.
-
-# From Rodrigo Severo (2008-06-24):
-# Just correcting the URL:
-# <a href="https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=do&secao=1&pagina=1&data=25/04/2008">
-# https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=do&secao=1&pagina=1&data=25/04/2008
-# </a>
-#
-# As a result of the above Decree I believe the America/Rio_Branco
-# timezone shall be modified from UTC-5 to UTC-4 and a new timezone shall
-# be created to represent the the west side of the Para State. I
-# suggest this new timezone be called Santarem as the most
-# important/populated city in the affected area.
-#
-# This new timezone would be the same as the Rio_Branco timezone up to
-# the 2008/06/24 change which would be to UTC-3 instead of UTC-4.
-
-# From Alex Krivenyshev (2008-06-24):
-# This is a quick reference page for New and Old Brazil Time Zones map.
-# <a href="http://www.worldtimezone.com/brazil-time-new-old.php">
-# http://www.worldtimezone.com/brazil-time-new-old.php
-# </a>
-#
-# - 4 time zones replaced by 3 time zones-eliminating time zone UTC- 05
-# (state Acre and the part of the Amazonas will be UTC/GMT- 04) - western
-# part of Par state is moving to one timezone UTC- 03 (from UTC -04).
-
-# From Paul Eggert (2002-10-10):
-# The official decrees referenced below are mostly taken from
-# <a href="http://pcdsh01.on.br/DecHV.html">
-# Decretos sobre o Horario de Verao no Brasil
-# </a>.
-
-# From Steffen Thorsen (2008-08-29):
-# As announced by the government and many newspapers in Brazil late
-# yesterday, Brazil will start DST on 2008-10-19 (need to change rule) and
-# it will end on 2009-02-15 (current rule for Brazil is fine). Based on
-# past years experience with the elections, there was a good chance that
-# the start was postponed to November, but it did not happen this year.
-#
-# It has not yet been posted to http://pcdsh01.on.br/DecHV.html
-#
-# An official page about it:
-# <a href="http://www.mme.gov.br/site/news/detail.do?newsId=16722">
-# http://www.mme.gov.br/site/news/detail.do?newsId=16722
-# </a>
-# Note that this link does not always work directly, but must be accessed
-# by going to
-# <a href="http://www.mme.gov.br/first">
-# http://www.mme.gov.br/first
-# </a>
-#
-# One example link that works directly:
-# <a href="http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54">
-# http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54
-# (Portuguese)
-# </a>
-#
-# We have a written a short article about it as well:
-# <a href="http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html">
-# http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html
-# </a>
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Decree <a href="http://pcdsh01.on.br/HV20466.htm">20,466</a> (1931-10-01)
-# Decree <a href="http://pcdsh01.on.br/HV21896.htm">21,896</a> (1932-01-10)
-Rule	Brazil	1931	only	-	Oct	 3	11:00	1:00	S
-Rule	Brazil	1932	1933	-	Apr	 1	 0:00	0	-
-Rule	Brazil	1932	only	-	Oct	 3	 0:00	1:00	S
-# Decree <a href="http://pcdsh01.on.br/HV23195.htm">23,195</a> (1933-10-10)
-# revoked DST.
-# Decree <a href="http://pcdsh01.on.br/HV27496.htm">27,496</a> (1949-11-24)
-# Decree <a href="http://pcdsh01.on.br/HV27998.htm">27,998</a> (1950-04-13)
-Rule	Brazil	1949	1952	-	Dec	 1	 0:00	1:00	S
-Rule	Brazil	1950	only	-	Apr	16	 1:00	0	-
-Rule	Brazil	1951	1952	-	Apr	 1	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV32308.htm">32,308</a> (1953-02-24)
-Rule	Brazil	1953	only	-	Mar	 1	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV34724.htm">34,724</a> (1953-11-30)
-# revoked DST.
-# Decree <a href="http://pcdsh01.on.br/HV52700.htm">52,700</a> (1963-10-18)
-# established DST from 1963-10-23 00:00 to 1964-02-29 00:00
-# in SP, RJ, GB, MG, ES, due to the prolongation of the drought.
-# Decree <a href="http://pcdsh01.on.br/HV53071.htm">53,071</a> (1963-12-03)
-# extended the above decree to all of the national territory on 12-09.
-Rule	Brazil	1963	only	-	Dec	 9	 0:00	1:00	S
-# Decree <a href="http://pcdsh01.on.br/HV53604.htm">53,604</a> (1964-02-25)
-# extended summer time by one day to 1964-03-01 00:00 (start of school).
-Rule	Brazil	1964	only	-	Mar	 1	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV55639.htm">55,639</a> (1965-01-27)
-Rule	Brazil	1965	only	-	Jan	31	 0:00	1:00	S
-Rule	Brazil	1965	only	-	Mar	31	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV57303.htm">57,303</a> (1965-11-22)
-Rule	Brazil	1965	only	-	Dec	 1	 0:00	1:00	S
-# Decree <a href="http://pcdsh01.on.br/HV57843.htm">57,843</a> (1966-02-18)
-Rule	Brazil	1966	1968	-	Mar	 1	 0:00	0	-
-Rule	Brazil	1966	1967	-	Nov	 1	 0:00	1:00	S
-# Decree <a href="http://pcdsh01.on.br/HV63429.htm">63,429</a> (1968-10-15)
-# revoked DST.
-# Decree <a href="http://pcdsh01.on.br/HV91698.htm">91,698</a> (1985-09-27)
-Rule	Brazil	1985	only	-	Nov	 2	 0:00	1:00	S
-# Decree 92,310 (1986-01-21)
-# Decree 92,463 (1986-03-13)
-Rule	Brazil	1986	only	-	Mar	15	 0:00	0	-
-# Decree 93,316 (1986-10-01)
-Rule	Brazil	1986	only	-	Oct	25	 0:00	1:00	S
-Rule	Brazil	1987	only	-	Feb	14	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV94922.htm">94,922</a> (1987-09-22)
-Rule	Brazil	1987	only	-	Oct	25	 0:00	1:00	S
-Rule	Brazil	1988	only	-	Feb	 7	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV96676.htm">96,676</a> (1988-09-12)
-# except for the states of AC, AM, PA, RR, RO, and AP (then a territory)
-Rule	Brazil	1988	only	-	Oct	16	 0:00	1:00	S
-Rule	Brazil	1989	only	-	Jan	29	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV98077.htm">98,077</a> (1989-08-21)
-# with the same exceptions
-Rule	Brazil	1989	only	-	Oct	15	 0:00	1:00	S
-Rule	Brazil	1990	only	-	Feb	11	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV99530.htm">99,530</a> (1990-09-17)
-# adopted by RS, SC, PR, SP, RJ, ES, MG, GO, MS, DF.
-# Decree 99,629 (1990-10-19) adds BA, MT.
-Rule	Brazil	1990	only	-	Oct	21	 0:00	1:00	S
-Rule	Brazil	1991	only	-	Feb	17	 0:00	0	-
-# <a href="http://pcdsh01.on.br/HV1991.htm">Unnumbered decree</a> (1991-09-25)
-# adopted by RS, SC, PR, SP, RJ, ES, MG, BA, GO, MT, MS, DF.
-Rule	Brazil	1991	only	-	Oct	20	 0:00	1:00	S
-Rule	Brazil	1992	only	-	Feb	 9	 0:00	0	-
-# <a href="http://pcdsh01.on.br/HV1992.htm">Unnumbered decree</a> (1992-10-16)
-# adopted by same states.
-Rule	Brazil	1992	only	-	Oct	25	 0:00	1:00	S
-Rule	Brazil	1993	only	-	Jan	31	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV942.htm">942</a> (1993-09-28)
-# adopted by same states, plus AM.
-# Decree <a href="http://pcdsh01.on.br/HV1252.htm">1,252</a> (1994-09-22;
-# web page corrected 2004-01-07) adopted by same states, minus AM.
-# Decree <a href="http://pcdsh01.on.br/HV1636.htm">1,636</a> (1995-09-14)
-# adopted by same states, plus MT and TO.
-# Decree <a href="http://pcdsh01.on.br/HV1674.htm">1,674</a> (1995-10-13)
-# adds AL, SE.
-Rule	Brazil	1993	1995	-	Oct	Sun>=11	 0:00	1:00	S
-Rule	Brazil	1994	1995	-	Feb	Sun>=15	 0:00	0	-
-Rule	Brazil	1996	only	-	Feb	11	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/HV2000.htm">2,000</a> (1996-09-04)
-# adopted by same states, minus AL, SE.
-Rule	Brazil	1996	only	-	Oct	 6	 0:00	1:00	S
-Rule	Brazil	1997	only	-	Feb	16	 0:00	0	-
-# From Daniel C. Sobral (1998-02-12):
-# In 1997, the DS began on October 6. The stated reason was that
-# because international television networks ignored Brazil's policy on DS,
-# they bought the wrong times on satellite for coverage of Pope's visit.
-# This year, the ending date of DS was postponed to March 1
-# to help dealing with the shortages of electric power.
-#
-# Decree 2,317 (1997-09-04), adopted by same states.
-Rule	Brazil	1997	only	-	Oct	 6	 0:00	1:00	S
-# Decree <a href="http://pcdsh01.on.br/figuras/HV2495.JPG">2,495</a>
-# (1998-02-10)
-Rule	Brazil	1998	only	-	Mar	 1	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/figuras/Hv98.jpg">2,780</a> (1998-09-11)
-# adopted by the same states as before.
-Rule	Brazil	1998	only	-	Oct	11	 0:00	1:00	S
-Rule	Brazil	1999	only	-	Feb	21	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/figuras/HV3150.gif">3,150</a>
-# (1999-08-23) adopted by same states.
-# Decree <a href="http://pcdsh01.on.br/DecHV99.gif">3,188</a> (1999-09-30)
-# adds SE, AL, PB, PE, RN, CE, PI, MA and RR.
-Rule	Brazil	1999	only	-	Oct	 3	 0:00	1:00	S
-Rule	Brazil	2000	only	-	Feb	27	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/DEC3592.htm">3,592</a> (2000-09-06)
-# adopted by the same states as before.
-# Decree <a href="http://pcdsh01.on.br/Dec3630.jpg">3,630</a> (2000-10-13)
-# repeals DST in PE and RR, effective 2000-10-15 00:00.
-# Decree <a href="http://pcdsh01.on.br/Dec3632.jpg">3,632</a> (2000-10-17)
-# repeals DST in SE, AL, PB, RN, CE, PI and MA, effective 2000-10-22 00:00.
-# Decree <a href="http://pcdsh01.on.br/figuras/HV3916.gif">3,916</a>
-# (2001-09-13) reestablishes DST in AL, CE, MA, PB, PE, PI, RN, SE.
-Rule	Brazil	2000	2001	-	Oct	Sun>=8	 0:00	1:00	S
-Rule	Brazil	2001	2006	-	Feb	Sun>=15	 0:00	0	-
-# Decree 4,399 (2002-10-01) repeals DST in AL, CE, MA, PB, PE, PI, RN, SE.
-# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2002/D4399.htm">4,399</a>
-Rule	Brazil	2002	only	-	Nov	 3	 0:00	1:00	S
-# Decree 4,844 (2003-09-24; corrected 2003-09-26) repeals DST in BA, MT, TO.
-# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2003/D4844.htm">4,844</a>
-Rule	Brazil	2003	only	-	Oct	19	 0:00	1:00	S
-# Decree 5,223 (2004-10-01) reestablishes DST in MT.
-# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2004-2006/2004/Decreto/D5223.htm">5,223</a>
-Rule	Brazil	2004	only	-	Nov	 2	 0:00	1:00	S
-# Decree <a href="http://pcdsh01.on.br/DecHV5539.gif">5,539</a> (2005-09-19),
-# adopted by the same states as before.
-Rule	Brazil	2005	only	-	Oct	16	 0:00	1:00	S
-# Decree <a href="http://pcdsh01.on.br/DecHV5920.gif">5,920</a> (2006-10-03),
-# adopted by the same states as before.
-Rule	Brazil	2006	only	-	Nov	 5	 0:00	1:00	S
-Rule	Brazil	2007	only	-	Feb	25	 0:00	0	-
-# Decree <a href="http://pcdsh01.on.br/DecHV6212.gif">6,212</a> (2007-09-26),
-# adopted by the same states as before.
-Rule	Brazil	2007	only	-	Oct	Sun>=8	 0:00	1:00	S
-# From Frederico A. C. Neves (2008-09-10):
-# Acording to this decree
-# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm">
-# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm
-# </a>
-# [t]he DST period in Brazil now on will be from the 3rd Oct Sunday to the
-# 3rd Feb Sunday. There is an exception on the return date when this is
-# the Carnival Sunday then the return date will be the next Sunday...
-Rule	Brazil	2008	max	-	Oct	Sun>=15	0:00	1:00	S
-Rule	Brazil	2008	2011	-	Feb	Sun>=15	0:00	0	-
-Rule	Brazil	2012	only	-	Feb	Sun>=22	0:00	0	-
-Rule	Brazil	2013	2014	-	Feb	Sun>=15	0:00	0	-
-Rule	Brazil	2015	only	-	Feb	Sun>=22	0:00	0	-
-Rule	Brazil	2016	2022	-	Feb	Sun>=15	0:00	0	-
-Rule	Brazil	2023	only	-	Feb	Sun>=22	0:00	0	-
-Rule	Brazil	2024	2025	-	Feb	Sun>=15	0:00	0	-
-Rule	Brazil	2026	only	-	Feb	Sun>=22	0:00	0	-
-Rule	Brazil	2027	2033	-	Feb	Sun>=15	0:00	0	-
-Rule	Brazil	2034	only	-	Feb	Sun>=22	0:00	0	-
-Rule	Brazil	2035	2036	-	Feb	Sun>=15	0:00	0	-
-Rule	Brazil	2037	only	-	Feb	Sun>=22	0:00	0	-
-# From Arthur David Olson (2008-09-29):
-# The next is wrong in some years but is better than nothing.
-Rule	Brazil	2038	max	-	Feb	Sun>=15	0:00	0	-
-
-# The latest ruleset listed above says that the following states observe DST:
-# DF, ES, GO, MG, MS, MT, PR, RJ, RS, SC, SP.
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-#
-# Fernando de Noronha (administratively part of PE)
-Zone America/Noronha	-2:09:40 -	LMT	1914
-			-2:00	Brazil	FN%sT	1990 Sep 17
-			-2:00	-	FNT	1999 Sep 30
-			-2:00	Brazil	FN%sT	2000 Oct 15
-			-2:00	-	FNT	2001 Sep 13
-			-2:00	Brazil	FN%sT	2002 Oct  1
-			-2:00	-	FNT
-# Other Atlantic islands have no permanent settlement.
-# These include Trindade and Martin Vaz (administratively part of ES),
-# Atol das Rocas (RN), and Penedos de Sao Pedro e Sao Paulo (PE).
-# Fernando de Noronha was a separate territory from 1942-09-02 to 1989-01-01;
-# it also included the Penedos.
-#
-# Amapa (AP), east Para (PA)
-# East Para includes Belem, Maraba, Serra Norte, and Sao Felix do Xingu.
-# The division between east and west Para is the river Xingu.
-# In the north a very small part from the river Javary (now Jari I guess,
-# the border with Amapa) to the Amazon, then to the Xingu.
-Zone America/Belem	-3:13:56 -	LMT	1914
-			-3:00	Brazil	BR%sT	1988 Sep 12
-			-3:00	-	BRT
-#
-# west Para (PA)
-# West Para includes Altamira, Oribidos, Prainha, Oriximina, and Santarem.
-Zone America/Santarem	-3:38:48 -	LMT	1914
-			-4:00	Brazil	AM%sT	1988 Sep 12
-			-4:00	-	AMT	2008 Jun 24 00:00
-			-3:00	-	BRT
-#
-# Maranhao (MA), Piaui (PI), Ceara (CE), Rio Grande do Norte (RN),
-# Paraiba (PB)
-Zone America/Fortaleza	-2:34:00 -	LMT	1914
-			-3:00	Brazil	BR%sT	1990 Sep 17
-			-3:00	-	BRT	1999 Sep 30
-			-3:00	Brazil	BR%sT	2000 Oct 22
-			-3:00	-	BRT	2001 Sep 13
-			-3:00	Brazil	BR%sT	2002 Oct  1
-			-3:00	-	BRT
-#
-# Pernambuco (PE) (except Atlantic islands)
-Zone America/Recife	-2:19:36 -	LMT	1914
-			-3:00	Brazil	BR%sT	1990 Sep 17
-			-3:00	-	BRT	1999 Sep 30
-			-3:00	Brazil	BR%sT	2000 Oct 15
-			-3:00	-	BRT	2001 Sep 13
-			-3:00	Brazil	BR%sT	2002 Oct  1
-			-3:00	-	BRT
-#
-# Tocantins (TO)
-Zone America/Araguaina	-3:12:48 -	LMT	1914
-			-3:00	Brazil	BR%sT	1990 Sep 17
-			-3:00	-	BRT	1995 Sep 14
-			-3:00	Brazil	BR%sT	2003 Sep 24
-			-3:00	-	BRT
-#
-# Alagoas (AL), Sergipe (SE)
-Zone America/Maceio	-2:22:52 -	LMT	1914
-			-3:00	Brazil	BR%sT	1990 Sep 17
-			-3:00	-	BRT	1995 Oct 13
-			-3:00	Brazil	BR%sT	1996 Sep  4
-			-3:00	-	BRT	1999 Sep 30
-			-3:00	Brazil	BR%sT	2000 Oct 22
-			-3:00	-	BRT	2001 Sep 13
-			-3:00	Brazil	BR%sT	2002 Oct  1
-			-3:00	-	BRT
-#
-# Bahia (BA)
-# There are too many Salvadors elsewhere, so use America/Bahia instead
-# of America/Salvador.
-Zone America/Bahia	-2:34:04 -	LMT	1914
-			-3:00	Brazil	BR%sT	2003 Sep 24
-			-3:00	-	BRT
-#
-# Goias (GO), Distrito Federal (DF), Minas Gerais (MG),
-# Espirito Santo (ES), Rio de Janeiro (RJ), Sao Paulo (SP), Parana (PR),
-# Santa Catarina (SC), Rio Grande do Sul (RS)
-Zone America/Sao_Paulo	-3:06:28 -	LMT	1914
-			-3:00	Brazil	BR%sT	1963 Oct 23 00:00
-			-3:00	1:00	BRST	1964
-			-3:00	Brazil	BR%sT
-#
-# Mato Grosso do Sul (MS)
-Zone America/Campo_Grande -3:38:28 -	LMT	1914
-			-4:00	Brazil	AM%sT
-#
-# Mato Grosso (MT)
-Zone America/Cuiaba	-3:44:20 -	LMT	1914
-			-4:00	Brazil	AM%sT	2003 Sep 24
-			-4:00	-	AMT	2004 Oct  1
-			-4:00	Brazil	AM%sT
-#
-# Rondonia (RO)
-Zone America/Porto_Velho -4:15:36 -	LMT	1914
-			-4:00	Brazil	AM%sT	1988 Sep 12
-			-4:00	-	AMT
-#
-# Roraima (RR)
-Zone America/Boa_Vista	-4:02:40 -	LMT	1914
-			-4:00	Brazil	AM%sT	1988 Sep 12
-			-4:00	-	AMT	1999 Sep 30
-			-4:00	Brazil	AM%sT	2000 Oct 15
-			-4:00	-	AMT
-#
-# east Amazonas (AM): Boca do Acre, Jutai, Manaus, Floriano Peixoto
-# The great circle line from Tabatinga to Porto Acre divides
-# east from west Amazonas.
-Zone America/Manaus	-4:00:04 -	LMT	1914
-			-4:00	Brazil	AM%sT	1988 Sep 12
-			-4:00	-	AMT	1993 Sep 28
-			-4:00	Brazil	AM%sT	1994 Sep 22
-			-4:00	-	AMT
-#
-# west Amazonas (AM): Atalaia do Norte, Boca do Maoco, Benjamin Constant,
-#	Eirunepe, Envira, Ipixuna
-Zone America/Eirunepe	-4:39:28 -	LMT	1914
-			-5:00	Brazil	AC%sT	1988 Sep 12
-			-5:00	-	ACT	1993 Sep 28
-			-5:00	Brazil	AC%sT	1994 Sep 22
-			-5:00	-	ACT	2008 Jun 24 00:00
-			-4:00	-	AMT
-#
-# Acre (AC)
-Zone America/Rio_Branco	-4:31:12 -	LMT	1914
-			-5:00	Brazil	AC%sT	1988 Sep 12
-			-5:00	-	ACT	2008 Jun 24 00:00
-			-4:00	-	AMT
-
-# Chile
-
-# From Eduardo Krell (1995-10-19):
-# The law says to switch to DST at midnight [24:00] on the second SATURDAY
-# of October....  The law is the same for March and October.
-# (1998-09-29):
-# Because of the drought this year, the government decided to go into
-# DST earlier (saturday 9/26 at 24:00). This is a one-time change only ...
-# (unless there's another dry season next year, I guess).
-
-# From Julio I. Pacheco Troncoso (1999-03-18):
-# Because of the same drought, the government decided to end DST later,
-# on April 3, (one-time change).
-
-# From Oscar van Vlijmen (2006-10-08):
-# http://www.horaoficial.cl/cambio.htm
-
-# From Jesper Norgaard Welen (2006-10-08):
-# I think that there are some obvious mistakes in the suggested link
-# from Oscar van Vlijmen,... for instance entry 66 says that GMT-4
-# ended 1990-09-12 while entry 67 only begins GMT-3 at 1990-09-15
-# (they should have been 1990-09-15 and 1990-09-16 respectively), but
-# anyhow it clears up some doubts too.
-
-# From Paul Eggert (2006-12-27):
-# The following data for Chile and America/Santiago are from
-# <http://www.horaoficial.cl/horaof.htm> (2006-09-20), transcribed by
-# Jesper Norgaard Welen.  The data for Pacific/Easter are from Shanks
-# & Pottenger, except with DST transitions after 1932 cloned from
-# America/Santiago.  The pre-1980 Pacific/Easter data are dubious,
-# but we have no other source.
-
-# From German Poo-Caaman~o (2008-03-03):
-# Due to drought, Chile extends Daylight Time in three weeks.  This
-# is one-time change (Saturday 3/29 at 24:00 for America/Santiago
-# and Saturday 3/29 at 22:00 for Pacific/Easter)
-# The Supreme Decree is located at 
-# <a href="http://www.shoa.cl/servicios/supremo316.pdf">
-# http://www.shoa.cl/servicios/supremo316.pdf
-# </a>
-# and the instructions for 2008 are located in:
-# <a href="http://www.horaoficial.cl/cambio.htm">
-# http://www.horaoficial.cl/cambio.htm
-# </a>.
-
-# From Jose Miguel Garrido (2008-03-05):
-# ...
-# You could see the announces of the change on 
-# <a href="http://www.shoa.cl/noticias/2008/04hora/hora.htm">
-# http://www.shoa.cl/noticias/2008/04hora/hora.htm
-# </a>.
-
-# From Angel Chiang (2010-03-04):
-# Subject: DST in Chile exceptionally extended to 3 April due to earthquake
-# <a href="http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098">
-# http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098
-# </a>
-# (in Spanish, last paragraph).
-#
-# This is breaking news. There should be more information available later.
-
-# From Arthur Daivd Olson (2010-03-06):
-# Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Chile	1927	1932	-	Sep	 1	0:00	1:00	S
-Rule	Chile	1928	1932	-	Apr	 1	0:00	0	-
-Rule	Chile	1942	only	-	Jun	 1	4:00u	0	-
-Rule	Chile	1942	only	-	Aug	 1	5:00u	1:00	S
-Rule	Chile	1946	only	-	Jul	15	4:00u	1:00	S
-Rule	Chile	1946	only	-	Sep	 1	3:00u	0:00	-
-Rule	Chile	1947	only	-	Apr	 1	4:00u	0	-
-Rule	Chile	1968	only	-	Nov	 3	4:00u	1:00	S
-Rule	Chile	1969	only	-	Mar	30	3:00u	0	-
-Rule	Chile	1969	only	-	Nov	23	4:00u	1:00	S
-Rule	Chile	1970	only	-	Mar	29	3:00u	0	-
-Rule	Chile	1971	only	-	Mar	14	3:00u	0	-
-Rule	Chile	1970	1972	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	Chile	1972	1986	-	Mar	Sun>=9	3:00u	0	-
-Rule	Chile	1973	only	-	Sep	30	4:00u	1:00	S
-Rule	Chile	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	Chile	1987	only	-	Apr	12	3:00u	0	-
-Rule	Chile	1988	1989	-	Mar	Sun>=9	3:00u	0	-
-Rule	Chile	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
-Rule	Chile	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	Chile	1990	only	-	Mar	18	3:00u	0	-
-Rule	Chile	1990	only	-	Sep	16	4:00u	1:00	S
-Rule	Chile	1991	1996	-	Mar	Sun>=9	3:00u	0	-
-Rule	Chile	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	Chile	1997	only	-	Mar	30	3:00u	0	-
-Rule	Chile	1998	only	-	Mar	Sun>=9	3:00u	0	-
-Rule	Chile	1998	only	-	Sep	27	4:00u	1:00	S
-Rule	Chile	1999	only	-	Apr	 4	3:00u	0	-
-Rule	Chile	1999	max	-	Oct	Sun>=9	4:00u	1:00	S
-Rule	Chile	2000	2007	-	Mar	Sun>=9	3:00u	0	-
-# N.B.: the end of March 29 in Chile is March 30 in Universal time,
-# which is used below in specifying the transition.
-Rule	Chile	2008	only	-	Mar	30	3:00u	0	-
-Rule	Chile	2009	only	-	Mar	Sun>=9	3:00u	0	-
-Rule	Chile	2010	only	-	Apr	 4	3:00u	0	-
-Rule	Chile	2011	max	-	Mar	Sun>=9	3:00u	0	-
-# IATA SSIM anomalies: (1992-02) says 1992-03-14;
-# (1996-09) says 1998-03-08.  Ignore these.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Santiago	-4:42:46 -	LMT	1890
-			-4:42:46 -	SMT	1910 	    # Santiago Mean Time
-			-5:00	-	CLT	1916 Jul  1 # Chile Time
-			-4:42:46 -	SMT	1918 Sep  1 # Santiago Mean Time
-			-4:00	-	CLT	1919 Jul  1 # Chile Time
-			-4:42:46 -	SMT	1927 Sep  1 # Santiago Mean Time
-			-5:00	Chile	CL%sT	1947 May 22 # Chile Time
-			-4:00	Chile	CL%sT
-Zone Pacific/Easter	-7:17:44 -	LMT	1890
-			-7:17:28 -	EMT	1932 Sep    # Easter Mean Time
-			-7:00	Chile	EAS%sT	1982 Mar 13 21:00 # Easter I Time
-			-6:00	Chile	EAS%sT
-#
-# Sala y Gomez Island is like Pacific/Easter.
-# Other Chilean locations, including Juan Fernandez Is, San Ambrosio,
-# San Felix, and Antarctic bases, are like America/Santiago.
-
-# Colombia
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	CO	1992	only	-	May	 3	0:00	1:00	S
-Rule	CO	1993	only	-	Apr	 4	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
-			-4:56:20 -	BMT	1914 Nov 23 # Bogota Mean Time
-			-5:00	CO	CO%sT	# Colombia Time
-# Malpelo, Providencia, San Andres
-# no information; probably like America/Bogota
-
-# Curacao
-#
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger say that The Bottom and Philipsburg have been at
-# -4:00 since standard time was introduced on 1912-03-02; and that
-# Kralendijk and Rincon used Kralendijk Mean Time (-4:33:08) from
-# 1912-02-02 to 1965-01-01.  The former is dubious, since S&P also say
-# Saba Island has been like Curacao.
-# This all predates our 1970 cutoff, though.
-#
-# By July 2007 Curacao and St Maarten are planned to become
-# associated states within the Netherlands, much like Aruba;
-# Bonaire, Saba and St Eustatius would become directly part of the
-# Netherlands as Kingdom Islands.  This won't affect their time zones
-# though, as far as we know.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Curacao	-4:35:44 -	LMT	1912 Feb 12	# Willemstad
-			-4:30	-	ANT	1965 # Netherlands Antilles Time
-			-4:00	-	AST
-
-# Ecuador
-#
-# From Paul Eggert (2007-03-04):
-# Apparently Ecuador had a failed experiment with DST in 1992.
-# <http://midena.gov.ec/content/view/1261/208/> (2007-02-27) and
-# <http://www.hoy.com.ec/NoticiaNue.asp?row_id=249856> (2006-11-06) both
-# talk about "hora Sixto".  Leave this alone for now, as we have no data.
-#
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Guayaquil	-5:19:20 -	LMT	1890
-			-5:14:00 -	QMT	1931 # Quito Mean Time
-			-5:00	-	ECT	     # Ecuador Time
-Zone Pacific/Galapagos	-5:58:24 -	LMT	1931 # Puerto Baquerizo Moreno
-			-5:00	-	ECT	1986
-			-6:00	-	GALT	     # Galapagos Time
-
-# Falklands
-
-# From Paul Eggert (2006-03-22):
-# Between 1990 and 2000 inclusive, Shanks & Pottenger and the IATA agree except
-# the IATA gives 1996-09-08.  Go with Shanks & Pottenger.
-
-# From Falkland Islands Government Office, London (2001-01-22)
-# via Jesper Norgaard:
-# ... the clocks revert back to Local Mean Time at 2 am on Sunday 15
-# April 2001 and advance one hour to summer time at 2 am on Sunday 2
-# September.  It is anticipated that the clocks will revert back at 2
-# am on Sunday 21 April 2002 and advance to summer time at 2 am on
-# Sunday 1 September.
-
-# From Rives McDow (2001-02-13):
-#
-# I have communicated several times with people there, and the last
-# time I had communications that was helpful was in 1998.  Here is
-# what was said then:
-#
-# "The general rule was that Stanley used daylight saving and the Camp
-# did not. However for various reasons many people in the Camp have
-# started to use daylight saving (known locally as 'Stanley Time')
-# There is no rule as to who uses daylight saving - it is a matter of
-# personal choice and so it is impossible to draw a map showing who
-# uses it and who does not. Any list would be out of date as soon as
-# it was produced. This year daylight saving ended on April 18/19th
-# and started again on September 12/13th.  I do not know what the rule
-# is, but can find out if you like.  We do not change at the same time
-# as UK or Chile."
-#
-# I did have in my notes that the rule was "Second Saturday in Sep at
-# 0:00 until third Saturday in Apr at 0:00".  I think that this does
-# not agree in some cases with Shanks; is this true?
-#
-# Also, there is no mention in the list that some areas in the
-# Falklands do not use DST.  I have found in my communications there
-# that these areas are on the western half of East Falkland and all of
-# West Falkland.  Stanley is the only place that consistently observes
-# DST.  Again, as in other places in the world, the farmers don't like
-# it.  West Falkland is almost entirely sheep farmers.
-#
-# I know one lady there that keeps a list of which farm keeps DST and
-# which doesn't each year.  She runs a shop in Stanley, and says that
-# the list changes each year.  She uses it to communicate to her
-# customers, catching them when they are home for lunch or dinner.
-
-# From Paul Eggert (2001-03-05):
-# For now, we'll just record the time in Stanley, since we have no
-# better info.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Falk	1937	1938	-	Sep	lastSun	0:00	1:00	S
-Rule	Falk	1938	1942	-	Mar	Sun>=19	0:00	0	-
-Rule	Falk	1939	only	-	Oct	1	0:00	1:00	S
-Rule	Falk	1940	1942	-	Sep	lastSun	0:00	1:00	S
-Rule	Falk	1943	only	-	Jan	1	0:00	0	-
-Rule	Falk	1983	only	-	Sep	lastSun	0:00	1:00	S
-Rule	Falk	1984	1985	-	Apr	lastSun	0:00	0	-
-Rule	Falk	1984	only	-	Sep	16	0:00	1:00	S
-Rule	Falk	1985	2000	-	Sep	Sun>=9	0:00	1:00	S
-Rule	Falk	1986	2000	-	Apr	Sun>=16	0:00	0	-
-Rule	Falk	2001	max	-	Apr	Sun>=15	2:00	0	-
-Rule	Falk	2001	max	-	Sep	Sun>=1	2:00	1:00	S
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/Stanley	-3:51:24 -	LMT	1890
-			-3:51:24 -	SMT	1912 Mar 12  # Stanley Mean Time
-			-4:00	Falk	FK%sT	1983 May     # Falkland Is Time
-			-3:00	Falk	FK%sT	1985 Sep 15
-			-4:00	Falk	FK%sT
-
-# French Guiana
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Cayenne	-3:29:20 -	LMT	1911 Jul
-			-4:00	-	GFT	1967 Oct # French Guiana Time
-			-3:00	-	GFT
-
-# Guyana
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Guyana	-3:52:40 -	LMT	1915 Mar	# Georgetown
-			-3:45	-	GBGT	1966 May 26 # Br Guiana Time
-			-3:45	-	GYT	1975 Jul 31 # Guyana Time
-			-3:00	-	GYT	1991
-# IATA SSIM (1996-06) says -4:00.  Assume a 1991 switch.
-			-4:00	-	GYT
-
-# Paraguay
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger say that spring transitions are from 01:00 -> 02:00,
-# and autumn transitions are from 00:00 -> 23:00.  Go with pre-1999
-# editions of Shanks, and with the IATA, who say transitions occur at 00:00.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Para	1975	1988	-	Oct	 1	0:00	1:00	S
-Rule	Para	1975	1978	-	Mar	 1	0:00	0	-
-Rule	Para	1979	1991	-	Apr	 1	0:00	0	-
-Rule	Para	1989	only	-	Oct	22	0:00	1:00	S
-Rule	Para	1990	only	-	Oct	 1	0:00	1:00	S
-Rule	Para	1991	only	-	Oct	 6	0:00	1:00	S
-Rule	Para	1992	only	-	Mar	 1	0:00	0	-
-Rule	Para	1992	only	-	Oct	 5	0:00	1:00	S
-Rule	Para	1993	only	-	Mar	31	0:00	0	-
-Rule	Para	1993	1995	-	Oct	 1	0:00	1:00	S
-Rule	Para	1994	1995	-	Feb	lastSun	0:00	0	-
-Rule	Para	1996	only	-	Mar	 1	0:00	0	-
-# IATA SSIM (2000-02) says 1999-10-10; ignore this for now.
-# From Steffen Thorsen (2000-10-02):
-# I have three independent reports that Paraguay changed to DST this Sunday
-# (10-01).
-#
-# Translated by Gwillim Law (2001-02-27) from
-# <a href="http://www.diarionoticias.com.py/011000/nacional/naciona1.htm">
-# Noticias, a daily paper in Asuncion, Paraguay (2000-10-01)
-# </a>:
-# Starting at 0:00 today, the clock will be set forward 60 minutes, in
-# fulfillment of Decree No. 7,273 of the Executive Power....  The time change
-# system has been operating for several years.  Formerly there was a separate
-# decree each year; the new law has the same effect, but permanently.  Every
-# year, the time will change on the first Sunday of October; likewise, the
-# clock will be set back on the first Sunday of March.
-#
-Rule	Para	1996	2001	-	Oct	Sun>=1	0:00	1:00	S
-# IATA SSIM (1997-09) says Mar 1; go with Shanks & Pottenger.
-Rule	Para	1997	only	-	Feb	lastSun	0:00	0	-
-# Shanks & Pottenger say 1999-02-28; IATA SSIM (1999-02) says 1999-02-27, but
-# (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27).
-Rule	Para	1998	2001	-	Mar	Sun>=1	0:00	0	-
-# From Rives McDow (2002-02-28):
-# A decree was issued in Paraguay (no. 16350) on 2002-02-26 that changed the
-# dst method to be from the first Sunday in September to the first Sunday in
-# April.
-Rule	Para	2002	2004	-	Apr	Sun>=1	0:00	0	-
-Rule	Para	2002	2003	-	Sep	Sun>=1	0:00	1:00	S
-#
-# From Jesper Norgaard Welen (2005-01-02):
-# There are several sources that claim that Paraguay made
-# a timezone rule change in autumn 2004.
-# From Steffen Thorsen (2005-01-05):
-# Decree 1,867 (2004-03-05)
-# From Carlos Raul Perasso via Jesper Norgaard Welen (2006-10-13)
-# <http://www.presidencia.gov.py/decretos/D1867.pdf>
-Rule	Para	2004	2009	-	Oct	Sun>=15	0:00	1:00	S
-Rule	Para	2005	2009	-	Mar	Sun>=8	0:00	0	-
-# From Carlos Raul Perasso (2010-02-18):
-# By decree number 3958 issued yesterday (
-# <a href="http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf">
-# http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf
-# </a>
-# )
-# Paraguay changes its DST schedule, postponing the March rule to April and
-# modifying the October date. The decree reads:
-# ...
-# Art. 1. It is hereby established that from the second Sunday of the month of
-# April of this year (2010), the official time is to be set back 60 minutes,
-# and that on the first Sunday of the month of October, it is to be set
-# forward 60 minutes, in all the territory of the Paraguayan Republic.
-# ...
-Rule	Para	2010	max	-	Oct	Sun>=1	0:00	1:00	S
-Rule	Para	2010	max	-	Apr	Sun>=8	0:00	0	-
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Asuncion	-3:50:40 -	LMT	1890
-			-3:50:40 -	AMT	1931 Oct 10 # Asuncion Mean Time
-			-4:00	-	PYT	1972 Oct # Paraguay Time
-			-3:00	-	PYT	1974 Apr
-			-4:00	Para	PY%sT
-
-# Peru
-#
-# <a href="news:xrGmb.39935$gA1.13896113@news4.srv.hcvlny.cv.net">
-# From Evelyn C. Leeper via Mark Brader (2003-10-26):</a>
-# When we were in Peru in 1985-1986, they apparently switched over
-# sometime between December 29 and January 3 while we were on the Amazon.
-#
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger don't have this transition.  Assume 1986 was like 1987.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Peru	1938	only	-	Jan	 1	0:00	1:00	S
-Rule	Peru	1938	only	-	Apr	 1	0:00	0	-
-Rule	Peru	1938	1939	-	Sep	lastSun	0:00	1:00	S
-Rule	Peru	1939	1940	-	Mar	Sun>=24	0:00	0	-
-Rule	Peru	1986	1987	-	Jan	 1	0:00	1:00	S
-Rule	Peru	1986	1987	-	Apr	 1	0:00	0	-
-Rule	Peru	1990	only	-	Jan	 1	0:00	1:00	S
-Rule	Peru	1990	only	-	Apr	 1	0:00	0	-
-# IATA is ambiguous for 1993/1995; go with Shanks & Pottenger.
-Rule	Peru	1994	only	-	Jan	 1	0:00	1:00	S
-Rule	Peru	1994	only	-	Apr	 1	0:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Lima	-5:08:12 -	LMT	1890
-			-5:08:36 -	LMT	1908 Jul 28 # Lima Mean Time?
-			-5:00	Peru	PE%sT	# Peru Time
-
-# South Georgia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/South_Georgia -2:26:08 -	LMT	1890		# Grytviken
-			-2:00	-	GST	# South Georgia Time
-
-# South Sandwich Is
-# uninhabited; scientific personnel have wintered
-
-# Suriname
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Paramaribo	-3:40:40 -	LMT	1911
-			-3:40:52 -	PMT	1935     # Paramaribo Mean Time
-			-3:40:36 -	PMT	1945 Oct # The capital moved?
-			-3:30	-	NEGT	1975 Nov 20 # Dutch Guiana Time
-			-3:30	-	SRT	1984 Oct # Suriname Time
-			-3:00	-	SRT
-
-# Trinidad and Tobago
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Port_of_Spain -4:06:04 -	LMT	1912 Mar 2
-			-4:00	-	AST
-
-# Uruguay
-# From Paul Eggert (1993-11-18):
-# Uruguay wins the prize for the strangest peacetime manipulation of the rules.
-# From Shanks & Pottenger:
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Whitman gives 1923 Oct 1; go with Shanks & Pottenger.
-Rule	Uruguay	1923	only	-	Oct	 2	 0:00	0:30	HS
-Rule	Uruguay	1924	1926	-	Apr	 1	 0:00	0	-
-Rule	Uruguay	1924	1925	-	Oct	 1	 0:00	0:30	HS
-Rule	Uruguay	1933	1935	-	Oct	lastSun	 0:00	0:30	HS
-# Shanks & Pottenger give 1935 Apr 1 0:00 & 1936 Mar 30 0:00; go with Whitman.
-Rule	Uruguay	1934	1936	-	Mar	Sat>=25	23:30s	0	-
-Rule	Uruguay	1936	only	-	Nov	 1	 0:00	0:30	HS
-Rule	Uruguay	1937	1941	-	Mar	lastSun	 0:00	0	-
-# Whitman gives 1937 Oct 3; go with Shanks & Pottenger.
-Rule	Uruguay	1937	1940	-	Oct	lastSun	 0:00	0:30	HS
-# Whitman gives 1941 Oct 24 - 1942 Mar 27, 1942 Dec 14 - 1943 Apr 13,
-# and 1943 Apr 13 ``to present time''; go with Shanks & Pottenger.
-Rule	Uruguay	1941	only	-	Aug	 1	 0:00	0:30	HS
-Rule	Uruguay	1942	only	-	Jan	 1	 0:00	0	-
-Rule	Uruguay	1942	only	-	Dec	14	 0:00	1:00	S
-Rule	Uruguay	1943	only	-	Mar	14	 0:00	0	-
-Rule	Uruguay	1959	only	-	May	24	 0:00	1:00	S
-Rule	Uruguay	1959	only	-	Nov	15	 0:00	0	-
-Rule	Uruguay	1960	only	-	Jan	17	 0:00	1:00	S
-Rule	Uruguay	1960	only	-	Mar	 6	 0:00	0	-
-Rule	Uruguay	1965	1967	-	Apr	Sun>=1	 0:00	1:00	S
-Rule	Uruguay	1965	only	-	Sep	26	 0:00	0	-
-Rule	Uruguay	1966	1967	-	Oct	31	 0:00	0	-
-Rule	Uruguay	1968	1970	-	May	27	 0:00	0:30	HS
-Rule	Uruguay	1968	1970	-	Dec	 2	 0:00	0	-
-Rule	Uruguay	1972	only	-	Apr	24	 0:00	1:00	S
-Rule	Uruguay	1972	only	-	Aug	15	 0:00	0	-
-Rule	Uruguay	1974	only	-	Mar	10	 0:00	0:30	HS
-Rule	Uruguay	1974	only	-	Dec	22	 0:00	1:00	S
-Rule	Uruguay	1976	only	-	Oct	 1	 0:00	0	-
-Rule	Uruguay	1977	only	-	Dec	 4	 0:00	1:00	S
-Rule	Uruguay	1978	only	-	Apr	 1	 0:00	0	-
-Rule	Uruguay	1979	only	-	Oct	 1	 0:00	1:00	S
-Rule	Uruguay	1980	only	-	May	 1	 0:00	0	-
-Rule	Uruguay	1987	only	-	Dec	14	 0:00	1:00	S
-Rule	Uruguay	1988	only	-	Mar	14	 0:00	0	-
-Rule	Uruguay	1988	only	-	Dec	11	 0:00	1:00	S
-Rule	Uruguay	1989	only	-	Mar	12	 0:00	0	-
-Rule	Uruguay	1989	only	-	Oct	29	 0:00	1:00	S
-# Shanks & Pottenger say no DST was observed in 1990/1 and 1991/2,
-# and that 1992/3's DST was from 10-25 to 03-01.  Go with IATA.
-Rule	Uruguay	1990	1992	-	Mar	Sun>=1	 0:00	0	-
-Rule	Uruguay	1990	1991	-	Oct	Sun>=21	 0:00	1:00	S
-Rule	Uruguay	1992	only	-	Oct	18	 0:00	1:00	S
-Rule	Uruguay	1993	only	-	Feb	28	 0:00	0	-
-# From Eduardo Cota (2004-09-20):
-# The uruguayan government has decreed a change in the local time....
-# http://www.presidencia.gub.uy/decretos/2004091502.htm
-Rule	Uruguay	2004	only	-	Sep	19	 0:00	1:00	S
-# From Steffen Thorsen (2005-03-11):
-# Uruguay's DST was scheduled to end on Sunday, 2005-03-13, but in order to
-# save energy ... it was postponed two weeks....
-# http://www.presidencia.gub.uy/_Web/noticias/2005/03/2005031005.htm
-Rule	Uruguay	2005	only	-	Mar	27	 2:00	0	-
-# From Eduardo Cota (2005-09-27):
-# http://www.presidencia.gub.uy/_Web/decretos/2005/09/CM%20119_09%2009%202005_00001.PDF
-# This means that from 2005-10-09 at 02:00 local time, until 2006-03-12 at
-# 02:00 local time, official time in Uruguay will be at GMT -2.
-Rule	Uruguay	2005	only	-	Oct	 9	 2:00	1:00	S
-Rule	Uruguay	2006	only	-	Mar	12	 2:00	0	-
-# From Jesper Norgaard Welen (2006-09-06):
-# http://www.presidencia.gub.uy/_web/decretos/2006/09/CM%20210_08%2006%202006_00001.PDF
-Rule	Uruguay	2006	max	-	Oct	Sun>=1	 2:00	1:00	S
-Rule	Uruguay	2007	max	-	Mar	Sun>=8	 2:00	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Montevideo	-3:44:44 -	LMT	1898 Jun 28
-			-3:44:44 -	MMT	1920 May  1	# Montevideo MT
-			-3:30	Uruguay	UY%sT	1942 Dec 14	# Uruguay Time
-			-3:00	Uruguay	UY%sT
-
-# Venezuela
-#
-# From John Stainforth (2007-11-28):
-# ... the change for Venezuela originally expected for 2007-12-31 has
-# been brought forward to 2007-12-09.  The official announcement was
-# published today in the "Gaceta Oficial de la Republica Bolivariana
-# de Venezuela, numero 38.819" (official document for all laws or
-# resolution publication)
-# http://www.globovision.com/news.php?nid=72208
-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Caracas	-4:27:44 -	LMT	1890
-			-4:27:40 -	CMT	1912 Feb 12 # Caracas Mean Time?
-			-4:30	-	VET	1965	     # Venezuela Time
-			-4:00	-	VET	2007 Dec  9 03:00
-			-4:30	-	VET
diff --git a/tools/zoneinfo/tzdata2010k/systemv b/tools/zoneinfo/tzdata2010k/systemv
deleted file mode 100644
index 767388d..0000000
--- a/tools/zoneinfo/tzdata2010k/systemv
+++ /dev/null
@@ -1,39 +0,0 @@
-# <pre>
-# @(#)systemv	8.2
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# Old rules, should the need arise.
-# No attempt is made to handle Newfoundland, since it cannot be expressed
-# using the System V "TZ" scheme (half-hour offset), or anything outside
-# North America (no support for non-standard DST start/end dates), nor
-# the changes in the DST rules in the US after 1976 (which occurred after
-# the old rules were written).
-#
-# If you need the old rules, uncomment ## lines.
-# Compile this *without* leap second correction for true conformance.
-
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
-Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
-Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
-Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
-Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
-Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
-Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
-Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
-
-# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
-## Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
-## Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
-## Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
-## Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
-## Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
-## Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
-## Zone	SystemV/AST4	-4:00	-		AST
-## Zone	SystemV/EST5	-5:00	-		EST
-## Zone	SystemV/CST6	-6:00	-		CST
-## Zone	SystemV/MST7	-7:00	-		MST
-## Zone	SystemV/PST8	-8:00	-		PST
-## Zone	SystemV/YST9	-9:00	-		YST
-## Zone	SystemV/HST10	-10:00	-		HST
diff --git a/tools/zoneinfo/tzdata2010k/yearistype.sh b/tools/zoneinfo/tzdata2010k/yearistype.sh
deleted file mode 100644
index 66dbf89..0000000
--- a/tools/zoneinfo/tzdata2010k/yearistype.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#! /bin/sh
-
-: 'This file is in the public domain, so clarified as of'
-: '2006-07-17 by Arthur David Olson.'
-
-: '@(#)yearistype.sh	8.2'
-
-case $#-$1 in
-	2-|2-0*|2-*[!0-9]*)
-		echo "$0: wild year - $1" >&2
-		exit 1 ;;
-esac
-
-case $#-$2 in
-	2-even)
-		case $1 in
-			*[24680])			exit 0 ;;
-			*)				exit 1 ;;
-		esac ;;
-	2-nonpres|2-nonuspres)
-		case $1 in
-			*[02468][048]|*[13579][26])	exit 1 ;;
-			*)				exit 0 ;;
-		esac ;;
-	2-odd)
-		case $1 in
-			*[13579])			exit 0 ;;
-			*)				exit 1 ;;
-		esac ;;
-	2-uspres)
-		case $1 in
-			*[02468][048]|*[13579][26])	exit 0 ;;
-			*)				exit 1 ;;
-		esac ;;
-	2-*)
-		echo "$0: wild type - $2" >&2 ;;
-esac
-
-echo "$0: usage is $0 year even|odd|uspres|nonpres|nonuspres" >&2
-exit 1
diff --git a/tools/zoneinfo/tzdata2010k/zone.tab b/tools/zoneinfo/tzdata2010k/zone.tab
deleted file mode 100644
index 1dc2add..0000000
--- a/tools/zoneinfo/tzdata2010k/zone.tab
+++ /dev/null
@@ -1,434 +0,0 @@
-# <pre>
-# @(#)zone.tab	8.37
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-#
-# TZ zone descriptions
-#
-# From Paul Eggert (1996-08-05):
-#
-# This file contains a table with the following columns:
-# 1.  ISO 3166 2-character country code.  See the file `iso3166.tab'.
-# 2.  Latitude and longitude of the zone's principal location
-#     in ISO 6709 sign-degrees-minutes-seconds format,
-#     either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
-#     first latitude (+ is north), then longitude (+ is east).
-# 3.  Zone name used in value of TZ environment variable.
-# 4.  Comments; present if and only if the country has multiple rows.
-#
-# Columns are separated by a single tab.
-# The table is sorted first by country, then an order within the country that
-# (1) makes some geographical sense, and
-# (2) puts the most populous zones first, where that does not contradict (1).
-#
-# Lines beginning with `#' are comments.
-#
-#country-
-#code	coordinates	TZ			comments
-AD	+4230+00131	Europe/Andorra
-AE	+2518+05518	Asia/Dubai
-AF	+3431+06912	Asia/Kabul
-AG	+1703-06148	America/Antigua
-AI	+1812-06304	America/Anguilla
-AL	+4120+01950	Europe/Tirane
-AM	+4011+04430	Asia/Yerevan
-AN	+1211-06900	America/Curacao
-AO	-0848+01314	Africa/Luanda
-AQ	-7750+16636	Antarctica/McMurdo	McMurdo Station, Ross Island
-AQ	-9000+00000	Antarctica/South_Pole	Amundsen-Scott Station, South Pole
-AQ	-6734-06808	Antarctica/Rothera	Rothera Station, Adelaide Island
-AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
-AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
-AQ	-6835+07758	Antarctica/Davis	Davis Station, Vestfold Hills
-AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
-AQ	-7824+10654	Antarctica/Vostok	Vostok Station, S Magnetic Pole
-AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
-AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
-AQ	-5430+15857	Antarctica/Macquarie	Macquarie Island Station, Macquarie Island
-AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
-AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
-AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
-AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
-AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
-AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
-AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
-AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
-AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
-AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
-AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
-AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
-AS	-1416-17042	Pacific/Pago_Pago
-AT	+4813+01620	Europe/Vienna
-AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
-AU	-4253+14719	Australia/Hobart	Tasmania - most locations
-AU	-3956+14352	Australia/Currie	Tasmania - King Island
-AU	-3749+14458	Australia/Melbourne	Victoria
-AU	-3352+15113	Australia/Sydney	New South Wales - most locations
-AU	-3157+14127	Australia/Broken_Hill	New South Wales - Yancowinna
-AU	-2728+15302	Australia/Brisbane	Queensland - most locations
-AU	-2016+14900	Australia/Lindeman	Queensland - Holiday Islands
-AU	-3455+13835	Australia/Adelaide	South Australia
-AU	-1228+13050	Australia/Darwin	Northern Territory
-AU	-3157+11551	Australia/Perth	Western Australia - most locations
-AU	-3143+12852	Australia/Eucla	Western Australia - Eucla area
-AW	+1230-06958	America/Aruba
-AX	+6006+01957	Europe/Mariehamn
-AZ	+4023+04951	Asia/Baku
-BA	+4352+01825	Europe/Sarajevo
-BB	+1306-05937	America/Barbados
-BD	+2343+09025	Asia/Dhaka
-BE	+5050+00420	Europe/Brussels
-BF	+1222-00131	Africa/Ouagadougou
-BG	+4241+02319	Europe/Sofia
-BH	+2623+05035	Asia/Bahrain
-BI	-0323+02922	Africa/Bujumbura
-BJ	+0629+00237	Africa/Porto-Novo
-BL	+1753-06251	America/St_Barthelemy
-BM	+3217-06446	Atlantic/Bermuda
-BN	+0456+11455	Asia/Brunei
-BO	-1630-06809	America/La_Paz
-BR	-0351-03225	America/Noronha	Atlantic islands
-BR	-0127-04829	America/Belem	Amapa, E Para
-BR	-0343-03830	America/Fortaleza	NE Brazil (MA, PI, CE, RN, PB)
-BR	-0803-03454	America/Recife	Pernambuco
-BR	-0712-04812	America/Araguaina	Tocantins
-BR	-0940-03543	America/Maceio	Alagoas, Sergipe
-BR	-1259-03831	America/Bahia	Bahia
-BR	-2332-04637	America/Sao_Paulo	S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS)
-BR	-2027-05437	America/Campo_Grande	Mato Grosso do Sul
-BR	-1535-05605	America/Cuiaba	Mato Grosso
-BR	-0226-05452	America/Santarem	W Para
-BR	-0846-06354	America/Porto_Velho	Rondonia
-BR	+0249-06040	America/Boa_Vista	Roraima
-BR	-0308-06001	America/Manaus	E Amazonas
-BR	-0640-06952	America/Eirunepe	W Amazonas
-BR	-0958-06748	America/Rio_Branco	Acre
-BS	+2505-07721	America/Nassau
-BT	+2728+08939	Asia/Thimphu
-BW	-2439+02555	Africa/Gaborone
-BY	+5354+02734	Europe/Minsk
-BZ	+1730-08812	America/Belize
-CA	+4734-05243	America/St_Johns	Newfoundland Time, including SE Labrador
-CA	+4439-06336	America/Halifax	Atlantic Time - Nova Scotia (most places), PEI
-CA	+4612-05957	America/Glace_Bay	Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
-CA	+4606-06447	America/Moncton	Atlantic Time - New Brunswick
-CA	+5320-06025	America/Goose_Bay	Atlantic Time - Labrador - most locations
-CA	+5125-05707	America/Blanc-Sablon	Atlantic Standard Time - Quebec - Lower North Shore
-CA	+4531-07334	America/Montreal	Eastern Time - Quebec - most locations
-CA	+4339-07923	America/Toronto	Eastern Time - Ontario - most locations
-CA	+4901-08816	America/Nipigon	Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
-CA	+4823-08915	America/Thunder_Bay	Eastern Time - Thunder Bay, Ontario
-CA	+6344-06828	America/Iqaluit	Eastern Time - east Nunavut - most locations
-CA	+6608-06544	America/Pangnirtung	Eastern Time - Pangnirtung, Nunavut
-CA	+744144-0944945	America/Resolute	Eastern Standard Time - Resolute, Nunavut
-CA	+484531-0913718	America/Atikokan	Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
-CA	+624900-0920459	America/Rankin_Inlet	Central Time - central Nunavut
-CA	+4953-09709	America/Winnipeg	Central Time - Manitoba & west Ontario
-CA	+4843-09434	America/Rainy_River	Central Time - Rainy River & Fort Frances, Ontario
-CA	+5024-10439	America/Regina	Central Standard Time - Saskatchewan - most locations
-CA	+5017-10750	America/Swift_Current	Central Standard Time - Saskatchewan - midwest
-CA	+5333-11328	America/Edmonton	Mountain Time - Alberta, east British Columbia & west Saskatchewan
-CA	+690650-1050310	America/Cambridge_Bay	Mountain Time - west Nunavut
-CA	+6227-11421	America/Yellowknife	Mountain Time - central Northwest Territories
-CA	+682059-1334300	America/Inuvik	Mountain Time - west Northwest Territories
-CA	+5946-12014	America/Dawson_Creek	Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
-CA	+4916-12307	America/Vancouver	Pacific Time - west British Columbia
-CA	+6043-13503	America/Whitehorse	Pacific Time - south Yukon
-CA	+6404-13925	America/Dawson	Pacific Time - north Yukon
-CC	-1210+09655	Indian/Cocos
-CD	-0418+01518	Africa/Kinshasa	west Dem. Rep. of Congo
-CD	-1140+02728	Africa/Lubumbashi	east Dem. Rep. of Congo
-CF	+0422+01835	Africa/Bangui
-CG	-0416+01517	Africa/Brazzaville
-CH	+4723+00832	Europe/Zurich
-CI	+0519-00402	Africa/Abidjan
-CK	-2114-15946	Pacific/Rarotonga
-CL	-3327-07040	America/Santiago	most locations
-CL	-2709-10926	Pacific/Easter	Easter Island & Sala y Gomez
-CM	+0403+00942	Africa/Douala
-CN	+3114+12128	Asia/Shanghai	east China - Beijing, Guangdong, Shanghai, etc.
-CN	+4545+12641	Asia/Harbin	Heilongjiang (except Mohe), Jilin
-CN	+2934+10635	Asia/Chongqing	central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
-CN	+4348+08735	Asia/Urumqi	most of Tibet & Xinjiang
-CN	+3929+07559	Asia/Kashgar	west Tibet & Xinjiang
-CO	+0436-07405	America/Bogota
-CR	+0956-08405	America/Costa_Rica
-CU	+2308-08222	America/Havana
-CV	+1455-02331	Atlantic/Cape_Verde
-CX	-1025+10543	Indian/Christmas
-CY	+3510+03322	Asia/Nicosia
-CZ	+5005+01426	Europe/Prague
-DE	+5230+01322	Europe/Berlin
-DJ	+1136+04309	Africa/Djibouti
-DK	+5540+01235	Europe/Copenhagen
-DM	+1518-06124	America/Dominica
-DO	+1828-06954	America/Santo_Domingo
-DZ	+3647+00303	Africa/Algiers
-EC	-0210-07950	America/Guayaquil	mainland
-EC	-0054-08936	Pacific/Galapagos	Galapagos Islands
-EE	+5925+02445	Europe/Tallinn
-EG	+3003+03115	Africa/Cairo
-EH	+2709-01312	Africa/El_Aaiun
-ER	+1520+03853	Africa/Asmara
-ES	+4024-00341	Europe/Madrid	mainland
-ES	+3553-00519	Africa/Ceuta	Ceuta & Melilla
-ES	+2806-01524	Atlantic/Canary	Canary Islands
-ET	+0902+03842	Africa/Addis_Ababa
-FI	+6010+02458	Europe/Helsinki
-FJ	-1808+17825	Pacific/Fiji
-FK	-5142-05751	Atlantic/Stanley
-FM	+0725+15147	Pacific/Chuuk	Chuuk (Truk) and Yap
-FM	+0658+15813	Pacific/Pohnpei	Pohnpei (Ponape)
-FM	+0519+16259	Pacific/Kosrae	Kosrae
-FO	+6201-00646	Atlantic/Faroe
-FR	+4852+00220	Europe/Paris
-GA	+0023+00927	Africa/Libreville
-GB	+513030-0000731	Europe/London
-GD	+1203-06145	America/Grenada
-GE	+4143+04449	Asia/Tbilisi
-GF	+0456-05220	America/Cayenne
-GG	+4927-00232	Europe/Guernsey
-GH	+0533-00013	Africa/Accra
-GI	+3608-00521	Europe/Gibraltar
-GL	+6411-05144	America/Godthab	most locations
-GL	+7646-01840	America/Danmarkshavn	east coast, north of Scoresbysund
-GL	+7029-02158	America/Scoresbysund	Scoresbysund / Ittoqqortoormiit
-GL	+7634-06847	America/Thule	Thule / Pituffik
-GM	+1328-01639	Africa/Banjul
-GN	+0931-01343	Africa/Conakry
-GP	+1614-06132	America/Guadeloupe
-GQ	+0345+00847	Africa/Malabo
-GR	+3758+02343	Europe/Athens
-GS	-5416-03632	Atlantic/South_Georgia
-GT	+1438-09031	America/Guatemala
-GU	+1328+14445	Pacific/Guam
-GW	+1151-01535	Africa/Bissau
-GY	+0648-05810	America/Guyana
-HK	+2217+11409	Asia/Hong_Kong
-HN	+1406-08713	America/Tegucigalpa
-HR	+4548+01558	Europe/Zagreb
-HT	+1832-07220	America/Port-au-Prince
-HU	+4730+01905	Europe/Budapest
-ID	-0610+10648	Asia/Jakarta	Java & Sumatra
-ID	-0002+10920	Asia/Pontianak	west & central Borneo
-ID	-0507+11924	Asia/Makassar	east & south Borneo, Celebes, Bali, Nusa Tengarra, west Timor
-ID	-0232+14042	Asia/Jayapura	Irian Jaya & the Moluccas
-IE	+5320-00615	Europe/Dublin
-IL	+3146+03514	Asia/Jerusalem
-IM	+5409-00428	Europe/Isle_of_Man
-IN	+2232+08822	Asia/Kolkata
-IO	-0720+07225	Indian/Chagos
-IQ	+3321+04425	Asia/Baghdad
-IR	+3540+05126	Asia/Tehran
-IS	+6409-02151	Atlantic/Reykjavik
-IT	+4154+01229	Europe/Rome
-JE	+4912-00207	Europe/Jersey
-JM	+1800-07648	America/Jamaica
-JO	+3157+03556	Asia/Amman
-JP	+353916+1394441	Asia/Tokyo
-KE	-0117+03649	Africa/Nairobi
-KG	+4254+07436	Asia/Bishkek
-KH	+1133+10455	Asia/Phnom_Penh
-KI	+0125+17300	Pacific/Tarawa	Gilbert Islands
-KI	-0308-17105	Pacific/Enderbury	Phoenix Islands
-KI	+0152-15720	Pacific/Kiritimati	Line Islands
-KM	-1141+04316	Indian/Comoro
-KN	+1718-06243	America/St_Kitts
-KP	+3901+12545	Asia/Pyongyang
-KR	+3733+12658	Asia/Seoul
-KW	+2920+04759	Asia/Kuwait
-KY	+1918-08123	America/Cayman
-KZ	+4315+07657	Asia/Almaty	most locations
-KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda (Kyzylorda, Kzyl-Orda)
-KZ	+5017+05710	Asia/Aqtobe	Aqtobe (Aktobe)
-KZ	+4431+05016	Asia/Aqtau	Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
-KZ	+5113+05121	Asia/Oral	West Kazakhstan
-LA	+1758+10236	Asia/Vientiane
-LB	+3353+03530	Asia/Beirut
-LC	+1401-06100	America/St_Lucia
-LI	+4709+00931	Europe/Vaduz
-LK	+0656+07951	Asia/Colombo
-LR	+0618-01047	Africa/Monrovia
-LS	-2928+02730	Africa/Maseru
-LT	+5441+02519	Europe/Vilnius
-LU	+4936+00609	Europe/Luxembourg
-LV	+5657+02406	Europe/Riga
-LY	+3254+01311	Africa/Tripoli
-MA	+3339-00735	Africa/Casablanca
-MC	+4342+00723	Europe/Monaco
-MD	+4700+02850	Europe/Chisinau
-ME	+4226+01916	Europe/Podgorica
-MF	+1804-06305	America/Marigot
-MG	-1855+04731	Indian/Antananarivo
-MH	+0709+17112	Pacific/Majuro	most locations
-MH	+0905+16720	Pacific/Kwajalein	Kwajalein
-MK	+4159+02126	Europe/Skopje
-ML	+1239-00800	Africa/Bamako
-MM	+1647+09610	Asia/Rangoon
-MN	+4755+10653	Asia/Ulaanbaatar	most locations
-MN	+4801+09139	Asia/Hovd	Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
-MN	+4804+11430	Asia/Choibalsan	Dornod, Sukhbaatar
-MO	+2214+11335	Asia/Macau
-MP	+1512+14545	Pacific/Saipan
-MQ	+1436-06105	America/Martinique
-MR	+1806-01557	Africa/Nouakchott
-MS	+1643-06213	America/Montserrat
-MT	+3554+01431	Europe/Malta
-MU	-2010+05730	Indian/Mauritius
-MV	+0410+07330	Indian/Maldives
-MW	-1547+03500	Africa/Blantyre
-MX	+1924-09909	America/Mexico_City	Central Time - most locations
-MX	+2105-08646	America/Cancun	Central Time - Quintana Roo
-MX	+2058-08937	America/Merida	Central Time - Campeche, Yucatan
-MX	+2540-10019	America/Monterrey	Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border
-MX	+2550-09730	America/Matamoros	US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border
-MX	+2313-10625	America/Mazatlan	Mountain Time - S Baja, Nayarit, Sinaloa
-MX	+2838-10605	America/Chihuahua	Mexican Mountain Time - Chihuahua away from US border
-MX	+2934-10425	America/Ojinaga	US Mountain Time - Chihuahua near US border
-MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
-MX	+3232-11701	America/Tijuana	US Pacific Time - Baja California near US border
-MX	+3018-11452	America/Santa_Isabel	Mexican Pacific Time - Baja California away from US border
-MX	+2048-10515	America/Bahia_Banderas	Mexican Central Time - Bahia de Banderas
-MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
-MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
-MZ	-2558+03235	Africa/Maputo
-NA	-2234+01706	Africa/Windhoek
-NC	-2216+16627	Pacific/Noumea
-NE	+1331+00207	Africa/Niamey
-NF	-2903+16758	Pacific/Norfolk
-NG	+0627+00324	Africa/Lagos
-NI	+1209-08617	America/Managua
-NL	+5222+00454	Europe/Amsterdam
-NO	+5955+01045	Europe/Oslo
-NP	+2743+08519	Asia/Kathmandu
-NR	-0031+16655	Pacific/Nauru
-NU	-1901-16955	Pacific/Niue
-NZ	-3652+17446	Pacific/Auckland	most locations
-NZ	-4357-17633	Pacific/Chatham	Chatham Islands
-OM	+2336+05835	Asia/Muscat
-PA	+0858-07932	America/Panama
-PE	-1203-07703	America/Lima
-PF	-1732-14934	Pacific/Tahiti	Society Islands
-PF	-0900-13930	Pacific/Marquesas	Marquesas Islands
-PF	-2308-13457	Pacific/Gambier	Gambier Islands
-PG	-0930+14710	Pacific/Port_Moresby
-PH	+1435+12100	Asia/Manila
-PK	+2452+06703	Asia/Karachi
-PL	+5215+02100	Europe/Warsaw
-PM	+4703-05620	America/Miquelon
-PN	-2504-13005	Pacific/Pitcairn
-PR	+182806-0660622	America/Puerto_Rico
-PS	+3130+03428	Asia/Gaza
-PT	+3843-00908	Europe/Lisbon	mainland
-PT	+3238-01654	Atlantic/Madeira	Madeira Islands
-PT	+3744-02540	Atlantic/Azores	Azores
-PW	+0720+13429	Pacific/Palau
-PY	-2516-05740	America/Asuncion
-QA	+2517+05132	Asia/Qatar
-RE	-2052+05528	Indian/Reunion
-RO	+4426+02606	Europe/Bucharest
-RS	+4450+02030	Europe/Belgrade
-RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
-RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
-RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
-RU	+5312+05009	Europe/Samara	Moscow - Samara, Udmurtia
-RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
-RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
-RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
-RU	+5345+08707	Asia/Novokuznetsk	Moscow+03 - Novokuznetsk
-RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
-RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
-RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
-RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
-RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
-RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
-RU	+5301+15839	Asia/Kamchatka	Moscow+08 - Kamchatka
-RU	+6445+17729	Asia/Anadyr	Moscow+08 - Bering Sea
-RW	-0157+03004	Africa/Kigali
-SA	+2438+04643	Asia/Riyadh
-SB	-0932+16012	Pacific/Guadalcanal
-SC	-0440+05528	Indian/Mahe
-SD	+1536+03232	Africa/Khartoum
-SE	+5920+01803	Europe/Stockholm
-SG	+0117+10351	Asia/Singapore
-SH	-1555-00542	Atlantic/St_Helena
-SI	+4603+01431	Europe/Ljubljana
-SJ	+7800+01600	Arctic/Longyearbyen
-SK	+4809+01707	Europe/Bratislava
-SL	+0830-01315	Africa/Freetown
-SM	+4355+01228	Europe/San_Marino
-SN	+1440-01726	Africa/Dakar
-SO	+0204+04522	Africa/Mogadishu
-SR	+0550-05510	America/Paramaribo
-ST	+0020+00644	Africa/Sao_Tome
-SV	+1342-08912	America/El_Salvador
-SY	+3330+03618	Asia/Damascus
-SZ	-2618+03106	Africa/Mbabane
-TC	+2128-07108	America/Grand_Turk
-TD	+1207+01503	Africa/Ndjamena
-TF	-492110+0701303	Indian/Kerguelen
-TG	+0608+00113	Africa/Lome
-TH	+1345+10031	Asia/Bangkok
-TJ	+3835+06848	Asia/Dushanbe
-TK	-0922-17114	Pacific/Fakaofo
-TL	-0833+12535	Asia/Dili
-TM	+3757+05823	Asia/Ashgabat
-TN	+3648+01011	Africa/Tunis
-TO	-2110-17510	Pacific/Tongatapu
-TR	+4101+02858	Europe/Istanbul
-TT	+1039-06131	America/Port_of_Spain
-TV	-0831+17913	Pacific/Funafuti
-TW	+2503+12130	Asia/Taipei
-TZ	-0648+03917	Africa/Dar_es_Salaam
-UA	+5026+03031	Europe/Kiev	most locations
-UA	+4837+02218	Europe/Uzhgorod	Ruthenia
-UA	+4750+03510	Europe/Zaporozhye	Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk
-UA	+4457+03406	Europe/Simferopol	central Crimea
-UG	+0019+03225	Africa/Kampala
-UM	+1645-16931	Pacific/Johnston	Johnston Atoll
-UM	+2813-17722	Pacific/Midway	Midway Islands
-UM	+1917+16637	Pacific/Wake	Wake Island
-US	+404251-0740023	America/New_York	Eastern Time
-US	+421953-0830245	America/Detroit	Eastern Time - Michigan - most locations
-US	+381515-0854534	America/Kentucky/Louisville	Eastern Time - Kentucky - Louisville area
-US	+364947-0845057	America/Kentucky/Monticello	Eastern Time - Kentucky - Wayne County
-US	+394606-0860929	America/Indiana/Indianapolis	Eastern Time - Indiana - most locations
-US	+384038-0873143	America/Indiana/Vincennes	Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
-US	+410305-0863611	America/Indiana/Winamac	Eastern Time - Indiana - Pulaski County
-US	+382232-0862041	America/Indiana/Marengo	Eastern Time - Indiana - Crawford County
-US	+382931-0871643	America/Indiana/Petersburg	Eastern Time - Indiana - Pike County
-US	+384452-0850402	America/Indiana/Vevay	Eastern Time - Indiana - Switzerland County
-US	+415100-0873900	America/Chicago	Central Time
-US	+375711-0864541	America/Indiana/Tell_City	Central Time - Indiana - Perry County
-US	+411745-0863730	America/Indiana/Knox	Central Time - Indiana - Starke County
-US	+450628-0873651	America/Menominee	Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
-US	+470659-1011757	America/North_Dakota/Center	Central Time - North Dakota - Oliver County
-US	+465042-1012439	America/North_Dakota/New_Salem	Central Time - North Dakota - Morton County (except Mandan area)
-US	+394421-1045903	America/Denver	Mountain Time
-US	+433649-1161209	America/Boise	Mountain Time - south Idaho & east Oregon
-US	+364708-1084111	America/Shiprock	Mountain Time - Navajo
-US	+332654-1120424	America/Phoenix	Mountain Standard Time - Arizona
-US	+340308-1181434	America/Los_Angeles	Pacific Time
-US	+611305-1495401	America/Anchorage	Alaska Time
-US	+581807-1342511	America/Juneau	Alaska Time - Alaska panhandle
-US	+593249-1394338	America/Yakutat	Alaska Time - Alaska panhandle neck
-US	+643004-1652423	America/Nome	Alaska Time - west Alaska
-US	+515248-1763929	America/Adak	Aleutian Islands
-US	+211825-1575130	Pacific/Honolulu	Hawaii
-UY	-3453-05611	America/Montevideo
-UZ	+3940+06648	Asia/Samarkand	west Uzbekistan
-UZ	+4120+06918	Asia/Tashkent	east Uzbekistan
-VA	+415408+0122711	Europe/Vatican
-VC	+1309-06114	America/St_Vincent
-VE	+1030-06656	America/Caracas
-VG	+1827-06437	America/Tortola
-VI	+1821-06456	America/St_Thomas
-VN	+1045+10640	Asia/Ho_Chi_Minh
-VU	-1740+16825	Pacific/Efate
-WF	-1318-17610	Pacific/Wallis
-WS	-1350-17144	Pacific/Apia
-YE	+1245+04512	Asia/Aden
-YT	-1247+04514	Indian/Mayotte
-ZA	-2615+02800	Africa/Johannesburg
-ZM	-1525+02817	Africa/Lusaka
-ZW	-1750+03103	Africa/Harare