am 40812f1c: am 1bf9f693: Merge "Use OUT_DIR in atree to find android.jar"

* commit '40812f1c4b312d8276eb2839c06d2d76dd4f97e1':
  Use OUT_DIR in atree to find android.jar
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/apps/Development/AndroidManifest.xml b/apps/Development/AndroidManifest.xml
index c809554..c91e21b 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" />
@@ -117,7 +118,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/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..fbb6a40 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" />
 
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..422bd7f 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>
@@ -208,4 +216,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/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..4cc1c91 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;
@@ -106,6 +110,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);
@@ -182,6 +197,7 @@
         updateDebugOptions();
         updateFinishOptions();
         updatePointerLocationOptions();
+        updateStrictModeVisualOptions();
         updateProcessLimitOptions();
         updateSharedOptions();
         updateFlingerOptions();
@@ -245,6 +261,24 @@
         mPointerLocationSpinner.setSelection(mPointerLocation);
     }
 
+    // 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);
@@ -456,6 +490,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/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/Fallback/res/values-ar/strings.xml b/apps/Fallback/res/values-ar/strings.xml
new file mode 100644
index 0000000..a695d8c
--- /dev/null
+++ b/apps/Fallback/res/values-ar/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"إجراء غير متاح"</string>
+    <string name="error" msgid="6539615832923362301">"هذا الإجراء غير متاح حاليًا."</string>
+</resources>
diff --git a/apps/Fallback/res/values-bg/strings.xml b/apps/Fallback/res/values-bg/strings.xml
new file mode 100644
index 0000000..2aaded2
--- /dev/null
+++ b/apps/Fallback/res/values-bg/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Неподдържано действие"</string>
+    <string name="error" msgid="6539615832923362301">"Понастоящем това действие не се поддържа."</string>
+</resources>
diff --git a/apps/Fallback/res/values-ca/strings.xml b/apps/Fallback/res/values-ca/strings.xml
new file mode 100644
index 0000000..c17ae77
--- /dev/null
+++ b/apps/Fallback/res/values-ca/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Acció no compatible"</string>
+    <string name="error" msgid="6539615832923362301">"Aquesta acció no és compatible actualment."</string>
+</resources>
diff --git a/apps/Fallback/res/values-en-rGB/strings.xml b/apps/Fallback/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..a7c82cb
--- /dev/null
+++ b/apps/Fallback/res/values-en-rGB/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Unsupported action"</string>
+    <string name="error" msgid="6539615832923362301">"That action is not currently supported."</string>
+</resources>
diff --git a/apps/Fallback/res/values-fa/strings.xml b/apps/Fallback/res/values-fa/strings.xml
new file mode 100644
index 0000000..6f6c60f
--- /dev/null
+++ b/apps/Fallback/res/values-fa/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"بازگشت"</string>
+    <string name="title" msgid="8156274565006125136">"عملکرد پشتیبانی نشده"</string>
+    <string name="error" msgid="6539615832923362301">"آن عملکرد در حال حاضر پشتیبانی نمی شود."</string>
+</resources>
diff --git a/apps/Fallback/res/values-fi/strings.xml b/apps/Fallback/res/values-fi/strings.xml
new file mode 100644
index 0000000..124eb73
--- /dev/null
+++ b/apps/Fallback/res/values-fi/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Toiminto ei ole tuettu"</string>
+    <string name="error" msgid="6539615832923362301">"Toiminto ei ole tuettu tällä hetkellä."</string>
+</resources>
diff --git a/apps/Fallback/res/values-hr/strings.xml b/apps/Fallback/res/values-hr/strings.xml
new file mode 100644
index 0000000..6b8fdc3
--- /dev/null
+++ b/apps/Fallback/res/values-hr/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Pričuvna aplikacija"</string>
+    <string name="title" msgid="8156274565006125136">"Nepodržana radnja"</string>
+    <string name="error" msgid="6539615832923362301">"Ova radnja trenutno nije podržana."</string>
+</resources>
diff --git a/apps/Fallback/res/values-hu/strings.xml b/apps/Fallback/res/values-hu/strings.xml
new file mode 100644
index 0000000..4c9ede6
--- /dev/null
+++ b/apps/Fallback/res/values-hu/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Tartalék"</string>
+    <string name="title" msgid="8156274565006125136">"Nem támogatott művelet"</string>
+    <string name="error" msgid="6539615832923362301">"Ez a művelet jelenleg nem támogatott."</string>
+</resources>
diff --git a/apps/Fallback/res/values-in/strings.xml b/apps/Fallback/res/values-in/strings.xml
new file mode 100644
index 0000000..0bfaf16
--- /dev/null
+++ b/apps/Fallback/res/values-in/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Tindakan yang tidak didukung"</string>
+    <string name="error" msgid="6539615832923362301">"Saat ini tindakan tersebut tidak didukung."</string>
+</resources>
diff --git a/apps/Fallback/res/values-iw/strings.xml b/apps/Fallback/res/values-iw/strings.xml
new file mode 100644
index 0000000..671919b
--- /dev/null
+++ b/apps/Fallback/res/values-iw/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"החזרה"</string>
+    <string name="title" msgid="8156274565006125136">"פעולה לא נתמכת"</string>
+    <string name="error" msgid="6539615832923362301">"הפעולה אינה נתמכת בשלב זה."</string>
+</resources>
diff --git a/apps/Fallback/res/values-lt/strings.xml b/apps/Fallback/res/values-lt/strings.xml
new file mode 100644
index 0000000..c715f42
--- /dev/null
+++ b/apps/Fallback/res/values-lt/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Nepalaikomas veiksmas"</string>
+    <string name="error" msgid="6539615832923362301">"Šis veiksmas šiuo metu nepalaikomas."</string>
+</resources>
diff --git a/apps/Fallback/res/values-lv/strings.xml b/apps/Fallback/res/values-lv/strings.xml
new file mode 100644
index 0000000..63b3384
--- /dev/null
+++ b/apps/Fallback/res/values-lv/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Atkāpšanās"</string>
+    <string name="title" msgid="8156274565006125136">"Darbība netiek atbalstīta"</string>
+    <string name="error" msgid="6539615832923362301">"Šī darbība pašlaik netiek atbalstīta."</string>
+</resources>
diff --git a/apps/Fallback/res/values-ro/strings.xml b/apps/Fallback/res/values-ro/strings.xml
new file mode 100644
index 0000000..222de48
--- /dev/null
+++ b/apps/Fallback/res/values-ro/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Alternativă"</string>
+    <string name="title" msgid="8156274565006125136">"Acţiune neacceptată"</string>
+    <string name="error" msgid="6539615832923362301">"Această acţiune nu este acceptată în prezent."</string>
+</resources>
diff --git a/apps/Fallback/res/values-sk/strings.xml b/apps/Fallback/res/values-sk/strings.xml
new file mode 100644
index 0000000..97ad356
--- /dev/null
+++ b/apps/Fallback/res/values-sk/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Záloha"</string>
+    <string name="title" msgid="8156274565006125136">"Akcia nie je podporovaná"</string>
+    <string name="error" msgid="6539615832923362301">"Táto akcia momentálne nie je podporovaná."</string>
+</resources>
diff --git a/apps/Fallback/res/values-sl/strings.xml b/apps/Fallback/res/values-sl/strings.xml
new file mode 100644
index 0000000..322f466
--- /dev/null
+++ b/apps/Fallback/res/values-sl/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Nadomestni program"</string>
+    <string name="title" msgid="8156274565006125136">"Dejanje ni podprto."</string>
+    <string name="error" msgid="6539615832923362301">"To dejanje trenutno še ni podprto."</string>
+</resources>
diff --git a/apps/Fallback/res/values-sr/strings.xml b/apps/Fallback/res/values-sr/strings.xml
new file mode 100644
index 0000000..c58ba4f
--- /dev/null
+++ b/apps/Fallback/res/values-sr/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Заменска апликација"</string>
+    <string name="title" msgid="8156274565006125136">"Неподржана радња"</string>
+    <string name="error" msgid="6539615832923362301">"Та радња тренутно није подржана."</string>
+</resources>
diff --git a/apps/Fallback/res/values-th/strings.xml b/apps/Fallback/res/values-th/strings.xml
new file mode 100644
index 0000000..3c9cd8a
--- /dev/null
+++ b/apps/Fallback/res/values-th/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"การทำงานไม่ได้รับการสนับสนุน"</string>
+    <string name="error" msgid="6539615832923362301">"การทำงานนี้ยังไม่ได้รับการสนับสนุนในปัจจุบัน"</string>
+</resources>
diff --git a/apps/Fallback/res/values-tl/strings.xml b/apps/Fallback/res/values-tl/strings.xml
new file mode 100644
index 0000000..c2f8b99
--- /dev/null
+++ b/apps/Fallback/res/values-tl/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Hindi suportadong pagkilos"</string>
+    <string name="error" msgid="6539615832923362301">"Hindi kasalukuyang suportado ang pagkilos na iyon."</string>
+</resources>
diff --git a/apps/Fallback/res/values-uk/strings.xml b/apps/Fallback/res/values-uk/strings.xml
new file mode 100644
index 0000000..62a722c
--- /dev/null
+++ b/apps/Fallback/res/values-uk/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Авар.режим"</string>
+    <string name="title" msgid="8156274565006125136">"Непідтримувана дія"</string>
+    <string name="error" msgid="6539615832923362301">"Дія наразі не підтримується."</string>
+</resources>
diff --git a/apps/Fallback/res/values-vi/strings.xml b/apps/Fallback/res/values-vi/strings.xml
new file mode 100644
index 0000000..56c21ae
--- /dev/null
+++ b/apps/Fallback/res/values-vi/strings.xml
@@ -0,0 +1,22 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Dự phòng"</string>
+    <string name="title" msgid="8156274565006125136">"Tác vụ không được hỗ trợ"</string>
+    <string name="error" msgid="6539615832923362301">"Tác vụ đó hiện không được hỗ trợ."</string>
+</resources>
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/NOTICE b/apps/GraphicsLab/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/apps/GraphicsLab/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/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/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/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/build/sdk.atree b/build/sdk.atree
index 0861351..cceec19 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -157,7 +157,6 @@
 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
@@ -172,6 +171,7 @@
 development/samples/VoiceRecognitionService  samples/${PLATFORM_NAME}/VoiceRecognitionService
 development/samples/Wiktionary               samples/${PLATFORM_NAME}/Wiktionary
 development/samples/WiktionarySimple         samples/${PLATFORM_NAME}/WiktionarySimple
+development/samples/XmlAdapters              samples/${PLATFORM_NAME}/XmlAdapters
 
 # NOTICE files are copied by build/core/Makefile from sdk.git
 sdk/files/sdk_files_NOTICE.txt samples/${PLATFORM_NAME}/NOTICE.txt
diff --git a/build/tools/windows_sdk.mk b/build/tools/windows_sdk.mk
index e7e63c7..7a0443d 100644
--- a/build/tools/windows_sdk.mk
+++ b/build/tools/windows_sdk.mk
@@ -40,7 +40,10 @@
 WIN_SDK_DIR   := $(subst $(HOST_OS)-$(HOST_ARCH),windows,$(LINUX_SDK_DIR))
 WIN_SDK_ZIP   := $(WIN_SDK_DIR)/$(WIN_SDK_NAME).zip
 
-$(call dist-for-goals, win_sdk, $(WIN_SDK_ZIP))
+# Also dist $(INTERNAL_SDK_TARGET), which is the original linux sdk package.
+# INTERNAL_SDK_TARGET is defined in build/core/Makefile.
+$(call dist-for-goals, win_sdk, $(WIN_SDK_ZIP) \
+    $(INTERNAL_SDK_TARGET))
 
 .PHONY: win_sdk winsdk-tools
 
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 68fb2a5..2f14a26 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -732,6 +732,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")) {
@@ -861,18 +864,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;
     }
 
@@ -1258,7 +1249,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");
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 f1edae1..8ff9c92 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..7e60b7f 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;
@@ -267,12 +268,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,23 +297,15 @@
 
                 // 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);
 
@@ -597,41 +599,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 +645,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/ide/eclipse/.classpath b/ide/eclipse/.classpath
index 1994220..44ecf3f 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -28,14 +28,15 @@
 	<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"/>
@@ -51,6 +52,7 @@
 	<classpathentry kind="src" path="frameworks/base/vpn/java"/>
 	<classpathentry kind="src" path="frameworks/base/wifi/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"/>
@@ -68,7 +70,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,6 +79,8 @@
 	<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"/>
@@ -90,10 +93,13 @@
 	<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/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/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/about/index.jd b/pdk/docs/about/index.jd
index 2f98b65..43d2a8d 100644
--- a/pdk/docs/about/index.jd
+++ b/pdk/docs/about/index.jd
@@ -3,10 +3,10 @@
 doc.hidenav=true
 @jd:body
 <p>Android is an open-source software stack created for mobile phones and
-other devices.  The Android Open Source Project (AOSP) is tasked with the
-maintenance and further development of Android. Many device manufacturers have
-brought to market devices running Android, and they are readibly available
-around the world.</p>
+other devices.  The Android Open Source Project (AOSP), led by Google, is
+tasked with the maintenance and further development of Android. Many device
+manufacturers have brought to market devices running Android, and they are
+readibly available around the world.</p>
 <p>Our primary purpose is to build an excellent software platform for everyday
 users. A number of companies have committed many engineers to achieve this
 goal, and the result is a full production quality consumer product whose
diff --git a/pdk/docs/about/philosophy.jd b/pdk/docs/about/philosophy.jd
index 1aa1ccf..1562e42 100644
--- a/pdk/docs/about/philosophy.jd
+++ b/pdk/docs/about/philosophy.jd
@@ -2,7 +2,7 @@
 doc.type=about
 doc.hidenav=true
 @jd:body
-<p>Android is an open-source software stack for mobile phones and similar
+<p>Android is an open-source software stack for mobile phones and other
 devices.</p>
 <h2>Origin and Goal</h2>
 <p>Android was originated by a group of companies known as the Open Handset
@@ -16,12 +16,11 @@
 ideas a reality. We wanted to make sure that there was no central point of
 failure, where one industry player could restrict or control the innovations
 of any other. The solution we chose was an open and open-source platform.</p>
-<p>But the ultimate goal, of course, is to improve the mobile experience for
-real users by facilitating innovation. Accordingly, the primary goal of the
-AOSP is to make sure Android is a success as an end user product.</p>
+<p>The goal of the Android Open Source Project is to create a successful
+real-world product that improves the mobile experience for end users.</p>
 <h2>Governance Philosophy</h2>
 <p>The companies that have invested in Android have done so on its merits,
-because we collectively believe that an open platform is necessary. Android is
+because we believe that an open platform is necessary. Android is
 intentionally and explicitly an open-source -- as opposed to free software --
 effort: a group of organizations with shared needs has pooled
 resources to collaborate on a single implementation of a shared product. 
@@ -34,20 +33,19 @@
 Anyone can (and will!) use the Android source code for any purpose, and we
 welcome all such uses. However, in order to take part in the shared
 ecosystem of applications that we are building around Android, device builders
-can take advantage of the Compatibility Program.</p>
+must participate in the Compatibility Program.</p>
 <p>Though Android consists of multiple sub-projects, this is strictly a
 project-management technique. We view and manage Android as a single,
 holistic software product, not a "distribution", specification, or collection
-of replaceable parts. Conceptually, our notion is that device builders port
+of replaceable parts. Our intent is that device builders port
 Android to a device; they don't implement a specification or curate a
 distribution.</p>
 <h2>How We Work</h2>
 <p>We know that quality does not come without hard work. Along with many
 partners, Google has contributed full-time engineers, product managers, UI
 designers, Quality Assurance, and all the other roles required to bring
-modern devices to market.  We integrate the open source administration and
+modern devices to market.  We roll the open source administration and
 maintenance into the larger product development cycle.</p>
-<p>In a nutshell:</p>
 <ul>
 <li>At any given moment, there is a current latest release of the Android
 platform. This typically takes the form of a branch in the tree.</li>
@@ -56,18 +54,9 @@
 features, and so on.</li>
 <li>In parallel, Google works internally on the next version of the
 Android platform and framework, working according to the product's needs and
-goals. Some of the work from the current latest tree will promoted into these
-releases.</li>
-<li>When the "n+1"th version is determined to be nearing completion, it will
-be published to the public source tree, and become the new latest
-release.</li>
-<li>Since Android is open source, nothing prevents device implementers from
-shipping devices on older (obsolete) Android builds. However, active work will
-be focused on the current platform release.</li>
+goals. We develop the next version of Android by working with a device partner
+on a flagship device whose specifications are chosen to push Android
+in the direction we believe it should go.</li>
+<li>When the "n+1"th version is ready, it will be published to the public
+source tree, and become the new latest release.</li>
 </ul>
-<p>To meet our goals, Android needs to achieve widespread, compatible
-adoption. We believe that the best way to accomplish that is to make sure that
-we ship high-quality, flagship devices with an intense product and end-user
-focus. The "next release" of Android is driven by the product needs for the next
-generation of mobile devices; the resulting excellent product is then released
-to open source and becomes the new current version of the platform.</p>
diff --git a/pdk/docs/community/groups-charter.jd b/pdk/docs/community/groups-charter.jd
index 6d5b501..959917e 100644
--- a/pdk/docs/community/groups-charter.jd
+++ b/pdk/docs/community/groups-charter.jd
@@ -1,26 +1,66 @@
 page.title=Android Discussion Groups Charter
 doc.type=community
+doc.hidenav=true
 @jd:body
-<h2>
-Audience
-</h2>
-<p>These discussion groups are intended for developers working with the Android platform. Everyone is welcome to join in, provided you follow our community's policies described below. Our users help each other, and many experts post to these groups, including members of the Open Handset Alliance.
+<h2>Audience</h2>
+<p>These discussion groups are intended for developers working with the
+Android platform. Everyone is welcome to join in, provided you follow our
+community's policies described below. Our users help each other, and many
+experts post to these groups, including members of the Open Handset Alliance.
 </p>
-<p>No topic is off-limits, provided it relates to Android in some way. However, since these are very busy lists, search the archives before posting your question; you may find your question has already been answered.
+<p>No topic is off-limits, provided it relates to Android in some way.
+However, since these are very busy lists, search the archives before posting
+your question; you may find your question has already been answered.
 </p>
-<h2>
-Mailing list rules
-</h2>
-<p>We love simplicity and hate restrictions, so we keep our policies minimal. The rules below describe what's expected of subscribers to the Android mailing lists.
+<h2>Mailing list rules</h2>
+<p>We love simplicity and hate restrictions, so we keep our policies minimal.
+The rules below describe what's expected of subscribers to the Android mailing
+lists.
 </p>
 <ul><li><b>Please be friendly</b>
-<br>Showing courtesy and respect to others is a vital part of the Android culture, and we expect everyone participating in the Android community to join us in accepting nothing less. Being courteous does not mean we can't constructively disagree with each other, but it does mean that we must be polite when we do so. There's never a reason to be antagonistic or dismissive toward anyone; if you think there is, think again before you post.<br><br>Mobile development is serious business, but it's also a lot of fun. Let's keep it that way. Let's strive to be one of the friendliest communities in all of open source.<br><br></li>
+<br>Showing courtesy and respect to others is a vital part of the Android
+culture, and we expect everyone participating in the Android community to join
+us in accepting nothing less. Being courteous does not mean we can't
+constructively disagree with each other, but it does mean that we must be
+polite when we do so. There's never a reason to be antagonistic or dismissive
+toward anyone; if you think there is, think again before you
+post.<br><br>Mobile development is serious business, but it's also a lot of
+fun. Let's keep it that way. Let's strive to be one of the friendliest
+communities in all of open source.<br><br></li>
+
 <li><b>Allowed discussion topics</b>
-<br>Most topics are technical discussions of Android or users helping each other, but this group is intended for discussions of<i>everything</i>
-in the world of Android. We welcome announcements and discussion of products, libraries, publications, and other interesting Android-related news. We even welcome (polite!) discussion of articles and ideas critical of Android--after all, we can't improve if we don't listen. There are no restrictions on the subject matter, and we don't exclude discussions of commercial products if users are interested in talking about them.<br><br>However, we hate spam almost as passionately as we love courtesy and respect, so we reserve the right to limit discussions that amount to spam. Outright spam will result in the spammer being immediately and permanently banned from the list.
+<br>Most of our groups are for technical discussions of Android or users
+helping each other. Generally we don't put hard restrictions on the topics
+discussed in the group: as long as the topic is relevant to Android in some
+way, it's welcome on our groups.  We welcome announcements and discussion of
+products, libraries, publications, and other interesting Android-related news,
+but <b>please do not cross-post</b>. Post only to the most relevant group for
+your message. We even welcome (polite!) discussion of articles and ideas
+critical of Android--after all, we can't improve if we don't listen.<br><br>
 </li>
+
+<li><b>Working Lists</b>
+<br>Some of our groups are considered "working lists", by which we mean that the
+list is intended to be used in support of the completion of specific tasks. On
+these groups, we don't welcome off-topic conversations, and will generally ask
+you to take general discussions to a different list. Since these are lists
+where people are trying to get work done, we will be pretty aggressive about
+keeping the noise level low. We ask that you respect our contributors' time
+and keep general discussions to appropriate lists.<br><br>
+</li>
+
+<li><b>Spam</b>
+<br>We hate spam almost as passionately as we love courtesy and respect, so we
+reserve the right to limit discussions that amount to spam. Outright spam will
+result in the spammer being immediately and permanently banned from the list.
+<br><br></li>
 </ul>
-<p>The most important rule is friendliness. Remember: disrespect and rudeness are not welcome in our community under any circumstances. We don't have a formal policy on dealing with troublemakers, and we hope we never need one.That said, we do pledge to do our best to be fair, and we will always try to warn someone before banning him or her.
+
+<p>The most important rule is friendliness. Remember: disrespect and rudeness
+are not welcome in our community under any circumstances. We don't have a
+formal policy on dealing with troublemakers, and we hope we never need
+one.That said, we do pledge to do our best to be fair, and we will always try
+to warn someone before banning him or her.
 </p>
 <h2>
 Contacting the moderators
diff --git a/pdk/docs/community/index.jd b/pdk/docs/community/index.jd
index 6e6f59e..46adf37 100644
--- a/pdk/docs/community/index.jd
+++ b/pdk/docs/community/index.jd
@@ -1,7 +1,7 @@
-page.title=Community
+page.title=Android Community
 doc.type=community
+doc.hidenav=true
 @jd:body
-<h1>Android Community</h1>
 <p>Welcome to the Android community!</p>
 <p>The key to any community is, obviously, communication. Like most projects,
 Android communicates via mailing lists. Because Android is an extremely large
@@ -37,6 +37,14 @@
 
 <h2>Open Source Project discussions</h2>
 <ul>
+<li><b>android-platform</b><br/>
+This list is for general discussion about the Android open-source project or
+the platform technologies.<br/><br/>
+Subscribe using Google Groups: <a
+href="http://groups.google.com/group/android-platform">android-platform</a><br/>
+Subscribe via email: <a href="mailto:android-platform+subscribe@googlegroups.com">android-platform+subscribe@googlegroups.com</a>
+</li>
+
 <li><b>android-building</b><br/>
 Subscribe to this list for discussion and help on building the Android source
 code, and on the build system. If you've just checked out the source code and
@@ -58,14 +66,14 @@
 Subscribe via email: <a href="mailto:android-porting+subscribe@googlegroups.com">android-porting+subscribe@googlegroups.com</a>
 </li>
 
-<li><b>android-platform</b><br/>
-This list is for developers who want to contribute code to the Android
-user-space projects, such as the core system libraries, the Android
-services, the public APIs, or the built-in applications. Note: contributors
+<li><b>android-contrib</b><br/>
+This list is for developers who want to contribute code to Android. This is a
+working list, and is not appropriate for general discussion. We ask that
+general discussion go to android-platform.  Note: contributors
 to the Android kernel should go to the android-kernel list, below.<br/><br/>
 Subscribe using Google Groups: <a
-href="http://groups.google.com/group/android-platform">android-platform</a><br/>
-Subscribe via email: <a href="mailto:android-platform+subscribe@googlegroups.com">android-platform+subscribe@googlegroups.com</a>
+href="http://groups.google.com/group/android-contrib">android-contrib</a><br/>
+Subscribe via email: <a href="mailto:android-contrib+subscribe@googlegroups.com">android-contrib+subscribe@googlegroups.com</a>
 </li>
 
 <li><b>android-kernel</b><br/>
@@ -88,27 +96,35 @@
 under "subscribe via email" in the lists above.</p>
 <p>To set up how you receive mailing list postings by email:</p>
 <ol>
-<li>Sign into the group via the Google Groups site. For example, for the android-framework group you would
-visit <a
-href="http://groups.google.com/group/android-framework">http://groups.google.com/group/android-framework</a>.</li>
+<li>Sign into the group via the Google Groups site. For example, for the android-platform group you would
+visit <a href="http://groups.google.com/group/android-platform">http://groups.google.com/group/android-platform</a>.</li>
 <li>Click "Edit my membership" on the right side.</li>
 <li>Under "How do you want to read this group?" select one of the email options.</li>
 </ol>
 
 <h2>Android on IRC</h2>
-<p>We also have a presence on IRC via Freenode. We maintain two official IRC
-channels on irc.freenode.net:</p>
+<p>We also have a presence on IRC via <a href="http://freenode.net/">freenode</a>.
+We maintain two official IRC channels on
+<a href="irc://irc.freenode.net/">irc.freenode.net</a> (access via the web
+at <a href="http://webchat.freenode.net/">freenode webchat</a>):</p>
 <ul>
-<li><b>#android</b> - dedicated to general Android discussion and porting concerns</li>
-<li><b>#android-dev</b> - dedicated to discussion about writing Android applications</li>
+<li><b><a href="irc://irc.freenode.net/android">#android</a></b>
+    &mdash; dedicated to general Android discussion and porting concerns</li>
+<li><b><a href="irc://irc.freenode.net/android-dev">#android-dev</a></b>
+    &mdash; dedicated to discussion about writing Android applications</li>
 </ul>
 <p>The channels above are official. There are a few other channels the
 community is using, but are not official. These aren't official or officially
 moderated/managed, so you use the channels below at your own risk. The Open
 Handset Alliance doesn't endorse these channels, there's no warranty express
-or implied, and so on. There may be more.</p>
+or implied, and so on. There may be more channels than just these listed.</p>
 <ul>
-<li><b>#android-offtopic</b> - for, well, off-topic discussions</li>
-<li><b>#android-root</b> - for discussion related to off-label uses of hardware</li>
-<li><b>#androidfra</b> - pour discuter d'Android en français</li>
+<li><b><a href="irc://irc.freenode.net/android-firehose">#android-firehose</a></b>
+    &mdash; displays in real-time the commits to the Android Open Source Project</li>
+<li><b><a href="irc://irc.freenode.net/android-fr">#android-fr</a></b>
+    &mdash; pour discuter d'Android en français</li>
+<li><b><a href="irc://irc.freenode.net/android-offtopic">#android-offtopic</a></b>
+    &mdash; for, well, off-topic discussions</li>
+<li><b><a href="irc://irc.freenode.net/android-root">#android-root</a></b>
+    &mdash; for discussion related to off-label uses of hardware</li>
 </ul>
diff --git a/pdk/docs/compatibility/2.1/versions.jd b/pdk/docs/compatibility/2.1/versions.jd
new file mode 100644
index 0000000..9687a96
--- /dev/null
+++ b/pdk/docs/compatibility/2.1/versions.jd
@@ -0,0 +1,19 @@
+page.title=Permitted Version Strings for Android 2.1
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.1-cdd.pdf">Android 2.1 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.1-based system. The only permitted values for
+<code>android.os.Build.VERSION.RELEASE</code> for Android 2.1 are:</p>
+<ul>
+<li>2.1</li>
+<li>2.1-update1</li>
+</ul>
diff --git a/pdk/docs/compatibility/2.2/versions.jd b/pdk/docs/compatibility/2.2/versions.jd
new file mode 100644
index 0000000..87b12eb
--- /dev/null
+++ b/pdk/docs/compatibility/2.2/versions.jd
@@ -0,0 +1,20 @@
+page.title=Permitted Version Strings for Android 2.2
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.2-cdd.pdf">Android 2.2 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.2-based system.</p>
+<p>The value of <code>android.os.Build.VERSION.RELEASE</code> for Android 2.2
+MUST be one of the following strings:</p>
+<ul>
+<li>2.2</li>
+<li>2.2.1</li>
+</ul>
diff --git a/pdk/docs/compatibility/2.3/versions.jd b/pdk/docs/compatibility/2.3/versions.jd
new file mode 100644
index 0000000..5f634ed
--- /dev/null
+++ b/pdk/docs/compatibility/2.3/versions.jd
@@ -0,0 +1,20 @@
+page.title=Permitted Version Strings for Android 2.3
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.3-cdd.pdf">Android 2.3 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.2-based system.</p>
+<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>
+</ul>
diff --git a/pdk/docs/compatibility/android-1.6-cdd.pdf b/pdk/docs/compatibility/android-1.6-cdd.pdf
new file mode 100644
index 0000000..ba7b4ad
--- /dev/null
+++ b/pdk/docs/compatibility/android-1.6-cdd.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/android-2.1-cdd.pdf b/pdk/docs/compatibility/android-2.1-cdd.pdf
new file mode 100644
index 0000000..7fe54c6
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.1-cdd.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/android-2.2-cdd.pdf b/pdk/docs/compatibility/android-2.2-cdd.pdf
new file mode 100644
index 0000000..fbc1e77
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.2-cdd.pdf
@@ -0,0 +1,4080 @@
+%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 105 0 R

+ /F4 107 0 R >>

+endobj

+% 'F1': class PDFType1Font 

+2 0 obj

+% Font Helvetica

+<< /BaseFont /Helvetica

+ /Encoding /WinAnsiEncoding

+ /Name /F1

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'FormXob.a31102908a592e8f94c7b4e032ffcc37': 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 [ 97 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 [ 97 0 R

+ /XYZ

+ 55

+ 456.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 [ 109 0 R

+ /XYZ

+ 55

+ 613.3887

+ 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 [ 109 0 R

+ /XYZ

+ 55

+ 530.11

+ 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 [ 109 0 R

+ /XYZ

+ 55

+ 420.985

+ 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 [ 109 0 R

+ /XYZ

+ 55

+ 344.6775

+ 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 [ 109 0 R

+ /XYZ

+ 55

+ 291.9275

+ 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 [ 111 0 R

+ /XYZ

+ 55

+ 742.865

+ 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 [ 111 0 R

+ /XYZ

+ 55

+ 678.865

+ 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 [ 111 0 R

+ /XYZ

+ 55

+ 246.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 [ 111 0 R

+ /XYZ

+ 55

+ 160.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 [ 113 0 R

+ /XYZ

+ 55

+ 722.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 [ 113 0 R

+ /XYZ

+ 55

+ 657.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 [ 113 0 R

+ /XYZ

+ 55

+ 306.9225

+ 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 [ 113 0 R

+ /XYZ

+ 55

+ 219.365

+ 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 [ 117 0 R

+ /XYZ

+ 55

+ 614.615

+ 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 [ 117 0 R

+ /XYZ

+ 55

+ 485.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 [ 117 0 R

+ /XYZ

+ 55

+ 297.4225

+ 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 [ 125 0 R

+ /XYZ

+ 55

+ 548.2975

+ 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 [ 125 0 R

+ /XYZ

+ 55

+ 450.4225

+ 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 [ 125 0 R

+ /XYZ

+ 55

+ 385.365

+ 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 [ 125 0 R

+ /XYZ

+ 55

+ 266.865

+ 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 [ 125 0 R

+ /XYZ

+ 55

+ 159.615

+ 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 [ 133 0 R

+ /XYZ

+ 55

+ 645.115

+ 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 [ 133 0 R

+ /XYZ

+ 55

+ 592.365

+ 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 [ 133 0 R

+ /XYZ

+ 55

+ 418.1388

+ 0 ]

+ /Rect [ 70

+ 267.6875

+ 189.625

+ 278.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER28': class LinkAnnotation 

+32 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 133 0 R

+ /XYZ

+ 55

+ 200.2013

+ 0 ]

+ /Rect [ 70

+ 256.4375

+ 197.1325

+ 267.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER29': class LinkAnnotation 

+33 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 134 0 R

+ /XYZ

+ 55

+ 747.2637

+ 0 ]

+ /Rect [ 70

+ 245.1875

+ 159.6025

+ 256.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER30': class LinkAnnotation 

+34 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 134 0 R

+ /XYZ

+ 55

+ 675.235

+ 0 ]

+ /Rect [ 85

+ 231.9375

+ 147.5275

+ 243.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER31': class LinkAnnotation 

+35 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 55

+ 698.7975

+ 0 ]

+ /Rect [ 85

+ 220.6875

+ 155.035

+ 231.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER32': class LinkAnnotation 

+36 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 55

+ 480.1725

+ 0 ]

+ /Rect [ 85

+ 209.4375

+ 147.1225

+ 220.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER33': class LinkAnnotation 

+37 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 141 0 R

+ /XYZ

+ 55

+ 747.2637

+ 0 ]

+ /Rect [ 70

+ 196.1875

+ 174.1975

+ 207.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER34': class LinkAnnotation 

+38 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 141 0 R

+ /XYZ

+ 55

+ 571.3262

+ 0 ]

+ /Rect [ 70

+ 184.9375

+ 155.8525

+ 196.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER35': class LinkAnnotation 

+39 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 141 0 R

+ /XYZ

+ 55

+ 320.2975

+ 0 ]

+ /Rect [ 85

+ 171.6875

+ 124.18

+ 182.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER36': class LinkAnnotation 

+40 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 146 0 R

+ /XYZ

+ 55

+ 607.115

+ 0 ]

+ /Rect [ 100

+ 158.4375

+ 244.645

+ 169.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER37': class LinkAnnotation 

+41 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 146 0 R

+ /XYZ

+ 55

+ 511.115

+ 0 ]

+ /Rect [ 100

+ 147.1875

+ 171.685

+ 158.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER38': class LinkAnnotation 

+42 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 146 0 R

+ /XYZ

+ 55

+ 469.615

+ 0 ]

+ /Rect [ 100

+ 135.9375

+ 205.0525

+ 147.1875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER39': class LinkAnnotation 

+43 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 146 0 R

+ /XYZ

+ 55

+ 404.7975

+ 0 ]

+ /Rect [ 85

+ 122.6875

+ 131.695

+ 133.9375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER40': class LinkAnnotation 

+44 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 146 0 R

+ /XYZ

+ 55

+ 253.9225

+ 0 ]

+ /Rect [ 85

+ 111.4375

+ 171.7075

+ 122.6875 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER41': class LinkAnnotation 

+45 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 146 0 R

+ /XYZ

+ 55

+ 165.2975

+ 0 ]

+ /Rect [ 85

+ 100.1875

+ 162.1225

+ 111.4375 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER42': class LinkAnnotation 

+46 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 148 0 R

+ /XYZ

+ 55

+ 710.0475

+ 0 ]

+ /Rect [ 85

+ 88.9375

+ 161.29

+ 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 237 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ]

+ /XObject << /FormXob.a31102908a592e8f94c7b4e032ffcc37 3 0 R >> >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER43': class LinkAnnotation 

+48 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 148 0 R

+ /XYZ

+ 55

+ 583.6725

+ 0 ]

+ /Rect [ 85

+ 730.6775

+ 115.015

+ 741.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER44': class LinkAnnotation 

+49 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 148 0 R

+ /XYZ

+ 55

+ 419.5475

+ 0 ]

+ /Rect [ 85

+ 719.4275

+ 152.53

+ 730.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER45': class LinkAnnotation 

+50 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 148 0 R

+ /XYZ

+ 55

+ 310.4225

+ 0 ]

+ /Rect [ 85

+ 708.1775

+ 185.86

+ 719.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER46': class LinkAnnotation 

+51 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 148 0 R

+ /XYZ

+ 55

+ 169.2975

+ 0 ]

+ /Rect [ 85

+ 696.9275

+ 126.265

+ 708.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER47': class LinkAnnotation 

+52 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 152 0 R

+ /XYZ

+ 55

+ 388.5475

+ 0 ]

+ /Rect [ 85

+ 685.6775

+ 152.11

+ 696.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER48': class LinkAnnotation 

+53 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 152 0 R

+ /XYZ

+ 55

+ 322.6725

+ 0 ]

+ /Rect [ 85

+ 674.4275

+ 135.4375

+ 685.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER49': class LinkAnnotation 

+54 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 152 0 R

+ /XYZ

+ 55

+ 256.7975

+ 0 ]

+ /Rect [ 85

+ 663.1775

+ 119.605

+ 674.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER50': class LinkAnnotation 

+55 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 152 0 R

+ /XYZ

+ 55

+ 202.1725

+ 0 ]

+ /Rect [ 85

+ 651.9275

+ 138.7825

+ 663.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER51': class LinkAnnotation 

+56 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 152 0 R

+ /XYZ

+ 55

+ 104.2975

+ 0 ]

+ /Rect [ 85

+ 640.6775

+ 173.7925

+ 651.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER52': class LinkAnnotation 

+57 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 154 0 R

+ /XYZ

+ 55

+ 612.2975

+ 0 ]

+ /Rect [ 85

+ 629.4275

+ 195.0625

+ 640.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER53': class LinkAnnotation 

+58 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 154 0 R

+ /XYZ

+ 55

+ 343.1725

+ 0 ]

+ /Rect [ 85

+ 618.1775

+ 135.4525

+ 629.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER54': class LinkAnnotation 

+59 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 154 0 R

+ /XYZ

+ 55

+ 222.3888

+ 0 ]

+ /Rect [ 70

+ 604.9275

+ 166.2775

+ 616.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER55': class LinkAnnotation 

+60 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 159 0 R

+ /XYZ

+ 55

+ 632.8888

+ 0 ]

+ /Rect [ 70

+ 593.6775

+ 177.115

+ 604.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER56': class LinkAnnotation 

+61 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 159 0 R

+ /XYZ

+ 55

+ 538.36

+ 0 ]

+ /Rect [ 85

+ 580.4275

+ 144.6025

+ 591.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER57': class LinkAnnotation 

+62 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 159 0 R

+ /XYZ

+ 55

+ 461.235

+ 0 ]

+ /Rect [ 85

+ 569.1775

+ 190.465

+ 580.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER58': class LinkAnnotation 

+63 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 159 0 R

+ /XYZ

+ 55

+ 384.11

+ 0 ]

+ /Rect [ 85

+ 557.9275

+ 182.5225

+ 569.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER59': class LinkAnnotation 

+64 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 159 0 R

+ /XYZ

+ 55

+ 318.235

+ 0 ]

+ /Rect [ 85

+ 546.6775

+ 216.73

+ 557.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER60': class LinkAnnotation 

+65 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 162 0 R

+ /XYZ

+ 55

+ 591.1387

+ 0 ]

+ /Rect [ 70

+ 533.4275

+ 161.2825

+ 544.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER61': class LinkAnnotation 

+66 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 162 0 R

+ /XYZ

+ 55

+ 452.9513

+ 0 ]

+ /Rect [ 70

+ 522.1775

+ 148.375

+ 533.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER62': class LinkAnnotation 

+67 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 162 0 R

+ /XYZ

+ 55

+ 226.0138

+ 0 ]

+ /Rect [ 70

+ 510.9275

+ 119.605

+ 522.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER63': class LinkAnnotation 

+68 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 163 0 R

+ /XYZ

+ 55

+ 747.2637

+ 0 ]

+ /Rect [ 70

+ 499.6775

+ 200.065

+ 510.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page2': class PDFPage 

+69 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 ]

+ /Contents 238 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER64': class LinkAnnotation 

+70 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 417.365

+ 0 ]

+ /Rect [ 125.8675

+ 663.865

+ 170.05

+ 675.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER65': class LinkAnnotation 

+71 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 404.115

+ 0 ]

+ /Rect [ 326.365

+ 565.865

+ 370.5475

+ 577.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER66': class LinkAnnotation 

+72 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 390.865

+ 0 ]

+ /Rect [ 309.6925

+ 522.615

+ 353.875

+ 533.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER67': class PDFDictionary 

+73 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 189.625

+ 405.1775

+ 297.1675

+ 416.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER68': class PDFDictionary 

+74 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 205.45

+ 391.9275

+ 369.6775

+ 403.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER69': class PDFDictionary 

+75 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 167.965

+ 378.6775

+ 254.6725

+ 389.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER70': class PDFDictionary 

+76 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 184.2325

+ 365.4275

+ 363.4825

+ 376.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER71': class PDFDictionary 

+77 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 172.9525

+ 352.1775

+ 413.8825

+ 363.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER72': class PDFDictionary 

+78 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 157.96

+ 338.9275

+ 358.885

+ 350.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER73': class PDFDictionary 

+79 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 186.715

+ 325.6775

+ 373.45

+ 336.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER74': class PDFDictionary 

+80 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 171.7

+ 312.4275

+ 400.96

+ 323.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER75': class PDFDictionary 

+81 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

+ 299.1775

+ 307.1575

+ 310.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER76': class PDFDictionary 

+82 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

+ 272.6775

+ 374.23

+ 283.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER77': class PDFDictionary 

+83 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

+ 259.4275

+ 346.2925

+ 270.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER78': class PDFDictionary 

+84 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 148.705

+ 246.1775

+ 368.8

+ 257.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER79': class PDFDictionary 

+85 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

+ 232.9275

+ 477.1975

+ 244.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER80': class PDFDictionary 

+86 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 129.535

+ 219.6775

+ 371.7325

+ 230.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER81': class PDFDictionary 

+87 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 96.6025

+ 206.4275

+ 313.3675

+ 217.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER82': class PDFDictionary 

+88 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 127.4425

+ 193.1775

+ 351.265

+ 204.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER83': class PDFDictionary 

+89 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 129.955

+ 179.9275

+ 269.1925

+ 191.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER84': class PDFDictionary 

+90 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 245.845

+ 166.6775

+ 453.865

+ 177.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER85': class PDFDictionary 

+91 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 164.1325

+ 153.4275

+ 364.645

+ 164.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER86': class PDFDictionary 

+92 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

+ 140.1775

+ 349.2025

+ 151.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER87': class PDFDictionary 

+93 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 138.7075

+ 126.9275

+ 355.06

+ 138.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER88': class PDFDictionary 

+94 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

+ 113.6775

+ 452.1775

+ 124.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER89': class PDFDictionary 

+95 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 167.8825

+ 100.4275

+ 389.23

+ 111.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER90': class PDFDictionary 

+96 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

+ 87.1775

+ 443.02

+ 98.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page3': class PDFPage 

+97 0 obj

+% Page dictionary

+<< /Annots [ 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

+ 89 0 R

+ 90 0 R

+ 91 0 R

+ 92 0 R

+ 93 0 R

+ 94 0 R

+ 95 0 R

+ 96 0 R ]

+ /Contents 239 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER91': class PDFDictionary 

+98 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 161.6125

+ 730.6775

+ 396.28

+ 741.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER92': class PDFDictionary 

+99 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 161.2075

+ 717.4275

+ 395.47

+ 728.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER93': class PDFDictionary 

+100 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 157.0525

+ 704.1775

+ 407.5825

+ 715.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER94': class PDFDictionary 

+101 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 220.3975

+ 690.9275

+ 429.6475

+ 702.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER95': class PDFDictionary 

+102 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

+ 677.6775

+ 388.825

+ 688.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER96': class LinkAnnotation 

+103 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 377.615

+ 0 ]

+ /Rect [ 460.615

+ 462.365

+ 504.7975

+ 473.615 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER97': class LinkAnnotation 

+104 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 364.365

+ 0 ]

+ /Rect [ 470.995

+ 311.74

+ 515.1775

+ 322.99 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F3': class PDFType1Font 

+105 0 obj

+% Font Courier

+<< /BaseFont /Courier

+ /Encoding /WinAnsiEncoding

+ /Name /F3

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER98': class LinkAnnotation 

+106 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 351.115

+ 0 ]

+ /Rect [ 336.2725

+ 258.99

+ 380.455

+ 270.24 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F4': class PDFType1Font 

+107 0 obj

+% Font Times-Roman

+<< /BaseFont /Times-Roman

+ /Encoding /WinAnsiEncoding

+ /Name /F4

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER99': class LinkAnnotation 

+108 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 337.865

+ 0 ]

+ /Rect [ 350.19

+ 182.99

+ 394.3725

+ 194.24 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page4': class PDFPage 

+109 0 obj

+% Page dictionary

+<< /Annots [ 98 0 R

+ 99 0 R

+ 100 0 R

+ 101 0 R

+ 102 0 R

+ 103 0 R

+ 104 0 R

+ 106 0 R

+ 108 0 R ]

+ /Contents 240 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page5': class PDFPage 

+110 0 obj

+% Page dictionary

+<< /Contents 241 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page6': class PDFPage 

+111 0 obj

+% Page dictionary

+<< /Contents 242 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER100': class LinkAnnotation 

+112 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 324.615

+ 0 ]

+ /Rect [ 381.61

+ 261.6775

+ 425.7925

+ 272.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page7': class PDFPage 

+113 0 obj

+% Page dictionary

+<< /Annots [ 112 0 R ]

+ /Contents 243 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER101': class LinkAnnotation 

+114 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 311.365

+ 0 ]

+ /Rect [ 447.265

+ 645.6775

+ 491.4475

+ 656.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER102': class LinkAnnotation 

+115 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 311.365

+ 0 ]

+ /Rect [ 160.4575

+ 506.4275

+ 204.64

+ 517.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER103': class LinkAnnotation 

+116 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 390.865

+ 0 ]

+ /Rect [ 125.4475

+ 429.3025

+ 169.63

+ 440.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page8': class PDFPage 

+117 0 obj

+% Page dictionary

+<< /Annots [ 114 0 R

+ 115 0 R

+ 116 0 R ]

+ /Contents 244 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER104': class LinkAnnotation 

+118 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 298.115

+ 0 ]

+ /Rect [ 500.1475

+ 503.0525

+ 548.5

+ 514.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER105': class LinkAnnotation 

+119 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 284.865

+ 0 ]

+ /Rect [ 515.1475

+ 352.4275

+ 553.075

+ 363.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER106': class LinkAnnotation 

+120 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 284.865

+ 0 ]

+ /Rect [ 55

+ 341.1775

+ 63.34

+ 352.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER107': class LinkAnnotation 

+121 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 271.615

+ 0 ]

+ /Rect [ 313.045

+ 233.9275

+ 361.3975

+ 245.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER108': class LinkAnnotation 

+122 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 258.365

+ 0 ]

+ /Rect [ 448.06

+ 201.9275

+ 496.4125

+ 213.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER109': class LinkAnnotation 

+123 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 245.115

+ 0 ]

+ /Rect [ 124.615

+ 190.6775

+ 172.9675

+ 201.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER110': class LinkAnnotation 

+124 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 231.865

+ 0 ]

+ /Rect [ 132.535

+ 126.6775

+ 180.8875

+ 137.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page9': class PDFPage 

+125 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 ]

+ /Contents 245 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER111': class LinkAnnotation 

+126 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 218.615

+ 0 ]

+ /Rect [ 217.9075

+ 612.1775

+ 266.26

+ 623.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER112': class LinkAnnotation 

+127 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 205.365

+ 0 ]

+ /Rect [ 73.7575

+ 548.1775

+ 122.11

+ 559.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER113': class LinkAnnotation 

+128 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 192.115

+ 0 ]

+ /Rect [ 188.2975

+ 319.49

+ 236.65

+ 330.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER114': class LinkAnnotation 

+129 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 178.865

+ 0 ]

+ /Rect [ 499.5925

+ 148.8025

+ 547.945

+ 160.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER115': class LinkAnnotation 

+130 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 165.615

+ 0 ]

+ /Rect [ 257.9875

+ 128.0525

+ 306.34

+ 139.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER116': class LinkAnnotation 

+131 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 152.365

+ 0 ]

+ /Rect [ 373.0375

+ 128.0525

+ 421.39

+ 139.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER117': class LinkAnnotation 

+132 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 298.115

+ 0 ]

+ /Rect [ 493.5025

+ 128.0525

+ 541.855

+ 139.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page10': class PDFPage 

+133 0 obj

+% Page dictionary

+<< /Annots [ 126 0 R

+ 127 0 R

+ 128 0 R

+ 129 0 R

+ 130 0 R

+ 131 0 R

+ 132 0 R ]

+ /Contents 246 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page11': class PDFPage 

+134 0 obj

+% Page dictionary

+<< /Contents 247 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page12': class PDFPage 

+135 0 obj

+% Page dictionary

+<< /Contents 248 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER118': class LinkAnnotation 

+136 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 178.865

+ 0 ]

+ /Rect [ 207.1

+ 663.865

+ 255.4525

+ 675.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER119': class LinkAnnotation 

+137 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 178.865

+ 0 ]

+ /Rect [ 239.6275

+ 628.115

+ 287.98

+ 639.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER120': class LinkAnnotation 

+138 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 139.115

+ 0 ]

+ /Rect [ 98.3425

+ 592.365

+ 146.695

+ 603.615 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER121': class LinkAnnotation 

+139 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 125.865

+ 0 ]

+ /Rect [ 392.7925

+ 329.6775

+ 441.145

+ 340.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER122': class LinkAnnotation 

+140 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 112.615

+ 0 ]

+ /Rect [ 332.6125

+ 263.8025

+ 380.965

+ 275.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page13': class PDFPage 

+141 0 obj

+% Page dictionary

+<< /Annots [ 136 0 R

+ 137 0 R

+ 138 0 R

+ 139 0 R

+ 140 0 R ]

+ /Contents 249 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER123': class LinkAnnotation 

+142 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 99.365

+ 0 ]

+ /Rect [ 273.535

+ 719.4275

+ 321.8875

+ 730.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER124': class LinkAnnotation 

+143 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 742.865

+ 0 ]

+ /Rect [ 460.75

+ 478.1775

+ 509.1025

+ 489.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER125': class LinkAnnotation 

+144 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 99.365

+ 0 ]

+ /Rect [ 259.42

+ 263.3025

+ 307.7725

+ 274.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER126': class LinkAnnotation 

+145 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 99.365

+ 0 ]

+ /Rect [ 381.79

+ 174.6775

+ 430.1425

+ 185.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page14': class PDFPage 

+146 0 obj

+% Page dictionary

+<< /Annots [ 142 0 R

+ 143 0 R

+ 144 0 R

+ 145 0 R ]

+ /Contents 250 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER127': class LinkAnnotation 

+147 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 69.925

+ 99.365

+ 0 ]

+ /Rect [ 304.7875

+ 617.5525

+ 353.14

+ 628.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page15': class PDFPage 

+148 0 obj

+% Page dictionary

+<< /Annots [ 147 0 R ]

+ /Contents 251 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER128': class LinkAnnotation 

+149 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 425.56

+ 574.4275

+ 473.9125

+ 585.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER129': class LinkAnnotation 

+150 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 716.365

+ 0 ]

+ /Rect [ 433.0675

+ 332.0525

+ 481.42

+ 343.3025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER130': class LinkAnnotation 

+151 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 716.365

+ 0 ]

+ /Rect [ 397.6375

+ 266.1775

+ 445.99

+ 277.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page16': class PDFPage 

+152 0 obj

+% Page dictionary

+<< /Annots [ 149 0 R

+ 150 0 R

+ 151 0 R ]

+ /Contents 252 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER131': class LinkAnnotation 

+153 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 689.865

+ 0 ]

+ /Rect [ 180.895

+ 286.6775

+ 229.2475

+ 297.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page17': class PDFPage 

+154 0 obj

+% Page dictionary

+<< /Annots [ 153 0 R ]

+ /Contents 253 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER132': class LinkAnnotation 

+155 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 703.115

+ 0 ]

+ /Rect [ 164.2225

+ 570.24

+ 212.575

+ 581.49 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER133': class LinkAnnotation 

+156 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 703.115

+ 0 ]

+ /Rect [ 465.5875

+ 493.115

+ 513.94

+ 504.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER134': class LinkAnnotation 

+157 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 703.115

+ 0 ]

+ /Rect [ 345.55

+ 393.49

+ 393.9025

+ 404.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER135': class LinkAnnotation 

+158 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 109 0 R

+ /XYZ

+ 69.925

+ 703.115

+ 0 ]

+ /Rect [ 57.085

+ 327.615

+ 105.4375

+ 338.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page18': class PDFPage 

+159 0 obj

+% Page dictionary

+<< /Annots [ 155 0 R

+ 156 0 R

+ 157 0 R

+ 158 0 R ]

+ /Contents 254 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER136': class LinkAnnotation 

+160 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 97 0 R

+ /XYZ

+ 66.25

+ 404.115

+ 0 ]

+ /Rect [ 323.41

+ 539.74

+ 367.5925

+ 550.99 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER137': class PDFDictionary 

+161 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 193.8325

+ 174.615

+ 283.9675

+ 185.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page19': class PDFPage 

+162 0 obj

+% Page dictionary

+<< /Annots [ 160 0 R

+ 161 0 R ]

+ /Contents 255 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page20': class PDFPage 

+163 0 obj

+% Page dictionary

+<< /Contents 256 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 236 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'R164': class PDFCatalog 

+164 0 obj

+% Document Root

+<< /Outlines 166 0 R

+ /PageMode /UseNone

+ /Pages 236 0 R

+ /Type /Catalog >>

+endobj

+% 'R165': class PDFInfo 

+165 0 obj

+<< /Author ()

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

+ /Keywords ()

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

+ /Subject ()

+ /Title (Android 2.2 Compatibility Definition) >>

+endobj

+% 'R166': class PDFOutlines 

+166 0 obj

+<< /Count 11

+ /First 167 0 R

+ /Last 167 0 R

+ /Type /Outlines >>

+endobj

+% 'Outline.0': class OutlineEntryObject 

+167 0 obj

+<< /Count -15

+ /Dest [ 47 0 R

+ /Fit ]

+ /First 168 0 R

+ /Last 230 0 R

+ /Parent 166 0 R

+ /Title (Android 2.2 Compatibility Definition) >>

+endobj

+% 'Outline.2.0': class OutlineEntryObject 

+168 0 obj

+<< /Dest [ 47 0 R

+ /Fit ]

+ /Next 169 0 R

+ /Parent 167 0 R

+ /Title (Table of Contents) >>

+endobj

+% 'Outline.2.1': class OutlineEntryObject 

+169 0 obj

+<< /Dest [ 97 0 R

+ /Fit ]

+ /Next 170 0 R

+ /Parent 167 0 R

+ /Prev 168 0 R

+ /Title (1. Introduction) >>

+endobj

+% 'Outline.2.2': class OutlineEntryObject 

+170 0 obj

+<< /Dest [ 97 0 R

+ /Fit ]

+ /Next 171 0 R

+ /Parent 167 0 R

+ /Prev 169 0 R

+ /Title (2. Resources) >>

+endobj

+% 'Outline.2.3': class OutlineEntryObject 

+171 0 obj

+<< /Count -8

+ /Dest [ 109 0 R

+ /Fit ]

+ /First 172 0 R

+ /Last 188 0 R

+ /Next 194 0 R

+ /Parent 167 0 R

+ /Prev 170 0 R

+ /Title (3. Software) >>

+endobj

+% 'Outline.3.0': class OutlineEntryObject 

+172 0 obj

+<< /Dest [ 109 0 R

+ /Fit ]

+ /Next 173 0 R

+ /Parent 171 0 R

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

+endobj

+% 'Outline.3.1': class OutlineEntryObject 

+173 0 obj

+<< /Count -7

+ /Dest [ 109 0 R

+ /Fit ]

+ /First 174 0 R

+ /Last 180 0 R

+ /Next 181 0 R

+ /Parent 171 0 R

+ /Prev 172 0 R

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

+endobj

+% 'Outline.4.0': class OutlineEntryObject 

+174 0 obj

+<< /Dest [ 109 0 R

+ /Fit ]

+ /Next 175 0 R

+ /Parent 173 0 R

+ /Title (3.2.1. Permissions) >>

+endobj

+% 'Outline.4.1': class OutlineEntryObject 

+175 0 obj

+<< /Dest [ 109 0 R

+ /Fit ]

+ /Next 176 0 R

+ /Parent 173 0 R

+ /Prev 174 0 R

+ /Title (3.2.2. Build Parameters) >>

+endobj

+% 'Outline.4.2': class OutlineEntryObject 

+176 0 obj

+<< /Dest [ 111 0 R

+ /Fit ]

+ /Next 177 0 R

+ /Parent 173 0 R

+ /Prev 175 0 R

+ /Title (3.2.3. Intent Compatibility) >>

+endobj

+% 'Outline.4.3': class OutlineEntryObject 

+177 0 obj

+<< /Dest [ 111 0 R

+ /Fit ]

+ /Next 178 0 R

+ /Parent 173 0 R

+ /Prev 176 0 R

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

+endobj

+% 'Outline.4.4': class OutlineEntryObject 

+178 0 obj

+<< /Dest [ 111 0 R

+ /Fit ]

+ /Next 179 0 R

+ /Parent 173 0 R

+ /Prev 177 0 R

+ /Title (3.2.3.2. Intent Overrides) >>

+endobj

+% 'Outline.4.5': class OutlineEntryObject 

+179 0 obj

+<< /Dest [ 111 0 R

+ /Fit ]

+ /Next 180 0 R

+ /Parent 173 0 R

+ /Prev 178 0 R

+ /Title (3.2.3.3. Intent Namespaces) >>

+endobj

+% 'Outline.4.6': class OutlineEntryObject 

+180 0 obj

+<< /Dest [ 113 0 R

+ /Fit ]

+ /Parent 173 0 R

+ /Prev 179 0 R

+ /Title (3.2.3.4. Broadcast Intents) >>

+endobj

+% 'Outline.3.2': class OutlineEntryObject 

+181 0 obj

+<< /Dest [ 113 0 R

+ /Fit ]

+ /Next 182 0 R

+ /Parent 171 0 R

+ /Prev 173 0 R

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

+endobj

+% 'Outline.3.3': class OutlineEntryObject 

+182 0 obj

+<< /Count -2

+ /Dest [ 113 0 R

+ /Fit ]

+ /First 183 0 R

+ /Last 184 0 R

+ /Next 185 0 R

+ /Parent 171 0 R

+ /Prev 181 0 R

+ /Title (3.4. Web Compatibility) >>

+endobj

+% 'Outline.5.0': class OutlineEntryObject 

+183 0 obj

+<< /Dest [ 113 0 R

+ /Fit ]

+ /Next 184 0 R

+ /Parent 182 0 R

+ /Title (3.4.1. WebView Compatibility) >>

+endobj

+% 'Outline.5.1': class OutlineEntryObject 

+184 0 obj

+<< /Dest [ 117 0 R

+ /Fit ]

+ /Parent 182 0 R

+ /Prev 183 0 R

+ /Title (3.4.2. Browser Compatibility) >>

+endobj

+% 'Outline.3.4': class OutlineEntryObject 

+185 0 obj

+<< /Dest [ 117 0 R

+ /Fit ]

+ /Next 186 0 R

+ /Parent 171 0 R

+ /Prev 182 0 R

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

+endobj

+% 'Outline.3.5': class OutlineEntryObject 

+186 0 obj

+<< /Dest [ 117 0 R

+ /Fit ]

+ /Next 187 0 R

+ /Parent 171 0 R

+ /Prev 185 0 R

+ /Title (3.6. API Namespaces) >>

+endobj

+% 'Outline.3.6': class OutlineEntryObject 

+187 0 obj

+<< /Dest [ 125 0 R

+ /Fit ]

+ /Next 188 0 R

+ /Parent 171 0 R

+ /Prev 186 0 R

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

+endobj

+% 'Outline.3.7': class OutlineEntryObject 

+188 0 obj

+<< /Count -5

+ /Dest [ 125 0 R

+ /Fit ]

+ /First 189 0 R

+ /Last 193 0 R

+ /Parent 171 0 R

+ /Prev 187 0 R

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

+endobj

+% 'Outline.6.0': class OutlineEntryObject 

+189 0 obj

+<< /Dest [ 125 0 R

+ /Fit ]

+ /Next 190 0 R

+ /Parent 188 0 R

+ /Title (3.8.1. Widgets) >>

+endobj

+% 'Outline.6.1': class OutlineEntryObject 

+190 0 obj

+<< /Dest [ 125 0 R

+ /Fit ]

+ /Next 191 0 R

+ /Parent 188 0 R

+ /Prev 189 0 R

+ /Title (3.8.2. Notifications) >>

+endobj

+% 'Outline.6.2': class OutlineEntryObject 

+191 0 obj

+<< /Dest [ 125 0 R

+ /Fit ]

+ /Next 192 0 R

+ /Parent 188 0 R

+ /Prev 190 0 R

+ /Title (3.8.3. Search) >>

+endobj

+% 'Outline.6.3': class OutlineEntryObject 

+192 0 obj

+<< /Dest [ 133 0 R

+ /Fit ]

+ /Next 193 0 R

+ /Parent 188 0 R

+ /Prev 191 0 R

+ /Title (3.8.4. Toasts) >>

+endobj

+% 'Outline.6.4': class OutlineEntryObject 

+193 0 obj

+<< /Dest [ 133 0 R

+ /Fit ]

+ /Parent 188 0 R

+ /Prev 192 0 R

+ /Title (3.8.5. Live Wallpapers) >>

+endobj

+% 'Outline.2.4': class OutlineEntryObject 

+194 0 obj

+<< /Dest [ 133 0 R

+ /Fit ]

+ /Next 195 0 R

+ /Parent 167 0 R

+ /Prev 171 0 R

+ /Title (4. Reference Software Compatibility) >>

+endobj

+% 'Outline.2.5': class OutlineEntryObject 

+195 0 obj

+<< /Dest [ 133 0 R

+ /Fit ]

+ /Next 196 0 R

+ /Parent 167 0 R

+ /Prev 194 0 R

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

+endobj

+% 'Outline.2.6': class OutlineEntryObject 

+196 0 obj

+<< /Count -3

+ /Dest [ 134 0 R

+ /Fit ]

+ /First 197 0 R

+ /Last 199 0 R

+ /Next 200 0 R

+ /Parent 167 0 R

+ /Prev 195 0 R

+ /Title (6. Multimedia Compatibility) >>

+endobj

+% 'Outline.7.0': class OutlineEntryObject 

+197 0 obj

+<< /Dest [ 134 0 R

+ /Fit ]

+ /Next 198 0 R

+ /Parent 196 0 R

+ /Title (6.1. Media Codecs) >>

+endobj

+% 'Outline.7.1': class OutlineEntryObject 

+198 0 obj

+<< /Dest [ 135 0 R

+ /Fit ]

+ /Next 199 0 R

+ /Parent 196 0 R

+ /Prev 197 0 R

+ /Title (6.2. Audio Recording) >>

+endobj

+% 'Outline.7.2': class OutlineEntryObject 

+199 0 obj

+<< /Dest [ 135 0 R

+ /Fit ]

+ /Parent 196 0 R

+ /Prev 198 0 R

+ /Title (6.3. Audio Latency) >>

+endobj

+% 'Outline.2.7': class OutlineEntryObject 

+200 0 obj

+<< /Dest [ 141 0 R

+ /Fit ]

+ /Next 201 0 R

+ /Parent 167 0 R

+ /Prev 196 0 R

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

+endobj

+% 'Outline.2.8': class OutlineEntryObject 

+201 0 obj

+<< /Count -16

+ /Dest [ 141 0 R

+ /Fit ]

+ /First 202 0 R

+ /Last 220 0 R

+ /Next 221 0 R

+ /Parent 167 0 R

+ /Prev 200 0 R

+ /Title (8. Hardware Compatibility) >>

+endobj

+% 'Outline.8.0': class OutlineEntryObject 

+202 0 obj

+<< /Count -3

+ /Dest [ 141 0 R

+ /Fit ]

+ /First 203 0 R

+ /Last 205 0 R

+ /Next 206 0 R

+ /Parent 201 0 R

+ /Title (8.1. Display) >>

+endobj

+% 'Outline.9.0': class OutlineEntryObject 

+203 0 obj

+<< /Dest [ 146 0 R

+ /Fit ]

+ /Next 204 0 R

+ /Parent 202 0 R

+ /Title (8.1.2. Non-Standard Display Configurations) >>

+endobj

+% 'Outline.9.1': class OutlineEntryObject 

+204 0 obj

+<< /Dest [ 146 0 R

+ /Fit ]

+ /Next 205 0 R

+ /Parent 202 0 R

+ /Prev 203 0 R

+ /Title (8.1.3. Display Metrics) >>

+endobj

+% 'Outline.9.2': class OutlineEntryObject 

+205 0 obj

+<< /Dest [ 146 0 R

+ /Fit ]

+ /Parent 202 0 R

+ /Prev 204 0 R

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

+endobj

+% 'Outline.8.1': class OutlineEntryObject 

+206 0 obj

+<< /Dest [ 146 0 R

+ /Fit ]

+ /Next 207 0 R

+ /Parent 201 0 R

+ /Prev 202 0 R

+ /Title (8.2. Keyboard) >>

+endobj

+% 'Outline.8.2': class OutlineEntryObject 

+207 0 obj

+<< /Dest [ 146 0 R

+ /Fit ]

+ /Next 208 0 R

+ /Parent 201 0 R

+ /Prev 206 0 R

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

+endobj

+% 'Outline.8.3': class OutlineEntryObject 

+208 0 obj

+<< /Dest [ 146 0 R

+ /Fit ]

+ /Next 209 0 R

+ /Parent 201 0 R

+ /Prev 207 0 R

+ /Title (8.4. Screen Orientation) >>

+endobj

+% 'Outline.8.4': class OutlineEntryObject 

+209 0 obj

+<< /Dest [ 148 0 R

+ /Fit ]

+ /Next 210 0 R

+ /Parent 201 0 R

+ /Prev 208 0 R

+ /Title (8.5. Touchscreen input) >>

+endobj

+% 'Outline.8.5': class OutlineEntryObject 

+210 0 obj

+<< /Dest [ 148 0 R

+ /Fit ]

+ /Next 211 0 R

+ /Parent 201 0 R

+ /Prev 209 0 R

+ /Title (8.6. USB) >>

+endobj

+% 'Outline.8.6': class OutlineEntryObject 

+211 0 obj

+<< /Dest [ 148 0 R

+ /Fit ]

+ /Next 212 0 R

+ /Parent 201 0 R

+ /Prev 210 0 R

+ /Title (8.7. Navigation keys) >>

+endobj

+% 'Outline.8.7': class OutlineEntryObject 

+212 0 obj

+<< /Dest [ 148 0 R

+ /Fit ]

+ /Next 213 0 R

+ /Parent 201 0 R

+ /Prev 211 0 R

+ /Title (8.8. Wireless Data Networking) >>

+endobj

+% 'Outline.8.8': class OutlineEntryObject 

+213 0 obj

+<< /Dest [ 148 0 R

+ /Fit ]

+ /Next 214 0 R

+ /Parent 201 0 R

+ /Prev 212 0 R

+ /Title (8.9. Camera) >>

+endobj

+% 'Outline.8.9': class OutlineEntryObject 

+214 0 obj

+<< /Dest [ 152 0 R

+ /Fit ]

+ /Next 215 0 R

+ /Parent 201 0 R

+ /Prev 213 0 R

+ /Title (8.10. Accelerometer) >>

+endobj

+% 'Outline.8.10': class OutlineEntryObject 

+215 0 obj

+<< /Dest [ 152 0 R

+ /Fit ]

+ /Next 216 0 R

+ /Parent 201 0 R

+ /Prev 214 0 R

+ /Title (8.11. Compass) >>

+endobj

+% 'Outline.8.11': class OutlineEntryObject 

+216 0 obj

+<< /Dest [ 152 0 R

+ /Fit ]

+ /Next 217 0 R

+ /Parent 201 0 R

+ /Prev 215 0 R

+ /Title (8.12. GPS) >>

+endobj

+% 'Outline.8.12': class OutlineEntryObject 

+217 0 obj

+<< /Dest [ 152 0 R

+ /Fit ]

+ /Next 218 0 R

+ /Parent 201 0 R

+ /Prev 216 0 R

+ /Title (8.13. Telephony) >>

+endobj

+% 'Outline.8.13': class OutlineEntryObject 

+218 0 obj

+<< /Dest [ 152 0 R

+ /Fit ]

+ /Next 219 0 R

+ /Parent 201 0 R

+ /Prev 217 0 R

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

+endobj

+% 'Outline.8.14': class OutlineEntryObject 

+219 0 obj

+<< /Dest [ 154 0 R

+ /Fit ]

+ /Next 220 0 R

+ /Parent 201 0 R

+ /Prev 218 0 R

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

+endobj

+% 'Outline.8.15': class OutlineEntryObject 

+220 0 obj

+<< /Dest [ 154 0 R

+ /Fit ]

+ /Parent 201 0 R

+ /Prev 219 0 R

+ /Title (8.16. Bluetooth) >>

+endobj

+% 'Outline.2.9': class OutlineEntryObject 

+221 0 obj

+<< /Dest [ 154 0 R

+ /Fit ]

+ /Next 222 0 R

+ /Parent 167 0 R

+ /Prev 201 0 R

+ /Title (9. Performance Compatibility) >>

+endobj

+% 'Outline.2.10': class OutlineEntryObject 

+222 0 obj

+<< /Count -4

+ /Dest [ 159 0 R

+ /Fit ]

+ /First 223 0 R

+ /Last 226 0 R

+ /Next 227 0 R

+ /Parent 167 0 R

+ /Prev 221 0 R

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

+endobj

+% 'Outline.10.0': class OutlineEntryObject 

+223 0 obj

+<< /Dest [ 159 0 R

+ /Fit ]

+ /Next 224 0 R

+ /Parent 222 0 R

+ /Title (10.1. Permissions) >>

+endobj

+% 'Outline.10.1': class OutlineEntryObject 

+224 0 obj

+<< /Dest [ 159 0 R

+ /Fit ]

+ /Next 225 0 R

+ /Parent 222 0 R

+ /Prev 223 0 R

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

+endobj

+% 'Outline.10.2': class OutlineEntryObject 

+225 0 obj

+<< /Dest [ 159 0 R

+ /Fit ]

+ /Next 226 0 R

+ /Parent 222 0 R

+ /Prev 224 0 R

+ /Title (10.3. Filesystem Permissions) >>

+endobj

+% 'Outline.10.3': class OutlineEntryObject 

+226 0 obj

+<< /Dest [ 159 0 R

+ /Fit ]

+ /Parent 222 0 R

+ /Prev 225 0 R

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

+endobj

+% 'Outline.2.11': class OutlineEntryObject 

+227 0 obj

+<< /Dest [ 162 0 R

+ /Fit ]

+ /Next 228 0 R

+ /Parent 167 0 R

+ /Prev 222 0 R

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

+endobj

+% 'Outline.2.12': class OutlineEntryObject 

+228 0 obj

+<< /Dest [ 162 0 R

+ /Fit ]

+ /Next 229 0 R

+ /Parent 167 0 R

+ /Prev 227 0 R

+ /Title (12. Updatable Software) >>

+endobj

+% 'Outline.2.13': class OutlineEntryObject 

+229 0 obj

+<< /Dest [ 162 0 R

+ /Fit ]

+ /Next 230 0 R

+ /Parent 167 0 R

+ /Prev 228 0 R

+ /Title (13. Contact Us) >>

+endobj

+% 'Outline.2.14': class OutlineEntryObject 

+230 0 obj

+<< /Count -5

+ /Dest [ 163 0 R

+ /Fit ]

+ /First 231 0 R

+ /Last 235 0 R

+ /Parent 167 0 R

+ /Prev 229 0 R

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

+endobj

+% 'Outline.11.0': class OutlineEntryObject 

+231 0 obj

+<< /Dest [ 163 0 R

+ /Fit ]

+ /Next 232 0 R

+ /Parent 230 0 R

+ /Title (Setup and Installation) >>

+endobj

+% 'Outline.11.1': class OutlineEntryObject 

+232 0 obj

+<< /Dest [ 163 0 R

+ /Fit ]

+ /Next 233 0 R

+ /Parent 230 0 R

+ /Prev 231 0 R

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

+endobj

+% 'Outline.11.2': class OutlineEntryObject 

+233 0 obj

+<< /Dest [ 163 0 R

+ /Fit ]

+ /Next 234 0 R

+ /Parent 230 0 R

+ /Prev 232 0 R

+ /Title (Test Pairing and Communication) >>

+endobj

+% 'Outline.11.3': class OutlineEntryObject 

+234 0 obj

+<< /Dest [ 163 0 R

+ /Fit ]

+ /Next 235 0 R

+ /Parent 230 0 R

+ /Prev 233 0 R

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

+endobj

+% 'Outline.11.4': class OutlineEntryObject 

+235 0 obj

+<< /Dest [ 163 0 R

+ /Fit ]

+ /Parent 230 0 R

+ /Prev 234 0 R

+ /Title (Test Re-Launches) >>

+endobj

+% 'R236': class PDFPages 

+236 0 obj

+% page tree

+<< /Count 20

+ /Kids [ 47 0 R

+ 69 0 R

+ 97 0 R

+ 109 0 R

+ 110 0 R

+ 111 0 R

+ 113 0 R

+ 117 0 R

+ 125 0 R

+ 133 0 R

+ 134 0 R

+ 135 0 R

+ 141 0 R

+ 146 0 R

+ 148 0 R

+ 152 0 R

+ 154 0 R

+ 159 0 R

+ 162 0 R

+ 163 0 R ]

+ /Type /Pages >>

+endobj

+% 'R237': class PDFStream 

+237 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 1796 >>

+stream

+Gatm<9lo&I&A<G1rrL0IdieGHa/r+lUmX9#'<=\8]tbm=USS5"U?p":c[qBl;R&e!c<0,cOB;Lpn*Sj5-mJ.Ng],5*TpIS-i\a/hU"LD_JH_KJTKd%d-XYUMh%#bQ0nrU52M:`<4f>o93$k(MM=+,7?rjjG.)f=5d;4Xf`UFc-pFE+CqB\`1k8*8!r<:IF6aL.SeN^LWYIfRNLRUm+*7K:_5O`/si]$8>na."-7'b,+`G=e*s4D+g32M;i,Z?I23h,<,8?[^oSB^4c_,GGngH@[]+ii$W#qkc_e'?#4d^-7JDskAc0;%tD4Q,d]^G<jOKYJ3/P!#s1b&PT&joE57p_fe2d6F[)B2&]k@H`t^Y#Jo69kBc3kZlG.D&QpM&V(@7bK(qi]iatL]5aJ"S=\7"P[GXjQtD1qR#oMiM[E`13XL2,!A&S/=5TNNgbe5%-7NDWP2FV*CDW7*DsIJ"Z`6@ZJ2M@nXkg*3EU1./]N`Y,;tOSl]BZ,GiGCZ"^KsaHA0s%W-Eq'OLa<!4>Q?>6C$.Kq`(+GF1%2X)GCQKm_,39!N9`sbbrQ\?#mhkk+JO9$!>UpZHjaHd*+WdP<=@pKVDO!FSLL?7bujGbK]tXH,fBE`HXJBPR#d/)#<To?P/c0q;sZ;L!;?@fL=%B^[Mr<3p"26ad?U7]GKT.emJm8Y$nRq@@ggD4M$T%lmq3uD?Lf.s/ItFt>p(9$mo6D)\jU1tDhgA1*^\E]0uRl`U]Q4;,nV:8"/]"[FQjW1FYTOMAK:K4#3$g&>c/!0J?d/J0#H<0isM/YC:?%c2=Q$GaNW]6Eau*^>q2b<]$YEDKXWB6>4cpp_"B,6&qU8&C`!!P$8W+E^D`"nR.`6>)j,dsSdZ9/;Ol03`03Ik$Ah4J.,Nf@MNb7QoPafiYH64:Cpg9:TtJZf&IQ=:mEtiNX.;'.Pk]O!HO@Cjd]?Mb;DPqN!3S>_b!N5"a#?!&)Bs,=_jUZ2AY>\YZoedDP^r"#arVk'&BskKg9!P>6Qr%.o_"ESOCohB55XjacmeH$!TY,sgR.nma&;\CJ=q9JqX1jiZBh#)cp0cXTUa%+PRh>bK0#/P:tPJ=f8'Za"kKu3_uTI==]A`&1E.4XMf<Bo\4qdGqF99ZlVr!8TLic9.ShK_T8dVEYfJn+gmD7eZWMt0hjuf6e(bpDHSU;Jj,WF<+^:Tnm8%0;7uR6\'.MVtT'qC(5jAg5W!qAt)Uh&b+9OC%Kqd>FKb4cF,K7U'`]]bs6VP&;;tVs<Wq"q(B"fk/PN2Vp5q?$l9FV,AT38+VP;>Ok>km%C79.l1XWHidVWl)F)mS@)O`H#::skt$<"BmPN<b5-$N34FVE.3e(PP'UcF)+Y,k:;e(G5ktZ?f6tV(2IG$WA^qB)pb6\#C:Pe>6#<QP%*pmJr!l,X:E$i1QGK!aSi#0nDdX7#r(?C=4/&[h1370q)'u:[58\Be3)SYc\-,`lI],p^76gD%Qja:%L?X5KKRi&B85m_3l:hU<l(4Wp.(.eWg:u!ZA=7<,O+\Ik"NSUtp,h',c3p\.;9mDm@;a3-efDo*e07DUtj\76(H\O6m5L'(*lKLqD]?rdH,m5"j=0ir=Z^%Ni^!lIO:b)HE+hQ<dJg*U2?12K$)AqcW\8%a]sMR;lC!(;f[SW.:?`\gj6$27hMC<n9,?J7^q?*jF7pV+:/l#=ep^S+Tl`:HNQV3BMl/k!.mZcurcGl#5/h3%tKn);8A[pP8@#2N?N,2fLO^2%0*;SaaOoJG^2P&'jCM#r\$^O+[,VS[GFuRkV.@e!'7cBaW\~>endstream

+endobj

+% 'R238': class PDFStream 

+238 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 946 >>

+stream

+Gat=)mn_[l&H.X=s5?.ZPNM\(3)2ZSp`ZGa?jYQMOID>p`$KDSrqF%71hdgaVJ9(!Q[:pRq7UDD:-Z,cGm//O_N.UuoH:gL$s3Mo0/uNN#ESSpf5qUTk:nCkZP?"*Np@OGgdb/UoAkF&`P.FE;(*Qh!0PZA>/.*dRHR7`qeKg5`VU#,?V%rblIY`T>eaOYh+WW2\!Gcd<Zcg`9b(q-knPEYMb$/<+_Me6&1JdUM<'g`>%C>(pP6Ni0Fh5NlO*cgcY4FfA-<bVk4'0adeIL;I:NI0IG9rfD&.*sMuZ5kp='*fc2sWpqToLI@,GT6Y`Obd14fpZhe2"+),X9R)M*33he74q18_-:2Kkh#mhMfC%k4Q?NQnHk[2Y=&S?4U'cp1[Rj36C4"10h>=NKDI3O3B:e,a?-Ch?9DQe>:lb=nUFGYlT7"Vice;`(LRD%"CPal$'bBAGZaoumR\1\dA<Wl\M/OY\u@F"5c)8f?/=JWNLfC7_h.rK%c0fi@$rl8(tF1\5s!0:`(DK*t]DAdMU'KuE1%Rjf_\T[)`lZH-+FPMBf1qV2EGKVNR]N7R-?)t8DQDL3X+dG;&d\W(&k(EHkZFOUJO%:(+4)2KC#U+6r4N)<^hl`O3.Vjf0:F1%`t.;k'L0['K/1Z1:q-7W@ZPQr"NWld'_pftohp6t:dRu>B2pTuqfYTV`IjZFH`\!P9HLeRZW9J/RG\f<%;$JP*QMRFgNZm-qh!l$`[[L0Z^FP[neH)jRgX:Zierj3fK>II"$T.!:B5:jp[lHCY9Gp*Ap'q`uO7AK0@e`ND;7]@'>rn`gnTFUOSH-TJ:MG<Nc%_<V8M)sB\n9Uku@0;(RRrtV<3&>2q26?IDG2=-.(55UI:UHnDHqLm(D5eZ*GNP=[GULAs.b,lh%G^;\$b<pMVo9#`_Y:mN<u\JfSM&bLoaY,4EpsTNLkcQ~>endstream

+endobj

+% 'R239': class PDFStream 

+239 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3247 >>

+stream

+GauHN>BA<(&q6a9s.ILu/=]>nqi*OBQa9Z-/kb=X&'HCo@r#\`Yq9J-)013)BuqEW4dj6[93_U/Htg"&YP!%IC^Z[#a3t"-)+&7RaEV>@b=8fAZ<Zajfa%08m.n!VqT!>gpKV7`3:PjohK]K7=dsIl0HJ@1d/*PoY\LQJ"ZZ-;1s:tl@CQa>eVF8"e<$R,;_HH*k9ZSqK4b/3U]7<C^2FM\giXsJI&mR"`#fi@0jR#TkE'7bgNS8'V[30.d!0+HbJD>9cS5g&pUMi#;T4ghr"1mb55J]@,NhWQS#r&C$'2-Gjq?&]I[<H#J`M]_P('T:8_#,0Jk2,+6D?J/)3p$>LmJE"d=R]5j)^Ma<31>I*p2abQtHSbC_#X[9Wlb.4=N9`&:fPVA)ING@*gp8n,*%OkKe/_QiI@.nZhC/Z4ni22Rb&3FM5k;K]/LW#Z=V.MYI6Y.!R?slea,RqR?P\;9*-7d^20ig`]_28sAYip.7L\^ea6N1NI\j8=lI^?DoP%klh.Z$=H,]p&<Rr4!Z*,5g!U>mu)iO=ABMuf&q6qD9Ig`htgeF9f7LJ<:HoHWOP>sH`<UkIh1JZp5\4u.+DT3"hL:lm"Y!U,3U5E[k+D4AOWVOQ^/F!Wp$1$!ZiNm4Mb#;_p=M,m!hDHMnf<eH,9%tgp7&Ef;,3si!ZLoOPjiLmjkG$LRVJS]+L'0hfhImhsmO'a6FuFaC'U<r1_:6]U0bK_PbqGB!pfRJK+Y=O"C3%ZkjDGC@m1l&9>u[T^A@?a8&8#VObPU(LDKsJj=[[gtE9;NQk"m55s_k#3#sSGu%e*OpVqmgR*HE^rTD#n'E_&,r5_U-/9*1<MIAe^M@=dW:RYQ\5Mf!h(f$V/:`jFVW.cuF2L&4NQ'L(Z#b)=+4,!hYk2=(!&rComXUCGDU:DA[JVbb[N:K;X!"-CRMc?-#>J6UneQ=7X[s(PF_MNIIE#k5*k8A?V!.-&\$PD(0+k`@/1#%>O?*LibNQsghNdW;5ck_Sd41,Z@OVJL1"]MU#jc=ugC=3,77t,ViZA?KdBsa;oVppOcr`Jt&aXi^!G8SS&*a9'\dW';'$VqtnIXchbKZEs8Z2k:10_M=-.>RTl3[3I!IF47l^NOt0I"e)(]+f7p['lclmTg;W'.O-B87K#(!7I3O'bqlQlF[]2,MsoD?E-h)5bkj2J:3j=26!7TS0!K(_@4g8N*5$Ki7:b?69G?<F9\n%7O97CV'?KV=#qCoEQ%-C!r$KA+WO.#_SG-#c1lU"Ji@COD6Ol%U#[#;58?H:b)*e<CZ8c">ek.fbj@(GM99i<;qTg4^Y(1J3XN<O<p8modpc5$HgNIq')DG?S8>[Su!^E5dg=d?:$_(FA_Vq*Yb_dI7Q'gZ;Lk7i)t80TpXnSF]ZBVWFR_7^,qU<93S,:#"Nh4,q2M7LR`>0;b]k]&njqfeAZU:#nrf]67d!*Y>Ra,Z0Y&tRR&em=61oV=Nsh\.[bH,irEN)((1mZ.Epe")gi[!IhoYi\.,r:V+n/7/VC^%mKl-iXn?U2!4S?hVqb(=#oLD:n4V*i!UYX2A\"8QV:%;+pH^Mc,ln<fRAd%.A5r^>[Tf(R%eBpCRO^'>qP-SabTu*K^!iJt#qUZ'h6DRq6L!l5e&apZgTJNCr]*i/+*[0iopUU/'baka[iAJ%[I"*6f>^k#3Sa!*&$#,@)n'Ig5&UfkoKh$qiYC10[[!)r/&PJmf9fFG^sIiRjW[`TPmK!kaRMNNrZioH_^KknKtAHh(;Lu]$fq9Z(.dPm,T6F\Wj>o!f+2:qa"Jd!o"uA(HE(F.BXrWNQ-@\Hcj)q->A$=\)+G]KFl`:?4(&BkJUM/*pS@3Z0HZ@X(ZB)$FbcZu6-GdiIQ1qqh=,75IX9m#mW9di;h@af%jAU=)^p%U[fqmkOSB%.\Mu:G?%4?kp-uuCJ0V6.^'@+&q7pnMq\(P;-A3_=7IXF;S$U+)P-Y=V't@qZ+39/r9L=Cs9SBAJVRHaLT]&QqCgc<*^St>(S<!_($uPN"g`[,&V!Z!SqSg=&ePE;U2qOX4!C0Y`3dJG?qaet<#P83s2Et<[$t`MDBf*7.'d;%u-inuG1s!^'(Oap$/qpV7rgM,NR)E@qr%BI.:n0l$F_^-l2N>`=@JJT>1K>'D"po6CCmr'6h1PR[4'-.lg[*r*n$+?j%K511WU"Y'cr_],Y=MLr,HaYS>[FOXH"1C3m]lm,meAi`%aA^V,]bW[%jU4EeK1,lQ4/<<$V>9i%Jl!JZ@ZE],DfJQVb#dr[_T(-4!6*Cm=05d8M8NtBqiii;#[iHk#KHg@6f6j.cIgj4&8kqg-K)V<A?KlDF_&&\gY:sA4bm6U9Ue%!d.tY*@-T$IFG+DL+S(h2YequJh?kRb@-occ9tiR%C`<%8`Y&k,Q_AKn^Z]68q,rD]*EEd/!:]"<g4H32?eB53GOME^^)@R<804H]donI_!E]e-nV'#NMI#*gE!DOLf&bWQ^f^-W[ZW^e4u=c8D7(S0m3UAFta@E,MHE:"pfRMjk>f6U[dSl1aUc#hc9fl+XLU&XuGel7Hj5*T8k'^g$Ylm:I:+(-RBJ:<@k26*lf2;ku>c:\5a#DloG#U"M)m)!bo9DUl8B:lZ4Itb#?J_.&;gU@Unn\ARq6.AX_S<fsS&&p:$U+&3C,54-(_!`ecZ3p$_,]FLjE<Z/[jK_I0\)1>Fqr2Kmn?$'C9cs83ja@(-huJI]76l4]p[a_4S.5tXtX'Fn$FGI;>USNoa(:;b(j-Og\'Gs*o*+^%T<I6k.TqCBO^d28A9$RJ=&$D+nFpc/h*hjc5R%/8(KAE'inDFT',n-"[-F8I_!Eh;uKZ-h/>M@brpU!k6?]L5>SM6ARnan4>koaE^>f^o+)0YZ=MU;UL/n&5)<=G3g4(Ch&Na7&e_?RAJd:5U!t:`gWAPn]Rd3;fmGY@h!;GsX@XkpaL2\5QrOHaoF:D&d`.S5^g9s3)i%YK^hb:!"itA(DK3&$D;r./a9@ChjqQL)]qbFcH@5'r_,UdJL60g#2Z8^!iUekg*X%DpBP0RC7GD(XT*TP[j%l0;*0+k684+"kYlorVs^.oiq%H1jVZKlJVmB^r1l/UW6EOcmq^b/u-LH:\FV6PM6_sM2?HqdGA)Ns6V68YB9L9H]lu\;=IJeR?)Z,*7E#Q>Z,n'G1a76(U]BDU)r6;?:&G5r%d8+[iOF@LR9d6VL<Vs[b0k9a09UR>FmM#Z78ZHhI(O6JRP<dp^jIPo4S(.k`(;@~>endstream

+endobj

+% 'R240': class PDFStream 

+240 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2935 >>

+stream

+Gau`U=``=W&q3VVrW?nAf!?Yg]ID*013U+343hAGmC[9/JKc6F1F/XoUceYNgC<WPAKCCTDsU(1*8QVBYJ4s?/ofgieUOJ#+n(b.p;&&X8![rM"uIIG?c^dgm@/%jf56h/!V&8jLTkDFmZOR(NmZML>q[IIDr6(E[o4!iGncEQ6!Tbn1rr1H0b%!VUOV>V\HmX0b<O)=mooU,qY+4kiO=5F@P9]Nc!_8:bmUnS;h&oK_MbA$%*c)<BLI@Ga4iO!ELhnT3$-HiS:b)NnH1c;]Gnr6c+kUbMU!cF7^0rWbNt1OOtr5QB=+gd:+s03k/mQZX!CKk:IL[djQ"rg<Gd5Sbqc_;\_&Z/gWc]GAs09aA7`nqc0,R)cA!P-VCM-p/5sa5"!QBV%ijVp_@qt;O6=I!n2N7\^KYq@M9PB#alq&B_.<,ld'VeE7blJ1&hW6Zri<tK4sDU#Fi%S@KH:Tcf$I&Yk(]-n8<O<'1L;CC,AN^Dm):/YjBq:V=Zmulo2ggoid>R:OSXlDcGTaCK)"G;o?K=Zgp"/O]XfKK?1OE*Jh+f/WCZ4Ha+`ifjr'Xg@LH-n;iU;7__].D]<>4^I-5=AU4=l5@A&"?IZGIpT@^.WU=t]QT0GLuF&oEI)<BbKaXs!^\gS3e13%S!kJh/%cZ8L-O+[3oV2sCD%F0)oh@m.@eV5LWQr]rI.8pB5K4I[H*Qq!n,tk9Yek*a%mXK"$$J\/*<:QnWDD(rHdA_0,o:2m!=k@4g6,Fm-C]Wad'i1$`<'kNbj]]_L_$0<GL6;m4r(XT5^;r]G(U-Q9U#]]Td,HlZ@-$,JiWks_,!Uup$VOM_a'?;gCL2$5'l6?._tbTWTVpqf\/AAiX^ii>",LnJ(dJ:?-ggD3WsIobJJ-m_'&8c%eODeZ_q^8LnBO1r=LosS\MI844BH&D`=CI3k1$JF'*TUp?K5"j&j)s8@7ah^Rfu>LkXBI\2Na8]+n,AQbTZUH7ls*dPWTlZV`=pbjZ>c8G^r!p^_#I:7,WYdR.;/J*cZUcL`O:XVrU=K/$)q7m/ofaUM&`8^h=iKJ'>$&Bn7<ddg@hbL(.%9.&Q$%,UH8XL;]l7rG\`ed>gPn,\/2VSV9[0!@0\lq*BQnIaF"/Wm_DKPfChcZ3&YjFg!8qi9i5UGAK-2[bDd0VEp&C.9U,#5]tIA/bi-R2@3PK.Pc<lp*&3N.(PTi92cd"'/\a06"\$L.?bka1(;)m!-$5,$(0:R*MqAFaj*;=/(`/,!,=I7NXH./?EtT,&RK9petnTTfDiQfC?7]"3]"T*9r<<=JV%j?1>1-Kn.FT%r"7k1_B>;n++i7@nY3jC6u?TVfF3o0;KCS<@E:j3m1$qrXM&8_DHH&;$$Csc.s)=Rbd!1nkf4u?MuKmrQV"pOInj(\g"Ft!$2Y+!*K<Qim^NrWL(ZK\UUud2lRgep%8V$n+2HcNW`eQ:aC^3>OBDUr7D[/OdK-M'i7A?m!>s4_CJs^g1,g-eR(F)@39Gg0!0MD,)BE!ZHedM^m:2]AG>eW*j##OoojIHg+W"+5C!]m&/-g#9:%0-))QcSa>AHFPN<?SWr+E3AqU0Ne',#Cc-E-qbT3[!a4;"^54BkX+9G;Kia.Ifd&lJ-jqdtnOEsT'pOqhlMS)UomdBu@i5j-5Y@b*Cu#CJ`jNKL+</s`?$MCf*AJ#-sc26DbiZBVPT*.cYu06,T5k!TS5hX1:dT\>OcT@>u%Yb/aFILr,/pA:(mlli^Z["h?tC'2AlqPL6[^u(?IB6#:&KcZ>Mis>hmHr0?b9goAnmE>7",m_aG=Q?ZT6bpn"^9X6.XsP08[f&YDoE^<j4AR4R"pdNRZUelI9"Kb04f,*]2.Y?HVq=XC"-Q'LiBXS[nVJU/mR$8HUM2qRnnF#&VYPPb177'<dEZGu//U)3_,A%%Ho--CjJ)*id:55WZOb(46Yp1C5f'oN$:\7_62!LZ\j8&p6b6BQ"R_JYdo>q[Tl(iSA%J2F1t=A7"A[M%XcSePCP+Yg`u`A!(/lLr97X\"US]m@53m,SE4<AhVi"IKTLb2@U1-.o3k2W/loHET$M?@B%o)<hA'i.@Q)XG"Z#!c[80KaSO2m_+qfG#nigu#d8?)>@cSP,PJ]<IR9ZEP-V"mF*H#p2@L2h-,([W`6(II_,%IJf9-*LXDQ5VXc1+qm%"n`k&Ym6^OgoK6cqr"sS\i4W&W-2IQTMp)$dQCCl'_7uHj:1QRAS,laKd)e0`O$Wc,DjZ_VR$Pa=7hGiH9lW&=',qZ5_]TRR-Qd\]-OSbjJ5\(=kQ(F29ut:ZHD]h"jMa$WbfI$r#WgrY39Y"@]G<2#\qjh]mY+OO)L%,DD,f%0kYl[\:N25[#WYGR!f5o=n162chd(5h<X*Z=qj4!1.P,"k>EfMQWdZQNB<4<L9G&%FBb38``]-<#;9c<M(b7MA>6hGIC]1KlR2PjlBePq2cl(2TC3kH`]e/*q0T7dd:bgtmZoqYTXTVd_9kn.E7\bQg&]gj=2qY=htd5X\`CV]XXbU,B>ShrbGe2FIHOS8,h"bhZES&`eslc9lbnB%Ma=5G<X\%C#W=]s5=sjg_/r0p==\j[V+sOrpuDAU-0t)D'TAn!FmtIh9IRS,18'LB&9LcD;@&cO#S5aUE1'Gj^%ZuZS^3stI'DI"TIZCs/m/:UPLfoZ4MOta(2B_$&t,B.Jk,fsIf'9f']G[Om/MtmL]5!)b_$sK:3Fj9:=+C>fiDiX(#=IR&6ClI=.^&"q=^J_AnGtBMheMpFt<6ef?UfC^!I^r&Jm>]H[GHDFt7EhrLO+h4>)!!8Zg6-c?aFF-O^e-m1N'%4#>[@S^a5hT+>ZVHK)G(>h@70pH6gT0AZBjO]*<f4lW:2k$r$e1>aIq@*hXMCSEn'46IU2Z?Q9m>&]buE:lJS=gRS9USg*ro%])UD:Y*`hiP<crWagtZ<.~>endstream

+endobj

+% 'R241': class PDFStream 

+241 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3185 >>

+stream

+Gb!SnlVH9V(B7^?s2,,u%r_]4+)sXB7SDrW<M1;ZPu^5_1A3!`efL_1Rl'lCh_Sbh4FZ$:E8(bs3-0Q33TloX(_*J6XmuF.+/*m/1qM8"VPDZ[Bk(_5<Zf_:p%HX3r_H2Gjr!?o1,XW\0Wq**/K7WcWhJZ(g:r%<;Dk.]WgljY[.9?V.6n+59]K),R7``oLDt>OStOWkB_?;Hr=AnrC\I6ffpHhJ3M5Rt=.P3+C.HlcUoE,e?#h6$24+mfFf&jKoXsN!-`UJ?R/PgFL_BuqUBFPA(V?96r&J-@0CE_C`U3Qar+:Di]):4?Z"0/<R`mI,C+@5FJCQm`=I_iJ1&<kYM4Q7O`lR!@'GL+`5g^>l#=#aW7]sMtY`DA/6PuQcL00R22B5&-fQPlLSOMZ8Oi7b5CJM:t0EaT.E/),946Be78W46Ecj9NHa<bL=q\D1"Z/o)K*YtL$60MO8JlZ*BVY8hn^0dSg]+oY1.)]aQ`=;qdEnp=+1KB7sVoZ?;>`eVh\K2EDU&\W]+Q*X,JhBoBfX\HPZ%9i*d'RsNGQ86SG)6=n#c%@L[C7G08aJZ.83f<Iim>\XG!McUn0!T(fg+=40F374R(Yp#2\oqA0YnpR'[g*Z\4#I/G_%F@+TXRt20M>.H&;Z$Lc7qX;`+>MLrA1e]Sh:C&2u(lNPqF/ChD,"^P`SX7Nn7gLZ>/)LD-LkIe*\#a-nc/opU8PGIb@)<e]8ChXTFpAubg"l<S=B%NQJRc"/R1.D3&TB?r>gk?1)[9p)-N\1WK2>sPC48=d^r8Al'=:`%P9Xng!;%$?52EL7W9=>N(_KsY<tUY!WYnT4uMo[hCZjlPm6/0C>`X781_I\J?]p6#_X/3hD!]OBNF^U)#?'IJ'7&bj&E*!PDfkNA&p`0LY-&_RLJm/ZOj^klpZGmi^VA2TVU)H725gthl4_-E!CokZ,eH1(tgB](na9;&LCZo@oS-'5;<5?J72ljJSbB:bq6Y3(3dhTlGWJh_VgIFnM/j23KZm;CpFB0DaBC'Snl0Y'%0ETHt`67.""<59)VCs;%unq=5X56kna0b<^"V=!"2-"ruB$]2b7e<oNY3\b6MS"SAkgCNo;Vrco]eS_Esl=3PXE(S`(QE_+2Cp])F<(1A*qG5hodmh2%2^[tE(jh$cgIm_u8@Q$c#i5N(p\EiLZ?Nck5bR-Y9)B6]j%6Nd4>5>7,2f,uo:XW?nF3aYNinAcT]:Mb*:q_OiFE(PT9a\&TAQi8%nZ(XT)$+jiT(%]ZX_g3rc*C4T@+OTJ=89$_R97+;[Qf9I^jkeiPnENiAl5o$&u]&XJ"m][;6qGr'O@p,CUJKmHjS$Y3;YVo)3Yk1(85I_%%q)IZ-4\#h/#($U2p@X\c,rE,b"HG;(7>RCU90@Y^R_5f1gP=U26!bDu?(BX(#-P[BeW/'Zu^gG#q=bQ<j,a5@9A*qQ?se1$"l7-/IfI%GoFcK->W-eZq])f9$&9WSfr:(`J&(oNlS-4ZuY")(0N')oe[PsDd#LUm[uBX!(gY!cU)5Q#\KhpE:`bEpf;_I9ihb`p4jeMcJU5U0uLfdW7N_'2.ERk.OlAGqs4N'9+-TDcn]Zl!s%d)Si@:Ut-Mq-Kk<2\`O8==4V[2'50O_+GmlE9iZ\m+ZBM5GlJ&G-%o]IRVcHk3j"I>@,7LA4n:\d!-#.\bs;Pq%ujRA@%:ZIR,8tSX:X^9A*<Im*[K,M=qcQ5_F3tNpjqK-MjcK$0dmUF6!2([;g832'6unX3J//?ghsLDAXslZlP0*/ni428?aHmhtXj]$()JrT#IEBQnT\;0=f3,B>G@,ZPn;/&M30#&*^X5E2b>X<QP$>]WGu76K7V"X_&&WR*Ur(ksfetiYqh%=UPN%"Zo2tF+e0]K0"^n(?a(]7p.r,,V@]G;Q`HE?lN$ZKeD,aJ-!S[h\&&^GgFU8b?!i0d]2lEB<+(=rEUs9oF+@C=li'KlC1m;n9sV]ign'F\2_Q^Q'Y:;[@o`A+'\!tGo_\<N$9q3d[M3?ginX9@`#9JY]IqtDb'@NUj,AoQQ&Mb_u9mqfNTnb&^h>UOEZq,L=l$P.jK:0:/0&AIGnKaDMDH_]tB>-:P4:8Lah)VVG3!+UdZuP/:I4r/>$PWS%n0/#/*)s?iL\R/hi$N6O.Jj?E/g.XtiS((AF\79\>jm?(8"Yig%dpl,JP:F9Fu_6ehkq$%r&N]7;kG?*_G,[NWZMQ#cSi41,/*o[A`2CtVF&`-Omrf5nl:CnN"HTQ(BC'F*r=T-^0php7XA&h:N?e:'*N$J+P+IK.A3gL[TcUW$4k\btL*0bCEG$@KQcYVBgeHpQ*8fK4eHp94&0?:Vc:3<'EgS?T1G.fWh(@):rU,s5?pr(P=So$Z;\pMAVaa.1"q(MOddO>/(95-APY!a`oQ!pHLf!>NP"aJ]?"^VspX:'.d^=[It+N@rh.e6rerOT8AfFk.7oA8?LEY>\m0#aIfc`2FEi!SQ@IpbH$]-O3Tsj=r-XZB(!r<$U(1%;3c`<=*g!'U[$!ee+HJL&E5q'%Ibm2A?7L^Hq@#Zt,4#W(IUU.\Xf$7Vf#dm'MMP8:[^n3bo'rPo4@u:8bu.&LrWPM,>d\n84QBLWX/I+p"\V7#X_dnZgK1C*YmC@4W%a.\Y.V!`OBa3hk*&Y^_<uU0;$UMW0.XZ9Xa**'I/7q=;VfJ4Y$SDN.hhArc#\.UPbg"te.hLY$A]H?l(iB^i]-j25h&nPc`pN"6`O\XtkkT'EZs@aLd%A,(!D?.+n0.ab?hVEnaZ7lae+:K8;P:>S83.6u=G&IKMp0:A7kf4cc1h5H=,1.$PeU+Jl9,$F)7UYp##A_&1M)sE6F^:<Y98l@0Q,sL:)!K_c/f3F2'Rq;j>Zk?_GZ\0r$]$]h%%D=kW#\`kD&]';nid,U7,E4aUh".%P1hnR3V-,$5)Ke.gN>\r?jVBM=AbY[NB5[4H8n5cFA3l?t(hBM0Z,/RgR[#sZNSjCI(hBM0Ysf*NV@pR'0C%YAGTrMiIAp&q?ul)--Y,e=2D4$D2_m+5Y0eMAgSB[7Z>gahd?FaVdAuf;8SY/911QMd%<T=C(n$-_!q4c2/Q][W9(_2T?>Cu"/R%r_@aoEu[-$"]F;qo1&`:W=RD$`*#'t`d<#Cj<OsEBW2,ZdM)RM2_>"'77,ac`ChrILaa=`N/2T_lXEXod2o+1QFE6A~>endstream

+endobj

+% 'R242': class PDFStream 

+242 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2279 >>

+stream

+Gb!;e=`<%S&:Q:Zs"NrcAd_*Ja_0<T2a+V%VJ-u&('X7q9=2r5,#sf3li$K<6QNlS3SP<(P,>\+A%oK5r5OLJr:/V#0EHDYKKn>gi!1qUKAZCV0ROD7LJOOiF2*/Y][MTXn9Q+FZhE10;nm_Bp!-`id"2#A-b-0`D:J1Rh$si,n9kgSj8-,mcg/rDBC88ci2$63%)9[KRG7\(qu'QEpp;JD051ANBnC29>$g-p4Er5*QPM2QOtnOW+r5?ALRdZsG5K!T=2s&<f-G:*H*',b*6:Z$&OC$=.0(3h$<T8&I)[=1b4'Xq)QG?JGm"2(9JjUb&k:[%3L@P01_ud3Aipo*K`T(Y2^IB0e7+)HC]5n!RO;tTc!t@*2;H8JH)WdQRcR_A;J.A#at-fsI6GNN@&g$N3+oV6<G*N:+;,BF(+cqD\U[.(XO./Z!@:;s_kl0][+4;<Y4E*#X_&d:^a,-o)'FSMRLk^<CT_C.\n!/LTbn.?`une+2's[sQEc6[D'i+f+er;?pnc]s5cD%Z2'KCWRgIk\N;kje^03MMd#;&`S%<7I_W?1V]j5[r/3TYJUACSgrVE8VPM/7qI(tEJ&((P1QVWUkS0__CY@NHFO+h],PZ]b.l_uTVM6Apa'24--@PfW)B1&!u/EXMM+oWi67\:CkA;DQR.<XBu,VpWt1hI+67UBI:.-\Pu^?/BF:2/X,n--]4-_\#Dj-k*>?nNu;5s?Xc#mTZ'-b1Y(Xn^1epX^kn:Gp17inuHs%IOckO$sl%/m8]W[^&7<W\+t3TM7Lon:h#/4!SlW)Ao6GMQh;Z&\&%/Q.B$u=LStk&:B"JDFGPK8@:&]-5i#4dKgkaVG(LJ=L/bIIk&<>'Z;C[3P\%rmS>r5.2^&SNn'X4f:'KK4(T;Z1Z_jX"_HJVKs<aC)umQ7U/$J3\c^H",V&l?#uH=bmu*AK^XmOIO\iYiQ0Y?F\mBAt$Q$&TDsO08#=f*nV,hZTFa]eSk3tkKoqKO]os+@a]*l$e$oQ85n59LA4U[9->VGU5d&].RG5qJ"@2?7?IA":!Z,Z(pKSd3&cu*fuJbk\O=AdYa41<o,`u:dm@l7`c2.nt?f#QOVZRgF0@,J:aL=67Meb6[=b2^Hup%1bUH1;eqP@'X[hOUTmVDmuT\p2@qI%08N<m&N#mdc!3I[(131]`p3.sL_Yi>kWBXNRq,<SD=ALqD$>f*)9(o(l\5]D9.ScHjds1i6K<A(ZHLq4!Sa?NXtH-Dkb_nePO;O#2i$d`&=Pd!k:/;19e)Tg$Weq6;9-CMka#EW)W/e`e,hcsEbH7\;]tYbM:1L*b^D=$c^,7.Pup[/7?6&2K3NLr50cTe]R:Wm)8f'j!t)FDf,_dp]LI5W$o*KI\s:?=#WaR'g+V1:uVo)D%693WDie"-4@^YQZ$oCh.L1[jaJ.ZC)rg:olY:d',RkNV^jmd.d"NPs:&-GLY1PMo/imFMV>t9+Ss7Wr1Z-A"c6<,!Sa7VJgH$UMo][=#\>+,=[&ZVb=_d4="fB)5'ghR)Oe=RX;"0SEDCCK,)s]XBHdRA,bg=?(":igEn@Od-MK+aNPFZ9!Tc6"3c.2Ac2_+koEq:V:REAA:P`HG&)#U)W#,](GIEY=0/!HF]D@]B+(M;PUo^5<*2dnC>5Ok9-5*)nn,i^#r(G]@"k,u!@eWV[I`"f3u:35Y.I"HBhU>U%i`915^2g]O)&\q6+mA2?n1OO,.<&P7pJNB@STV**@m[sa.[9'ONAC1^UYXLG\t^GR!WD3kEBI?m2A2WBiB_W.kfn&KE#9+lPn*b'u%Br>GX=8W(`t:AM;&[7DXqM>fUd,ZIlnDO5n..OO@%W5%?=MKaBNs'CH/$gbj;uoc(;'Mp,\>)@l2V82UU8CF&>Apr?PaY1;^`<8QtO`afC(VnRdanT'P.m@mmDW2F)MBVf:Ob+!o)C1:&;9%6:1AaEOWodFaQ7`$iQfL:C.>YM,4WuD17]9]Q?;mMcdKkn=8Woa&'dLD9/:1W5.9i0@A'thq7.VDg,:(_$\pN:69LV/*q:&[K]IbC@nJ>/JHohds5qn<$_S)4IEm<dYM8&MC>gqGg>je@X3Wh.?DH.T\aDM7*B;A89G0=>7daGeqiZf-n$\j@#6(W1Gu+.AJF0*]>GDm)?SEH.*_=LWYY(t:AC;h_9rE]LdF+A6jDrQ^1k0InhL'UpK"6"o1_'FZ@E[qpZ1:"!Nj`(Ee)kg$(S4^h7dlQYD]IVtFH>fG\`PUL#%ckJpp[a<2MBA&)!)#)&<bfP&4*'AZ?+4=7(`r~>endstream

+endobj

+% 'R243': class PDFStream 

+243 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2767 >>

+stream

+Gb!;eD0+IA&cSAir.k6tRE@Z1(9(@oTDY"n(YQN\jQg(::'Vsd$YPXL!Mg^sf68#R.8l=GfstARYnKbU!Bc9gG5#.dK,4H2pAZ6>3$,uRHOi4\``)@fX97K+S;lF?q;)$rq;^9@pce"fED5c2#Q%hINV-LmcgSaLgG_*m="`!8K3fA60mFbWgGhF"fOnJnZ=SOX/N!<N0`DO$J$Z3UCk$pf55`&'VXJ`C0:ME))OP:tP7s?VPlQ9p$'3T<apb'QdMYisbXEYP;M6`()Lg`T%M;KS1O^hsLq#1VJ4s>r!]roAp"1KiY*mr-r)*1`S+a7Xce>J<i)hKN#2H"nStmQ%c-?<9^"2U8f`&.1]\R&a*F5GXrAiKo')6hqaahk.)UK[3!cE'?'/5JlMEZm=<KkkL5j4H-6ZQ,iAti0`?.,)We.dKPqTjGHVO;EEhK(7Kh.tLs[@]mnOBNqb:/SU/EKl,[a`'I@nJq'm+p"B>a8kD7\/pV[+=t0AK"*<I$UhM-(1rTh#XX=?Bf4M*VZP)jU^0jLkeSj2"2Yf\'50Bl7`qOF7OsKo5=)6"N)8:-g7='`oM!S\eC,ISFZ[:Q@)JrbEoaIn]\6kJI`][da)t.c)-eAqKn,qjcJ^&+8f>`m\MMt-T`#SYn&*<VbR_1mnUV#NkU];9E_HBojj?EO6,403(I`S*B]mUHc_?=61:/[?jJ\.Y(n]^%<$Iek,p5/d^'A87]0ooA^FoEE,>5U-p6?UGRETe-P::+>9FD'&p*l*n4;&qtEluNMLbcn]ZM@bie?6)p*3C.BL0*Ad\@^;D-=hjcij]Vi8U1pm4I8<S!YD@(PU!W+`fHJL2g\p8/sOKY\Ne)6V^dSR4jA[c.=quQ>AtI"$GZGSJ)?e^4l6nF&HZgq\.r$a&kbi34F!W@j7Q^6,?3D(kX`0mfo"i9^^W@+r1LT,hX'WIG3A@o\G:V44%?PdT$CYOH+V,NYLMMJ)AH[6<-Gb'D_pkTqYD`=qOdQ7-9s,K#'8@:r7sD]blNhC'^a6>#2lsp9S1SE^N8%S[=NcM',gD?<g$4,pgJC$;&m7":`i\R^7'u@_lu_,@&<WF!Xn"G[USi?VtF#@pc]ne0g/Doh&-`9,='pb8/UAJZA8a0/(Mpt5X[q#.HNB\0l_W->a=eVjHnjoM^0!?kQds4ki:4dn?ar*qBX@<)0HVC2*AH9EleWo(!,/]o?[gjP^K<4/s7-S5?VD!/a9TB'BHOWa']i*n@@(>LeeCr<+<VeZ%QN"`"N8]HRNI,$9,Tk$11%QS!E_8r98I-kO$b=$H2<gJ.sM:BN1i2;=2YH)NpcoSdCGVL"-W3ROC[7+qmofo`;G7*,\VO-KG=USY7PK6&gNc-&N8fo7bPgk.dqA5K5e7!8>^3MI]K-K9:j[$iGaC1)NUR#sFRb>%\uR(#)iXAe?r:'uUlF_NB.SN$3pr;elt0>[Bds*1I+-bE6I562&NY)XdIg%*kbT8(0.%Tq"k4U+fKrkc679bprEZ2`Bp?dQ(5O"ueU;>;Q"Pe+l\]pd-Hi"X9o=NmFA;a+(*Qr:tUKZWMrBN(u==YSiPr54<?K.a?tXh2>J&FED>'-^S;@7P$&MW!NjRX0($jqfW"B_4>M41@-ua;92L]])E48B:l<Yd%DrK=u*`p#+S:RmSNOXC1FM.ITUa(&R&bo,#X<]$W^Q)IVKWo;STgQ--g37&D@'1kECu(#[kU!0Bi[1#+$eSY!hb5Zq#G`&rkFmdimQ0b1P5s8QfgDAjO*8Y"X?R4srXBXd?;nI\_#*]NnFoA`\`A((RbYbcj/F#t[Vkn*TXr1jM7"9i&UL<#/>%&a'9EVqKn\(>"e$IQ@<'.i@'Ej;*"jOoVhU4Vbaj4AQc)>\A,*;"/^^m^X9;krY&_<ot('YRUP)7.VT)]J.;&6&Y[jLKPW%rt(A1SmqN0^EZJ.c-IKg^.G!bUU9aq`LGa/GVQT&KGgC5Y=1/A?H)Yj-VGWhlHm*'"m4kN:M>Ys>rY!.g!'YA0.(luA[n)A89)D4IdB?^r6*r9L^D7;iCZ;bN^7s6_>JLs?7%O,;m.*QI+YA9<V'5B93%Kjg7!h4Z/pO;Lgtd'1fVJ))0$ZoXg4cAcnH#<E2TM)$;XMjW=m[;ID<!Y7g-+cZl64(koHt)f9^D2c:bEu<P&r)AJc4C$h8&6E=$k!9oSm=-h),'1$n<E>'-Lh]qKJ\g!Di+Z<Q0!Oo<NX9fgM);/J>`ZH2aNKE&nPPO0Q8NRjL0Y"(bk5@G.Cbn"qd[T(ln]P;Q&-#+;;Mh"`7^h&W'<ki,:ThnpL;H76@jGc7eR:5ZaWb-C+a\[2nP&,bb"kUF<frea8*t&7A^VL:YA=en8TifG2^^6)M&d!f34qX+2jmHd+?E;=o5E/e,iBQfki]2[5,ho^HCsPk+I<cIZRcc@4:Jer_7:#/dgXp<)c?%:$C)([3=J]*"0nE+[;AB5m1S=:kZIDU8k;#EF"U0=58;T.O/.%h',b7BscNk6RoOTMei/lqm9lB!'$F^F,qR&^l,gHB?Nf)rMh"86G'HF5lbWD2kH]/n9Vc]$tX1("BmbHn=p(e7C\@!C@#b/B8(fb?a+r"\/TP(pg55Zc'lPR+3"K&P=.m,:Y9N^M+!puGT<ARU-F?q8nn^@7`k,AaN#&NTh0%<r?7Jrh%>1dU"AWhIe#M8E:k5=><J\$)JIW]qBpPursY>1+4BDImPX4+BuG%\7s3ku-DfB:'#Rm"DP?(Gr[4`H(gBmcY<fgJDZpXhbr]RBBYX]H_m~>endstream

+endobj

+% 'R244': class PDFStream 

+244 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2605 >>

+stream

+Gb!Sm>Ar7c'7CCQs"Ft3:^VJ8MPMX870,Jn>CW7cVid.:W;EeC=4/G.PtT9I^[KB!8PuoI;iY'-JIPt2fq$<S1M9`H=SQInT0Wm)152&ZgL(P"3X=DN/kdqVD#4(_htl*1*qrnV%%-MB4'U<R33qjcbdSR=i5*\0B=OttCuhqMd"?$@[a";"Y"q.UbbHaArKT%/2gPMR%l!rgn,AgUrk&0i\(ept"8>[D(_]B_EsB*JEpfCgM[2MDf.Z'qaH]G_QS,W&17cNX^kC$Z/mipb_sBO@hm+00gM?F%9:OSA68g0;)^FgbdCZi8?^jN.m1'B`eE`Qqku,<S8#:`X%L)k'h0&2bg"XXEeS>SU.WUq.i:>]7$8\CE.io)V9)ia7S>SA\Md"NrnKc=W)7!5HP>XjnWto8bcS!M'-YK!F3un&$`RZ(dgOAGGmYUOI^V^/%EV8VlibT:kafee7/l"-o;3]r$LX%8K&>[E?,R$M7ku\1)R2#H8ItsDJ,_Ut$Mio_]?iO1ZP)HllTh+i36(-oG6lkn@/if8V1)K_+)Xs[[.MOBNM!iCTSHfMqCW$/5e`kc+dir-Pffc,ule>m4PBZ1+Vb\8Zo@$3_o:T<r:Mt>k7-<Xd?_0JT^_m[8!$a?<Z*?7)dYP_^L<Of=f!Pc1*SA=4a'qfqW;eJ^n"mOF]!=?dKaG1]JuD);:h>rhH(e_A&c[!"H/V'1$U3U.a<SkP)423B*\8g*=br;%6=2p*F0=Fs*IM?BD?!Y8[*/WGqClf))9`"gcn_btT+5Jh!Psin8oH"COd\LaWh*oKdY!-)=LA-sg4r4J7"du@r/\&V,fjOt<-N'sL/RPEKL@e(,Q#`2)&6g'nCm(iPY!-b#&3)td\M]I$jfs^U7fUP>(]@Z+oPdW/'51XV(-`n`s0A+CXsB8hKZQ&$4bHqK=eX5R*,[B:@e$HTe!=p35[SJ&<b#D]9/]6]i:R7oV]9!JW-p+`7WhSBolQGi^c*9@328%B\[FAS1qD`M9%DA-/H3G1RQRB86#l+4'&jRre$;"<>,G:_NP0@Zg*Z>"Npr6B!I()@6hor#smkVZ9X)?2[H(h&,7p]3QDjGUkQl'?L0RL.Srd+AKpJV=P_/_keK^DU0VbC'bXo;d?g.7aRYRQ.Pt<pk2B1Wo4$P4?8^9]phX4"'75L$@:@FM3nDPD"PR8#Q@/b_S\`c@I0Ws$Do2]V8-)/8"JmTrfVBTX<)V5:$G@m3"/$BtmOl)GnY6Gfh-Op@A$1S="T+C$RJp[-@lAEf=)N5K8%4]fC?N0PZP4>4%4F'lAJdVIisHqk?cB&*>?K';(@aX;#aI`Q@&kbpJD+lT#eRSTQ6\6ph&k(0kj9p$8g7Os\<Mi/YskbkQ29=].J<+@]2hkceMnM;WI`V@eoX^!6?1`,c_u7(l<8b:-U/,a*mQ/1@:qC>F,-O<*O+03o>eR2bE*=EW_QH#B=jLTN#[KaZ/dF'&u.XnTst2[3LrqHmO8k-17ATI=!bb#gLWaM\Y-!6gY2f7\QS$i+ohsfJ4R5F#ScS5<PW`1jpCSb'"1EqaHXd5E`Hg'A8/u-N6FYbMOI72<=niYaC;+bb4PU$"55XOl]%>gX/&1:3)h3GOhj46P(#Y[hH(]B?,\]n;3e1U"EH*si4+\g1MCEb0)s9]V:L/+pOdEDWW,$nc)n7MMpA7li:YV7!pntU;jfKOLsTVI'C$JQWEOK++e0oKX4KNP.*!Dm<3>n&p0U&N\:(r/@+;Qrd6W]O>QjACc5cE+5>#=s'J`K3K%(TI:e!S!ogBVH)J^VT-l=Ki76LY03>":=f8!j8+"P9B+3@$.rf'c6q1b&$&[:R;h,?(N2>)B5fY'N+37c#GdF%0QJop`6C:a]pfO6BlKV%uj>nPGF?;W[0Bq[hVMkr\5XZ;c#O=$fu8!$ejpO7\SNf"\2..^00@oqFE5mBR>Ynbk5Sg61tA"a*RQ*N]XBl[Tpg)T1U\;Y*OCduHkBY6Z$7oIp!^8VqiV&*<8MjQ]d]\cC#\N"=^#:1/mnMoZ7k?-7D`)KZZ+lQPSJ"4J0q#F?Efpn9>#Gg\BX6BcaB7ZE![YLg.Zt-5-6rdB_>`?(&]J#%gR$E@p$*$5pk8H2LFtQ``XgtaQXP)[?Q/E-;flZpNC$hLO!=G@qa`o"02`.Q&230I/.+)%=':o.1/9OA*\[fg&gA2E3Q`fs'iX0CmG%']%4VVt*R+!.'NK/id2D&qja4/E#ZZQK$-HA1]gC,kWmGAhTGLF?_QX`e2<6:T;?K/g*=qmm.L:+9"H^u:$TnA#GIB9V1DDoe>m]()RMYJ\:AKNU#m/-4B>4u%`k,/=ZZq#T>O(5mT=&kY.ii)<hrfH3ao!:NX42BIArO%q?&gdE+L[X)@+8BsE1X?BbgrI1[@8qGo[B7gW&H0HN\_Tbb\oU`59^g3J)>6/g+QO1C;dhlWW/h,J*o/5"Cq+d0TdEF'0,DM^%;@.Gm@%Q+0<j8Amj.G3l)V@NEMgY*oRf-[2"/YbLr'6X?l?N4?@oPe3<#\DQnlJY3*PW(m@B#(jqBII_0Vd27XgP9I$`mW;4WPBM)=B;=QE2&84"?IZ>#Ll4_BkofnGT;.>-g0rW,51?K2~>endstream

+endobj

+% 'R245': class PDFStream 

+245 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2902 >>

+stream

+Gau`UgN)&i&Uekgs.N(=CN!&U6%Tol09KbJf-u';?-0WVP_UD9,UWXIn-gEloC_A9_.>lg'Wa9`P3aBD\b)CUICab>_AIbhr]e[.?=1V=IL%*e_"AV_.#?gX"2)<rrp1$mL@t%="HuE]R,ORlo+93bk#no*:W(9_G0cf>WaWNe,$<-'E1K93#5B+gV]?SiN4'_tO4h=,MjJD]0=_"QGQ4(\^GI$]4u?j`:4nbMoIL8$JhU^K]U^^sP'6_t04*FeMZoS>G'R_JppfaNh1hiRr'oPB=G"\Q<+[m=V6TO[o@5_ro][8^P(:XJ:fOJp`T\H)YD'D?!U0em\9VM`GRMATS-j&."`6NP12@Ip4//oo-.@NSA?t!*r)d]=8_I#')fK&8rek[nbtAsZDC&Qeq7Qs:dW[H+iMC$:](]sR(_\C:\F_31A!i:/kn&_X_V$XtcTkW&44^qo9bj#!gF<=B+6U4g7)mr:&h!$F\ReU_rifCZ4G-=p>=l?re#L4J;Ija7-Ut->XKE!.37`opi-c(R7iBrnPLr_?H?+lKc;_mHc8brS.8h/6\WIuc#36tl[NPU4iFoIe)a)3LbJ0hJ\$GK#>bpOD7uT3oW3qLOW=Y:+XJunW+B*S>3^Zs]8UDgZW<cW`PL$hXD_9a8-p4P(Fb0E#-e!IKq!I<d$o&+5\?_sV(jH8oEJL<OIGmPFIM&,P5jra3@C7J1N*K"caFf;,a;m.Ffn`o3S&#QlLL+ZJ;WP)&_+DA&I;D=m]s5k7NRjRu#2dn4<b3`qVR,M%Ye/f_(aR$@&rjO5i6%$QpS6k^ZUnqr^R;DM[k$qJdXLA!EO`&^bN\Lao*rD3IZ86VO"1o6'6X,$ptT72+^Fe\c/@UGDT/IhFrYIm32<Yh-1Z(fjgn&EP1N\TPD;T,b.VkG0:k\J-J-^8UB*;,8%cBNkLGWc5(@eZGKQqk(7d]M%1:H.\3@2nDJGHPF.fKJes[SEQUW-T3?r?/^7dpPE71g"L_usAWC_tg4Z_ThN-U;:i%'?tX7@c]`,$2Qak'%gqe6<8KPK_0,QNckSQ<!o0]t/Q-9a#'c8%h^Q3]i+jECka%j\[3dtaCh-ZLL>dZ"hV^J#6X$>K#;?Xj;FOuK,V.ko>'b(reEO@D!iZ)m';hi[h%&l&76YYr%'`7F-eK@q]7e&p+eC^G!ud9!?5@U:@$X`DBQ1>F=B0USJ-cXAN!7J#X3^+[LBiaUl:0b9S.g)H6q282:/bQIWu11_b0paG.(_Pm=+DuO..UPhPP%^%58b?s*hJ!NG9c%7W946Jmd,C;4ON!bp6HO<hMX(MsLLS$,7<>=.H,,-3Un4'3tl5&7U.c[NCX-D]*c.g!A"h*-OP2[$h+lbKF1+hc_LCdXW#p`;_i?&K$Z^XYb764_iPSK55GL"un%OXe(S$Hi0mg6OZPUeL.)_(Bi&k8Cin?H*e-E>56.I3gVGFm^u$4D"Y7bLs^.O,lT8VGPl,JmR'P`SLG9;M*uf;/)-bd:fPQABU[bXIZF5.P$04`9.XD736FC(^ubWmeZ!m+,!rC78`B>YhfO@P/d`U*Mag^*8P,PK2,H2\M6a!1tk*^\:I[njEqTU*[QK,.aY3WpU@S<0WV9SWY@fGcf8%=!Q>)'mYjF[.C;1o(lDQ>O(ugTkF,.`$A2_l*Z(4Bh<F<E]IaHJm4c!j)+emr4^9q\4p9'p9u.Hjh<Hd7)[)k58B&+?$s("cC='G0t]Gm<0o!,d3lqe!W5qD)d1nRG"n^/UmLo0V3f:Z\7kKW1)TnL35lk?!'`()Q(,;mVG[*dE8&cEigPX--rAU;"U*Dc3G,1;+mV1n.?*Q/LS(GY/`V8L8roRR5US_f<<G1`-mWGl7H%'-CH<,cb:o3AB<%8k@<aG8JKIIU$CSesCUUdWOu\"9_3A5M$2>XIoVP*s1Y!M>*Rq!2GN$DOFS1uBK1MPsA;"O'gi^%<49dYWMotb?=?IL\*1FF7&9eFhG[O5-(T4IL*mM79\.W5`pZ1'YbT4,q@G=[\-+fSK-?;Kh%purZF%;/ebmP8Z1jMXI]F<`HS(e@Z9kRCO#J4i<QKK`9d;Gs5.aC,c7nh@"I`EG^\?F/g[3spA%joG,-'&d'V=_@mDsZgnhqHYPJrnEK.Vj;m@aQ]ZA;<3\7\J=-<Wsg\RTR_NFaXcWWE_J\DlO?kJL+\I=NWdaGN=^^o2AV![Z#&$ieK:WppCZ]"eVRO2nVsN,4lO$J%E7liRVH!1"\NoYU;5+pLr^4p2iD-VGtnNPO>,U6mI)]C7QslEl)6l3u(CYr6C:V]]2OBeLO>]/+:lTl\:(A;"eX&/q@^>\phZa3X$h5\kXVIpV3W,N'+@5\s;6Z,Kr9>D9;^n,,M@lXFqHd]Pp%P?=EW3SRQ(gSjP=E-FIJ2Pg5(S[a._1EYNK@=g&MFOV&E$;mjDjX4`h2U>.U>?/kPFN#_>0dp[!"6^^[t2.B?r)?u:*a*\!5^;+%t-!JAF%^87$*M0L5CJA=dSmp4AOAR7dAm_fA>Je#gpa.>JP^DKWVBU>W>!*]o<ts^r1Ac?T`>MU01lB`t?i0UZd^2I\C[Lq!qqg^BQh2?!;#4Mf<8Ut"HFEI`KIctQ>D2_(YW('RLklPbYP]V?LckQAC\0H6.k+.>&W^,'*;[\U5Pc/*q/kah0+J>To^QVeI`k!(:p!O@G]lX<j4`pFDjIYERmPZ+F8Jtb^";.MM'GX?:2XdP8bG]O9nV]=#iM8tV'0CnaVM?V_3)?_lsFXoFs'.ToW^<j@4;s(DQWLNL#50NoO&9j$Crgb`?ZKL;&27;^%JD@bspF`d^5R#/W;c31S3U#9!M4W2%T*cS.?`XAApe_leA>L2!<6Rl9PPPmrAK[@GOB/"05?'Zfn\dhVW*(%,_>2\&1L1Ij.qOq6U)$olUe;~>endstream

+endobj

+% 'R246': class PDFStream 

+246 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2747 >>

+stream

+Gb!;egN)%.&q*PUrh7Lgj(ugWOeQa":Yn&mP8\(tM3ZfK>0d:=Jelo_^_!.QrV^mA,Xk>69OFZ/;Rr/!5bQNfFS>h"_[ukCpAZNCpr<Gbr21'S!/h!XcjO9%$1AY5?[]>3rG)*eKHTc]@sk3'm_bH"[s?H]a:H:pH2S(_op^Z4hJ=s%70^Kp@5lJ-.o*c4/NL1fMAnPJLMpSj5?Rj.0)qF>qmCnJD;Uf(FPboFa#nN=*s_a\^Yil>E=c9Enr-5ZN)3EiLG)^:&2Hl$QidFBjA!c%TNA5Q1&fsC_m?\/^g>8g&Zq_U]YHH70+s!Q7P&2qP_2T$i%.#I,/^,9bmi9B"X1-<kP3-7W;?2"1g]Rnj0mKt?re8m5J>\D^^RG(<?$biR\qXuKr2Bg?IC#JU%b\-cFd!>ei#Dfa%;_!'VI>s=IuE7E_F0#BfLMQTB3..gWnSb$]F&*O0FJ<W(^EqDm3Aa$,Q[[V'mWMnKq7/Q8XIt@l"j@&)JZVebq!BQ8jLTBGcf$N>]@ij<VUe3\2^k7&*m7b][C=M0Zt\eA.6NfNP3TY($3AjmiJ&-\Gp&o9=*#_j?YINGVqW#g!BrHl\Q?S_\T^JnQfh_Wd7.W"U<Qh"1JW"N^Cg0H*?>W$7WT1\V$(*l,'<[>T2?Kn0p?qG+*0TLWJn"[T)\/r`_Ki%U"T,i@Uo0eh($PK>E/W2_7=^E^CEJWOYibM1fD$C:4A.W,K7\F"&#X$Rq`7$6RgD';qWfkgHrn-%4,9")PZ*[>UcKcVcZdmj)?Bftk-(YAKYkLZm_pliL_&!:Tj&oK\HLC=5>DmF.MiTg4a4)]m#iU%6nLD.;G'+;kR.7P?_:eV`)f5BEH6Sj,P>*Xg'Rm1W`h!Dd_^M-38?E(eL@ZY5i-!1N.'U[aHCr7tYM8L)*n1A/cZ3XQaS4;cr$c*Llj=4-aY`\J[P0nnlRBa39JVU%#fg-+LQa[\r/*-FsgoSfP6Aq\5,_S0M8m_/Qj*2K*n,HK^N]jldCC^BaA=><S4T4Xdq2`j5*Lb8-*HkRHR3M0IP&rPQ7X_)L\VpnB@W3m:r!ee2Y^kJ#\';HXk`I?"=c\\DQF>;3MM+LS.-7R'W"5U%Q7FFJ=<fL3AI?W0aduF,=tFO#B/At\J=,a0_uWuK(,@<oB?^EsAgjkC'.%@TM%h07]<PPM%%:XpZ*B+R`Q9-pVr5.C)p<@nNnVtj%4LP"QL,#<;qrr[*[FL:s'B#$hFEc$fIrTiJsC1_V$3_Og^dF$e;R[!QjS5tP(\rcPE`l8m(a/=BcP9J,]^,;Imd;U:u#.i.LIW803<sFUd$`Fi8TaJD)j/GB\2j[G`D;=#81RIZ#e_%%4S=NMH-odeQ\%N-19>ZOSh>Cidg8j_=VJmR4PHL*]1<fc`lbF1a%'$mJH:K0>t`(V;rD4[36`&MtN*];R._1\Zn=ENG5j,Zp-_;)VE"3j[]cE42LFE>dks`>/_nr%pWl+#;/B\P6Z'b`uLB0c^3R:6S^O7+1SW8hi*c[&l#<8[V_A.$HcsA`!2?jb1M,#Ud8O[m80T9f#7u+O+usUc`+io-o2#FCMc@9WqA6hTEC'Ve(m?mIB*hD?F!eQk6,c]N\uUiW3_soPnt@n\s#9$`.R!oe[Z2'7.65R<#9Tr'k0a,FfB=^Xa?N^dGE(@l%L.V*''WoeUt6.am^,\XRc/<a2JW8HG_J+@9oEE5C9&i8&K:$5=?\\iAd8e/EYfBk,BV[5Oo)l%Nm0?5P#$<<2+`Bn<dT$rt\6[]#[I:rcV(lhTUI0&_)Ft"H.Cc-6]]#Y8%Pl/hg=^<YULL,%X$SiSe(6\I.1"Z(Lm]3?3@_amhOO^!YF1k-X#XPP96j?MdYK1<?Q/4mCbRe!k8Y)O2a-QoV?GX&GeDrDsfM?GGanK4+6mmXJ@]>[gthi0)bcnLQ>$G`D`>-?KCfB]K><%0)/#Nh'SPB>-=X2-@]o<6$TSi.slqD%H9(Cd7/bWag'pFs*.K]6]9gM=6^KT=K(U][nSQ>-:ZSR\B/InqWa9O$=^gEQcVa;2:6bj^1YX<*(I;h'LR.Jm+@?j\Vq-G?6&J*^f"sG7T"Pl23i95;UErA'rG*1:9_ib##sXlnQiC-ujG8N/Z5#Ph*Gf)-CMl[Sq`ao$3Ys.MF9"cbNpNqkHg?GoR39a@Pi[E=_?Hg;h<LfMge'L1a4-UFJc()dP)BW)m?@+dHV/gY5ei&lNB-QCliESlQ#IdHpb4K'0\Si0i$>b5O[<I_Rc0"-Y$(YD<>i:3U;U:V9t<4k14$]u0>*VS#=nY[ic]k4RuLqb:Od=@hWtUlmg7XabN`-h@T2!aeR6O7D;DgDG<Id4Mu(R"(QVpVXdni8AU9fEfCA)pa/FfEgYk2\5@Y)c%7Jh62V-bE=Fc"D(k':HXs#Sj4Jt\jOtd_kk&(_=FjRGM\;?L+`=%$>m(IT1T_.$'mKU@4jO>A`ce?133T/G;urm*XpH0jO[f%bq#+cA)A5Z],'^QM:**eo;F`m1mrT`q8(Dh1\l84FG>N+eG&"nhUimY!e'Nb*PhMhK]u=X^DXVfkJCP[&4?Zi0h?oT4sYcH[ZVi.r,D"Ns6tHd',N3*Md,8(iK9#n;,SB9Ye(`O7E1;`p/$pPJIU?p"h.??)FIj#[JR=(=4N>Lp,b`4G?`T<j6^DL-\8fIUReEaZIp8-+EVpQG:2c^DX62S\J-H5D$nRoI3"%,_0KNu:$KCA*W(JDgh%m.T2kB9]cV6dpQ%`M]RKO'-8H+L~>endstream

+endobj

+% 'R247': class PDFStream 

+247 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 4322 >>

+stream

+Gb!;g?$DdJ(4Dg_k!/&a^!dP.JFVAg^H8o=1QA<]LVAieVbFq:(oNSpl`Z>%5^XSDC%1\1B2,Z)hF@fb9B&;u`28#)pA^V@OCq4,p<"P=99sAQGa:jcn&W]6YJ5Hts#ChMpPA-=F.[2NjUO:n7%#pAB9);A+2@eAUH3NdF"7ZHZHS-b=;7Y&TuOY)6^9S,>MPATa*C";J!9!/=S70Js1XDD5J#OlS\S^B+UQQ]B!rL,H5S`GjT`%O:MO;AiOhe+--j_dW3+8FMd5Vt1<JNU&s;@&[Z/Gj3_>P+*_Eo5D_M]I4aIPses8-sa3eSE(\(dO'9a]rVK!Ai8t'_5fo_1WYEi_4:Xf1F,#OelX?"&ebI9Qk?icG89tF]NA@LH6o:dMr]]]R1a]J#WNi_6r9p&]$/(%*>f5[8ZGY4^TMHmjjnE7D",`C]GP[A.7Hr!DE7=Gp=G0/m4h!UA+S0j_-$:Itr9>B;rd..:(:Menr_Q_qO[P_Dk2@1qf-+rd&-?5tY.Ykg]l_d;@(b2V7+DZcSL$i(+.;`e_LL.`!jICC;^'<FH(7cH\1%a<CmBdUbG-jKcjUWd+<g@K'"kt5-a$h/>j*\0_nmp8_OEH[u9Him9gNZ)gnpNgMj0Hc+Nc.O<8,0nel%n<\*c(S>D9[07\B?^hBQJ%]18^r_Q"1OUoX"tr3mV_C!"*n<m.B/]+gRjfK=5k7D<QggdC5L'RsS&O[,lIRl``pnNnA:0c-8GaNXH[[pQUaRX4(obPkTi+?W=_>S*X\]25f_M6]5$miFPdX430.-?=_:hTqUM\7`C7-.a>Bh@+sqIrCtCLN`LAGN`O<nl?5>^%#kVQSlQL2e4:hIE7V\13jH7#W/Xgu_iL_&.A.Eimh;XhSIA)hV`-[u;q,D.i\\B--r_q8k34?JG5=[2d!:3=KUY=#,4#*3=!!nOfS\ocl_VtR@%h\[E+$@iOKD\@rIG^4mJH.<[U"o`NYF;AM!*)8(0%LafEjkYGC::HB<qTW4kK,^;R;$tBGYUL=T\ct;;:GcPf7qYE9>H>P'XZinPJH2jnetMnp1lej>EDY%[U67-)p#6laa*7cWt5I1qLWN#F="nr*C[`I.f\#ZQ?f)WLNA;<F035WL%`b,3Yl>^m2aR)foCe3^8*hhE=)M\%FO:(C*KjR#Qn(AG"Pg/BiLr1.^Wl&)6ha1VLtpMgU_\?'Y%STjCDfDXn6@2!MSF00,ifloNhhl]-AK/CPoY=J6N8j>n_]6'p=Hfl(Yj?;3D19tjnOGAuBqW$6P-!/j'?89Y@$O-j5\KQ%ggL#:bbf4^]#K"7!O$nq;;h4i1`p?_J6-2DRjc#1!tT!Zf>ipu3s;\-*KlTMA.Xiu^;4L*!)>[2s6&DUS,d169\Q-,ibk0"F%8RrSh*d:'p38ZYJ:MG-!%S`&aqjVJTeQd-N%*dpt6Y)uQQW0MHo,;k$n2O(nG_`l<$br4MS$-cUZ6BhDiP;^YWdcDBa/jJtFKU):]7lr$ro2u&qe'NSG(?qVgI_%lnRNorG^"%GTD,\PdY#?>U:QZ6QIPVK8k8'ZM><TcJ6$NhLdkmlp.[06*]c.W1)q4]B4X&t9qRO#^i1+H:L8^^Eca[^X4]pa!Qpu9"]f$_"6:E73^)66i1[:aIDUIEN#sE$*^J15re&7P)jjnk4=%IqbF-cA3CHVS_rhRK)3,g-5n>LfnKql3`\9NG\b:O2<fZ#\_L5c?>p2C]p6"5!d+ahtW(<ZK[!@a+LY=299BtG25Va6`#BDN5-^u!6/mEgkHVe$e?bA68=q`8o334IP`b\1+oDaa30so-GnpVP,hsd5eBjT<%G]uS?`Pi=Y^Gr@9$Ecf]?bBkGMu5VuL)qqTaAqi3[K_V"F'IcGGgcoD-(C1hj)V\XGP6%Pq'l-D4E$fg5k*hY:@jb5Hgb_I3ha[?eq;`/\+Mj.2_?!?a\$jho1ufD9!"!N"-6s;dp:gK(JkiX=f.@b.0',6KJaU>Go=FO\VI2N"#S-fc"7j6f3\n,15nEPhNCZ[ELgc,;m5>PWREVlCSoCsE3;3][Lkmr!!WMZhqf7iHPT<Q*9QhfKpehdccFJ`PNQH>CY.cNk7R1L_G`X2#H.'[!VQ[cc!j/SR2So7H_<<C23K:(V<@/jl[n*GkO]eafD2>20RA19GIk>iqA51Rd(=s$*8(G_1>c]k/b[2s]ue'0Qoi<3)5%,bAq1M%T)hQ7N<XetJ(h0`8UL+(bEoEWAt=bl14./i,h[tkBB!a1UL!fP[`E@pfQVS<\NN@)%ML4f\QEfT05PE!kC[K8qU]Xm)-QhZ8XZ][#>*%]jN#bBQ*lZ%-1:6t@d8ljpL_nJj9_7!gW,IPjlsn91%Y"AUr0kcKN#W?G]mN(UMK^bb\$,(o.dTCdBl^2kG-.sg@+s,UMJdWjAW@AoliLp+atMbiG]`fiG]TbiG]IY_g<&I2t;nZpr(9j8*<_X2R/\A.$>0hRZCpFM2f^aI*YL;8K)A.'<^2IKp1uA"_W0on&2)!b4)gkoEcDLCd+:''(:5(LV5Hhd&&;;h7=+7&#ZjI_]S&L-NbfEjGJA2eN=m)o!S*f:i"SU<o>%BrEhF"%[*".a>p+uWlE=M;X1G!G`FEP*A[G[<ZJoI3U-P?nMMT2'&(])]E#Y^bD:(`eT"3a3+UKI]3P[nH^r@>\d4/[q$r#]iX;]_$9K(dmSt%rlDi^;oI>IuklO1N%8AJdGJU>CM]%QV4[n!ikY])1rnZLo-L:kF9SSLA"@nbW(%DeGp#7\YK+O:jadT4^r\:0S5fR@HU(S_S;q8iON786V\-t]'Jg>-O/:dplCsf0cHneSql#n2h<)_"C'eg2u6J.^2@te,4:$D7d<$C:jL8D0_&s"at#Z3H9PuWor9uEX(?Mf^c"b>lj[9c7oeek9JLap#E0nEM<Qqei?G_ZVTSCNXaCL]WiaX.orfNHWI%Hl60d-Fnn,NB]YdBO,n&%ETG<.^oU)^M(i)H>7*^VOriCMgVpB8B;6e.70`/#u"?gZCAHW$It7BsEbY.POOD&QR)6`U&TU0qC_^C2$n"$^6_@,f%J&*:BR;b("*4\Z?7PJJhad\5o?h2817m'*q^6QFM5]Ta8pH!`l6GY24i7#gNPS<i@=IhW1gFY-;&%4m]Lpe7Kf0A>G\L0KCm*Z%:h(bBL?Dm)B,[LCf^nknsp<$#GW13l06#(D[\:*5clMV.V2--EoLbklaZ*6s*.,.ZLV"Q,.L1I3=]8<cX/Z/V^#Wjk`>cR[P=E>r2$A0tq%oCbcocn[o%&&/:Be7RJo%\%i]0U9_[M.)tioQpOVK()RK<g>.`tTYH9)D=MI27TqeQX[`/l>#=lZi<WR$H<m`(&>G>4.ViE8fk/.4[(MIa,biF.=A6/IE@rj-@lfIFZ4%M4D2"KQbP7H",-(!^`Pek+dLCL+6#F&W4X8c6):MrO7Vj2Sdmpeqm)EO?It=X'8^Be,8B1?>$CtShR0\_mf`"42'.c9[@5/YS?RU#JV.Uu'->&N42rKspo%%kdWLV?=19QaQ$3PDl"*^jn+@IOG<:7Rh19/,DSO?Gf#E-^&!lK*m;<8iM-DLnVdn)rmHa&m);d-cH=&bhKX.@pq(g2C,(2T]B8&*L/3sWCOLX`Mj;?_`PC6i`a[`duOPqsaSqO4VldA)8]pnnFNWj!G'E>aG."A.1#b4oTZ\fhr\@@0foA<EgOIl3o=PHc![klaWpM>I!;(qMF>Rph[ZY[l.k9sC"P<>s\D=,+k7[S+2PIo?b,!V@VY#X;A"8(*&sf2_qjf/,%DD30"X'G.!RBI_1J!J)[B7+KX`G!Q02;a?/=TrG,F"@R&LX+l!VMV3AaF%/4d!O4tGi^j\Ce8S-W$GF0G.L8o%/03JQ+b<m,R'*=N=9j`jj9ieH2,2+T=A0i=(oF?J3YoSA@TJV5"'uj2jD+h-*-_N&f/,%TL"_k1?#p;X;)L2<J$>$M'c<f`G\[7d0nCi/9\8d`rkW%F=(%DuiMld.`Pe8jlZul'+[6O@C]V<cd#e'6N#sRR@`9CbDCBjr)bM'6n2`^]$E[4?94Nc"8q8jB<bs_mO<X$ZiYu_g7E(A`U(Xo2?8!/Q@tSMGMBic+Yc[_IdJ3\Z<)ZX>JZ+?@n^i]=pXZ"+MBW?r]72rs\-6VAcN=9G2W&i(2i>_^X5[FoWLP!'SnRnmf<IqJ5/scT\/@a\Z)=k0KdpgIDM6D6lj9b/To,:kRp\&eHg9m"W1rG4"rIe,g>.p$TYEu.0c.uD^p-D?**$18R8:H7YfGE:<qlPp(uX'QTB#3c+,^4`)rYjCh</9fJ7g*SNiW&(/C%AD$GP$!HuC_7op>[Z02eX2~>endstream

+endobj

+% 'R248': class PDFStream 

+248 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2420 >>

+stream

+Gb"/(gMYb*&:H4YIi&;j+Ph0>e+[sVH:856*d@?)0=4,Oge+;5;Kf`\^GDZ2bHV^2D7W8q,">s51-%I<B'.=)5o9Qgq]D[8:T!XN"U!>.koA=u(r5c$4J1KFpVjgJq=nn/]j<B6ichi61H8gn[:%eWZec6op[@(@XPRV19L_C:VSH;a[rHiME?#C$bHC`k$TMb3#;H)]VSBb15If=3lHP*Ber74(>-+8Tqql9/g$].D2HIOl<e-1?`IIZ;cOp8+VNq9-,n+>,66_BmPD`8_AI()+2950!nYM=NUa!,Lk"8"@n?JgKKS!#h+uB<o@sX.SQ+88Y/.LO\D'q-\2%Qet70g[rCKq,hZ,Fs'DT=K`d>I7E/XZlu0jMn4%Aq3fV/9d@\SfQ2&79EcI)7@WWm]C1o43+b]!O(38]6de"ig*a_JR]s=.-=F8"GQ=aYZfK\[dtT1N<'Yh5AlNC3+(!=>"&kC=B2HncTL2pHX#0%MX2"Ag101=@QaPZ]/N2n:%_%$;PFOC,G>^ltT"pTK=-P-BfJ@Y\l-Y*IIL=K#tNu:TrbUP<bn9(Vo&TOpXC1;!CM_MtTX67mXn4'OJe%FrE'cK'Rp,+p3k/4ASR7d1HQiK5_LTcL-H@qUJZ.OUG@7-qHcPH/MH^%p;)!DfQ8IhnL@*,(G[V\jF8NkJ/ef,9a21"IG7,e+K/E\:;%i\]ROu(^(@Z:ieDF#agI90;[+Z;1$sK0Gn*?NVs`uET0oK\]4?k)oq,X4EcIA<VnrC^"+s@^/`TX]LG?R*11M1.06^AJ=PXi`$D[[$IBY;%r!Go7G!>99Z@<NH#)qq>Zd78WBs^+bd!kaXB*Hf@5FFD*m-"B()s8DAc.f)Lp+)%,Y]^RX03.e'3I3U#o4/26tqQM^f"iE@$.3F,-l.s+f90OkX&cjPbInoPGFCQh1>1SLcMf&q[bpTi"m,3f'U>tIjmep]'aE^`5b63KC:#D^+dVZ0<hg@bXa7Nd]OMt1]m+[R*]+2k&B$CbeU.Y;dZ\.63C8#Ohge_g&'Ca&*T$Cs5C<.is9ELP/tGZ2eS?hLNJg2"rj+pB737_7c><sfsQE];giNpn#N+">OL?4IFB=D6a<dM#tbW/8Ko=?5F2jHJ;N"5!Yl=t5YW@K.,W)tIHMA?2a*d/fS$CMTDq0]:%q'?4'KYiah!M/1=Re7<@4m-L]6B&-5pGmlX?)M<JHnYZ`HT08EFSRHmGPPX;S8"/kHWXis&HN,j33d6ZM;O@+%98!tKJpQ\i!K$V!3/mHngW*pq+L<@eg2<:@QK:k_W63qb]Do`hA)/6srKjM=!"iW%P'2o)l%j48LUdN%T49I?!SSrq0]c6`*>LO!;9m;kEr`&8o;GXbn?<V+j57k)*t:If=eSP>0Dd@lT?FNQ[L-BjE=Vk&n^=HOPW_$h>fT"Tm@GU8Q,#ZA&^]AR(4E7*SDSq!SOj<SAkIF>-sFJ^tQ-!4Gh>>W!\.sEP\[FZ[/<OT\BJY`lu04-\0+;Mc]47;eKGAQ_uCBVTpgbGe+Ro.4o3'=aZI'^Tmp+=mu8B)JA6M&9f6JfD+7dKgd%/[m@d3SCc-L!Cn'fAC+"1t>/%K%r%!H2f6NMU<UBuM<-6.MQIj)C>&b+L%._V18?a/ntk=\^poMM8&L_Ur&<W:D&Map(At6G(9"NkoTR>77l4\o0hO<flU`r>.6\2Us;]n:kR(f+Ms0e[0VN.RQr1RMp2[;r@#h.Kr6q1,4_6Am-*[,UZWi!lTI=69Kl6.peiIQ^"Ytqs3(=pF*W%[)gC<!mEN'[<sTgn-C<q($,8@T$7*H`<b)o[-)^a1AnE;Xqs:)+YRr?9!k(b[dQug(m7+9r]1Bd&s;Kbg%K;HU/7jV#\c11h\&B4+]Lsi-Y4/$FPA[l<?Q.5$@X&$2HHVkr\:/gAOM`s8p$hNO]kV+/]k2c3>rg_hN>M#"#J1`ilDiA\NAhB9W+760XJ<p(+B[!ZlH=0<TiOd0*XtP(t;]V4b(i8X51V<&tU!+V*YpZ#(8"]6/SD!o6k9IFn-^+b[t-:\_s*bai`YOnWSUZZ1POZAQThX0Y,?]0[]Ebe'Q+b0X9m#OtY`B720J'g>8Y&Es/Sf]Oej"j71hCmPau'QeGF!#/=:bQS+KuoXP:_`mRN%JVO0bIra0gb$cg3Br=Z=rBmo7Dg4f%g_gaSnU63#[F`lqUu.kn!`gI6Q+7I6hS7fbl&b&Xf.Qokf:Hn7k5Ya1"'fFIih\+;hr<#=Hi5%c#sT;_:0dgp=?#'ucjq;M@!;FVNa.dV[j]\ZbK1eE>UQN,VD6L?!D-D?S1)AE=e`8m##bK[VFg.ul*<C-`uZ8`nb>:-fOTB#N-Ca&\Q$HX/q`,,i\DQ[4aOWWY[":02\J&c`9qLmfj>0d:F8")bO3(3W;YN1f7`tOK_[!_0Z3j9rrJ0S1L0~>endstream

+endobj

+% 'R249': class PDFStream 

+249 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3929 >>

+stream

+Gb!;f8U&t"&\e-*rs.>Race^/Xi[0(-An/.:2ERe*24FGDFi"aQSusO7eu_V!k<d*"[L,QG\fU*LT$2dmjh@gZH3/sg\gM_6HIJ3jMs2;YoRk+:MeAJaNXt\kF:),^@FL3-16,uENHq\S^);G>hJ^*.p0<ij-/ZXYJ@0o3!ua+l'%TifX:t,?lqN9QB*X7r-/-*c><4[Eq:flq'1+`RK*(ds5W]Z1kE?I\@7<F^n&+,QE+=[[UV<j2\89WXCW5J@6)8L/[X5g/?m21HX_!'@l_*AZC(P=96R\$m\2Zj?REYX`k2^HiCbh\A,1e6D-J6Y&9G3j,YE5793>@a^faj&O2"rWOCGuZAU-ki/L-VH-I8F2_)iECQY0+AL2BJGG3#g0rb@S]*Eu&.d@/)FbB^dCZ**X11U>ur.sH3=:=>OUnf3qLTCfJQqNg;>B<RLHG@A#`GZ&igR'%c+UC1_DFqF/i0J7&eK^g^6?b]3im5pV.SBtI8\>opU((8=W6*PVMPA?.@(&QY'/+'Cdhq*%dme.1Pk<.H\0QMO6QtFYnT`q-Z]A"EPm*b3jOalmk_BGBD_MW0%_\SdFU7*suins\6q0qS$#XCX)LMl,`_WV5E^JEIu!!KmTepB56!jS53NM;=4E2`#06WoSKjSI]iJ,+$e^]W%">X#P$]R'[cpN.LDkN$O,3KUQcVhC4]_=@uFL<L>OV?pIFBc7]m.5Olio9<eM!HHhQYdEreY?&e\0Jf:fcWWA\hgr0#=KCquJA.cJ;tO1gnRIkSAX8NqQ?1tU^trmjid3pK`\@I17KFK&#MGGtY#3!oJF!j:c^U<j+a][?)jW>AW7aKI=]4jdncEb']O`N3)**12,RrF9og*_XlXLVhk=+YgHSQa;i*3Vr=kZ766tGgmbOseu*Ir[ub0%/Y/*Y/!=*aue4NRg6!h=LG01Na$SE#,AV<`@:`>1C.\0^l0:"XNQ5JkF:)j8Q<cin/Hd3tko+;&R7[u6q!&=/ta!ZmBWh>XDZF_#ga^K%0J>3$^K2pW0JK]@A@%mY)%K/_BI%@5@l?E`Ko<59!0/B,%,G+gMpRtD_oGsU"A'W`^2!/363`ZjYU-PLM2'[ArD2g_*lpX-lB(E3aI9=0W]+G,hTdLpq+2ie,N^Hld?[LF>%9+"[<>9t$l'haJ=_<%Th=>TNL.!W"^lp8SB"McN&N&M1kNf(.#!S#-CW`s@Tfs(N=:Bp[CA7)^K<Vb$4Woo)eo[%THrI'/+NCggAJte>[ZD2[_XnOQpgPk&PB.7Z&8-uKAn1]VC_=J-(3$b&Y[bO@JjoUOT8/lg!1OKHGNW<B1g9[M[';!Q#Spfrh8d>m@k#g]Q/:oO?Ej\LTAIuR9+L'ea!JEZ1@Yfq?*&O(2Jn7$N:1Fd;nMf-3OMNb(aUXsKXe%6#ps>X+4=?M.r9uE<%?I@B\Y;*(Y@Ca8q\=t)/O1JUq@A9fBRTaG!(HBZ5<60Mi6->6*=gq%mi_dWCeLBEXB9T`g-WA:aJ[][[_p6\M@=5D'\3<saH&eoCa$.]q-)Fcb@DcQ'39"W9pMNEnOY1c6UcHunK,dFbi^OU0M,5Qih42j8`(s*g<"BQ5]J+Cqo]d"WRmPLpOmUq8YV_U/<.<&SKtK=2;d$##Q.r4YV&NCZGT<^BIYDW"]I]YZ">H0UTDTB]PN/#qmqi/T!j6[UG$j[?m82YZe[N4?]`Su&NK"L#bP_n"[6gMKCd4uYB\\IoVp];1(qV2qt5:Af5ZkoTKIY40'pplShD\!Rag/4C"ZhiKMN]Ir8Ng@f@UNfaDT;ALg3**%r/(XKW9i6V>0d`7/;l8`mY/n?G@1#9.oP0i_@tUh4>(8r,B*rq3K8jZQm[ng:(_HAI]a,OGTETeR_L*a;0bn"`FJPF_U4UlP!PgdKfK.VXSfd2p"X+9o`fQi)liY)e\899@\aj_Y9@)f]Uujcr*S(91p=X";&.#ODU,\W7]'gJ*_0fV(+G^W1>'8Q?IJLFrfID/bOj5o5P(LKVk;p\Hcc\W#d:YT^mB,*an3GbRhg1W'<,Y5+6\_3DGDIiRgFtI+cCOQA^c2*T^+QTj:A]RE5_n5^QhKBKM3pm<E98cM)&-<4n<*#1XfC;)eXJLk.B^`F8HTP@4"m_8ni_[+G#`*+&pYWRU0"Kl!qjld"^!FT.B"\8M9"\P9gq3j@B8+%VFfb4Gm!>\WruP#'%O6B\G.6NCF9DZg:T&un/5X?sS.W#E6.!Zq#qD`j[<s5N03hqMmOIQX]Z+I'?=*Thr,/l^Nnos/SNc5@UV2_R7ipKF:GQmK1j7N7`pDU1L8^Tk;_pJhE2#PMsG^15R.[PSKA&KOi\Z<$`n42fNY.aU</,Po1\it!\h.(9YB^X/3p5_;<.>gRm,f3QW1e*H3^N4dEArD#"6:Gc7]-b9ZZ$>R4qFa.L03=d\IXhZ`Lqj>l^rl<bd'C*mVPiF?SfKMr)Y+lk6`UA(-AM)"-R+)PH,4-qT>phIhNJKVg=<Fh]!tHpcb;6.=8"Fb!,b-/1;\I@gPd`=ki@I:*0L[)jI3TBM'&)5^0JR(r/9.)_csKu%aU?!*@iEW*Q738U$-I<0,9"i?'G-AT0JoN_/>4(M_cbtSUS6ig2UY))<JDch,q/0;Y9MpV6$]0W=ZB3SXMkcai@LZC6,HdaqT(SB4u(uh47rL0gNKBI,WpKCg0h*$Gl!4__cHF%&\428h"(r0_:-GI"S#5/e@XpQCVVsNl2Qjc2f:hh3Ht%M9IY2VJ3r-L@bf'-&fml!iD(HF&UZZc9SRX&`kJ>qmdq*Zo'Q&]R3$?(jN%[ZEP>k.H2>$7d/63$'3`Abe&Q"S='dGZ"odfc#ho=QTUR;[;teHLQ0FDi:K0M"npJ?EQ?cpqBAu$nl*/PYImNP<K!Qd&$HV1UnHWVZWb;6T)=VS)\Xa:]iDop?59?#/Y=Ts84[c9g\?o@U*_k:)^8MOQOB/9%42O.qTn1t&j)n6Um/(V[nY`-K'?_dV/M"1idZT=<\`5b`k#"EJ=6XqI,nm\9f3Oiu7g3U4V;DlO9[s&)B45Bo'r5u;IRdWu0oC(<I21HHoS;t>'PK[g-DV_JW^m1`$QXLeIOIMg3t\F`_nLUX99_&*8Wlp)kU>ZD7DfY98Ko'R3Z@kEd;XbRP)+jXNeT`W1`W3X,be_DUS1I4%7_><3Nt9_)l5gk0f:-QG<ls85\Zo:YK8@b#[o(^Q%%B[Y@a'J"Y*(VC)\/sI7e5K5rD5%_b*EdT2HSf:e_SMYgUqGVj)o\<0K^,XE6;k.AbuoK/Em7L3]O.BYM8/V#N'G+pfYLFQ><iV$J727%hs=qu5-I;S#+>8O@9hUS(C3%6pd<M.g#UB]rAe_\&n?+rXKC)Z#]HE.hthLk_1TL-DFj*,2Y>^re?LPQIH&.<E"L_O`uo<QSopB[g$aGoG9@ANspq9Gg0;cWB=16MaZK[#,3^YL9MJoH?G5()8r=V--CS6[R64.X8["Z]`aln>+`/PW"tc3$!Ap^8!#C%M*.9k@=(bbQMO5c%iFo&aAf#p+ShRm%@=k0WNM-9g`sV(s:AZj#X<l1^qF,Tj58dY1$!;6Z:`ub1/$&3j$mggr?IUUJ'/U^t6Mf,OT1S6:4&:]t#$3BnV^!*-2cO?:HfhY)b"ONa"kJVnId(d;#J!^c5m<Kq7qoED3PJdfJQp9b_d)Hc@eR7SF&W;`7M*C$ueWoGTG)OA=K!6DL@.a5cB8pn!S/DLg`0;65`BZr.74Nk#I#0;BHEJWFf8Na!0@g1"b_WteQ#FNUDh_A6ocHEE\UU/NthQ*j_`dVIso&=p*UY,K=nP[5l<L?OlH.5]1n"*g><WkVh2&%g`%HIBKF=2P:a1`ZqH_m5tHG7'BU7SmtW+YVDh!'"^",o9Ju69kctUS^k.0r6#rFFZ8a$7-Ke)F?[o>be/c;,h=%3"fS0am3%."g[)\]D~>endstream

+endobj

+% 'R250': class PDFStream 

+250 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2421 >>

+stream

+Gb!SnCN%rc'`D>\s+/7X\jO\F00cmR5e"2>co"7-%n3bi""hnY(VN.-EP5_oHV$hqj2@6h(Mea.JPAuUH1'Y%k>H:j%t5Ms2bXMQGs\+;G)51Aac&2CouZ9=nnN4=j@9/1[X6pGf;4*"mb)8t8Csipkb.*!DEsM#:LI/"IaETTqZ3*1`,R21L@Oej!ug)BHhp7X8]U@nOicKknst7-Hi8:iI<^6c2?V!pD.h>mB_m/Pp$>7B>\?S00-G].#=DTs6JR$^%e4&Z'U/'X`Af+-3%\2&P2D.Y'9V?1:O$'I6=d&>@4!:%H'UoDSWb6B=is;o,K56J<Nn;h14i9c9[$.DmpX]3QBSe-N$i/Yl\dmBgEk0%=m4TDN#Ao&g/TO]:Pf_aE9L5og0o7J@h1`dX^LuXIJ*DOY?F3sjrcGl;0Yh:o;43IqFblrp5XID*V-+G1'ljm5B)mQ1?@_P\:/kNi:7ZjA#9sr&aR\,pP7$KJNbPsj"0/BZM^0P/A,S9Y/l1qp'FC2N2o8GA?6nN7ae@\+p*/1CkXhqKINY<*2A(IAOPWB'Jg=6kbU\P,*JdD:<CN[KLV8AMVV5L/k@cN(HNtN/<7%_FJr[Sd85O-,)&$bs4-l2!VAmo!IOmI#!sP&XG5uU$_8e\0[TF.8aVLqM8^9K.(q24(+s[M$ePuUHI)j^d';(TM]nb?:^,mVA2-K-98m)nB<7%"]-GW8*f2X4-Wcl)1g?j0j#i0=EK4O<GfDDoe:EI^YcO`iYF`-4Mq?#2[Z*p3U*gAm<\.E([AIo/F4:<-/465ZJ[";p]LIH)i;:DX;^%&Zlm4pL+T<?H#.,*MP##.5k_t3a-;bk3OF%Ja%+kCV!4rg6`A,H"GmdkC>7Z7l2qhaB^0+ujWQ4,4$8ROe;A9Kj*uiXV5p/$C!F@"n56IR`:'?GYFQ!9SQC*Fd7QDacXl8-J((<^2Z=<5[>!iX`.Cm[Nm^P"u087PY[NZYs5daoli!8Z:@uHT>or-Iln93N04B41u-`hhLgqnld6D;'oC5dFo9a$"KcbjZn+b:2%,d<]UGc(Um@.)O_=_@4Ce'!t7P'W9YLM71*i%@=+[-U1&#)"0RN%Y;2btTBO:/*]@9F:l1&C\nW3M(D]dfOoLZ!D$6lsaQL!(KYng*f_>n<t.0lbmC;CKQXN7n#2_[O*>ffe'9[dea2u':<lMfL.r4[m\c+C\)*7&s(abO8s$G@lSUq2n[?ADJ5fl,t@Y#lDe>F*>iTF=5Z.#*,$YC2jLU,[\,,Y/<7\gmGM8h%!D6%0]:B\":Ann@Ls<;Y.8$"[WJIcj\kgX`):W3!8kX7l%Hrp(^MHM2q:8WDK."3$Lf4bJ3c-sl\"+=4O.sf7N_fCXom1u+77;"-VuLXetVi'(K,qRe]JuDHd(.F25T3Z1:JkbrP5=+ceVT!Sfia?1/M&=&C4PrQX&JZ8&A8*9ah;@G=?82ikao`/4</`H;3m4f7!V0Fl*5D#hi@-a)]'f`<AiO14!cZjftfAg/#%6CsS4WB!`B!1-T-I]'q)jK`LLS<<&?Kpo:>e+0PEhe1D]q:N`d-RF\"="4%<^`3_(1-*RIAf%.t8EtX\)=Qd(qVXA$!V(IMI,"n'*N>4XrCoe.)llpQ.66X%Hp=9MK;;/FdhFWQ`8a\"a>0#J=!/Yk(hk@a!mgk3.#mY45dD,mr:Jh`U;/OrEW<tQM%:;gcYTrOJ(O3=ER[U/'U@r44T'Pa4iSun_Yf@8_>Xj*nU.DfOd_%+:C^S7m3_@&OOOCNK]]tm/b4)&/\#BA>R55.`f4J%,fU/BZa0!$4e>m[$,-FJG9*BrsVQs>V?(GcS)"\HN&\nCdYRf+O<eJlo3FC2uC`n#[,HUrgUo\,r,\#%uTj9lL7k2UJE#Jd(q&J*u0K3)U//K:3()2N3m(L+Bm#ctd0.dYn"*-oJ4rO0>nU0l+-@V`Zf`bu7s5a_2Xc/;^(sS3i3q)B%<SS#f#ApoQXcZ>Ilh5_k]?N8^JP-6#*B*Wt=iGHM*C*X_4G_q/<P5;!)hfRH<e5bI$P0f\]%.?NfR!./e^7;2E:s1M=!&c]0!I0Sgb(_I&CkG*A,Du^f],S"A5#+,5#c&pmp<;(0jh[9C:/rU=+6e:V&mSn\rTmAZ:#D2B@8h+BcS=Zjjd3sbsncYln*p%iUp1)l_p;Z85g4c*fgh>W7)jff*B8h[IW*:0Y=#ZY^<>/mo?DUS42I,lp__mc/@P6=_YIXUQ/EH@tM.;bo?*BlR.i1.*QNkr_A>cf=##'BQ%&DF_^JSeu*TOjK3_A@k3.EQ*Nf2Ya=W4kr1?A;BF%G(YW*Q/X!qn"R<oj'c"$eWbn4m:bo"nYW\"6_+RD.Xp"6d%?QKm^%&J-8fq5(WNQ'MG[#UR;][uF!hiIR`o2,:]X_^QO!GX!bkfTMY/6Zu4o#o+l077~>endstream

+endobj

+% 'R251': class PDFStream 

+251 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2286 >>

+stream

+Gb!SmgN)%,&:MkuraF^LFC\K!,ua6$*BBHXS=>aT3cuMe&sCV'!!@aLr:f"N8Vr<FS+\gUh6Fs48R*$DGL'S45Tg"-s$+U+:8W""/:\jrko>9U)o2)'S5(.jqVj_*4a]5>0P'\bkNpt7?pA>mZ+(kZi=OS$+5s69Att`Q%Yla_+UAoK`q=&dQjmcQ^AftsfF*F0@/;fUJ+_R2pRa+`O8%O('*f-8.a@\j$]\=#FHC;i<\b7&c9>"#?pp]J"1Ju+BOaHi@)]HM^g%h.2t`qqZ&k4F=?4_tiYQf:Wue@/6A^s]n>-hD5D>B`IMu:ed5#9i<Xsm@,:n2AeQa_!j6*`A3Xo&8c*W`MCGqKeaS5pC#krL(pjDQ.8IqWtNVaPPIeV9rCS9P'q/@%Qk^'oIX?R[EN^fB*mBcR9XoLXrUUWcQCuB2@4CUY^;dC_CRi!:_86(nW]9pKuhr)PCB4V2go-+in"0MO(]7eRfdIu0_GdUX*BoY`qNC_rTY]h/,Ynr@p])(44@6:(:)uc#(cq;,kFk$BViSZ'Mr--J9r'tmO+hdau]\j)G+7GjqTpJC;0CFKd^OMGgI>>&p&X[>'&'l=^;@j=u=A5.j@N7ZuEX7`QE!P,Z),.1<[O\J/9;`Mal8a)<&"Z57PeA$HZ(A5RA.S\3[jnXrZOaq<dNFJB+<59j<J(.&;Tpq-EiBfhWS9b?PcgPMU:H3!91H[5+VHf%abGCORKoru0qbin$qKi?jbCm8[i\t<_3TdVjLi^B$RG1?'E\:`LKDdjj>2P%6;,h#5o%HJau4;5!Z(>^EtV&f1]1!%?@FkmImO].AFOSZdTti\m$u&m)aS7qb<Jt_-?e&^*!7#B"d4hMU)lA+;X!RsQB;d1&!u!2=<l#L[<9PNgnaRMrtrg44+fFV_YdbK7P9!l;(mmIXB`PtOm)q8O:kZIm!Oju,Wg*V3C=%<$7809aF`sXPO<s\L?sJsh\CqZ/igBVD+GV[fER;G![)j51;-.-o+kE^,/RCdRjr[XE<uh#>LscWo[tPu*S<1lqcrBebe$B65o`'ZSEhS%>2`8LbJ\(T1fdmBb^&3H^1dgZYVNlq/q`p755R_<Y^8s@0NjYjai]iGFf!XfL<+aa^5Pl!Au28ICirb8g8->=(/-hV;T;AeBR."fqTObSZ:#YXTo_n,,&"3m[(4;?DF^=-o^ESmgZt.C2Yg5+,p:r*,F4^%`=b_CQH4TgVX,u\f;hLQ#3PJ,dRD&,]1Pf-JsiR:"%UUqcF;V]MK7Q:]a['TqRH/?3XTf*lL$+%MAa(c/%MU_q(+/0kCc\h@#*>=Q`F-DTmnm)fO5S+R%eb1kT#$<9W4+84`Guj1$6X$#>5H[@"!ms;GQeaM$$K9<SO8bh!e8qEX#TXG*NHur3N:m,g4aS.kWV5TN9n.[m<bHJ;/eE$(T5=68E#$:7P2J6)Wm7OYq<=%djIPkr4OPk!!Pe<4B;6Oj[LI6Cr0Veka![@]J8C)nAR6r*o?SXV$m@/;//B+h<!6J068&og$$?[Frb!Aa0,'rn3`If\-]Y\IG781fE8U-Fau)OY8BM!\Z[nq(>p)da"i@WirjR,9qI-(0VD?5Ii_,78oroSfoqEd4=HK_H%[XE._Pm1L2mcRSO:ER>f^bH5,V5I*cq;Z.+Y%-d-DT<"):E%;!LA&]]^D-Y\7Cj=tiuh?^UAjtdoXG@@8amZ$ZFX:b,.FSFLkZLB3\\"h*W3Ts?nQMVLo:rt/W=`)I.@+%F\XO;GiaQU4Sf)?\#Jm6AF`-,M&fd6f7AIW(_s(Wn:JJAL%h#b7p9oQpQ=&(hY3NYi<8nWGnKrkEK7;;,d!\^?<7f$$B5!G2hP+@W*TD%3^jPB@7*Idk^rqL=@7f<nYoV*Odm[EPSm\K)/]i95:p[39[!h'38I1bF"R?SRJOR&-DdTohp?HQfh'.#!c=07=:gAI=,GU+S5k9p(!p>Gc-beFI/3^,X&QNFP0mcGH6X(8G8^>J/1bO/12nL`T5h:qfEb'l8e=0<!$6*@kcqDnZECtDj[I!14R2Dk3r3]&(p4If;+MFL\JT2LDu?:Kar[P'3^#VcW%ptY>K8^6#hF%N\2/j3C1c`l?A"nmT<VNg88kk0bJ;k=B7]?:uFp_MqG[(LQBN?b'7Z]A[mn+c`(pq3C?O^9c8He7U4^/\87^JnjTht1=!V6eT+&nQWRc%_<iH<=P]P''R<7tZTRi,6:3>%3#Wg_>"to_r***UILJa]VjBG7n@f<GId^6#%\<d?(.5<u.4\GEDH7^0RpeD7p.7+8l;QW!(*~>endstream

+endobj

+% 'R252': class PDFStream 

+252 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2729 >>

+stream

+Gb!;eD/\/g')l41s+/fUk8nHB-,7O8qijaBG&bdMY2)/j2N*0Qka5RGF@ds]pXe:2.EPKK(HG2+35c(B]aTZPcTLe-j,lP'GkQ?K&G!"bq=2lXSknKAiXP.6bWh2uo@L1[fT2@`4rP'kVniYqWEo6hcRZ0GTKhrD&UAd&$ESR8633X97qA2&c_GFum,Ns(*T<00qkNRN`uDc:o0:=omrnN!mH7.4jl`Pu"TInH41fp>/3QF'b4YMckhLGL?sQ.7G&PgrXQ;pTc@.&ip;"dJI-"4D.DngmWQ<hPRnIeRiEm$i,9Du'YK_sG,s96.kjAnmUnUAVpjkETK/='i;h?jukh(7H-lr9?#ijKqj)GcI(hXF.N%AJ9=-WWi,\G$;3D6kk`GJo9n(O9).u@E7-<D:%F)l[b-OW[Y@E@J$`*b0N:SaeBBG#=N/CIbA*s@'UB5tRliFc7Y)jZ4i:-'o&_&,t)iqGbYXrro@lkM.TSH5H@[:CHLOt;U'f%)Ra?H47#7_fCFLO[:XKo%aAVecrtWNH2Yr1ZaNm8`JgO-bJC:n>c?B=%?)Y&5lKIQI?c^WGr2Ja<C!$Es3:G&uJeM&E),+u9d0J0o%a>6Kg4p]C?E3u20#_*^T3[58kNB*Nek9gT0&<(s*B6k\jadb'XtLllk=&VMdtItI`6+uVTH'"ri--R?'7Q8tn^Ym\kr83gTOW2R1;b&")oeg/]]`k?_u-bZc.qOEFZhAZXUO^9\Wm"e3`0i*%/nr;B*-ndW+aZ,TI(lnh*Se=q8\>JUU([.IM0f+@"ZeM,E5MC&4DpLl/P^:[<,**dRU'BdsQTH0UTGJl/-ZtmK#Hf1-0imLEjsUUhC2S&_>tUA9F4UH:hn?;]PZEn6ZBON)]/5K(64\pD(&I7li`pmMqYa3r>FVmLCEdAPGiXLm^&iFRh*@@&>.7#lBJQD3jDrVFK4fC8s&^laV00E@WG*s:><f#'i!VH&,sB5P@sFCWM+98TFeGc;-<;mRcJqf0VRf=TdO(:\5?@CA3gi^DE0+4=%0,^=Z=[9-Oo\C"kA$DCA=4lk6XeHe?bZN#mm0#AAV>3pQD>Wmk/b_4f,VsSb&Ea_U@l<Q>bN+1S`"Rg;TP"I,2Q-uFM>%"kdk=VW#%S:q3#<oGo$%@pP.^o"R9n(o'Z1OPRN.-*K>n?U!qBl\2aQj!oNOinle_!/MPdpNOKSB3/cf`3WRnMMC'ecGNPPiI-QpK`P8*dL085Qr+>!S]YelAiEBhCjH'^5..90gIRaG@fL,M:+G&qjQpdI/RBJ;CWN=6aZcpKgb=[\rOKI2&J?BMi;Z\LM<_,1<,hf[+(oq:b^rAYZ!F*UmJTBIDjO>g0ZEHU@^ucrsgtTG6QS`IG#?uj:]3dQi@bG&(i\>qeQ&Xi2=45sV>IP9]H#!s%a4$>>IHK-".*'5K^$Q@Z'bBDS.fOP>[ZW*#P-]*2FH^o+TRt,5ZUh>-U?&b/Nhn/=WW^`sDhlhP#kAc3/=b/7?rg1q#&1,kU<_>*WJmV--"eP,bJe.V"1W`gPa_DP3%ML?\i&DUoi_!qWef[NMdk]Y-0I#e&YO[_]Aud6ES,7#K?lHW+FJ/:7EBSej%fEA&ip^CAb;)URh<kKN[n!U5`9p4/,R0=D1-]Wr6]@CL^qA&bQcQ]\e2acjU>-m02Sla+k3[+>89id\/.&sC5kn*eqi"\q$Afi0_PI,b.'Ve/")hI%%nAX/na7YHpf,n98i14:2Q_Cg?;Rl"C!QRQ^K62\UjOTb/O:/Ui7X7[#>']&.;\B4]r5?@^R9b2n(3\<8EqM"(<2qLTlTK.?<7nfg:L(adg/a<O!j'`XV`*@fkVR.7\SIdqQ$lSU@]Oj`n^XMQeM_[^_@RFknc?4Y0`DH,kfQf?eggP_DNCY\c<T!3G*b#B]l>)k(V*[OKQ$BT0cSWr-RF>E?VcF,gBF[]mF4U9pIj%W)ll2Y@_');;>pTO]GJ.gQ?,*'9?jgVXdPD6?5P(@]sc;oX)aM!F.:\`D.?"SUb`(J)_UP&Thq;Z'07<2&KjP"V^Ue7')`-W&1BUQ`ScHlh[-0V1rVK];Z=0F]"sN3*gf.=T)d<Do5]Gab.V+UB5;D%bV#k`;]eG[0#uIs%#?U&?_@32XS[VM!]u?XBrTIEreJ2lQ7%9nOJh5XDAN@R/*0!pIN(3eV=f@tEeD-mkX56I&)Lo);GGNdJi)]S6h!`$M73E=4B5F.s\S.]B^eK!k:<>+nXZ;!_&H<G_p?C=07Ve#l-Q@3TU7%@2)'!<;uTYV9c$$gg7F:Ck`^0*P/_79G/QWP)s)rfMhl(<@KlF?HKFF"m"1l1D/KB';/1#*[nXJ?4b1`A6<N75lGJOnda`#kRj(-@.*pqNSY)S[J3n5GCZ.8&+6_D[@`Z)2AhWX:@WDc/.?*r,>LsU4J-eq%,I#*rlO*PXkN*&&dsVQ&75_79h$7Ol0c&-D</Dm\/hX$#cFg0,W*O,Zt5b5EP4Mk-@^.n,1:9mnT)@D3'^W!Z*^W'Y1>DLi+@fSBd3sL_P+j`W""WW?S+0Lh9lM7Ncj+_QMS2+U\aSZ-'<#BeqkRGuT%\DK^^BFFJ4P[e4Mgl#n&!Q!,mAB*9uEqi2!m_'``<^S1K$h4-TJbdWMV?8nBJ8"J7qlP%9,YCGoRZ/8[C1QM(1Q=T.-/=FjVQi'qCknOd'"WeFdF7Ug1B@*+7*=ma3h"4Ku32GVm-W4e$oba[\rLn^bPLm#;#A[!QrV~>endstream

+endobj

+% 'R253': class PDFStream 

+253 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2810 >>

+stream

+Gb!#]gN)%.&q*PUrh4+6f%H3(Oh1"N*'9S4-=`+5bfnXMCC27/#nmkH!)g,rlaIfU.I(B3:1dG0?&;87dXCt6T*?9%)o"c7Dk$l69]>+!&Ae^MEsTBD(T-ZZCARk]BD3&T_g>[FU0u?c3IB(>3"O2F_4]TjUE46C5JpL=C84'Km.XnV65Tq%)V:l-#=4EZCqFVlJ?s4a!iCIao^?\p?eiujo#!,9edTDjd+"N]$k#Qk(cJVbP-7<u6)6$Q;m%mA$*>bks"KkXP-$aK$m]IDK2M:?!q[I1SnbS8[Uqk3RH0HDaHdf0EML#HV@ps%2g3/L*l&KI\=%6R)=F;N-&J:3BI6[4@`8tRZ\0\MAf4D.rK<RZ_[M<&V^nmr645]4QbY-hQ3c:rVRP@+<WfJ97&u"FV)-1m_G/:j^KFf6AOal$JXGd/Ud#:&_gmER[Z?6ml?o][Nl5V`9H1Fu[J7tRE=mbTAW.hm^hGf&*!@p%G=jsB?IGM+Bk?*<XI.+WbfVo2AlN2[ju`[nYh)##T(6k3oj6-!5qi"6,CKh1_a!>$3:&6$R9oJ#,c?8Mq=4=!]?A*r7)Sm8j]%DM%W\:1FI*s9BMLC[4PW<-e"42q5:U`G7^J_0`k>AcLukiTM^?*m7i-SU8Z%aHCW=aFmbEFo.$<YkFkFJlcZ1#;7`5QW"F$p[UIA)NmCp6,/M+K9(30df`B#BQh0(71V/^i_.D9Er3l@d?%lacED&oiOHS39(PjT1`\Bdi>O_rp<6W5N,:71rmMY)Y:TH?=a,@SseFo0)8EOfcgK@.Ij^E3jh"neWG&*i3t#+1<&?EGJmMu]GW$kT4k%ru`DqdC%"D"(L5ksNuucf[hQlV0&.l%654b^)]=(pl&E/MP/(MAnsN!m!VWrl^oF[qPC:)#g.Z0r#Y\k$jI:],Qka%p_tRY,JGGW5d%a0!c>kT_"+_N%2nBhu+,%>Q;m_gnNSg9/tn4aE$uLW;I-Z"8=oY)4SR3j[VAl7*.#ZQ<`U-:pJ4X$k)i!m5CML$n4`@5/H%<[.tJK]>EPYB@7_0.kO`O4M]e#i&_6!=%I:XM;;"&j.'HIjKu5!UAV+&8VO##'`<.OG'`i%eaLtfgRlOTrg6B_DoZe!:8iY"`<R7_^JBPh)4p1n`$Znc@l=Ch.IqIg7-=+C)+Oa0927,VHBp:Z$:V!5gH7OqhKKO%n\;`*<aoA"j#N$-N\1nJ-olV@cmSm0<R!+J$'.YL/l?RCA1Fi%X0g)IdrCR/QeSf#WR*k@"d;h_l[W.!VFpXIUqGFYj,9Is*sT0TTCrT\G<4Umr`d*%>U0AS<\1U;V9]C,+S87k<#,!>V?@Am9J001EOdPCPZuq_7a,feM?1`9Z#poU0cl"8=KSP$j]PmWMs>TfT!M_qFd8B7]cKsXNr>7!g5MrS6155:O0o=%gd?;'T\h"/Dd<GpUs-+&EX\dJMu$q;lUNo+9:@&Fr/MBGed2^Gh-H@9+#<p@^NB)Q.oC5(;2[g.I!Z4S=t>B%WrdmgSeEn^7X19ce`<8^50;"M/_qFISHZFj'UDXcB^(sVf>[Wnk@%22P'WA$@U:kX[/7A;h50ICgspf-6NAjuo@_[=6_^,nZirNZcm=@d3Dp_q'DCSZqXG!GDa(i!\.1p?;!HMNCJc)t\/OLC0aHZn<a&"1q?@+X#9R;0c^/PLbOXbue-LP9.sd[!Gp6;[\2VA2as*j^0$I-dO&Ei#IJA(&AVpYq\eg.6<%#QG9GQMgUVPC6j%=b+r"K[4(mgU"BZBH0$BL<_s,HK6NJis.$BMFr+6*[Nk,Xb*RBL%@[YoRYFB4__I"I`-nF6!C%R=.=04`?aNJ9@"0'\M3jBfog]7';KR0%aM$qEGd#<7786urUh+R0GOcQl3P-XinnFM@J4Ztllr&:@kqNYTamHYlUOT`0*:)0>]Oeb/h6k;.j%>?biio+j>d.sNp/V.l.:Iobs;cglRt_;7U6o+k-ifJg4bhs-bVlp$QeC@&mpE66]?5O<4(Z_&K.Y4EQ%QT)%hf^Z/SYARN_I<"q,$[<ElXuT_F[$;6Q<`+XZdt[#7NhV!lQ&>N/4J;<7X1aFL.E@Y?,Sq?UM/LO.Ip@\b2,XE.VHB<F2WR%g7>FfHC(uffO*L^il4%*acraP?fA:!8B!j+QVR`^!&42lN=A+m4Cr>d&k`Ngi@H"+njDSMi\\s)`U$Z0%EJ;X8ML(X?-.IO"Mp^)`=bVW'QpnQ-jm'R<]ui+ND^MU+12MA9>imJ6kD@$f;"\WJ%+0*sGLX"g;1+>iTh<6DN17-u*/-\foC)o4L:Pe$p.*020++G&V^R"hTO4mO^,b(\`$g-TDHnh[;;*6bF+_)%d/2N4oSX!'Xa%t-KuRL@;KJJsW*KeK;IUcK=&HS7PA3\Cp<KH2%d>T*JPpTq=JC``W[6bHbt7N\SN+Y-a9H+T<lA%]VgZ7Tq-.;ZY&=^i/at])^B/,c/C1>c<9u%krKY:.UkU\+]a(TA!(j.=BCY&<LhM:g>]]&T92e@Xnp2!6iMQ;0;k=j=4.*8`.8`RW<VN1e\krP\e?7.7-\!cAjr_j9'm5+:H(lk-m^ViY283q>^[=Ou^[7;-47ic4o6/KXYOIX@mVVj+Hcb-$HcbK=KC9g-c!1S\iO:VET%MMgiHC%_QY(Da3hpV+-YAUTI=KnV#_&NHs2==$oJM0:s/E%C]/J/D[>RaXkdA%AB@fd*[r5FZ-m$g8p?BtSa[./=?V^-$h".Il?LAI"LCJF#;=3DkHb9&-oj)a9;[dZ\d?;Y3C`gt/GAEL_pNPAO5CqWRM`ul&3N\%/B*^VLp-2MgcX-~>endstream

+endobj

+% 'R254': class PDFStream 

+254 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2804 >>

+stream

+Gb!;e=``=e&q5%is$OQ'P*-rX4L/0qV-%o8>q9n=HFL?6q_/),ikthO`W27qn'aFP@fV*)W&UrfU`uKm]>*Ujl[]9nrd+Ds:'&(9_"eo[4<G=hn3SLU`ERT#Gkp?_rq!/K;$ao)9I$(VC%pQ0X4s/D)gHf7pFfn3Wa<$Ze<s#T=JXl#%X-n/[,]YmBM2G,k'(e(c+\bJDm9";DuYapqc#fXd[+PY9PSS4-1nY/DaNquXc.1t;U5bbdY.>^.AAoZ6`NQ7<4UXt&eVH:a:-q215jbg&1N)q59&%M8$Yg$"*!^oEhC/(eFC0`&hhfU<\d8-]u]Vl[IPhECKVuW8@0GG$7GSB=GmRpS>S8-(+[4f:nWus;-G#)MIHE7-0D"&UWMAQP7QMlWb!EkL@I#9NBH:jF*Xs6rZ*7h.0P66i!$9QWhTQM-FChFM88fWc2#WWNK(aGBE5oQ<Vq]-jlrg6`ZK$t-IHK,Jm^bHJ71)qpt3R1*N'R)!TWCtQU*#j3E'LLcHVUIp-KNGdCi7*-mZ_dh'BYKfodp9K[A'l?a2@8JAm5pMW,3m9MQVQ6n?QQK#lrID!%2R$RjXtNZ1Vf"j;gI9-!M'AE<o0EZ$+uVg;u=ocdW&;Cl7oifEH/h+_Fi$k9^Wa]<eBIpJZJbE`^G,QX=HauLulL+dsChSbg&&Ykt^8T$qR#dTE4;Lt*6Nq9M3f5^&qqg=^\;$IJT1+(3BHd+>hK`i;e2p8;UQGY<;=`[if%f,Z0EdhX"dCC\.QJbUl+4'L5bHP^%S:I^KSs'2Wd;EZ(W7OB;P\!C!?^CSPH,s7GM%#C!nq=8[@9iX:(^<)SO:VAaNISio-M0*JrqET\O:6I89WsnJ!3Y08JK&?`gebK/\)$)liq4QQ8@SJ=HSp%lAuF+Ib^,g\98ZhHHJMWFJYe,__e>*giR!NQa/1eSp1_(<aI_4$?oU!<]3@/:hX(:uHP\T5KgW2ZG3,U9\*F(1pF^k2f4O:jZ9(4OKnb62)32,K*INWCVLH!5Y-YDOcp+-C'SfaFb.G?lenNW>m`nrDi%h[jPM"@u/9D*^.m1.`n8uL%V]*)(AA28jpl7S4aV;`K2c)3XJ]pWAlql3t<dq1R2`r^6iX".VaV/oQHiaEGX[o[5>jOnQUX4'ohCbGW;l*ZYAfScX49Kfqpcc.`1M7bkm&3@+&U8%JC#DIV7[.RcC:rV3&L6<Z)O9lpW7'\uqjU%/#Rj[l;lXhpEKF!#ohe0/jZa&%OE%,q3LCA?R>D>N+]`Okn3huenN7OYf`^=\k:<.q%#%p.\C=teL#9k].g>t'"-'mfaKJjj1.Or[$N@^&1J7YMR9>BVjBJ4s%;+mOD6:8L:ViaIbsph@"`hI*1&5.Y)M&W!<bG%[Ob+U65mYT<5X+_;'Y,A#W:t<]W#l]PVH*XYk';MX/^?fa\]SK`#@l/N'=5V@Y0L1,$R0ijN#$6P?t,=\Vj\0\!@L9f8XC4>NY8pRDU+$X84%u%l%E$+Md(6l78oc;]\>4^Y8%sI9#ra6pa-*-V!H9C'M`8H?#OnWl+D%K6YpLE2AY+iA^;5LUOsbFPOP6$HQ4r^?+!U7%N@n4*$4RPJa3GKpt$>bm5SS`ae0T5n;?72XYGj"Y$hf4bVKYAW"*I]G?[o`!SMuhhH^&d/)O\WP?g?),>rHAW@/,5nLQt$NXq+[=:V'p8o/S,W\;uCJ&jMA\E><kI9Wu;VW>qq]e/s.-'jJMi!NSH]s7rIbWtNB$Q2UJ_@gi>[3lUs6783aSR+LH(\nQR7l>Bb2AIiL.;=CiBRtfhoUru).m;Y9r&K(,";</agai`X_-F`ldXLmY4Nai#']O3b+,jj[<<CsZ"e)a*B6tbeN/F^)6(*R*-&;5_GW8X@,KAsdDk,(RA:hW=F$P0"0J54_Q0FlD\%5..BS"\[7]FbfY:_n;c&B6iR<a.MJO@iGP=MQM*F377THZ%!j)-pZAm_]r2TJ$8`Z2ETjA4`#3r+&+-ZJ"'^ln[/Gu=F>>SQsge)^jJESQuL/!4Tif^C<2Pt0Z]+6tC,5pdH7-up^J4i_:US,AJOa.I]c/F\B(>Yq$7aQ[%rT^Fj[][!r0QPlJ[hN%O'E5FU*VX4lu;bX4RSs<65d[.&jd`d@bY-m\OSl/EN;\E_6[#,hF=2d>!=1ZmMigRtWhEA=!B[n[b/mabnBhTd`FH<>4+iIj50k`/L"$aqTUcnN&)DK.sjp63Q"<Be9XoJ%b65+3Hk<e^!anKNkF7J%o>3/(N7\IF*A/9;K^jUlfMLlpY_H7I9cP2rc+^,P^Nk%Ib5tJ7Eg2ab=h5;s<3P36]"LjEr[/uh"^>&g.%jISnIZF]MX6S,F/EC36+nK=6rrZeBA;JcAcE`&MX9kYU`:-h32p0k<!S!$`f`@D+-WQX@'l?(8QN)lCn[ul1DhUQKLGU`jH7PB]U?)5H:s44V2r/_1N'X#B>FELGlRtoCPI@8L!r$AWbUptYhXs*e[8s<k"s65pV2KZL)I4.[S/#Vl#C`W$_Eh90kRmFsa\W%ckp'RBk)MO[*'Yf%*H,bad,r!sl\FrK/*5$Gi4rJ+C[u,PJUK^e2a@<>rp=9F2+/goC1i-Bk'\@u)h)8X8Zr48HJ_()QhkZqPG,dJfHKMS5;-L/_`-UAG,'\Uo/2(m/>=UnkXH216*b9lC<^eZQdnCoWIumAqMUDY`t?F%:E'"eTK\(u+36O@$E\$a!-\2bBQ%&n6$$@5CoBN+N1"d7Bo!_2B<<eml<QOb`qF/%5K%q:<CAI_]CdieYc]KrKBg6&0@;gWAP1rcGH"B.0>)]&413AgD?~>endstream

+endobj

+% 'R255': class PDFStream 

+255 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2377 >>

+stream

+Gb!#\>BAOW'7J2#rW=KC:.JnblJAGM8M?LR=/V<GSPIW=L]f"L,estar9<,5/3m*t/DG8"R7o`"6]f+Ofs>=8&[ESZK^S:gBC*5Fqtc)0Kb7Oc/0"n)[X--2?Tio4ao-ncl]X&]U0omq2b21]Fr<3aK%Y)W7MBtBr#'YegOj+SHob]:S:tC%AaE2?c@Q?C3HTbn%D)l^0A5Um>CGUns2FqaC4?!?e='MsI`.cJ2KXscO=BSmpF]^`%qd\2)VK8i8afeX8$=Zu9#[o?AYlKPKjk"n=g$E'f.30W9#Y"X/+%Mq2C2FJ^i[]L_Z*+ON5r1WL0;df<\VEkZI]&r(9oJb@1'+LWA_,bZ!O^dQ'>J3Z_GNObcTC;":kK\0?SLiVMcf5i]_75M]`H.+_C_p_Zk3FE!NlmHLCM0,[Df8=*mu4E[NZJ_599dYZ?H+.ta2G?^+aKpFk>l=Jbcj2RM6>H1C$>Io*&liTC;\"`FHKHt4ZgFT1ed:gX)qQq8$*<<<l2ngNja'fhI<h[&s&9>jTFGVLj,OUG_@LqpX.4ri4naGm2%JIar%4\MTUf\3X<e2_C$U.2260qm7HGNT%W)Wc,fZd'K:+9'CADd`V/Y=HEs7/`A.\#iJGcrclNPdOf;#A4--+R?GsLleBEN&Lb<9>OB?VFc!Y2j_ND"<GAF]j'rq&?s]N>:+?Q,[RrWl+Fou&;_'iS:;6[dh**534^U0$QX`/Q*C]nM:`rU:))rqA]QH%i=g+]/"VZ^&(ls3Q3/IM*)OL4HQ*AslY7t5'N3n#a!hOS-'(h!"EC`+R*!sJ+BKHbV0<jh!qsWHI^?^a4'?;er*kKeoLdTenEEJ:>I.dFn?pK9Q,<=o!<tPc8sFsT2g.Aq8.YK`*Q;hFZ8Q=>QdQe7V82n[1f1!N]9R@>!8a8Up4OE:7"t5f71.6[%EHr:?"o1JBKDT-r\&jPmGfrE@c8`.Ho\A,@DH46]R]Yb^cbm.+L8*0+mP+-4<+RCC",)JrSk"F5(BG31n=m3OH##]1aH"@L:;cV!cPNn1:DS1#)pH-g..fCT2W'WdgPSgH:[B!E'c%f=tSXHA:HSW]FD7FY;O(WjAEPM&,qd_*LE2;MFO#gK<>TDD!@/\?)^&E(la>]<_Fog4dCn;b\Uif&F#-Km4Cj-CXl;IJ6aIX,e(SArSW]bMpeik:Y.OD?TWgYPSYcZ7,>\UWD$sK4P3X@6(3tgg/;VF'V'iLWl3pIPc8&%I"WiTNk)-)AA4A!WdY:ch5;N=P\d0U%2QZ+G\Pq+iF'A[[Op(P'=)R>R0N8e2lV.cE\n1oI0pX1%HKE(/.m"nLN9Pg(f>B8IUZM)pe?_)8e_P_V]gVX4k_4FqaS4pY?^U$<uXL1aM6(MoF=h#TWSAg"Cdi#isZAug0l"<3_k=Z!]6.U';7DI<G!NYKJ;bgB`cdALAVUNi)COBWXYLA>QO/UO;UY'Oq/M?QIX!!ZDt&r::rZJ9:I6U3!s7!NTq0Z&Oi<\Q3"s!O`9Vk=k5M*[W42H#G]VrjZXBb\q*7:P)FS.Pr(L@\J.KP@ilP8+\Q8<D>Wc@h^20kW/%RU.<>@e.^nY-?=\((?EgHFUk*o-.<0Xt]+!u0\kSBB=>W`r.6^`kr!<KCTtUAOcs@llF()O=JNPEfR/4o*L*jTte<bLmX]p2be;!Z#"Osn6q"gdar.&U*M\+3c+1D+!WQm8IgT<^(GtQ=9objqT#!k34hKN9`Wl0U0q?&fGc$ic4^Xu25CWOgJJ@ag)L=Y\@'tSrahl9BA`;&:_V^XYr"H_%MC+D;`>%>54O&.fcN-\h^68)BV%4B8U)??!*JAuJmhtd8,Z`StZ^O+KQNo;7.Ucs:=E*R`J*7,fl1lQC-[,sph%UC2R\g"3Ic4pLmFicR<W!OKSmOUi6d:6;XbL[rGHO!i#K<hNqVCDo^NGbD_o[/rC^TPn*ZR1sWJGlRO3/jD.@F0Jo]^7*W[GFt.\o=ZnD2#&iQ=qAD@l-ZH.Tuca&OhW9On%hRBcQ$W9`bu>8NLa^g6H^18bZI10qP-<Vs:NUVnNp5*?)8l_]'F@C*)o8)b^g]46V,k`>4YY.dH0='j7&8Bnl<jUq7R3/(e).f^7)MEo0F,?$F*5'I/Zsl1("rb)o@MWScU*>hGRYS:YsF;=638hU07$e'4C><YmVD%pbuPXtIEU4Q.nigeJ+>I&J/ni)a1+oi%<9E%uW[E;nHmaq7AE#X*.:1&Xh:b^sj7L8R,fLSK,K+5qK)_]+'9O.pp(R*Ib=:8e!(V's+Eb!db^*HYi=ETJg!GQn&]R#=M,%-U4JqNcJ+#'bGLXh-S>c?LeecJ>n#b"AR'Kkm$N0pS[j\+VM4o&o&<1!OiAB.?=jI#'QEq6Rg95[?'p~>endstream

+endobj

+% 'R256': class PDFStream 

+256 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2070 >>

+stream

+Gb!;f?$"^Z'RfFDs21D?1t_m_[]p9i9=!r,B:A3XkW\)sfE0RTQ7L(Nr;40jbVohTCM5a_)'[b^e^;pXk=TcgK-/_CNAH*c!W;cM"kSCC#i)T3Ku$9(2gG;dL\\O3j$=JDc\V^NB<BsC[Q?-`U5n\g!DHk8_H,J]8!27.!uPS,\dhbNqmshh$$;LSo+>IlpGs*Ep^Vp@9_Vo<pW*3PQVD6>2fq`3:Dec@q42EUhm1>r*&$q/CK00tHVn@?#HmOZ<nAn7/..gnlmH%))m7VP.aHQI##m)I/9jjP;U?eM?ai-+,H'kZL3!%7[Ggm$a01-b?p`h@B*D.KaASmIFpPQ';\W=TVe&1@`'iTl2'E<9r]gVqM.A@1JdQmfkJ0Si9AqX%"D8$gI=M4[k%4d`bKkZ"n:=@a^>&dH%F^SG-@sCG3feQPPrXas_\*<m'p!VI6`R#Jk)dpp(/rlfL;o<;k6e7t<2Smg'\Z:q(sW+c;!)*kU<I\ENrdKN]'F?.X%"'KH7nHCP3+6b[Am,4=cq,@bH)!XbAP&M%Y1@<6U@M)".k_pakMY[%qsX:5e:HB\TJ!j=2oh$[:M2V;l@?:F@5ANa'3$,!B/0@l+m*`CCr9aaMkZl[0&soi;lgjF8nf#a4g0\?fZ(G97^J[ZeoJUF!2skXa=8q,S58KZtE,/HsY^]#KI4BrglQb)j(jXqAP_))NRphhmlTp/CS4uL>:cn'6^*u2dm"iFLU!Vgf=M-q++3d+uUuTRXjDOjfPl@LTBJ'jd:0[loVB)1gWsD\*S&UG*3V/4:WB'"XV8!mW1S:/%";njAO\56s_YbJW(s5Kot;]JU)HT6Y`L7;G4W=BojJ=&NDR0/-o_/H#g@*Q01lj<c-4LquT2=XG*]t7"s-0,$&`E(/hW<_R"q`T,E/22R&&F@YUqs5WV0E9P=$D0F0^7&FPJCSY-qqHJ=Rqj$`hqY_UM=>dl\o%fVcoZ7tG@SP)E"oWZFF][5p0Z*Q/WEh+N`l,k^')V$pF\;(;Yi(Z]/BgqsjNEn1_?dO5?oJ%sF9CqiH6IjW@UY$L&bA.fqb!1%l<^faCrb_'%F1"jaQ>XIPfA.Bu`BPq*RpkcRW,1(?rOq0l&W/:=GU`;^5q8SikmT6nOS),mm@I(d1eSQ*8X[V_%9`JIoX8-g@HiO!:RECELm%r'hKS_6]ba9Ts&-[&1TMF;+U"$<YlIc29R$8()USU=F;3"-AOC8_n[U)4Nm].\,irMLNUauqpRV]WFtH=KP=/]G2%q=Dd*fc)H8Pr/4W6PBIb3df/ZH-o$d?31H'T5>\tDqup#jp;rSKKHhIt$91QH5H0Y7mb6`_-PCP(XeN-'8Mb'=&26hBm:iW.nO#gO5)JNl:e`"Iu9KTre7YdoEO"@TR]$XBd!M>jF&nbm.iSm>hkG8g_^Q6HlX8!A&70h]ZfP[lmHPEL0rJ6kV:YRq,M@K"?F"cXtn7#'h[<71gUe0,]mmr_FHI6jVf?Dh&V*?.^7Qqsca!`MYMP/[\H;5tDX5OaV4Ko9io%tG3Yf#bugC_Xa)\QP"E5.B=s0RhT)jYEt[^f4BDOjl?T';Va6YK$:S#o(:)5Otl3DFWO[Ms9>FLm7C\cuDjX2h)2aiH;i_jXWia&mNf]"A6Q&qPVMANhRf-UAH[A`:LGC4=#o=p:"D+P5(:d_X$upA%eXqLdt$T9gr<Lp`>PJ./I2CNt==1WN(-P_3-5^cbse'erBU@19J(eq3ACh!S$"nEkB$6ANn@.4reHdSD`T,_<J7iAqSu6iKc>,[qbfshIU\sq[`^G7GjQmOs)<+lH6nq4Qo/aN)hkZVA"\lBdANu)j=;uR[XM97We',@5P0Q$Z7\3hK%JW5/Yo0('I@S4<_6jY>h?VF$s?u`^snSj2:?Z`(Y*?+tmfYe(QA]CP(!12W`q)/uQk'rcCJJ\CAbX`MbYMr[^q_1M&18LlCGa$8GfOUS#N6j.%e>7d@gt.V*"OVW_&3B6&$:IWodU@Bn0lTN00uk(ZlkptAhh*;sA1(b?\,#Of$T<cI@d)X)q<$HA/o5m>Dl%*^&<H+i2dDhQ`GrWBM$(6n~>endstream

+endobj

+xref

+0 257

+0000000000 65535 f

+0000000113 00000 n

+0000000249 00000 n

+0000000455 00000 n

+0000012239 00000 n

+0000012426 00000 n

+0000012668 00000 n

+0000012897 00000 n

+0000013126 00000 n

+0000013355 00000 n

+0000013582 00000 n

+0000013810 00000 n

+0000014042 00000 n

+0000014274 00000 n

+0000014506 00000 n

+0000014737 00000 n

+0000014967 00000 n

+0000015199 00000 n

+0000015429 00000 n

+0000015661 00000 n

+0000015893 00000 n

+0000016123 00000 n

+0000016353 00000 n

+0000016585 00000 n

+0000016817 00000 n

+0000017048 00000 n

+0000017280 00000 n

+0000017510 00000 n

+0000017741 00000 n

+0000017971 00000 n

+0000018203 00000 n

+0000018435 00000 n

+0000018666 00000 n

+0000018898 00000 n

+0000019130 00000 n

+0000019361 00000 n

+0000019592 00000 n

+0000019824 00000 n

+0000020056 00000 n

+0000020288 00000 n

+0000020518 00000 n

+0000020749 00000 n

+0000020980 00000 n

+0000021212 00000 n

+0000021443 00000 n

+0000021675 00000 n

+0000021907 00000 n

+0000022120 00000 n

+0000022858 00000 n

+0000023089 00000 n

+0000023319 00000 n

+0000023549 00000 n

+0000023780 00000 n

+0000024010 00000 n

+0000024242 00000 n

+0000024473 00000 n

+0000024705 00000 n

+0000024937 00000 n

+0000025169 00000 n

+0000025401 00000 n

+0000025633 00000 n

+0000025864 00000 n

+0000026094 00000 n

+0000026324 00000 n

+0000026554 00000 n

+0000026783 00000 n

+0000027015 00000 n

+0000027246 00000 n

+0000027477 00000 n

+0000027692 00000 n

+0000028181 00000 n

+0000028416 00000 n

+0000028652 00000 n

+0000028887 00000 n

+0000029141 00000 n

+0000029409 00000 n

+0000029654 00000 n

+0000029926 00000 n

+0000030217 00000 n

+0000030494 00000 n

+0000030768 00000 n

+0000031049 00000 n

+0000031327 00000 n

+0000031622 00000 n

+0000031913 00000 n

+0000032194 00000 n

+0000032508 00000 n

+0000032796 00000 n

+0000033079 00000 n

+0000033366 00000 n

+0000033626 00000 n

+0000033906 00000 n

+0000034184 00000 n

+0000034474 00000 n

+0000034755 00000 n

+0000035051 00000 n

+0000035334 00000 n

+0000035612 00000 n

+0000036154 00000 n

+0000036443 00000 n

+0000036728 00000 n

+0000037021 00000 n

+0000037306 00000 n

+0000037604 00000 n

+0000037841 00000 n

+0000038062 00000 n

+0000038239 00000 n

+0000038460 00000 n

+0000038645 00000 n

+0000038863 00000 n

+0000039236 00000 n

+0000039509 00000 n

+0000039799 00000 n

+0000040021 00000 n

+0000040333 00000 n

+0000040573 00000 n

+0000040812 00000 n

+0000041034 00000 n

+0000041366 00000 n

+0000041605 00000 n

+0000041846 00000 n

+0000042079 00000 n

+0000042320 00000 n

+0000042560 00000 n

+0000042801 00000 n

+0000043025 00000 n

+0000043397 00000 n

+0000043637 00000 n

+0000043876 00000 n

+0000044112 00000 n

+0000044353 00000 n

+0000044593 00000 n

+0000044833 00000 n

+0000045058 00000 n

+0000045414 00000 n

+0000045688 00000 n

+0000045978 00000 n

+0000046215 00000 n

+0000046453 00000 n

+0000046691 00000 n

+0000046932 00000 n

+0000047157 00000 n

+0000047509 00000 n

+0000047749 00000 n

+0000047990 00000 n

+0000048229 00000 n

+0000048452 00000 n

+0000048794 00000 n

+0000049017 00000 n

+0000049329 00000 n

+0000049570 00000 n

+0000049811 00000 n

+0000050036 00000 n

+0000050368 00000 n

+0000050594 00000 n

+0000050906 00000 n

+0000051144 00000 n

+0000051383 00000 n

+0000051620 00000 n

+0000051843 00000 n

+0000052185 00000 n

+0000052419 00000 n

+0000052656 00000 n

+0000052962 00000 n

+0000053237 00000 n

+0000053379 00000 n

+0000053623 00000 n

+0000053752 00000 n

+0000053958 00000 n

+0000054115 00000 n

+0000054286 00000 n

+0000054454 00000 n

+0000054667 00000 n

+0000054838 00000 n

+0000055067 00000 n

+0000055226 00000 n

+0000055406 00000 n

+0000055590 00000 n

+0000055780 00000 n

+0000055962 00000 n

+0000056145 00000 n

+0000056312 00000 n

+0000056498 00000 n

+0000056722 00000 n

+0000056891 00000 n

+0000057060 00000 n

+0000057250 00000 n

+0000057426 00000 n

+0000057617 00000 n

+0000057836 00000 n

+0000057991 00000 n

+0000058168 00000 n

+0000058338 00000 n

+0000058508 00000 n

+0000058671 00000 n

+0000058863 00000 n

+0000059058 00000 n

+0000059287 00000 n

+0000059445 00000 n

+0000059622 00000 n

+0000059781 00000 n

+0000059969 00000 n

+0000060197 00000 n

+0000060395 00000 n

+0000060578 00000 n

+0000060757 00000 n

+0000060928 00000 n

+0000061098 00000 n

+0000061280 00000 n

+0000061460 00000 n

+0000061639 00000 n

+0000061804 00000 n

+0000061981 00000 n

+0000062167 00000 n

+0000062335 00000 n

+0000062512 00000 n

+0000062683 00000 n

+0000062850 00000 n

+0000063023 00000 n

+0000063205 00000 n

+0000063395 00000 n

+0000063551 00000 n

+0000063737 00000 n

+0000063972 00000 n

+0000064131 00000 n

+0000064320 00000 n

+0000064506 00000 n

+0000064686 00000 n

+0000064872 00000 n

+0000065052 00000 n

+0000065224 00000 n

+0000065448 00000 n

+0000065612 00000 n

+0000065800 00000 n

+0000065988 00000 n

+0000066201 00000 n

+0000066341 00000 n

+0000066640 00000 n

+0000068581 00000 n

+0000069671 00000 n

+0000073063 00000 n

+0000076143 00000 n

+0000079473 00000 n

+0000081897 00000 n

+0000084809 00000 n

+0000087559 00000 n

+0000090606 00000 n

+0000093498 00000 n

+0000097965 00000 n

+0000100530 00000 n

+0000104604 00000 n

+0000107170 00000 n

+0000109601 00000 n

+0000112475 00000 n

+0000115430 00000 n

+0000118379 00000 n

+0000120901 00000 n

+trailer

+<< /ID 

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

+ [(\022>\213\334V\233\247\366\264\322\211\021\001\252\337\213) (\022>\213\334V\233\247\366\264\322\211\021\001\252\337\213)] 

+

+ /Info 165 0 R

+ /Root 164 0 R

+ /Size 257 >>

+startxref

+123088

+%%EOF

diff --git a/pdk/docs/compatibility/android-2.3-cdd.pdf b/pdk/docs/compatibility/android-2.3-cdd.pdf
new file mode 100644
index 0000000..eb77a7d
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.3-cdd.pdf
@@ -0,0 +1,5223 @@
+%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 131 0 R

+ /F4 133 0 R

+ /F5 145 0 R >>

+endobj

+% 'F1': class PDFType1Font 

+2 0 obj

+% Font Helvetica

+<< /BaseFont /Helvetica

+ /Encoding /WinAnsiEncoding

+ /Name /F1

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'FormXob.c4c4c9f90f2c427799b277ddd57a9a5b': 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 [ 121 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 [ 121 0 R

+ /XYZ

+ 55

+ 501.8263

+ 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 [ 135 0 R

+ /XYZ

+ 55

+ 586.8887

+ 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 [ 135 0 R

+ /XYZ

+ 55

+ 503.61

+ 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 [ 135 0 R

+ /XYZ

+ 55

+ 362.485

+ 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 [ 135 0 R

+ /XYZ

+ 55

+ 286.1775

+ 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 [ 137 0 R

+ /XYZ

+ 55

+ 701.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 [ 137 0 R

+ /XYZ

+ 55

+ 701.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 [ 137 0 R

+ /XYZ

+ 55

+ 637.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 [ 137 0 R

+ /XYZ

+ 55

+ 271.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 [ 137 0 R

+ /XYZ

+ 55

+ 185.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 [ 139 0 R

+ /XYZ

+ 55

+ 742.865

+ 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 [ 139 0 R

+ /XYZ

+ 55

+ 678.0475

+ 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 [ 139 0 R

+ /XYZ

+ 55

+ 206.1725

+ 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 [ 139 0 R

+ /XYZ

+ 55

+ 118.615

+ 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 [ 154 0 R

+ /XYZ

+ 55

+ 390.615

+ 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 [ 154 0 R

+ /XYZ

+ 55

+ 171.2975

+ 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 [ 156 0 R

+ /XYZ

+ 55

+ 653.5475

+ 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 [ 156 0 R

+ /XYZ

+ 55

+ 227.9225

+ 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 [ 156 0 R

+ /XYZ

+ 55

+ 130.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 [ 165 0 R

+ /XYZ

+ 55

+ 710.865

+ 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 [ 165 0 R

+ /XYZ

+ 55

+ 592.365

+ 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 [ 165 0 R

+ /XYZ

+ 55

+ 485.115

+ 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 [ 165 0 R

+ /XYZ

+ 55

+ 312.115

+ 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 [ 165 0 R

+ /XYZ

+ 55

+ 259.365

+ 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 [ 170 0 R

+ /XYZ

+ 55

+ 747.2637

+ 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 [ 170 0 R

+ /XYZ

+ 55

+ 642.8262

+ 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 [ 170 0 R

+ /XYZ

+ 55

+ 559.5475

+ 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 [ 170 0 R

+ /XYZ

+ 55

+ 407.1725

+ 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 [ 171 0 R

+ /XYZ

+ 55

+ 620.5475

+ 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 [ 171 0 R

+ /XYZ

+ 55

+ 297.6035

+ 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 [ 176 0 R

+ /XYZ

+ 55

+ 745.7975

+ 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 [ 176 0 R

+ /XYZ

+ 55

+ 302.7638

+ 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 [ 179 0 R

+ /XYZ

+ 55

+ 720.8887

+ 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 [ 179 0 R

+ /XYZ

+ 55

+ 445.36

+ 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 [ 179 0 R

+ /XYZ

+ 55

+ 369.0525

+ 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 [ 182 0 R

+ /XYZ

+ 55

+ 722.115

+ 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 [ 182 0 R

+ /XYZ

+ 55

+ 680.615

+ 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 [ 182 0 R

+ /XYZ

+ 55

+ 616.615

+ 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 [ 182 0 R

+ /XYZ

+ 55

+ 509.365

+ 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 [ 182 0 R

+ /XYZ

+ 55

+ 303.2975

+ 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 303 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ]

+ /XObject << /FormXob.c4c4c9f90f2c427799b277ddd57a9a5b 3 0 R >> >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER43': class LinkAnnotation 

+48 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 182 0 R

+ /XYZ

+ 55

+ 249.49

+ 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 [ 182 0 R

+ /XYZ

+ 55

+ 111.74

+ 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 [ 187 0 R

+ /XYZ

+ 55

+ 684.365

+ 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 [ 187 0 R

+ /XYZ

+ 55

+ 588.365

+ 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 [ 187 0 R

+ /XYZ

+ 55

+ 474.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 [ 187 0 R

+ /XYZ

+ 55

+ 232.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 [ 187 0 R

+ /XYZ

+ 55

+ 116.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 [ 189 0 R

+ /XYZ

+ 55

+ 669.115

+ 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 [ 189 0 R

+ /XYZ

+ 55

+ 616.365

+ 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 [ 189 0 R

+ /XYZ

+ 55

+ 516.365

+ 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 [ 189 0 R

+ /XYZ

+ 55

+ 440.865

+ 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 [ 189 0 R

+ /XYZ

+ 55

+ 376.865

+ 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 [ 189 0 R

+ /XYZ

+ 55

+ 335.365

+ 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 [ 189 0 R

+ /XYZ

+ 55

+ 259.2975

+ 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 [ 189 0 R

+ /XYZ

+ 55

+ 194.24

+ 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 [ 193 0 R

+ /XYZ

+ 55

+ 699.615

+ 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 [ 193 0 R

+ /XYZ

+ 55

+ 646.865

+ 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 [ 193 0 R

+ /XYZ

+ 55

+ 539.615

+ 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 [ 193 0 R

+ /XYZ

+ 55

+ 398.365

+ 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 [ 193 0 R

+ /XYZ

+ 55

+ 280.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 [ 193 0 R

+ /XYZ

+ 55

+ 193.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 [ 196 0 R

+ /XYZ

+ 55

+ 710.865

+ 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 [ 196 0 R

+ /XYZ

+ 55

+ 475.115

+ 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 [ 196 0 R

+ /XYZ

+ 55

+ 223.115

+ 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 [ 196 0 R

+ /XYZ

+ 55

+ 158.2975

+ 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 [ 196 0 R

+ /XYZ

+ 55

+ 93.24

+ 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 [ 197 0 R

+ /XYZ

+ 55

+ 592.365

+ 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 [ 197 0 R

+ /XYZ

+ 55

+ 335.5475

+ 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 [ 197 0 R

+ /XYZ

+ 55

+ 171.0138

+ 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 [ 202 0 R

+ /XYZ

+ 55

+ 621.6388

+ 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 [ 202 0 R

+ /XYZ

+ 55

+ 527.11

+ 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 [ 202 0 R

+ /XYZ

+ 55

+ 449.985

+ 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 [ 202 0 R

+ /XYZ

+ 55

+ 372.86

+ 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 [ 202 0 R

+ /XYZ

+ 55

+ 306.985

+ 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 [ 205 0 R

+ /XYZ

+ 55

+ 591.1387

+ 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 [ 205 0 R

+ /XYZ

+ 55

+ 475.86

+ 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 [ 205 0 R

+ /XYZ

+ 55

+ 300.985

+ 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 [ 205 0 R

+ /XYZ

+ 55

+ 137.36

+ 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 [ 208 0 R

+ /XYZ

+ 55

+ 686.8887

+ 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 [ 208 0 R

+ /XYZ

+ 55

+ 459.9513

+ 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 [ 209 0 R

+ /XYZ

+ 55

+ 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 304 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 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 [ 121 0 R

+ /XYZ

+ 66.25

+ 462.615

+ 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 [ 205 0 R

+ /XYZ

+ 55

+ 591.1387

+ 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 [ 121 0 R

+ /XYZ

+ 66.25

+ 436.115

+ 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

+ 450.4275

+ 297.1675

+ 461.6775 ]

+ /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

+ 437.1775

+ 369.6775

+ 448.4275 ]

+ /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

+ 423.9275

+ 254.6725

+ 435.1775 ]

+ /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

+ 410.6775

+ 363.4825

+ 421.9275 ]

+ /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

+ 397.4275

+ 413.8825

+ 408.6775 ]

+ /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

+ 384.1775

+ 358.885

+ 395.4275 ]

+ /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

+ 370.9275

+ 373.45

+ 382.1775 ]

+ /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

+ 357.6775

+ 400.96

+ 368.9275 ]

+ /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

+ 344.4275

+ 307.1575

+ 355.6775 ]

+ /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

+ 331.1775

+ 327.52

+ 342.4275 ]

+ /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

+ 317.9275

+ 296.68

+ 329.1775 ]

+ /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

+ 304.6775

+ 300.8425

+ 315.9275 ]

+ /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

+ 291.4275

+ 298.765

+ 302.6775 ]

+ /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

+ 278.1775

+ 283.75

+ 289.4275 ]

+ /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

+ 251.6775

+ 374.23

+ 262.9275 ]

+ /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

+ 238.4275

+ 346.2925

+ 249.6775 ]

+ /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

+ 225.1775

+ 368.8

+ 236.4275 ]

+ /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

+ 211.9275

+ 477.1975

+ 223.1775 ]

+ /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

+ 198.6775

+ 371.7325

+ 209.9275 ]

+ /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

+ 185.4275

+ 313.3675

+ 196.6775 ]

+ /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

+ 172.1775

+ 351.265

+ 183.4275 ]

+ /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

+ 158.9275

+ 453.865

+ 170.1775 ]

+ /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

+ 145.6775

+ 364.645

+ 156.9275 ]

+ /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

+ 132.4275

+ 349.2025

+ 143.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER111': class PDFDictionary 

+117 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 138.7075

+ 119.1775

+ 355.06

+ 130.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER112': class PDFDictionary 

+118 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

+ 105.9275

+ 452.1775

+ 117.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER113': class PDFDictionary 

+119 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 167.8825

+ 92.6775

+ 389.23

+ 103.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER114': class PDFDictionary 

+120 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 161.6125

+ 79.4275

+ 396.28

+ 90.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page3': class PDFPage 

+121 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

+ 117 0 R

+ 118 0 R

+ 119 0 R

+ 120 0 R ]

+ /Contents 305 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+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

+ 730.6775

+ 443.02

+ 741.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

+ 717.4275

+ 407.5825

+ 728.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

+ 704.1775

+ 388.825

+ 715.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER118': class PDFDictionary 

+125 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

+ 690.9275

+ 474.6625

+ 702.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER119': class PDFDictionary 

+126 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 161.2075

+ 677.6775

+ 395.47

+ 688.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER120': class PDFDictionary 

+127 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 220.3975

+ 664.4275

+ 429.6475

+ 675.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER121': class PDFDictionary 

+128 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 129.955

+ 651.1775

+ 269.1925

+ 662.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER122': class LinkAnnotation 

+129 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 422.865

+ 0 ]

+ /Rect [ 460.615

+ 435.865

+ 504.7975

+ 447.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER123': class LinkAnnotation 

+130 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 409.615

+ 0 ]

+ /Rect [ 470.995

+ 253.24

+ 515.1775

+ 264.49 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F3': class PDFType1Font 

+131 0 obj

+% Font Courier

+<< /BaseFont /Courier

+ /Encoding /WinAnsiEncoding

+ /Name /F3

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER124': class LinkAnnotation 

+132 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 396.365

+ 0 ]

+ /Rect [ 336.2725

+ 200.49

+ 380.455

+ 211.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F4': class PDFType1Font 

+133 0 obj

+% Font Times-Roman

+<< /BaseFont /Times-Roman

+ /Encoding /WinAnsiEncoding

+ /Name /F4

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER125': class LinkAnnotation 

+134 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 383.115

+ 0 ]

+ /Rect [ 350.19

+ 124.49

+ 394.3725

+ 135.74 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page4': class PDFPage 

+135 0 obj

+% Page dictionary

+<< /Annots [ 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

+ 132 0 R

+ 134 0 R ]

+ /Contents 306 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page5': class PDFPage 

+136 0 obj

+% Page dictionary

+<< /Contents 307 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page6': class PDFPage 

+137 0 obj

+% Page dictionary

+<< /Contents 308 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER126': class LinkAnnotation 

+138 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 369.865

+ 0 ]

+ /Rect [ 381.61

+ 160.9275

+ 425.7925

+ 172.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page7': class PDFPage 

+139 0 obj

+% Page dictionary

+<< /Annots [ 138 0 R ]

+ /Contents 309 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER127': class LinkAnnotation 

+140 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 356.615

+ 0 ]

+ /Rect [ 307.5925

+ 532.9275

+ 351.775

+ 544.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER128': class LinkAnnotation 

+141 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 343.365

+ 0 ]

+ /Rect [ 183.8125

+ 500.9275

+ 232.165

+ 512.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER129': class LinkAnnotation 

+142 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 330.115

+ 0 ]

+ /Rect [ 122.125

+ 487.6775

+ 170.4775

+ 498.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER130': class LinkAnnotation 

+143 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 316.865

+ 0 ]

+ /Rect [ 108.775

+ 474.4275

+ 157.1275

+ 485.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER131': class LinkAnnotation 

+144 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 303.615

+ 0 ]

+ /Rect [ 343.435

+ 453.6775

+ 391.7875

+ 464.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'F5': class PDFType1Font 

+145 0 obj

+% Font Helvetica-Oblique

+<< /BaseFont /Helvetica-Oblique

+ /Encoding /WinAnsiEncoding

+ /Name /F5

+ /Subtype /Type1

+ /Type /Font >>

+endobj

+% 'Annot.NUMBER132': class LinkAnnotation 

+146 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 290.365

+ 0 ]

+ /Rect [ 110.4475

+ 442.4275

+ 158.8

+ 453.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER133': class LinkAnnotation 

+147 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 356.615

+ 0 ]

+ /Rect [ 160.4575

+ 282.4275

+ 204.64

+ 293.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER134': class LinkAnnotation 

+148 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 343.365

+ 0 ]

+ /Rect [ 183.8125

+ 250.4275

+ 232.165

+ 261.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER135': class LinkAnnotation 

+149 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 330.115

+ 0 ]

+ /Rect [ 122.125

+ 237.1775

+ 170.4775

+ 248.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER136': class LinkAnnotation 

+150 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 316.865

+ 0 ]

+ /Rect [ 108.775

+ 223.9275

+ 157.1275

+ 235.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER137': class LinkAnnotation 

+151 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 303.615

+ 0 ]

+ /Rect [ 343.435

+ 203.1775

+ 391.7875

+ 214.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER138': class LinkAnnotation 

+152 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 290.365

+ 0 ]

+ /Rect [ 110.4475

+ 191.9275

+ 158.8

+ 203.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER139': class LinkAnnotation 

+153 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 436.115

+ 0 ]

+ /Rect [ 125.4475

+ 114.8025

+ 169.63

+ 126.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page8': class PDFPage 

+154 0 obj

+% Page dictionary

+<< /Annots [ 140 0 R

+ 141 0 R

+ 142 0 R

+ 143 0 R

+ 144 0 R

+ 146 0 R

+ 147 0 R

+ 148 0 R

+ 149 0 R

+ 150 0 R

+ 151 0 R

+ 152 0 R

+ 153 0 R ]

+ /Contents 310 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER140': class LinkAnnotation 

+155 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 277.115

+ 0 ]

+ /Rect [ 500.1475

+ 182.6775

+ 548.5

+ 193.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page9': class PDFPage 

+156 0 obj

+% Page dictionary

+<< /Annots [ 155 0 R ]

+ /Contents 311 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER141': class LinkAnnotation 

+157 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 263.865

+ 0 ]

+ /Rect [ 515.1475

+ 677.9275

+ 553.075

+ 689.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER142': class LinkAnnotation 

+158 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 263.865

+ 0 ]

+ /Rect [ 55

+ 666.6775

+ 63.34

+ 677.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER143': class LinkAnnotation 

+159 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 250.615

+ 0 ]

+ /Rect [ 313.045

+ 559.4275

+ 361.3975

+ 570.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER144': class LinkAnnotation 

+160 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 237.365

+ 0 ]

+ /Rect [ 448.06

+ 527.4275

+ 496.4125

+ 538.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER145': class LinkAnnotation 

+161 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 224.115

+ 0 ]

+ /Rect [ 124.615

+ 516.1775

+ 172.9675

+ 527.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER146': class LinkAnnotation 

+162 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 210.865

+ 0 ]

+ /Rect [ 132.535

+ 452.1775

+ 180.8875

+ 463.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER147': class LinkAnnotation 

+163 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 197.615

+ 0 ]

+ /Rect [ 217.9075

+ 279.1775

+ 266.26

+ 290.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER148': class LinkAnnotation 

+164 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 184.365

+ 0 ]

+ /Rect [ 73.7575

+ 215.1775

+ 122.11

+ 226.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page10': class PDFPage 

+165 0 obj

+% Page dictionary

+<< /Annots [ 157 0 R

+ 158 0 R

+ 159 0 R

+ 160 0 R

+ 161 0 R

+ 162 0 R

+ 163 0 R

+ 164 0 R ]

+ /Contents 312 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER149': class LinkAnnotation 

+166 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 171.115

+ 0 ]

+ /Rect [ 499.5925

+ 695.865

+ 547.945

+ 707.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER150': class LinkAnnotation 

+167 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 157.865

+ 0 ]

+ /Rect [ 257.9875

+ 675.115

+ 306.34

+ 686.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER151': class LinkAnnotation 

+168 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 144.615

+ 0 ]

+ /Rect [ 373.0375

+ 675.115

+ 421.39

+ 686.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER152': class LinkAnnotation 

+169 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 277.115

+ 0 ]

+ /Rect [ 493.5025

+ 675.115

+ 541.855

+ 686.365 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page11': class PDFPage 

+170 0 obj

+% Page dictionary

+<< /Annots [ 166 0 R

+ 167 0 R

+ 168 0 R

+ 169 0 R ]

+ /Contents 313 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page12': class PDFPage 

+171 0 obj

+% Page dictionary

+<< /Contents 314 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER153': class LinkAnnotation 

+172 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 118.115

+ 0 ]

+ /Rect [ 378.895

+ 323.8025

+ 427.2475

+ 335.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER154': class LinkAnnotation 

+173 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 171.115

+ 0 ]

+ /Rect [ 207.1

+ 219.365

+ 255.4525

+ 230.615 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER155': class LinkAnnotation 

+174 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 171.115

+ 0 ]

+ /Rect [ 239.6275

+ 183.615

+ 287.98

+ 194.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER156': class LinkAnnotation 

+175 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 131.365

+ 0 ]

+ /Rect [ 98.3425

+ 147.865

+ 146.695

+ 159.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page13': class PDFPage 

+176 0 obj

+% Page dictionary

+<< /Annots [ 172 0 R

+ 173 0 R

+ 174 0 R

+ 175 0 R ]

+ /Contents 315 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER157': class LinkAnnotation 

+177 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 118.115

+ 0 ]

+ /Rect [ 392.7925

+ 454.74

+ 441.145

+ 465.99 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER158': class LinkAnnotation 

+178 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 104.865

+ 0 ]

+ /Rect [ 258.0025

+ 388.865

+ 306.355

+ 400.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page14': class PDFPage 

+179 0 obj

+% Page dictionary

+<< /Annots [ 177 0 R

+ 178 0 R ]

+ /Contents 316 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER159': class LinkAnnotation 

+180 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 91.615

+ 0 ]

+ /Rect [ 462.835

+ 689.1775

+ 511.1875

+ 700.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER160': class LinkAnnotation 

+181 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 742.865

+ 0 ]

+ /Rect [ 259.42

+ 120.3025

+ 307.7725

+ 131.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page15': class PDFPage 

+182 0 obj

+% Page dictionary

+<< /Annots [ 180 0 R

+ 181 0 R ]

+ /Contents 317 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER161': class LinkAnnotation 

+183 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 742.865

+ 0 ]

+ /Rect [ 381.79

+ 717.4275

+ 430.1425

+ 728.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER162': class LinkAnnotation 

+184 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 742.865

+ 0 ]

+ /Rect [ 304.7875

+ 508.1775

+ 353.14

+ 519.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER163': class LinkAnnotation 

+185 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 118.115

+ 0 ]

+ /Rect [ 468.19

+ 385.8025

+ 516.5425

+ 397.0525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER164': class LinkAnnotation 

+186 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 382.21

+ 165.3025

+ 430.5625

+ 176.5525 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page16': class PDFPage 

+187 0 obj

+% Page dictionary

+<< /Annots [ 183 0 R

+ 184 0 R

+ 185 0 R

+ 186 0 R ]

+ /Contents 318 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER165': class LinkAnnotation 

+188 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 729.615

+ 0 ]

+ /Rect [ 382.21

+ 717.4275

+ 430.5625

+ 728.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page17': class PDFPage 

+189 0 obj

+% Page dictionary

+<< /Annots [ 188 0 R ]

+ /Contents 319 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER166': class LinkAnnotation 

+190 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 716.365

+ 0 ]

+ /Rect [ 297.6025

+ 602.6775

+ 345.955

+ 613.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER167': class LinkAnnotation 

+191 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 118.115

+ 0 ]

+ /Rect [ 68.335

+ 463.4275

+ 116.6875

+ 474.6775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER168': class LinkAnnotation 

+192 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 69.925

+ 118.115

+ 0 ]

+ /Rect [ 320.2675

+ 418.1775

+ 368.62

+ 429.4275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page18': class PDFPage 

+193 0 obj

+% Page dictionary

+<< /Annots [ 190 0 R

+ 191 0 R

+ 192 0 R ]

+ /Contents 320 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER169': class LinkAnnotation 

+194 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 703.115

+ 0 ]

+ /Rect [ 293.17

+ 545.9275

+ 341.5225

+ 557.1775 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER170': class LinkAnnotation 

+195 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 689.865

+ 0 ]

+ /Rect [ 425.56

+ 353.6775

+ 473.9125

+ 364.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page19': class PDFPage 

+196 0 obj

+% Page dictionary

+<< /Annots [ 194 0 R

+ 195 0 R ]

+ /Contents 321 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page20': class PDFPage 

+197 0 obj

+% Page dictionary

+<< /Contents 322 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER171': class LinkAnnotation 

+198 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 676.615

+ 0 ]

+ /Rect [ 164.2225

+ 558.99

+ 212.575

+ 570.24 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER172': class LinkAnnotation 

+199 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 676.615

+ 0 ]

+ /Rect [ 465.5875

+ 481.865

+ 513.94

+ 493.115 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER173': class LinkAnnotation 

+200 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 676.615

+ 0 ]

+ /Rect [ 345.55

+ 382.24

+ 393.9025

+ 393.49 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER174': class LinkAnnotation 

+201 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 676.615

+ 0 ]

+ /Rect [ 57.085

+ 316.365

+ 105.4375

+ 327.615 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page21': class PDFPage 

+202 0 obj

+% Page dictionary

+<< /Annots [ 198 0 R

+ 199 0 R

+ 200 0 R

+ 201 0 R ]

+ /Contents 323 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER175': class LinkAnnotation 

+203 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 449.365

+ 0 ]

+ /Rect [ 323.41

+ 430.615

+ 367.5925

+ 441.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER176': class LinkAnnotation 

+204 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 121 0 R

+ /XYZ

+ 66.25

+ 449.365

+ 0 ]

+ /Rect [ 315.115

+ 321.615

+ 359.2975

+ 332.865 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page22': class PDFPage 

+205 0 obj

+% Page dictionary

+<< /Annots [ 203 0 R

+ 204 0 R ]

+ /Contents 324 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Annot.NUMBER177': class LinkAnnotation 

+206 0 obj

+<< /Border [ 0

+ 0

+ 0 ]

+ /Contents ()

+ /Dest [ 135 0 R

+ /XYZ

+ 69.925

+ 663.365

+ 0 ]

+ /Rect [ 188.2975

+ 730.6775

+ 236.65

+ 741.9275 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Annot.NUMBER178': class PDFDictionary 

+207 0 obj

+<< /A << /S /URI

+ /Type /Action

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

+ /Border [ 0

+ 0

+ 0 ]

+ /Rect [ 193.8325

+ 408.5525

+ 283.9675

+ 419.8025 ]

+ /Subtype /Link

+ /Type /Annot >>

+endobj

+% 'Page23': class PDFPage 

+208 0 obj

+% Page dictionary

+<< /Annots [ 206 0 R

+ 207 0 R ]

+ /Contents 325 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'Page24': class PDFPage 

+209 0 obj

+% Page dictionary

+<< /Contents 326 0 R

+ /MediaBox [ 0

+ 0

+ 612

+ 792 ]

+ /Parent 302 0 R

+ /Resources << /Font 1 0 R

+ /ProcSet [ /PDF

+ /Text

+ /ImageB

+ /ImageC

+ /ImageI ] >>

+ /Rotate 0

+ /Trans <<  >>

+ /Type /Page >>

+endobj

+% 'R210': class PDFCatalog 

+210 0 obj

+% Document Root

+<< /Outlines 212 0 R

+ /PageMode /UseNone

+ /Pages 302 0 R

+ /Type /Catalog >>

+endobj

+% 'R211': class PDFInfo 

+211 0 obj

+<< /Author ()

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

+ /Keywords ()

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

+ /Subject ()

+ /Title (Android 2.3 Compatibility Definition) >>

+endobj

+% 'R212': class PDFOutlines 

+212 0 obj

+<< /Count 17

+ /First 213 0 R

+ /Last 213 0 R

+ /Type /Outlines >>

+endobj

+% 'Outline.0': class OutlineEntryObject 

+213 0 obj

+<< /Count -14

+ /Dest [ 47 0 R

+ /Fit ]

+ /First 214 0 R

+ /Last 296 0 R

+ /Parent 212 0 R

+ /Title (Android 2.3 Compatibility Definition) >>

+endobj

+% 'Outline.2.0': class OutlineEntryObject 

+214 0 obj

+<< /Dest [ 47 0 R

+ /Fit ]

+ /Next 215 0 R

+ /Parent 213 0 R

+ /Title (Table of Contents) >>

+endobj

+% 'Outline.2.1': class OutlineEntryObject 

+215 0 obj

+<< /Dest [ 121 0 R

+ /Fit ]

+ /Next 216 0 R

+ /Parent 213 0 R

+ /Prev 214 0 R

+ /Title (1. Introduction) >>

+endobj

+% 'Outline.2.2': class OutlineEntryObject 

+216 0 obj

+<< /Dest [ 121 0 R

+ /Fit ]

+ /Next 217 0 R

+ /Parent 213 0 R

+ /Prev 215 0 R

+ /Title (2. Resources) >>

+endobj

+% 'Outline.2.3': class OutlineEntryObject 

+217 0 obj

+<< /Count -8

+ /Dest [ 135 0 R

+ /Fit ]

+ /First 218 0 R

+ /Last 234 0 R

+ /Next 240 0 R

+ /Parent 213 0 R

+ /Prev 216 0 R

+ /Title (3. Software) >>

+endobj

+% 'Outline.3.0': class OutlineEntryObject 

+218 0 obj

+<< /Dest [ 135 0 R

+ /Fit ]

+ /Next 219 0 R

+ /Parent 217 0 R

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

+endobj

+% 'Outline.3.1': class OutlineEntryObject 

+219 0 obj

+<< /Count -7

+ /Dest [ 135 0 R

+ /Fit ]

+ /First 220 0 R

+ /Last 226 0 R

+ /Next 227 0 R

+ /Parent 217 0 R

+ /Prev 218 0 R

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

+endobj

+% 'Outline.4.0': class OutlineEntryObject 

+220 0 obj

+<< /Dest [ 135 0 R

+ /Fit ]

+ /Next 221 0 R

+ /Parent 219 0 R

+ /Title (3.2.1. Permissions) >>

+endobj

+% 'Outline.4.1': class OutlineEntryObject 

+221 0 obj

+<< /Dest [ 135 0 R

+ /Fit ]

+ /Next 222 0 R

+ /Parent 219 0 R

+ /Prev 220 0 R

+ /Title (3.2.2. Build Parameters) >>

+endobj

+% 'Outline.4.2': class OutlineEntryObject 

+222 0 obj

+<< /Dest [ 137 0 R

+ /Fit ]

+ /Next 223 0 R

+ /Parent 219 0 R

+ /Prev 221 0 R

+ /Title (3.2.3. Intent Compatibility) >>

+endobj

+% 'Outline.4.3': class OutlineEntryObject 

+223 0 obj

+<< /Dest [ 137 0 R

+ /Fit ]

+ /Next 224 0 R

+ /Parent 219 0 R

+ /Prev 222 0 R

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

+endobj

+% 'Outline.4.4': class OutlineEntryObject 

+224 0 obj

+<< /Dest [ 137 0 R

+ /Fit ]

+ /Next 225 0 R

+ /Parent 219 0 R

+ /Prev 223 0 R

+ /Title (3.2.3.2. Intent Overrides) >>

+endobj

+% 'Outline.4.5': class OutlineEntryObject 

+225 0 obj

+<< /Dest [ 137 0 R

+ /Fit ]

+ /Next 226 0 R

+ /Parent 219 0 R

+ /Prev 224 0 R

+ /Title (3.2.3.3. Intent Namespaces) >>

+endobj

+% 'Outline.4.6': class OutlineEntryObject 

+226 0 obj

+<< /Dest [ 139 0 R

+ /Fit ]

+ /Parent 219 0 R

+ /Prev 225 0 R

+ /Title (3.2.3.4. Broadcast Intents) >>

+endobj

+% 'Outline.3.2': class OutlineEntryObject 

+227 0 obj

+<< /Dest [ 139 0 R

+ /Fit ]

+ /Next 228 0 R

+ /Parent 217 0 R

+ /Prev 219 0 R

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

+endobj

+% 'Outline.3.3': class OutlineEntryObject 

+228 0 obj

+<< /Count -2

+ /Dest [ 139 0 R

+ /Fit ]

+ /First 229 0 R

+ /Last 230 0 R

+ /Next 231 0 R

+ /Parent 217 0 R

+ /Prev 227 0 R

+ /Title (3.4. Web Compatibility) >>

+endobj

+% 'Outline.5.0': class OutlineEntryObject 

+229 0 obj

+<< /Dest [ 139 0 R

+ /Fit ]

+ /Next 230 0 R

+ /Parent 228 0 R

+ /Title (3.4.1. WebView Compatibility) >>

+endobj

+% 'Outline.5.1': class OutlineEntryObject 

+230 0 obj

+<< /Dest [ 154 0 R

+ /Fit ]

+ /Parent 228 0 R

+ /Prev 229 0 R

+ /Title (3.4.2. Browser Compatibility) >>

+endobj

+% 'Outline.3.4': class OutlineEntryObject 

+231 0 obj

+<< /Dest [ 154 0 R

+ /Fit ]

+ /Next 232 0 R

+ /Parent 217 0 R

+ /Prev 228 0 R

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

+endobj

+% 'Outline.3.5': class OutlineEntryObject 

+232 0 obj

+<< /Dest [ 156 0 R

+ /Fit ]

+ /Next 233 0 R

+ /Parent 217 0 R

+ /Prev 231 0 R

+ /Title (3.6. API Namespaces) >>

+endobj

+% 'Outline.3.6': class OutlineEntryObject 

+233 0 obj

+<< /Dest [ 156 0 R

+ /Fit ]

+ /Next 234 0 R

+ /Parent 217 0 R

+ /Prev 232 0 R

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

+endobj

+% 'Outline.3.7': class OutlineEntryObject 

+234 0 obj

+<< /Count -5

+ /Dest [ 156 0 R

+ /Fit ]

+ /First 235 0 R

+ /Last 239 0 R

+ /Parent 217 0 R

+ /Prev 233 0 R

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

+endobj

+% 'Outline.6.0': class OutlineEntryObject 

+235 0 obj

+<< /Dest [ 165 0 R

+ /Fit ]

+ /Next 236 0 R

+ /Parent 234 0 R

+ /Title (3.8.1. Widgets) >>

+endobj

+% 'Outline.6.1': class OutlineEntryObject 

+236 0 obj

+<< /Dest [ 165 0 R

+ /Fit ]

+ /Next 237 0 R

+ /Parent 234 0 R

+ /Prev 235 0 R

+ /Title (3.8.2. Notifications) >>

+endobj

+% 'Outline.6.2': class OutlineEntryObject 

+237 0 obj

+<< /Dest [ 165 0 R

+ /Fit ]

+ /Next 238 0 R

+ /Parent 234 0 R

+ /Prev 236 0 R

+ /Title (3.8.3. Search) >>

+endobj

+% 'Outline.6.3': class OutlineEntryObject 

+238 0 obj

+<< /Dest [ 165 0 R

+ /Fit ]

+ /Next 239 0 R

+ /Parent 234 0 R

+ /Prev 237 0 R

+ /Title (3.8.4. Toasts) >>

+endobj

+% 'Outline.6.4': class OutlineEntryObject 

+239 0 obj

+<< /Dest [ 165 0 R

+ /Fit ]

+ /Parent 234 0 R

+ /Prev 238 0 R

+ /Title (3.8.5. Live Wallpapers) >>

+endobj

+% 'Outline.2.4': class OutlineEntryObject 

+240 0 obj

+<< /Dest [ 170 0 R

+ /Fit ]

+ /Next 241 0 R

+ /Parent 213 0 R

+ /Prev 217 0 R

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

+endobj

+% 'Outline.2.5': class OutlineEntryObject 

+241 0 obj

+<< /Count -5

+ /Dest [ 170 0 R

+ /Fit ]

+ /First 242 0 R

+ /Last 246 0 R

+ /Next 247 0 R

+ /Parent 213 0 R

+ /Prev 240 0 R

+ /Title (5. Multimedia Compatibility) >>

+endobj

+% 'Outline.7.0': class OutlineEntryObject 

+242 0 obj

+<< /Dest [ 170 0 R

+ /Fit ]

+ /Next 243 0 R

+ /Parent 241 0 R

+ /Title (5.1. Media Codecs) >>

+endobj

+% 'Outline.7.1': class OutlineEntryObject 

+243 0 obj

+<< /Dest [ 170 0 R

+ /Fit ]

+ /Next 244 0 R

+ /Parent 241 0 R

+ /Prev 242 0 R

+ /Title (5.1.1. Media Decoders) >>

+endobj

+% 'Outline.7.2': class OutlineEntryObject 

+244 0 obj

+<< /Dest [ 171 0 R

+ /Fit ]

+ /Next 245 0 R

+ /Parent 241 0 R

+ /Prev 243 0 R

+ /Title (5.1.2. Media Encoders) >>

+endobj

+% 'Outline.7.3': class OutlineEntryObject 

+245 0 obj

+<< /Dest [ 171 0 R

+ /Fit ]

+ /Next 246 0 R

+ /Parent 241 0 R

+ /Prev 244 0 R

+ /Title (5.2. Audio Recording) >>

+endobj

+% 'Outline.7.4': class OutlineEntryObject 

+246 0 obj

+<< /Dest [ 176 0 R

+ /Fit ]

+ /Parent 241 0 R

+ /Prev 245 0 R

+ /Title (5.3. Audio Latency) >>

+endobj

+% 'Outline.2.6': class OutlineEntryObject 

+247 0 obj

+<< /Dest [ 176 0 R

+ /Fit ]

+ /Next 248 0 R

+ /Parent 213 0 R

+ /Prev 241 0 R

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

+endobj

+% 'Outline.2.7': class OutlineEntryObject 

+248 0 obj

+<< /Count -7

+ /Dest [ 179 0 R

+ /Fit ]

+ /First 249 0 R

+ /Last 283 0 R

+ /Next 284 0 R

+ /Parent 213 0 R

+ /Prev 247 0 R

+ /Title (7. Hardware Compatibility) >>

+endobj

+% 'Outline.8.0': class OutlineEntryObject 

+249 0 obj

+<< /Count -5

+ /Dest [ 179 0 R

+ /Fit ]

+ /First 250 0 R

+ /Last 254 0 R

+ /Next 255 0 R

+ /Parent 248 0 R

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

+endobj

+% 'Outline.9.0': class OutlineEntryObject 

+250 0 obj

+<< /Dest [ 179 0 R

+ /Fit ]

+ /Next 251 0 R

+ /Parent 249 0 R

+ /Title (7.1.1. Screen Configurations) >>

+endobj

+% 'Outline.9.1': class OutlineEntryObject 

+251 0 obj

+<< /Dest [ 182 0 R

+ /Fit ]

+ /Next 252 0 R

+ /Parent 249 0 R

+ /Prev 250 0 R

+ /Title (7.1.2. Display Metrics) >>

+endobj

+% 'Outline.9.2': class OutlineEntryObject 

+252 0 obj

+<< /Dest [ 182 0 R

+ /Fit ]

+ /Next 253 0 R

+ /Parent 249 0 R

+ /Prev 251 0 R

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

+endobj

+% 'Outline.9.3': class OutlineEntryObject 

+253 0 obj

+<< /Dest [ 182 0 R

+ /Fit ]

+ /Next 254 0 R

+ /Parent 249 0 R

+ /Prev 252 0 R

+ /Title (7.1.4. Screen Orientation) >>

+endobj

+% 'Outline.9.4': class OutlineEntryObject 

+254 0 obj

+<< /Dest [ 182 0 R

+ /Fit ]

+ /Parent 249 0 R

+ /Prev 253 0 R

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

+endobj

+% 'Outline.8.1': class OutlineEntryObject 

+255 0 obj

+<< /Count -4

+ /Dest [ 182 0 R

+ /Fit ]

+ /First 256 0 R

+ /Last 259 0 R

+ /Next 260 0 R

+ /Parent 248 0 R

+ /Prev 249 0 R

+ /Title (7.2. Input Devices) >>

+endobj

+% 'Outline.10.0': class OutlineEntryObject 

+256 0 obj

+<< /Dest [ 182 0 R

+ /Fit ]

+ /Next 257 0 R

+ /Parent 255 0 R

+ /Title (7.2.1. Keyboard) >>

+endobj

+% 'Outline.10.1': class OutlineEntryObject 

+257 0 obj

+<< /Dest [ 182 0 R

+ /Fit ]

+ /Next 258 0 R

+ /Parent 255 0 R

+ /Prev 256 0 R

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

+endobj

+% 'Outline.10.2': class OutlineEntryObject 

+258 0 obj

+<< /Dest [ 187 0 R

+ /Fit ]

+ /Next 259 0 R

+ /Parent 255 0 R

+ /Prev 257 0 R

+ /Title (7.2.3. Navigation keys) >>

+endobj

+% 'Outline.10.3': class OutlineEntryObject 

+259 0 obj

+<< /Dest [ 187 0 R

+ /Fit ]

+ /Parent 255 0 R

+ /Prev 258 0 R

+ /Title (7.2.4. Touchscreen input) >>

+endobj

+% 'Outline.8.2': class OutlineEntryObject 

+260 0 obj

+<< /Count -8

+ /Dest [ 187 0 R

+ /Fit ]

+ /First 261 0 R

+ /Last 268 0 R

+ /Next 269 0 R

+ /Parent 248 0 R

+ /Prev 255 0 R

+ /Title (7.3. Sensors) >>

+endobj

+% 'Outline.11.0': class OutlineEntryObject 

+261 0 obj

+<< /Dest [ 187 0 R

+ /Fit ]

+ /Next 262 0 R

+ /Parent 260 0 R

+ /Title (7.3.1. Accelerometer) >>

+endobj

+% 'Outline.11.1': class OutlineEntryObject 

+262 0 obj

+<< /Dest [ 187 0 R

+ /Fit ]

+ /Next 263 0 R

+ /Parent 260 0 R

+ /Prev 261 0 R

+ /Title (7.3.2. Magnetometer) >>

+endobj

+% 'Outline.11.2': class OutlineEntryObject 

+263 0 obj

+<< /Dest [ 189 0 R

+ /Fit ]

+ /Next 264 0 R

+ /Parent 260 0 R

+ /Prev 262 0 R

+ /Title (7.3.3. GPS) >>

+endobj

+% 'Outline.11.3': class OutlineEntryObject 

+264 0 obj

+<< /Dest [ 189 0 R

+ /Fit ]

+ /Next 265 0 R

+ /Parent 260 0 R

+ /Prev 263 0 R

+ /Title (7.3.4. Gyroscope) >>

+endobj

+% 'Outline.11.4': class OutlineEntryObject 

+265 0 obj

+<< /Dest [ 189 0 R

+ /Fit ]

+ /Next 266 0 R

+ /Parent 260 0 R

+ /Prev 264 0 R

+ /Title (7.3.5. Barometer) >>

+endobj

+% 'Outline.11.5': class OutlineEntryObject 

+266 0 obj

+<< /Dest [ 189 0 R

+ /Fit ]

+ /Next 267 0 R

+ /Parent 260 0 R

+ /Prev 265 0 R

+ /Title (7.3.7. Thermometer) >>

+endobj

+% 'Outline.11.6': class OutlineEntryObject 

+267 0 obj

+<< /Dest [ 189 0 R

+ /Fit ]

+ /Next 268 0 R

+ /Parent 260 0 R

+ /Prev 266 0 R

+ /Title (7.3.7. Photometer) >>

+endobj

+% 'Outline.11.7': class OutlineEntryObject 

+268 0 obj

+<< /Dest [ 189 0 R

+ /Fit ]

+ /Parent 260 0 R

+ /Prev 267 0 R

+ /Title (7.3.8. Proximity Sensor) >>

+endobj

+% 'Outline.8.3': class OutlineEntryObject 

+269 0 obj

+<< /Count -5

+ /Dest [ 189 0 R

+ /Fit ]

+ /First 270 0 R

+ /Last 274 0 R

+ /Next 275 0 R

+ /Parent 248 0 R

+ /Prev 260 0 R

+ /Title (7.4. Data Connectivity) >>

+endobj

+% 'Outline.12.0': class OutlineEntryObject 

+270 0 obj

+<< /Dest [ 189 0 R

+ /Fit ]

+ /Next 271 0 R

+ /Parent 269 0 R

+ /Title (7.4.1. Telephony) >>

+endobj

+% 'Outline.12.1': class OutlineEntryObject 

+271 0 obj

+<< /Dest [ 193 0 R

+ /Fit ]

+ /Next 272 0 R

+ /Parent 269 0 R

+ /Prev 270 0 R

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

+endobj

+% 'Outline.12.2': class OutlineEntryObject 

+272 0 obj

+<< /Dest [ 193 0 R

+ /Fit ]

+ /Next 273 0 R

+ /Parent 269 0 R

+ /Prev 271 0 R

+ /Title (7.4.3. Bluetooth) >>

+endobj

+% 'Outline.12.3': class OutlineEntryObject 

+273 0 obj

+<< /Dest [ 193 0 R

+ /Fit ]

+ /Next 274 0 R

+ /Parent 269 0 R

+ /Prev 272 0 R

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

+endobj

+% 'Outline.12.4': class OutlineEntryObject 

+274 0 obj

+<< /Dest [ 193 0 R

+ /Fit ]

+ /Parent 269 0 R

+ /Prev 273 0 R

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

+endobj

+% 'Outline.8.4': class OutlineEntryObject 

+275 0 obj

+<< /Count -4

+ /Dest [ 193 0 R

+ /Fit ]

+ /First 276 0 R

+ /Last 279 0 R

+ /Next 280 0 R

+ /Parent 248 0 R

+ /Prev 269 0 R

+ /Title (7.5. Cameras) >>

+endobj

+% 'Outline.13.0': class OutlineEntryObject 

+276 0 obj

+<< /Dest [ 193 0 R

+ /Fit ]

+ /Next 277 0 R

+ /Parent 275 0 R

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

+endobj

+% 'Outline.13.1': class OutlineEntryObject 

+277 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Next 278 0 R

+ /Parent 275 0 R

+ /Prev 276 0 R

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

+endobj

+% 'Outline.13.2': class OutlineEntryObject 

+278 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Next 279 0 R

+ /Parent 275 0 R

+ /Prev 277 0 R

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

+endobj

+% 'Outline.13.3': class OutlineEntryObject 

+279 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Parent 275 0 R

+ /Prev 278 0 R

+ /Title (7.5.4. Camera Orientation) >>

+endobj

+% 'Outline.8.5': class OutlineEntryObject 

+280 0 obj

+<< /Count -2

+ /Dest [ 196 0 R

+ /Fit ]

+ /First 281 0 R

+ /Last 282 0 R

+ /Next 283 0 R

+ /Parent 248 0 R

+ /Prev 275 0 R

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

+endobj

+% 'Outline.14.0': class OutlineEntryObject 

+281 0 obj

+<< /Dest [ 196 0 R

+ /Fit ]

+ /Next 282 0 R

+ /Parent 280 0 R

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

+endobj

+% 'Outline.14.1': class OutlineEntryObject 

+282 0 obj

+<< /Dest [ 197 0 R

+ /Fit ]

+ /Parent 280 0 R

+ /Prev 281 0 R

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

+endobj

+% 'Outline.8.6': class OutlineEntryObject 

+283 0 obj

+<< /Dest [ 197 0 R

+ /Fit ]

+ /Parent 248 0 R

+ /Prev 280 0 R

+ /Title (7.7. USB) >>

+endobj

+% 'Outline.2.8': class OutlineEntryObject 

+284 0 obj

+<< /Dest [ 197 0 R

+ /Fit ]

+ /Next 285 0 R

+ /Parent 213 0 R

+ /Prev 248 0 R

+ /Title (8. Performance Compatibility) >>

+endobj

+% 'Outline.2.9': class OutlineEntryObject 

+285 0 obj

+<< /Count -4

+ /Dest [ 202 0 R

+ /Fit ]

+ /First 286 0 R

+ /Last 289 0 R

+ /Next 290 0 R

+ /Parent 213 0 R

+ /Prev 284 0 R

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

+endobj

+% 'Outline.15.0': class OutlineEntryObject 

+286 0 obj

+<< /Dest [ 202 0 R

+ /Fit ]

+ /Next 287 0 R

+ /Parent 285 0 R

+ /Title (9.1. Permissions) >>

+endobj

+% 'Outline.15.1': class OutlineEntryObject 

+287 0 obj

+<< /Dest [ 202 0 R

+ /Fit ]

+ /Next 288 0 R

+ /Parent 285 0 R

+ /Prev 286 0 R

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

+endobj

+% 'Outline.15.2': class OutlineEntryObject 

+288 0 obj

+<< /Dest [ 202 0 R

+ /Fit ]

+ /Next 289 0 R

+ /Parent 285 0 R

+ /Prev 287 0 R

+ /Title (9.3. Filesystem Permissions) >>

+endobj

+% 'Outline.15.3': class OutlineEntryObject 

+289 0 obj

+<< /Dest [ 202 0 R

+ /Fit ]

+ /Parent 285 0 R

+ /Prev 288 0 R

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

+endobj

+% 'Outline.2.10': class OutlineEntryObject 

+290 0 obj

+<< /Count -3

+ /Dest [ 205 0 R

+ /Fit ]

+ /First 291 0 R

+ /Last 293 0 R

+ /Next 294 0 R

+ /Parent 213 0 R

+ /Prev 285 0 R

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

+endobj

+% 'Outline.16.0': class OutlineEntryObject 

+291 0 obj

+<< /Dest [ 205 0 R

+ /Fit ]

+ /Next 292 0 R

+ /Parent 290 0 R

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

+endobj

+% 'Outline.16.1': class OutlineEntryObject 

+292 0 obj

+<< /Dest [ 205 0 R

+ /Fit ]

+ /Next 293 0 R

+ /Parent 290 0 R

+ /Prev 291 0 R

+ /Title (10.2. CTS Verifier) >>

+endobj

+% 'Outline.16.2': class OutlineEntryObject 

+293 0 obj

+<< /Dest [ 205 0 R

+ /Fit ]

+ /Parent 290 0 R

+ /Prev 292 0 R

+ /Title (10.3. Reference Applications) >>

+endobj

+% 'Outline.2.11': class OutlineEntryObject 

+294 0 obj

+<< /Dest [ 208 0 R

+ /Fit ]

+ /Next 295 0 R

+ /Parent 213 0 R

+ /Prev 290 0 R

+ /Title (11. Updatable Software) >>

+endobj

+% 'Outline.2.12': class OutlineEntryObject 

+295 0 obj

+<< /Dest [ 208 0 R

+ /Fit ]

+ /Next 296 0 R

+ /Parent 213 0 R

+ /Prev 294 0 R

+ /Title (12. Contact Us) >>

+endobj

+% 'Outline.2.13': class OutlineEntryObject 

+296 0 obj

+<< /Count -5

+ /Dest [ 209 0 R

+ /Fit ]

+ /First 297 0 R

+ /Last 301 0 R

+ /Parent 213 0 R

+ /Prev 295 0 R

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

+endobj

+% 'Outline.17.0': class OutlineEntryObject 

+297 0 obj

+<< /Dest [ 209 0 R

+ /Fit ]

+ /Next 298 0 R

+ /Parent 296 0 R

+ /Title (Setup and Installation) >>

+endobj

+% 'Outline.17.1': class OutlineEntryObject 

+298 0 obj

+<< /Dest [ 209 0 R

+ /Fit ]

+ /Next 299 0 R

+ /Parent 296 0 R

+ /Prev 297 0 R

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

+endobj

+% 'Outline.17.2': class OutlineEntryObject 

+299 0 obj

+<< /Dest [ 209 0 R

+ /Fit ]

+ /Next 300 0 R

+ /Parent 296 0 R

+ /Prev 298 0 R

+ /Title (Test Pairing and Communication) >>

+endobj

+% 'Outline.17.3': class OutlineEntryObject 

+300 0 obj

+<< /Dest [ 209 0 R

+ /Fit ]

+ /Next 301 0 R

+ /Parent 296 0 R

+ /Prev 299 0 R

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

+endobj

+% 'Outline.17.4': class OutlineEntryObject 

+301 0 obj

+<< /Dest [ 209 0 R

+ /Fit ]

+ /Parent 296 0 R

+ /Prev 300 0 R

+ /Title (Test Re-Launches) >>

+endobj

+% 'R302': class PDFPages 

+302 0 obj

+% page tree

+<< /Count 24

+ /Kids [ 47 0 R

+ 89 0 R

+ 121 0 R

+ 135 0 R

+ 136 0 R

+ 137 0 R

+ 139 0 R

+ 154 0 R

+ 156 0 R

+ 165 0 R

+ 170 0 R

+ 171 0 R

+ 176 0 R

+ 179 0 R

+ 182 0 R

+ 187 0 R

+ 189 0 R

+ 193 0 R

+ 196 0 R

+ 197 0 R

+ 202 0 R

+ 205 0 R

+ 208 0 R

+ 209 0 R ]

+ /Type /Pages >>

+endobj

+% 'R303': class PDFStream 

+303 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 1782 >>

+stream

+Gatm=9lo&I&A<G1rrL0KdieGHa/sNTUm[&[-WZEPH@\XY7SAjN7+mcRT*6[c,V,!2m#acT+gD/nhqPUJL`umBgAGPUK[+5oofJ$Z6aJeI!Xgj^Lu-EP:VJbp\fEC,@LU9iCjPh)H:<&PE(i6&&j;bV^g$&PU)58?7'e26'Z4F*^RHstdS3<%O'SDckc\[n0:Mjjbl50KIc"FY*\Jd3;bY[1otZp5O^#2>`j]"X'?OFifC(3$r4BPZR=J'o:W],<K#M_uhSO3&k;$);P.0YLC=[@J6]S!i-b.6-9NrV5;pY$;^SuSB]R86ME5:Rd^G<dUKYJ3/&fk'pjZ)C?EIct*r!^t=oZt\8<[NUkE:g#2Y#K7U9k!</kX*TiBkgS3,6/0RbK(qiSQL%fgMpTWT:V9d'k&7!Gg-ktn3Sc%2[XX_F;"@64]qET>5b[;EEAobR&#NM8q';!X(kLFoV'J_3\(Qe$s4aTf@o*I*&im>ceI..Ha7OJr_RJ(0\gNbmcX0KQV8[eaTT&2'+q)@#FAj7n[S6339$[=K:',Qm(,D[\):pW#E6i0QhB&O;[EaUW@+EG(]bA;i,f?;"<:rlk>h]HEDmdnZdoggJ0q@=CVo_+4d+cGKKV#T'?nKcWeI!Q?qG49I$<qRU'LDP:km@6]rj7Oe*F8Y*2B!<?9]j=6b!4$+<dt.dZ#h((FI!T[_/)tPWHoJ)I)WnR_(gMF>$Xn(-4ruf,siM1`f!7#1:J-18Fu)R7.-"'g8Em'"-uf7<R"Q3b9<+(jk6c\m2-A<.M76C`!(eGB!d[Y-hQ(oc!Th6"K+s38^)I8(Yn`V674s1uV/$JJLBj3,h"d\;27n0\ZaqK#.qKp:&%N&#NXV_+$hALe%CHPSD0f(\+GjJO3fX+2utp7rdUVJIW/Tr(U`[3a8]nP:<DN>D,,CA:$-th.pe#4sb['k`GpJ5aq@<9hM:h'#6A/WB=,FqY1,i=[N=P6Wc-@:^.9LIEPPr64'$>V<jC6'S:T6T\\q3C+.$lS%a;o(@m+]b@`c*!]gK+,(McVFW6N/s&]Vp$kSZ,7R'!ePcQ%k"#Q+c%k-UL!Te`4j.MDXp=(tVf/;R'@%OcBO;OWS/.'H,[q?rGH/UDn&iU,:Y4'lRWN7S@!bg(%qoVird8siD%8:fAZ9)"MVbECaoTpe_dkj.Afq(n]kd\OA7*$,l9`&*4o[2[g`^EFB\`\:4e<>4W2Ca9$L5,=s$-7W*CSBtcE+).%?qW4oWptnBdh%]roMkc_S8);/[@(sVmc8W%GL4KEG>eT0gLh8NaiQJ.Q@*e^j-qNUQ!,3phkoWb8ap&+:]dS>8aYp?-ku>f9KK,%)1^@^>G5htrMLF.>kk3R"SHe6e7P\$URn%#1hFMrTV'HQ:>@@j#GhPA((jY>>aON`.2im56GPLTOFXBRU;-9DBA%*![lEM2)bh_>GX)*mB4*F-+*%R%BCNA%0nA4qS(q!,$bYBZ^ru9<HoM&"JrVi!,%)+?Fj,L1hT9S)H4ugiQUu*Dm2,V*(DV`HLh-13^&Z=RT??<akiV\D/Oc%=%SgLZn9CaNEKB_dST@'P$aX.Sl3C3uNo"!J\hf*Y5NuDkI\P7f/@W5<_H4#I*=-ec0gQfcKkf3:B+T0H"%>6\lU$9jIUAr[M-D.7afO'i48YS<`Pt[I(icTH3u2)dg)_M)hh&J!apQ4IHoL03B!nXT4_6)9C]%]Pm,upK+fdDNlH1dRlpPJh<bQiuEg!C.%mEbUrEDS_Mkja%S?gku:85tKD8u[<d-8YJM37pn~>endstream

+endobj

+% 'R304': class PDFStream 

+304 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 1512 >>

+stream

+Gatm<>uTK=&:J2Gs0.ROSO'Y/b9)d1"2in%V+nIJl&0NadB.8^Z301Fhj&c2VSQ::6XUaB2tHC.ZY)32!rSbZhn0(OR_bm8$C&Bn#&$OoR/I,Ng&Bj3p-kUt70nj7=J/IYSAG;T4sP'_.2-[8^PAFR2]'FYM$2$pTTnBhq"aX'QjA%Md/KD:pqT)1lp$m9e_^;5IJnKkkNg<HM,NX6.$&:q45Jep+;>@kKEVYd;F2:cZu]'ZFNBRjB`7-c3I4/rF#N#N@smaeQR3tQ3_(Et&IG(JAXKdK8aG##Zji%YL^p;N[],8n,F$"$Edb&G1N*rA.>09=hin__d+(FW=8;nMZ9*2u2+gq[DObg-iMTr4@iceERD#EANKb0VC:S).pXt+Y(Z:*ZGGo]Vc%Ad*A'@g>HFgWhYb*/X9MB"tCU55fUX=lcpdKgc5ZbAp?:\b`3>qp)bdVge<u/$cfbeDU#4Djb1>O"13"!6NH[tq$<h$E-h[Zu,&7B4bW(kZ<`.$2G6DRuTa)+9KM[.@p7'>V5QJ@7@/dlB8.2uuUM8q3cca2@u2K%Z5kL7W=Qkcq&FDZ,jl_PT-'a0OPa+oYY9.Zkfh5k)fQOE0t=G"O^5H%I;lR0jO0G[m5S(eG_0[J/DoH10QkH)e`=BCd3)g-qpq8?kAJ7g7p1#&uip1#uk8AMo<)s(CF:M'tbg<>K.;;6s4GV,;0)3NN,AG'u:WuVB1gENQA-Be`]D'O`V+24chp#G)")fkhS=CET(c!nm4EHNE\F)[ja0h6>Njf24(X7miB+'Q[VX%JYX&jN/%fB+G#B?TXF'qX=lHmZ_EiX6CGpL,%2GFXrHA3PkmipU*,>KR+5/+]?N.J70X:C-]Y5`R9fL*b2p^(lq`hcai.\Z0P>W\FoS@6&C<FOg;W(On%q*+#5QO^-ho]1Y-[?K&oiMc$cp?C@e5d=N*^qm:-O]SNie5sHjk\Lb-k6WVH?g1Z]+mMGuE6_fdQi,h7&H%T!;'>e0Sd^1<Y;d/Cnl+&(<mu60e>V:r4"q/mKB&oGe)t:>2#0#uC3[W-d=48CT0R0+49j@8/?B3>J]7P_05_:WQ^g^'p0k0<ABl::,ZRV;B;3tDOf/.L5QeDU!?Ptr6T'Np<`a$QjMXB'&WH;)FQd(W(M@dAm6jPT63f4K[G&,3=F;D%>>/(LjiPk-CRZ5TiK2P?c/7tmHH>FWp/[qq/5.B>J(Q_nQ24W4.)#^$P[Gl8%$<aRu7[EHYUA>iF\.M_D,@U.ni+\\'Uq0JQJ0jKCcfDrWin(F3KYj1ukn'I,]*^1^0\&,,4a+t3,B/UE)cV'C(g5k3h0%]$ra[&6j#]h('_oM6iDc0Q_&N,!m[.1rp[:+rkt3gc;MLd!p>ag?rfot/W8XiuXgt"`DPWE'-$C!L#G<W,r.ZNOh^(:&Y$GCI+rmoj09li`3uRfW!0*ObLR#JTcEek00'%a0K2o,j_mqbM)n6gQ/6Eusc.)n9_SLDXI"XuDg#f>@=7%CUm-jl`Ut%jt~>endstream

+endobj

+% 'R305': class PDFStream 

+305 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3315 >>

+stream

+GauHOgN)%.&q*PUrW2,+fZ]WjhJ[\_A\=5,GU?p9`t(79.>WX&N(JU%5V(]phZcVKU1.?V`@NMoM]s+U3K;MD!:1gIIN7s/=s3HdJuhTM3A-cEOQ0gm9g5=Z-Egd)1EWNC4ReL!i[B>$HM8G%iN2J+aS$T45g.c_^oGj@']D"[d%ipeKAgUMY?Qs)TUW=5O-l\$hTom+2k'Zn[/PjVHs9nSZ/(hh$*e42RJoHeT'_<T%io[qm"SiroI7Ub*4<J#OlKke[F[,<UJI^!4KDE"Gkk#lqgAn5"=N&a@Q%@CM)([R"YCI`-2\NH;2NeS,!iuo9Mk\Q^-NG_C8oREU4Ol59#O.f"e'F^$9i#]7Fd!VqIQfO8pO8G`MRU(aj^C*.l5"EL0X*(i>;^F4rA*@2U>\/lh.:k75hp^7RHGHROen@JF3#h*8PFPS7$SR#_Ec@Os3(WB,[AJoB%t]\[cTDbk/;JO?Dta<_pd?YOcRY[=/c#"Rrb[jaoUb+];q9N*"_m8:H;D]F#M&A:=;cEf$TD#DgH%n@m$.N0Q6KA6iPkE#g;ls"Rk=_peduVNTOTV=GTdh,hkRrjrD2DK$^o#GM,lC=(58e><VG,D+2rHI#KH=Ae2"H)Wb*=%-c8)t4Kfi(:*M(d<"=ZMtMr/-5o1k7oN1nB:t'>S9=Sa_+4Q+Na6/4=BF"KSMUq2a&.oqlqBcqGptWH`WWUcSR!EWa@S%c:a7DA+DBhB7;9I8-9FqN!PrK8+D`*lJFN6O;Q?3+&o0O<,)Kdb^X:F?o_-rkbIiqVTkWTXKXJ)lcbGn5'3A?_*Z:5`O4Q6kaiB"Ba/u<;n<4HG0n>10R,N6aba<iKI?nN>"s#X^b^Pbm[fQ;-f4Uq&BD3p22J;VA&1fSS0[D^g[FTPfafG2p4gMLgBA_P:<AM'mI6RdcDMi$./eZi"e.DTDMcdN25(XCp6HugM'=+mR&OCcft?H)-l97`l-t`hkW**e25.fm.d`4tIt1/W]0@c5k:I7WBIR`%NaL&#`d?ro-C+;#/XOH?dYnbV'pO6ES==+kcMi/Z96=ZC(4?emD]%8N1@/l$YTD#Q6i5,a=teFBT^-c4DX/1ln!Y;;gC4Rt@sciNJm)Y,3@X.e",o?r:67K'd4q.^bp?r\LFESflFtJN[$jYg7d1&Mi_l5UcLpP"?16)($JM/K3((q=!Se(fE)0S2o^alTMd;EQFM#mkL?(cj%ceOS*iGf%Mh_Z/To,ZX=<FmS$!QF9Kn1*#8.L8(Ts&63fH-/%Y7_!9:.$;YTO^a!:][2@LBn;$I,GU'?8;fP;]W@+X*Ue`Z!sS#"c%jg2OgtYc=&,n3Y1%SiubSmhNm'%]lI/C-5P[6JTU"7H)^%1RgF1ep;_N?2H;I6K+ArNkr8Kk3mm<Ne4cu5n]`@1opF$IU-b?f0Vq)JR)U-uc1%.$)g$3A"c)UM61#[0$iODn/7f1XJL#9YZ4'9r54h5=E&%'/ReOH1T.6[]1$U+PnG`5II^XH]BCHj,S*3%Y]m0)UW&RJKFH<#N5+[fYBA:L`?!kXIkinVI;>u-#Kh4d9.Hg@bKVQjSLQQMa"b34Fp"$F7b9^b"bqS3gQC+NFT/M8NG;U@QcZF"4T\\Eh#<(MNJ[5SMEYt>SkLK4mcWX/h\KD(PrLSmn7[Hoeh0:V#D1I/iC\@><@ShK#`sYo._pN\f;5!Z,6P#AA$%#ZZ!`M1$:Q55sZ"afbLBD>h3u1XfL9830>;lR3m0SS]a4QGK#4@gR)_#;25uo/FKTN)S?56&+LN8_==VXNs+I:4L]\6#KOgI1ei7ARj#CYrk(rrPl^3/cq<"ob(*K>ORi1[ZiGHEBoZY,A"i2X,t-P]K@QFr!b\ZiK]oO`XZ9Upop'p;h]pGL.#e$6]bAM!6UI5h`)d=D/6_3*3-X79ep4imhGYm7*mcBij2!3.?O%\j/;bthq*4$tLMZs$]2C/EiI'`d4o+r'$M'7N0uS-UK^q^%fi0njQ1oM8"e:msc5FfaU^2QbQmScj<.83nBOM8*t=g[=1l!T`^cWUe2=-WcpmkHa_+P^U`cajXfi;lP>]+B9_iZk`YP\l`umB,+81Z3oUYn2pr]MQug0Ym1QI&&G[ZFQDGs*=B-.F\QGB8N$]k`+QEHPn^'j,"=7'IEpsEdPDSN2\$6.egfiAY5M:7D[$-Z7X'"hiOIpPYe+/"6L=D\<<l.g(S]iZAX"E.k/ZCtN#[M^S&Ag9]JH4.Kj<+#qs+@cNr@q9k'lMu\)%?HV`a.e64nf1i)pq4GaM`?)_YL49@dP0a2(kN1^!#Ef7X!2'6t*YiCa4_)P.O0beigVi&=t'&9JK5YloPAAa9IY9);1jY*kG+L\iI4bX/Xsmt[[p]lG7X5r&r.O-d1#5jor>n(A`XP6k6Q**n\KT`_4Dibk1[mD]oofe?ZL0Pp)CS0Ob)B$=Bq:ZZ#8Jh2p.gUkYW+Ft4QlBb"e_<0fBr3!&;=Z30mcbt3;6\)OEq^p6rfiN5f-S(9O)O"Ma.bVJL3j9\RSi`7,n#fcDP/Q5lPluV3?6G:-`moC-jUbH,Y?7eRYtAL5MUhF#20oBMg'^EFA9SKP5WlIOPJkA::Ffk6j=PK>?)+<Rd=R&7SBl7k-s>*&)jTb^dOrJ\fF`ehiAbZ?Y%Sgp)Mia7jh"@<-8,pVD\Q'V7.5st/2`>H%hKqDqk$X(OJQf4Wn:+qZo]R#.T*+D(5Gn%:9s1:jlpruG*g:4NruRMNC"V10-G*jP_aD^Z+_K).ZRdA,#r23(0cEH:Eq5Z7Z'%jmUB<8a*'[u%:\\kZ*uf^O9m:ThpDDER[a]YQ8*Oc#@TUG[dWY$)/:)Imurhus'D@GqonIW\g;W.&Ug6j?S^=H@M&VJQGZ-$p+DZ%]d!dh]Q)R@:eE)nNr.T#8SjhX2&k0'nLVY)hVYV,J%a6bV+ES!P(Qa!*+`7rs8)PQOL%-GC?^K6,?sj<Ol[maKp2U,\=I#?H[@chiU@;JiRq@<&<c;gc1Lh;k$2B'ruQ57H_/c!7L\na0iQ.&a,2CZpROYfa$J4A1`s@'$O$=V-F%"?Qm/D@%<WI'9`HQ]&WAu30NOFk?0B8>K'Cn_[Z0[jqf'FZiT2).0ZP0Xfgh-oPGhMjllJHJD3)TRJ1YK^[Jk.j08Zp>a&0%R2=&lfcNVZA-+]J*kVJDu*^1L2N^;'e:\.ai@=;i"b8d&pa5L^JA]WH1gHR4kaF!nZXH),d<Q0Z[0iqs3'Z/$f.O[Gr@:ieWb/VM(fedY-0p+CqHl93i&E;($o)c=YHhnJF'stAX3W@*1Q'6tRWWY_K@jd<qC%Y3g_[_"klMi?.(1$~>endstream

+endobj

+% 'R306': class PDFStream 

+306 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3224 >>

+stream

+Gau`V=``=W&q3VVrW?p/@@\tV+t4S]]]F+@1-7KCf$;Hb+".bb0LHH]5fr&9^YJl#:t@q)S%'FA7sCa*lg>:f?/iY,=+="d6Ja<8jJ,@QO"=>Mor1_&^QQdZlW6=CQWl*RI,]E.$=HYJga-I>)5E<MFhN=\]RC#^h,[B@B44%@3H8=3di]_i7PmAqNrCQ\jMHC6(4VFb5IC.Ao[f/d_f,Fl7%SnJR_pISRce?UX8_>$`RLU81,R08U(RA&T<DT:i4V.AcX8l2IP:l9E\a31W8k8f)7f%#A6dNN25MHIEl]Ffj.s1UV;Nds6rC4`U66u%?5+p(hTE@fUA1-i@uV8ZZ)ObokK+u\4-k_d8_T$B-^(U!A4=?^p#r1e$o;YH'21>bSi%Z0>6Z/Tf3YQ:81tZ,pO&nZO#fQk<.ROA4*j[;X=I="+\<l29R.4ON2SL,fOI:UM.LuH9/\Nq06[\T#=g/3cgV>r&g$LXGXA%JK;]TWl'+A%E8G/1<XDW?aP1X**ZL8R,A[D^r\IleZ.e>c/8lUBQe;`MAU66_o8#GV04fNT:;cQ=U@LLnR>cua*'gXlc;TCobnq[3#N]l]<?J_#ZhX60VsX>4(Y/2JLIEb7?`YXN!t&=)4f=oE^-hk_fm6QVASSmU*'npR>_:X%oq1/i=MfS`kP_VQ4q7JSl'(A6nKbYSa]@utQ@Nbm2^WUK'OY4/f'2peeU#D;2Q9*d'/`XpnFjaE!p'Y?er%>NOc$@Xfl?S5*kV#V.!fgT;NV\JKfWV^U617rdBsPON9N<dP8JJ'@HY-1cXYd[B.fQ5_cd#mO1k&Y/e-V;pO^_2ED+6-<#_\O5ZW`D9UI##)G&!rhm&EA>dC0J@%ARUB`GQ),0,+k@u3^RjQaXt7QM3#Ga=I<,HG[D@-s"2fE0,H.\=QrWJ'-N$h/(P=qNDq.'?Cbhc8_&Mc:tV]P/LQHn#D*SAYbn]\,Q%_'Z>+H]aZ!AB?W$`=He($a-=Xc)@R*^L.E@CcRTsPcK$\)+rpS=)]`.5^I08c1#/B#j;M*YMaL8g_Fb.%CB6-gG'&l\Kqt`2MF>=b,UhAMNh$*@!ucbc+7AX?mNk&3#+*cNp0):d[.FT!S/+[,.P.AAS#>l422eW#X*/>gd>]cd/!;j4onkd`t.?WnE5,I$ZRsH&EjO7[)Sb/gaP\1p0]kVj@ZL'lq#%]F+?9)Vb>bBOp3P6dik(BK`udq3#,o4#ofZM!V1m5aQ!?CC5O!(NOn(8"/?`f</J^pUcJmK(^!;af^k:.GPn6Q&[b=k,ZYg2TC`;MW*<9,*-\jm^L>;?<3-L9ehB0SaT@Y.RYMr!^k[N'!,1buaQV%)LN!?]`n&RKBk$+9KP'!naDCW1@1pLEL4M;j!7'4L#1GW7U\(ZtZ8E6Uaq\10!4A;@a+XX(5Hl/`&Y>=,CK!ifci:^_B]W&KFCp,3l:h#YKbB&3Q-#WcKYtXn8)XGe4+SL!Ap;'#AU@`n4/=dA%;bm^Ft*7B+e`8"L>.WI+D:%($[0,_qbEeGKQZ\OkN5me3q3(\Ud>%R`J6G-nNY&eW7gG.)oDRU/u.sXMB/%X^eeJL`TWVNj3<VNfS1akZPtj.d&iGT%aABm"mkA30@lp&>RSC6$]"g#;6-`rnj"t^)\n`E$8<H@_)?hbD,D,j>#KFsh`ol93XtPh$+.]d\?kJGl;:hl:`ZE!ds\G@1l4'+F'rdj-4t-Tq9V&1oP3rh4YlZC@/qP3[o4WPruI\:^qh+Kepa48WB5dOSFZ3:Y6uOp?>8<`<TFR?XIWmU)t9a")J\nFU(`'PF*q2,aj'qENsmbkjhHdd+i^5Z!UR"CPuUOY<65ce_Vti$%DI[g-8HqsbWX`&T't<-kk;tei`4u<#YMH:3H2@[&q.A9c+R%'p'p*XVM/R85YX&_e-7.!)'>[[K<,raDNL;"N`uHuYbN>#!`dcm["PAe\\[-uj+lG#3j</"!g:-JP&h;o!ZPPVDg(t&OZ'Y)?,$EB1r$s=Pcu?t>hgQ-E1ri5VtnLL[33fBX%2e(D`0[mm.6;jAGg.V0NI!KlngVgfn9^DmAT=XR1_Yd#'m>W&)n,M]AbgiMZPZ=,?pq?SEheXN!uB`!A;qD%l53L_HPXKq@02u4Qfiu@53;0;Kdu_oaoBX^n*kl#Yp,`T`gd5eSAmO(H<NN/NuJbCsH]M_jW-bXeJ+#WmTQGG_Ts9:#^6sb8KruK>ak:ZfZl2&;oV(Zhs7hZTf2rmU?P["6c0GC,=YVBm:`cHIU,l1-H/()o7,pH\DrPUW=A&jQica,Ekhbgm4duV@;%SdrF`9XRDZZN3NN,gKi,:M9]bih%ah%CNbS5"Eu6tq'%;co:UeQPKU*r19OH'Sc3T)k[=n&*-#PWR8%OeV_XEnP\'U))h_c`]YlrIDbuALD0_G1D_]U<L+sQ^U)S@g"e@RSb9@etAounBNHtV%I;<L<FAI0Zen(h``__VPD8$/H"dQ=pRP;-N]4:DOg;n'e^kJN:FnL>ei<;fY=K,6?$hoe8^[2f9_%AM]7.MYQFo[IHEWs?CT^[iAiZ%#t*bH+pK+Sg8(bZ#mD+8\g[`+Pr8-*<CAhN4CWR@#@aaa_%Xi^j\W[(A6bnXN&MG7/,cZZ_-WjC#*X2BgaX0mD&)kJ*,Mlegbe?G<foJ'G;2]OsGpD]R';gdR5UUr`9ckF^8bR0)9<gue#cJo)EMjOZY9@p1P<b^+`'3]M;k=JB#dGHUl?[_eIKmpf7p%%M#jh:RNSK<$j5&0N]7g\CYiLK]1PJkZGC(&5_UG!6V\cu61*L'b+,eUG341cNb0+r69DL72:9ZRFmPhKr)G)kOQOQr&f8Q`=('k^@iF^F;_Kd^&u"k+7jRhY8HO7AfPaO,j='g;$jXs7?PnUH+QohmsZ7Uq37pr@e.P[5+Cd)6=ug8N!tKM?H>LZTjeVIP"D^YNDk.5[6Lf#&9mm#`I5)G%!C%T);#,o'WObLB?4o.sM<a=lbt5JTQ.re\_q^R0'*h]'d%TJ/1%F"VG0qQnJU69?Z8(Y")IauR-2KHOQ=&'Cnbp@c"@#]!q^;U9[6CnoAc]O;^u@6Ls+B4#/\dam(<3H3.$Z3QoLg3ht_#A8%neDe,D@VKXjqKpq[g=,3U6&g:g*7p#4R[O/H3uY`-qqaJVb2]c4SCHDCm&W_>]-QSLg.>[H[-)8fS0M52c@84iY&`s5mV+Ckp:Y_C1e0s*4&N?/3g6O%jRoSR!D#KKNW~>endstream

+endobj

+% 'R307': class PDFStream 

+307 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3151 >>

+stream

+Gb!SnD0+Gi')nJjr!/1X+7)(G(9'7Ih\99iFVEN/XE:>AmlE938Sgpo+\4-KYJ163Jfsh<T;/8r4#'/dqo[a6/nc9uiEPLF>96-"QK[[)8%O8;/#3]`+^0=[ZfTq#?hf\R^dgb&(trL'1qEKElKROrD:0Ni`X(tg^&bCJ&2_e[a!7t`OKNB'%/cO3M)JfeqtrNXUQa(S>5j)=s5;=Ti]geuMk<s[-55cU1:lD<;\iX)g!()mI;XueR?E^CQjmPRV"K_@Xr>1oqb?43g6lF`47F7po;VF9Ea2iGH+%sbhqr/>];rp;G':?bI]0MR;Tfo:Qsuh3O>f0bli6o=rtl!pTT.o/oPD)N7b5SWR%U??$9&gTpt;o+EkJN44\S0^^b+iQM&A?bboq1e/SF0IWE2idR,="?ii?)o"@2/<Hh],",#1"TI>mB]L=kf9LS.B&RA:X,dl*h'/6K%P^b\=e/N4/6oXk(oYXE^09D!m7J9qmI2?F`$S^e'';2EDna><4BOnifS/n9l-+(8V'TF7]QVC:5<*QrQXNEBhTZuRj&!#GWYL^iYn7_=XiD%n3dj?8&e5Wn_7^qr7X-XkrFi'ij2_/D4["O7%lcD67H$U!%.huJ!/DTl%L,;U(95UQCR4rF&@EWYZSML:TY2i=/i=1Tnaiia-SL9Ldl-d9,\7'=^TB&'W"%JP[5!IHM]-_8QCWR`]9GlWn[\orOBETEX;G<]A<+-qUABQSnYbaCCJ1gPUUe4[Ym?^Z3MK+Wq%N>^A1(.::GEZ@aC%Ae>.'qD]rV%-^Eb_o_""sALY&?/7t5P^t.`,pce<;BW8*q5$bGqhEj+^-V*r)cUU$;QfA'*S"#iG(PH&0?r"Ts`iq"2'Y!1I1a$2SbRAOqO>A$rYuTFT1m$g&#jEqmG=nd(7!drr(.b3ZKM1TT__U@5o->KB">r@X<6#+q07eUMNH@9a"pO8bcgReagDU8bQGgFDI("J&76-P:hpNB?-$+[u53=Bi*E0ZjhCEZ<2+lV2=,1PqM9n1_K*BB=BF,c_(JHAe=J!!OSN6CU[&uCa[B'#l=Nu6T;C"dJLB<g!B8jfg3/'\EG$c@(nTD7f@L2^#%$7NQK=G7fgp;[eU^i[Cq>"JGL;s*=l))9\4uWkWf8@X?SCE_(9I)TiFX?s1`=E?jsfi`fUAsAq'K'[eRA"h_"/:jiO<Z3N)L1NSrc@agBYi4U>ltAUOMV8CECd^,7+[QO(5#XH05u<$f6K4@B]EhLGB@*=i6!oa(cQ?Kl>eN^r$MG?o\7Z[g/-lU#$ojN^e9lA*Cn^:-:tT#'O/`VoJ-X(D2P/hHNMDaY[C0B"[W',RtcZfsi_5#3#[%$<9pns>CDF?+dLn9CtQ/PhHIT;@([d_/mie+3!r[u[lbN)(7MQ2\KS[)(F3EAa/S%0iSc9/cUupaKC=Kp[V.cZi5YV6X?4_5"f^(7p==5rcf',F]33^gV"^X?N&'Bn^r1R]he`aW&0t:K+dJg.ms`WT0-:j?I/<<1b[CFW#Q[b!]E#!Y"-j`\3q%A5.8C\:I6bCE`Iq&WNHdR$:N<`!-g>%kTP14hn=,-BO40//tlE2Vu#[;c[jr^,@kVH2DIEc&_T0%>@:-*rCSQipuXIP-\V:ToIg7Ls6))K$(!b'HCr_AlgZ;P@@mS$@Q4G)-f2#:hF_>Jf.g44F@o'`\;uan:4gkMWT\R+3%]i*>%F)*Bo:,>gq>FKe+u[nV(*SL]G&k+%a@n=d4cS@_qn>1.nlM7d?#f*(Y5r]&g'@N/O%\6),1Yk4!FOjC+F1aEeT3r7jscL+u&3LU%T)aIsR2'CIQaJGQ=.*@9d-^?B"MSiW,BAp)?>9(o*"f]j?&Qq`U10t6o/Zbqfbp%/1?E$Sj^Tr(3B7eD?@_W*HBGD&C-YD5\?-7P+s[E&lu9Q8rpH$h`DdtJeC#G5uAXTBFliorLJqCCjDi:Wg#f<RFj355B[X$/YEL;$:,-6;Sa@;EMn^[P;n/g.CaDqSS8-Tmh8eBWcVR"Wp4QlecV6L@SuhEjW7"ng.L*7i/\!lRi?BfnJ%a4/='Cg#"71s+YLM9s6*q!B]'Y7:os8_GM?oPW:O4jWIl]J\@M,9+1t6h=r/Y%`e@"Y*F$UIG9VLu_9:HLW7TR9e=!#Wq%^G*e8I*@^O^^Vb9o@cU+aX,a^UO!i!)oU#1(_p0I@\Vb)YKQ.nMchcLoh!rk.&E84ofkuH(.GM?,qcs#k(@,5SO.P^QHp#X/klKJpr4PYVVhe:0+<p/d<ZM7FjRee9Oegsq-Smpu>8u1F9$ACjkgh+>(DjPui?l?B]MhU5oI"sXS:#W3=EW9aemVQ+4e(`@f/BR[8Zq]un208\g[kpH0,@-/5Qm&!f*&(f([kLKnAlaMEI05f`lWQ5(Ho#"U]-@YYi"`7KPgfE7RdE?]D#bXim1l0%$1HX%Q\Zq_Bqdk;+?FXYc'i,7Nqkj*6PY1&]rb6E*oBUp)[+6ebH'Y`<#4q7!LIjegCP63Fk<O;!H"mD2Op$e:s/tJ0Kb(D/r&0'5R)4UVQRE;HVKFW"-cHin_9qUEt=65`p]gOb+2f/%$gPZ;DQ1+p!Q@b-]8&'qSO@G8^XnpQ37l`^dEb_Y\^X)#Aqt7Nqkj*/'@ePk\@[:!o/ag+X-G:ukHM9o_bm@L_1.'\M80$EG'eeY5#GIY6q-=BV,8\O`:e-\mOC<,,;&@"T5b+C-Tt(U]>1e0ic(N<W6s4d';Rm?9"&?]8>TGo9B.+C.qq1LK2SnV7J9Wjc`>F)\^h;AQ*%nA:Bf[_>d53tLCS<;W<q_%r4N2dV6&jGQHl;YVAi83U!D=1qQ`SUnbS8m.B2_$a&3gA4trm6$J?;<`^*"C#DT!PAgd$'/.e)I\'&bcWE@Wh-2UaH5qL8u"pNJZ>V`XK:R?_U=CQgt%WGIbPFe/`#SD6OF.)Q<BV[2G,a)`"1B23R!SJTLPZ/<P;UOAMrolQKF"(D66./`JN6mngb,13A79D<m-"baj*cJPrd"q4#nsl.nIt$"`IIH>pl>2jYDH<gFLkNON\1`4FrXU-7]F_YZb5mQfShpT2\JEj)2N(d&7Q\;Y>(,Q.<NO==OnafNPj9S^U.(Eb@5g^9B:s;JT10jlI*lVI..$,fC8EHPKSGo4tQU-'E)$:V5!.2ua&mKGOI~>endstream

+endobj

+% 'R308': class PDFStream 

+308 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2527 >>

+stream

+Gb!;fa`?,q&A=tks3RUc,Z?TG;O`l?ChFW`ZIHg]_c5_!OcY55";lZRUA=ZM#!n.#/38u*@P=u\@d2L(IR$+CKJ%_.mb]u-\/<,I=!<5/N2I6\K0G7O_TVJe#@H7fkaN+Z&4OEKJ:0>ILN"/4c[o$'(IeL/5(%mUL@ms0i+tB'E=-+ki+j=)AfLsVR^26CbmYX&+2dk0N.6&Xs6783<58@AD9Ss5Vm0ptC'6K]P?3/<]+.K`5Z7:A&VSSk/KjIUpDB,\4"*cK7Z/P=2Rk/g9S1$^?[fWk?Ghe:0Ha"`]0VcI_U`nus)l6UkUbr*1&i4-90$YfL#iNA?@\V653M%"T,ur!<oc;Q3D\G::QP$'b@/C*2sr-'Y4+WD3#BATc4(#5hb&O[?OC4db#N=F.lY&aGV#^9L8d'jFucP+0GRh>-hVHVCWs,tS5A;9m]Yq2]`0[?#nC328S6Fb4O*F3f\?`i6^p0.:QL._6P.'Qo(-L9i/g,lYl41RCN?S!XE*/in[msN,2nt3%_@)_R!pr"KJ[f$V/50R<;h$P1g`\(B_0dN_+qbDRd-2Ys1@5OZg='hG8=rDh/0h[9A-1&b:RB<%XAI[eZFC:+3tAAHGOeM]kB@TH9i8;!k;,gAcc6&1h4(`#V#=E42)gVqqXDgG/2071stWtUkt8rL]OSI?m4.;ijmtT%T7)cjm"\R74+-1"?)Yk4UB:+$."s..puL,7I6UKU'OG:b@B-LiANT'Jn&_\L#K=J)"#c,HOektF/*Qr&rn"Q2]sct[F,9V9NF.<6Gsj3MC-`$e^PBckkJb\'B0b6,iq^FU7nQp]-8'&#r87l,!fsB:q>X,+Y5=%6q5e`:qo`J4P(`9#0:rN0k;_oAL\sbNLL2IKM"k/iZIj3(1M+h\d>Xdfg=UB8=@9@nb']>Q=l4s?ZS5]:Og6E%g-)(\/1[=(I5B_>$F$I)n!-HOO4=l$sP9+gqE":()_!?S>?qqcP2+e:PEho<(/jaf\tBr'>!>s4onkqJ/C/eE2hfJ&km=e!\s[N$)?B7Y/hF^4OO#f"Ob0HG*kk0U1Ub:XN''OJ/<TC8Mug0Km2^0A!14I>cYANmA:W&'KI't.nnn89[a/gE]MM'ms%=t=apB<09JmIqNZ9_*o"k+FST,^-0Y9471E7g3Z;t8RB8.In;=O8.jJsV#>?jK53H3V"HL;tmI[7rRt3p"^^$7f\\RgXg8[l"OC;s&=X-U\RPBGRYn8P2r(P$fBSb2RG)$@rqEO\X:?aI_;X,P?f7qOl_F&fUF>\'@bC_9cm)nHQh.Zhi4fGT7)l!9b)V.,!1c9r=0-5NK7jDX\=g['^V/oi:l34XUE%,pWdiN85HR+'T/D:K,QWOm-L>"j]ikI%m92F=0ToSt>%Via6f!rMJQbERUiD/oh5G7j9\384<ke8D0bEN=d*[pG+pCl_*-Lmn^^81$aq_Y&E!EJCkPLl=mGhsK[pZu4<IEMs4cgS*moU[*c)#^aBhpE=J4j^P)T'#;qcZ;3J[ccO*eD44)p9j8]W">"1G!W'/('ta/bQqM,=su@E-j;S&RULX.j:i47[SG>CXI.q%*R[SO"3&EGWXGmXN0k=T\h*2m*VpZRRV@uWU]W&MOW_Lf(5I*tdZZ[q\69KhOp-V9D@567?Z#GH_uE/UEoe4*J?+*EM_E4EFoj/%]nCeV6Jg2.K$mc70lqt1)?$C,96\9?0Tp[hICf-!=^!bLDstt#PEpDf%VSXLm92(Mk+hAp7;oN5B(K$RkXnk,G+n5EUUo;nFpE#(fc#/50LnWoYMV((XtXU(]n*"<$*J6Uhg6;Wa._-L`u<a6#[#SdFe3:7PNKZR'G4P['OeeP6g_=!8YK<t=Mm5nm=5A-EYL3GB6"6D%t992*7Y,_#BZ+pRV>R3iRtKRn'Tp/Z"aJ?]=m7[f%q2gec>`-\?)&g:?kMJ2bUc.kYs>F3?phbN9$:*A,$bK=2cJX>^M=]9:7'S+K=YSGmRPVRa,(lg/>O%)H::VcEOq2Kg>ekH-r$kbKDRe@8C#LoB1mKcug0D?L,F$i`Ja5P0^WOQ-,r6f<4"%chGXnG=49sARl"/aXQ6TA?2]WWRJ!j9pP!$ZaNEhDpm'mQKp!"Z+^-tW97V6BV[Lkq5ZgR`2]P(oL2V5[M5_1[fVDj$jkZ%AERu.f+=fX?=)&#KUEHU/Eam,M;GZ>Eg(mgALXaJ2\[^P>+gMW<7IplD;lO$8q'<ZCnL:WE:h$]IXU8K*_j$[qVr&'+%G..VJ;7Tr@f(sfc+8Q[dNI@<3>G]WXi(j0(0KWlWP^NXB^;aqnd$4`6@@*g+f248`s&lIQ>.=n:#d)I<e#*q>/"L^Kk<544XkEn!ummZX*NZJD]2%](:-BiI;4BgON.pf\W@jKEdI2@+[KR@5GKkVsKgjWR\(Fn$7j01T&)T/k(fU;:I/YN\!qK7hZPk`h.R#NF#9Pe`D\-`4,PK;Jr+H:W"9VQ#Es3\MZ+@B2eoAHd'Kh@,gVFhQR.cajdC7T>qStPM8fr_qPa>_[$2Cq043.~>endstream

+endobj

+% 'R309': class PDFStream 

+309 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2436 >>

+stream

+Gb!;f>BAQ-&q8/#rkgoLXc8.dc0h'>8_i#p)_(0EF56"F,U=NV!<iJbW5$'Yi'ilA8!K4/M8lhQOT_nTDnfR/'L3Ue!rk2O!DZ/Snl5ZU#bq\/?.O_W'jQ]h5PsMK61K3'$Xq*\4WLeO4b1GC]Z(0C:([-WmeJZ/25h9/YbQXX7O\H@_qR.8XZ0]O>-dOFbS465(GP[cUEBF!^\QKZo$)+IKc,R"D^\>i.8>SOXM_UX:6"CU`3"Ybjb.[J$Y$9^fKT^F;\:+#]-_d#brSSc31<DP+3qE:9AoDe+sZNO<YgWbQCnu&R=KS"h*d_HS;)$[@3gfl;O*^!9r4DN/87cbH32KQX/W<Go4_gl`-9uBcj$SC3<*<`Keuu03!CgleN-R4d5!nEF?2p;`ef4J/7aET?,%JAC-m18Z8'L-]3%[YlPa3pW/`"b:d:`<7WKll0!.Ja`I].Y^i)KD`PP)6N^\m_<O1#0_t.4Xeknn7H[E$[IdRB@o49T[XPN49O,c,g)RS2UG`[9[c]/2E+:B9p6aFVf#)-7e3;N4[c3dLm7(Qr>Bm[l@7e$6m>WrA>DSZ*7",L9)`M_pP8B1d*VNb%YEpYk_(@i\<>iBUai$C]tY-EHl]tKN4pR]Ds%H"trr$+l\!fNhW'jP"W!bQS(M-u,=@mJD-,:hj95cim?JXW'A-CortAd!`"]-`EB0U's'L/]_d6H+bM1:T+;A<J5fKo7(l/M/HHRF6q`/e=T\"roXc$6t(Rb0mOK'O`@HPtn18VK-O3J8?R&@ck+AEdDG<?^-9nB=p8)je09K(&*>f^?UqXBHbIabHkR5+.g,,HZP"L%%7"ZMT72R[2<.D:p/S1+ObT[WmDmECN4_Lh$d<X,`la_A>E67,iV*9]lYrUoCi.5q.d?Q((]AOU((tdRq%TE]B0.I)hcrIngee3QY`Fk,X\"$S'C-M30-%PA#U+["[1pqC9C:?]hOu=8i^KL*eZDuO%GU/r^Un6DM(6HLInSL&YC"V[G[@L-_<!8ZY#d*1dDUC$]:l/'-d>ZC#K%I91*E`F^2m&_!j-en<,B(^qmPVq<%8A70Q:6E$6SR]*#X]_);@C(fK8<*?.1ULtb&BU6Th4,#M.U[k5^`jCWugGL`E,.0^4gA'[R/"%k%37,q30GQj.?R%QZTd\-%A3ArjsFD2pR)>d6JDX3tUPN(HQRR^4e0ZRRi0Z!p`/5]f!PNpb]RbP4U'K#"*QXL'b*5Fm]s*97UH-S6?>BZIW,\G-kJ)OoW*)BR&F'#a'XM<)c0C5lB6?^l0"4pRBhl<WjdT@Vi(W';F%-HVhQ=67"\pH9dM=82,6Pg%M).niKF*1g_N0@1'&P>>GA3m;H(0i2V=J[]f2Rgs;SlSnD=CN9dF'q`8!K462)0GI^^V:6/?Wen<#Uh`"g*9hO91TK+Eq^en2TYVM\GM_7=67WZ\E9VT\(fYAqS_G,+UOa*=_*f)\#\<kpQhgUgD&153G-_fBTBLQ^2h9%<&3RW>%MsPj,_H-Dtj"70#OEJWnKT.2qGK[*:@lmj'J+QS:]_idhE+/#I&CVa86k=J"uT7`W*[)2Sr@sZ&A=C\Fqf0;<p2-p#Dn.WJlr&e43qj;80NIM=j"^s8)"i\-W'p];GSWD<ibh2m9FC@L*!Mmp_!rnNP".[mG>s"Q=5F#e-+<hm3VA?=2gj(Zeq2#+O_$^q9t?]9?MoJpZWC-AE%':(<iAW$c(tF00G/]#TapNZV^mXJ,`M3l?Bo<RF1m=Y+\u)sr01n>O+J*)ZDbl9S<K$p;Cfe2Mi.<<f#-V2\oc50iu@pW-D`>J%;qlDE4H8LHPp3@oKP,Q22uDR:)QY'6&VR1#Qf$>tQGTEg,)8<$&NFIYecm:79YP'UlQQ_4i7[Z_,rh8X.5=!0\"l`_M6>/aU=eIFL9LS+%kDr+O.V=g/SP+Dd*L*oRap2\gB>1J'pPLnM#l\@3:`\U!(KqblC_(4F1Q#qu/X]AbX44@>!J0P.%:-CH&^AG>S-9lqWrSlX_^nT0)1g,E,Oj8pSniI9uS`n@"Vf5WDB\d/5(@o_T6uYt0)<]pf^$s:1R7QI"\KqB\l."Jp!H'Lg*s]A_#(MI!'2NY$cqi='./D,3YFe$XH-m>aL7*a4OtakW'T%fF<n@s$rem\hFD/6NR[SS6@%)H7M[ErKisVh\l1RWZh03?+;*'Hor*>2lc!GUYE,4E^r^JLpamr3f9gsC/8(F_HbWj:W@VH+<B!jqFLG9n$_-3pdT3]mhT6SlMKh"V-*$pg)"#kk+9P)(8Z:%UbitC=h!MgR*7KFu1?])(3,Rt#,%Q$^t:=n`M'ga1Rpl%\.(i+`>q*Q-(ZlmO],Hj&?T5JM9QblY2eZ%t+;n)\EaQe_OTQ!\q6M!.2l`8lN`94j'MDht3jW7$A3s7R0N;r<ILq5/,!Ud5?1s"YOZ[VsU6Uo<~>endstream

+endobj

+% 'R310': class PDFStream 

+310 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2636 >>

+stream

+Gb"/)>Ar99&q1@Qs"FreN`%9@;'^9E3@J:UDW=cXgIOn5*;*`//u<E0$SQPM?f.8WP+o+V>R*iY^kOF\Qb0T]HugSCkhqMqr]1(q`<=K#2o+Xo_umnd(/.2:20o&ZKDIH_l*^cO0'h8:cc1)0Sf?cKf'etqf7po8:N0=/g8N=%4W>^K(^@ld>b?3+1Rki>W1RT1Xhcf\quN""eaC2Nh[eh(?ab[QGIk.^1MQQ4glTqM0XHUtPD+PYcqP_K_JLhj(e8l2#`q@=Ma2q5cX[_VSr+4;SGT@Sr?O0i7-KLrL3!pb>_W<cBRPf-W"+=N]if7+id)Da-YDgY`c.Vq;VW#9.`kj&/qh,^5JV,H$=T0M-[7+R^*j#!iGPf#$9sE!K+eE.+r2@rjUq_/Ba/9(1BCgHi%XS#'/s3nR0_Mg]<!)Q,UqN]*Dbmp9)^X_NqB+LH(8K'huV&Bl+7LP,mH-#M3UcRJ[UYM0J4.#^;'O5&P?m1TkF&e@HWBV/VE^)V=#7f6dg:Wl@T2@WR:/b_+:SQBssXRRUp7hNjJ.o$[i1YqO\"VApYi+b*dbt:Bg#WBaS\*A4EO]X\CI*!]="m\M/b1X`^DS)4FR%`H7Ni@'W%dlK)R?ppl<[_Un]W77O*Co$AQ5\1b0'i43gBaV4O1acCZSX]nmESWU`H8;a/)^K$F3Rt6d$=VSqAMkd%ae-pI5Qkuu_ma,p92G12?1N=2b[k$NGhbJ_!\>*5B-5LtX;*6s19u;'n>VrKRVR<+_2mMM08"]`Nr_Klh'H`-CO3V30h@#0*#=q6&,oO"$[]5t2U6[QaWUptq9NsEGZVKDIkYLI?r6/anR'oI>bWigl[kB61Ho#WQ]6Z9I^3r.mp4C#<DI8urY)4kk\!L0kkqfglDOoa?Mmq<5bNUgqF<72\[>N9eXf&:n?;5<,D=HZa[8Zof3:A)^rsm/'l92IMOIKo1I0!jGnO2ZS[gf@"^?jgO\VnlSW$:CLHE#UF(t%`Jd@$65jF/^R<nDIkEhLpi$4&a*^i^@@2j2-$oN4u5PhoNI.!p"m\iLp?2)Y]ODr$Thm(dBFRIM`$^c'^.rD(DEA9nRTpsncdd3W8eqpCt'F?R@WfH)Zm-C&3f\=G#YZXedidIE>4om&OCd;I_(>Hp^C4E=`]&YbIXYEW$6JP1<0SgS4)IY:S/&k]&)c1TOAr_;0$S]rB7?S0qNcVlTjIfuR$]7*FEY:guLk@nF\h7PAgK5Z3`qBU`sNHboS%H6<;!Nm#"GM$F(IdN:/j24=/.K6+Oa-?Nm+iWicprg#mc!q+=\dCtOTNh_E6UB.Ts!nrZ^9ll=OfB*KD8WRrd[U21GK3R\.M)eC16_h$o"-bI/VC(99dteSH@&UN()Z4!?Xo+`VNE)`V&4D3>837bWhMU^o7Fds2Qml[L#(7H?uuWi5hCA,Z8E6`/nXb,<tl/T)t\.KF3K*;TMh&SK><ANaRad/6_da/qYCd5)kCg\2b/.$S5PZ$C7onZl6a_g]G;C?UYng6r1B.G[?RhMoZ-DCj7B&@)@slt2dfu&]XGrI=<_"@/cu#SnBOHj)9BL5m61TA]0fl9H,F@6bmt$&12Zs8L'9-*M-cc;<nFe9r!'/l;6.GD-B*u,"q?2Qe#MikFep_#n+"q.U`d6!-[bWgq3(SD=;WEQ>EZT^WZZ@e5o\M@hW:d<EK(.n8)[c\gq/KP]aH>(#.mJE?:PkZ(d'=4$gN0UXg12.[jW+ig_=@_/#cI0:g\j1W</"K'[3%0^;Qt\(+i^!5.q/r]gmCMKZ1u63#'YWKpf`lN%#8!iZE24an@bl@u01'jVd4=Yge@UKuTi8DVd'$LZX58V@Ug0FEFCqX\3Iq?GV\Mai@.#j/a(HF$*O$*7G)A4E-"pF2'\XeN:l??_hC=G`[@c@RLb0S':dFLl`BK'*;9.Y.IYIcMa:L'lA@#CAmR?(OJd/]=SH8afoYoE03P4e5LXLC.Dd'8a:X[(U?.#/FDs*NCg8'19ono&c'N1lBq7/KJLi`#Vd"_F^KuaE(1Mg]Vo0cp8r:TrnBo_P#qLN'f.W(/4'a_o+a[7#&;HRY\<Y`GZAq\n8AT\6PlPFGTirOHf[YZ7If1,hs/gsmCJH>:*N:H>[;p(`-i]uKUSLu^%ZV^of:ae\6P/j;9]5$<+.=Wh\:lJ`X+Kjglk>-c)3YTgCusHV$j7D8>qR6SsEiJgE3=ho-8F*-\UtVWHnfEZ+Um3XWd"5NuX/jYeJE'C$TX['X9UNp/PnBBPHqI<B]TGF"J!/cQ/i)XM?bf_k#fRZ]p9m]JQ\m<g#>D$+lMr"_H0_hQ!eq)U2Ko?`V&mnMLMX%(Q?4R]lp9B>E_8%rD/lXU)[BKO7,9BOJXA*V[JVle#6V0\@r[401[5CDuj_OfkX%$;t`l3&X^h\L=%iA#B:16H?kuFjSe+%bORlU[=uInIZ&uTM%>JeQtG^:IuqACdfM/X^^A8Zk`'AH%<k%)L7^hA'lHd`D\dm$0GUrB#U#(4(r1\bt.6%m7du-lA6O$@dC_&@\\QoB4,6\T50(p7A<#.D9"2>a"/*eM3QQ6)T[?0Np5'$8XGoZ?0D`Wc^YG,2#?G,\+UGjK,*NRCqU"85UoUdR<0-B]Q,1Z+0o&n\-FI-qW'<o-5S6~>endstream

+endobj

+% 'R311': class PDFStream 

+311 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2626 >>

+stream

+Gb!Sm>BAOW(4OS'rkk/:XHScK;-/,!fi^8#Y'6=-CSfLNH647BP)tb*$\39)^OFK08<C,nMfR;"AB,UL";3]'mp$IB!<6O&5KNr?T>NUk@Yfdn?U?l8`\@E)?HsWWqV?SZlLi79L;R[__*'mG1%aLP/Xd,<nSeQ]O!!>[E?I)r:8\bmk7GZG50!2Ni[gN0aas?<.l]P9$M+c^J**^0j?C?1?[fT.bUaf(pG0(m6$sHeZ"'Irq2@9>jR7J8EYZo4N]#gs-0+CPH5RZRpWNJdDa_GO]RG>jLGs/7^bX(jfJSFX/:"Nq1(HpcIMeY4BglJr/V-4(2#\mZL7>UTVa[pLQKO@.]MOba$We^Q9\-uf>]NR2H>oHXYn;06KBGj1I-I2&)j,0sX,V)8D%^,;]uMHY$o/Z]TNs,^0_$"iZ=elO^tUY3Z=\-rSJ?%@gK5e$VGenQc@mu>abOPCn(De<lf_IV!B>VW+<#BbH]I[%L"[*hN!3WT.dM&Kq3jr$2EV%ekrC@N.i'<raM=>+bEo'0*0KoAIX1T#/1qeo@O8uk,cECF']N"^V`)t5OYOII3X>Qf$bg3lTesq4[;^3u(8Z.IYUk\6&hb5CFGf2b0l:Z#Wj>-#A3<?nPNO>Zc:cFN,QcT7Y2-g5R;+$GG[#+nQ`AOA#P<WZ4L#L2;WNR'=*%u<lp9o5dO&Q-LR8$cqu4VP:mq_JriAMaW8J*u)-`csD?N$h(9Z7/=YCI5$b,an1Yb9T0Stb\"7]Z&@giX#p>-m67ce_ONDAr'lZ"bKN2NSOHU*JodHk]3OlfGZ:`IuqCP-I<9d;WIG6)VaN`K]SE1M9ESAe?QIrOZ1(0tEjD4dZI13Mu8L\uU3(_Y3m+j$*;=/j/(1Wp5r`1]?U9-JQfMlkb-:UE;">-0X)F!4VH@:1PS+S;]7e6C<LFP8+SD?Im\;.O?Y8*<o02Xr;1+,SN"O^@(a(-0N;lL<g/`0A'Z78Q6i?U`b=7a*!Fq.k1!bqSM>&#:j:"+3?q7F/Q'3gh#*itj<4Vdj6XNt0-a032+Pb$u^9]K,p_Xic%83_%hJp=6`)7a1(W8\Fe:Ho=,ur'/ij]Xo[0$^kO:b.C0tnT9-m:quMfVb(?_6CL#+HLdK2-l89LZ7YQA=<4(FZ'<%m8+'>UTub1ElY:Z:\Wd>?DV$A77`m)sWh,TsjGTFjlHps%C7\o[K\P:?fG'!%9>RsaF>'`8j2"SaiiB>I.lGWPe[A4%Z$":!UpjW>el=/%b?+G@(#="_?uOiDYR#D`/FKDsW[d#-n-V(JWiBE-;N386LIO_YD,<70DXlffe%9cq7$a^Z.uX:k9l"LjEWnbL/?(=FNoPP>^3L5FY5e?Oh;k^H"k,@+6eU]eg%D$L1Xb-td;4%U[J`)pof5.F9:o"YKdDF_[pZ9i?*>VP^K&mVncW/sJp_6-TDX*h;Z6g"H2S>%5Vtl##7;REao[X_/.]S#eT=9"JY#B&@o3*2dcmI6_6XQ5?WYWT=6$5e;7Bdbd.@Sh!&E\2#^;"2CeAkj+Bd8s&p:Sq%XaX/1a+An`/+Y@2sH'4.nCi)VN^ZkIg*5)[SU#kD[N;t*ET#P0kJ-T?ZuK-)'1T%g=IWrDc.LSnlB9IF?,\1<ba,m/]Ls'X1GH;<7IH#9<L/*(,a+-;^ANLQk]R?C3Pl'QJH3U7ME^eO[T+-/h.[8Jo.@6.c\o4U2!(KBOi!*qA(%^IW4`u<47l<7!&Qurlo96Wuon\R`;j+bk(9aC+6[g9+.R.S>W>/O]Y)n$(C&5PenfMWZj69*J5iD6%>uBP90nXc54PYo2C_.`YOKZ?996@ZLQ^-e$td%Kk;6?83183CBV7uj*r8Y0sV(CMq+=H`u&(mPoSIq?B&\.SUBU$:@M94Y>4dAJ#clbE'(no:">C\3<j&*V:"XMaV3Ef1Jf_]%AO7Gb9Tf@:^3ebF,dg"Xu;f1r\m^Ni\n\!C'q'kFuUK#\u*<BOuuDlpLYZ#n?bcOW$VWl3>8E@=_9:N/k_UWeBrN]H.bqXmBuOq[@Pi6q!)R3Do>cf)`PV>>=JM;%3b;uN,$11<L?69OB(?'Y*aR;()SQ,G'65jj%!:?1jZqMbX#qX$ZL%-l`$ne$9IG1Lr>@qf>CJ`0Om=\K(fK@Ols"g)Pbf=cQV.U.&S.5]0m7D\NS%ZIA*WYB"^8RHJeR5Z/L]S7C[s)=6,%4<dWeIRID]B[4.7^guQbkp-M;gMR?LHC@,Mon^5IBg791oaeK5^7p'=6+1SZQ9V^KJ"MY4Z9:!D0QE5eQEMq0Oj*3KLIL56\rqs[o7hWG=8JI5*lSKMULts%TI_%kIIqN`rYeL+N-J"Cb?%b2u?p)Ng"j8g`,J<rmPL@$HJZFtN07UsN]@^<T/dtFiP>Lm2:fNp%C9Y7;qT\9No1^e7b^EU/_B>G'B:dq/GDA[N3cN.9kJZOF'^FsmK*d@WW[0q_;;#Y;)l9:QqsL1X?2%:/]0_j'-9r)GMA<OSPo;(QB:2*b@MNT#_h;V6_lphQ5[WV1l=*T5\'<e($f&YtXi5#q\5H:%>L!"+X%2Y?*'7I/F1XQP%^/SP]X?1eWl^\4T#60fkfV$)$@&/&8F>s*?u#^8J`S_?pBG]u7GV$gN[sVod=22T`7n)~>endstream

+endobj

+% 'R312': class PDFStream 

+312 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2892 >>

+stream

+Gb!;eD/\1M&cNgos'ah=9a[:9;Ueq>PHWU#!r+BlB*F'bl%^"aP-u^J%!QDSs1U9VE_4E:6G"t0,"=n_q_C8)bVRR]Hl1lcTDspLJ0.h]h;<YM"'BEU&%rNT\+$lWlW9_Sa017o6O3a35/fOqpHDjZbr]i-T(p,9p9.i^WkR5$mO`$L=JasQ*e)-%BudbCV(KacVqAj*J,C'_s+]'rH2HLokB$7agT`VWJ)UpFk+#lZde!D<QE><CDR-e!.Y^%tG,'s0<#-ck/.EGe8r2S]9QVlp\G>g2!P9!\7$?b^qZYklfP,bp;t7uhU?5jb9VF:&%q!Ig,9lBgO7GS*&lb;I16n7B<p@iDcQDUVNJlZOp:A=f+fqK9$nc-\(5jAkO7+SDGakWg<Zc6G#0K;Cg'E?4q#sQk1)[tJhsJ)bZ02F%[euH$#Te>Bi[m:MK0N>JQ.?AQ.pNPg8G2NIGHY@b&C/:e+6&-/Kt!R)n0*L)\a[Vp<sdZQ>l^MZpo0^mn0VT@qsh%b4!nHU1*fX6,fXkWnM240dV5j?":EdK/cfC2YDPXbHlK,&95rguM;$&7&1+Ua:g>-h',B%?6c^Aa[%V'hl6ah-^L'89=c(<UR/Y3iW/N+1I[<Nj"_)9.0^@!>R*,&NH-jg4&%TpBNb:X$2mSM_5:'4cr[u"igkmkFG.;8,eER<W:`nU<X3<<K)9E+o4:f;]Lc?HlK9H,_<cUtZ;uM7/22=)o.55sZk)PV[7"plYnC3gXT>=>+GUrF"fb!"$jq6UGT5X]0VHb(@ChYoN,/Fd-q@nus#It:uoDGLFb!Tq/pu0\+%rOFLS"U&SIerR(p;\L<YV&pbY>s_4D9<idb6%6Ja4V\lBFV[siG=)^l"m-'AKgA!_Wgj7WfW?;%^9#XV_UG@@qX,6B3T]inrun7Xm,M;7Gjk5p;j#J#h5`G<Dc;YBI+Qh43!?@^g%@pTcXt08:Zi5?n1UF]S0sN=_6)$e(3L*`MK'FAE$NnoE7"s6NZ#c&q/]S0A<F#_ahVH$\REhFm1rS,.E?V/nn,$1N0Rh:BqO,:`7[-T&Zoq;B[8L*9s3^%K.mb"#u)liB7.7foLFQ,StPgfM+seU7HpDPR,_Thu\P2V_17)pL&"ZnWtL]qusj"=_n@cl[m0;YjQ=OQLT_S`Kg_ZU)4BQE%rH;0Y3sK/19;!#3"2BlH"]NSKWu7mk.W2fogWh,6WB^`,^#m$2h9&I1sYYS4:5ofV:)%X.XHXB4=5sNi=]Z#sQoG+L9#R`u&bH@&"?dKs[!:l"q+'Qm5mX+sZUjU)(e*)F6I^Ne?Tso7Oh3&RiU!&?jiOi,rc(jZp="+Zmj5f.A=^/02#m>dij0?+=pDeWRb>IsiI*S_7l-4/GaL;<Y6u.AL1pQ@>:,_QQn?8MU$0@JrVhdMlAs*YGM1`>\RK$+Vg\^G&#N4LgTLBF3\a2Yk1qPkZ6mT1ll]MhAYG4e>C*DjcG0l1tIAKCL[Vc]`^bI5C4bf+k<WbjETJ8"]g7)Fmog-9L"!'>5/QdpZ9]GjnI?Z63m*c5-/16/i`865S`O76AX583.T@.'l*p'-*=2MQ#+;hGaCoWM,M*Uf'7G91hf=7][$,Qj;*&J_R:`<I,!2%m-0DaN\s%N&!\qdd%o5(oKK#aH@R?9\2Jaf"&rXXWU#el?u,sXaJs%hMKc3Kpd):Udd"I".!C#2a4Eg39oc6Vop?U%52qOmNJIDYZmM'G7dU.G9F1YnJh4rEmbs>M4E*),-6kM\[IA6M[gpF1Eq"HL;R(gcV*RdH.fXgAR"';-=[99a1*1D)jdV__DGN3Lp+'(^cXaIbYd!dI+2CG<Mlnk(YJ2\A7<f97k)T>S61?J9tG(UWakDXhNOm"^EYTk.RV=D,Zl\P``1`7nl+<b'1^O>C]n>TXQ<2>.'1@05Ib<TenGS?\ZQBc[`N?DK$kq]lc&S):WOYCHr^G79@]Ym2"fN`Pri]!-4u>\etkNIR0Ds@-4bN;oZ!Uq@gWPITa>jU/I?3Q8VG5ubu'<`fZoH\l5RmG)RAusL:=0H&,KUUZ*PlI.egNa+7X=LjPkAQ0g_t:dN*UXG_0N%_AX`=>+pXq_JN^8$_F%gr)qr0a7EX/(m'$LDr!Htdur]r&XJ)#53EZ9j3sL/,GQ)]dOG1#:;O*+PF6#Q+uRj&26mA81Ku!8S)YI')LXRQ;2$D"Z(ZIs@#ai."/NnY>>0l,&<%DY\"*\&n>b6'8%4]Tp08d9mX9lHjn46]C9:UOU`r0ko)q11rl\Yb9Kfn^mbeU$dp,`2)/Pq[>WeS#H8&VI*VN>kRj7G%:G8Sb7:O89@sPXHEbb??g0sG#pXKfXNuQH@Fh&9F9Vm^sc\3ZO2r"WWQ)]MKhGdmjWYdS/GF!:^2+o6>#bFX,QT'kG6&sYX)i]Yr<QB9"O7']R:^?s7IfUF4%OSN$(mk2SQ#4jq_GlLaN,<do(PIX^k6";CN*qfF0_T?;e:odinK<Z.])+H*;-,Id2]RPj67C6Bj9f=ToV]Ma\@M2lQU>Z9RWV#Wh*1e@a9IcAH*%aR+[sr;YqD?Sk/`Z-ipN<>_>g&Y*[*ZrK\;?Haca[%p4"R5B39=3)u*SRci)I&58"=T%*8V4H;?fC2s_OmAO]bB\RhCr`oQ.\S^38k#52PYEhjA6PJQbHVK5n&TiH]3I8j)8ESsa2(RfGo_j;nBDSc(eA86Ypi6GAPZ'?TtCTU3@oD?b_8a2PYfO3brD>B\31`.*S*6L*N?*#dTBR"S/PG69#BIqniVUYJ^beYc*jI6&[)XU`NTUj"kUFUPIUTIAa(`s4!)-qU*g"'MHG`"/?s'(og<IC/l0Z\@@1f9st,ZO#7bK4)B&KOS0-PtL(8q_T7U8PRXB.Q0a";W&nHrsZ.i^,K[orJ)m/r?j-~>endstream

+endobj

+% 'R313': class PDFStream 

+313 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3636 >>

+stream

+GauHN=]=*H&q5%Xs$MKI(@O.JV3:\">7A5X^h07[1D.eo<4Akn7RpZ\K@sVHR8l:?-P?W"LM9_UQ!%ICH'Egl'E1o*s#M:`h3&b*TS-KZ\KTH\CpH/Hn!C4brK.%m-LTO)ZAb1R3gJlmm*km#0f']T*-1fM($nO#6Si49FiZ<\PT$b7qkM,uiLib@rf+,&*i3esniL"R;k!_Rrqhh-pnR9%N(sgrXiDS=a%UikBQuos_j[m!Eb]#VkHiAaMbn$DXqf9!K,ed<^:37((PUq/YAa3$(LE6!.+lDCQ03MYI?4,&f;J4oZ!`3h</]o]?bZr)D;0fOJEKkKG0oQ*fF,l)f]<d=>W`Mr@r^h:"n@2H0*2`_nurE\rUXJi]J)pfmh6bR,i4790Qc?rF3,ARDf=KoNTZ4Qn:Y&':rGI2/m7"ooNI>8S8Zk8,`Nui2Hfo=(Y65qY!nh>\+[==lumCH48Fqj;7V]nSVncI`G:T0LrG6/jmdh[iL&@u($>%R>:'?/Wn,s-A>!-:24.Z5Oe@J_dCE\kW[O><;&9[=S';D_ZmqgDHtpkGV^AITeWjRe1t_:/-g`Yfno[OBcW!/cKa7.)AWSU]]g8ph6(&GW4QW9G&P:]Wmkj^4QlL2If"1quV.(IUU2L:jfHFnHhBn*^SgI"<A@K9"SD8,F,u;Wg[.@S/NQ!Kb!0<jBA2N/];32G4P<@lQLnE9r*/et)h\2pjOT]BheGrqf=2A[6H7Fb2+W$cbrcrNh\@)KdLi4h&+r2=mn$Ye+$Qdfl")3pl0p/V<Q)_.i8B=gI-U@eT_A?H#aaK>0?pq-tM&o3QVlHhY5u)WQl35&tp`mt]1M$ZpqT1Om4cqWa*sbaq&M0G<H-4%2cRfj1<a/]TJ[=*J'W2(I>i,[J@\!MZP'-,nKNmq\-2ct%0h!gW"@AoI239O9;Eb/B-HP>MS`^@<\Bm,XEe@g"5oTQN6[hP!5UQZp.c7dC7&!tuh5-=P/X:bk8[a6.5WVT[[G^KH)E#83ALFeU`$'5T9E^@mL6-1Y()GBlE;hoBHC2IE@o):Z-@\a"[`IYo20AOA3`O3oJ\E"C0cYg/ZkkOYJ_=T7=!>=,rC*mO'LR=+l,Ac%.>P322!n#u"$_l1M$a`3q%1%BOb[KrC:S(1OD;6G2LGp\Zq9`E@DRc245'U;=kdC^b.C3H*6Ri2P54t+XU+YSA2bWDEV(:,)U9)P@1RA>Gm_V1Ar\!BPR>s&_Q<!NN1qgE(KCFRdudFfc3\#9!:=bWqZ145jS1l[!WXc#^l^]9iiifa=6tO(M"AI,Mr"=`O4/I>(XV^$Ud/a7.9iJ^iZNb[:*ZKZQ%qYi.*IVZn[dkfM_W2*S];P!mdAZ*ZHV-/0+kAXWuc7P);#\5Rq+qk/],dFSm#8I91Wq$Xat2;hb4"W7,c236eh/c"=A7'-@%+C%FZ-&*0r@:lc=:D$B<sM'Sbj^1A4dpZ39Vp^;@]S<bC>\8/aH4e6OJfCCc/5ZLUm5]5o)+j@$G9+9F8k_C-X^6'`,oSmX0BP!KB3T*eF$n`,__CI!'VK00:@e6#X=gPnTulLrR@.+?O?GjI`Nb6pr);7:DY[nu"nS=G++.O<GB\!5*3;dLN&W51##\mQSlrsXMtFH/r\<Lm*s0h\]gfA>%8:89gOfh%n!7&otA-_.t'QFlC.JX9g`gd%J_4Ni:W7YfHKbt[50)H5%PNo^6]%rY2Om[0'7LellsMD6>l)2[=GX%k!E/3(iiP2UHR;1lVAeR[K)Al:hPHmrg6>Jk-XfWo1+W\:7D>>a^')'b%'rCP]U"k6KWEi:7t#9R?qP](:fm6+1Ha=qM]S/KR<-'ui2hUFM:D[NRXcjk'6lT'm3-afhiU5kq7S',RKQ=KRqYh?ZX5\Ht%^dYo55OYkln3@D?T]J-dj3k3&c3EDhS(!_ol2qHR#=fA:/(De1I#uH0bf;9%FM9G4hN0nWbEgRtG^)VONXegMB;:&NS_4;D7LfT@@ieN*:STU)\:FI>D!Rc7BqW>Z5Zh!iFVLpiYUGi`#K>gqA@jGN7*&\)V^ArWD%g&9'+X[N7^59L2<^;rmfX&2F&]C,2kU(.MKj6cg29%uZ)[k:c%f"jm,Qb:\_K!neb8R94Q>VYqiCV44q"fBGu$:!RpWnKhGCb2a8Cqt?OAMaj*Z:NFr[Jop9TtZe,+R_o9R80i9S.tHK[J@g1;=/i1UF[nM]Eja1,ln%cgDi+\pAX^UtLe*S@.^?(INu_e(8VVIAanL8Aoljt5Nemt.LuPOo#tX^pJ%W71R@'(X\Rs"uRsFA,@+e[R83!EZbbW?DYYQQ@En"cF7>Vhffq]V#Fmi6cps!Q6)+LP>Q*Nh)cH;*:5j>Ad1hdGOSI@(sr<o62Sfg+7b=c%$\jEpr5J3Aa"bBX_qda3.<Tin-oujgFl(mi)Un@`e5^6$6p#Orr!@(UMT:a.GkaKX"l3aY+0di&"TRAJW##Bo!\gpuI$SK0(aqN!1T->dOq1pZVo?2+9$_mIAs%L#I_L-c+/sk!'=5Bh?/4j`5WeE5)6s6G>&_e^#VU;n.Up"+S[]&WMbh:nBA[FL3;24a05OT>:a2&)[ghNQ#TBr?NT+O\n/7e'nWE3;n-u<aq`JP#9BlW<N^pGes>L\m%sVZYKU#ldZaG(<%eBi0?+5#X>e*AD@Xh-"+To?<rPm=&?'d`FAA=hOP[XNf)]-Bpe[N^=\)phcG(]h8eh2re-HT"Pa2Xg[;68*A-,go,"n]]@Vt6rn$,<pIL0'If#4R(ASE1p^T3[ph*(]?h$'Rd()79<>)6=Q4-^mrQ`^'aaVP=bm1(9p(ZW4%f+u+/BZIOgQ'6^?'F9!_X(j,/u-.C17"*Nlq?jLLI!r,7@rX'k)3ij;Qi%-&c&.P-r6re2-[-IkpP"MjQB;(l6RjZSLNG]'?sRSI(!51D=O85f0.IpKBt2U:`H*kcW9AC<81arBm?:"[RHk8`h4aD)tZOl>lkm/kHgZZq>s:O9/S:1rEKDD:nP?NfA]_/0*Sc!k^,P6H;A?4"&>ltKk\8'e(!B[9;p0r\9FY'@j".qksJcY0;\!UGG$0j50L:HZ68n1Ps/uA3pO%,U?_>XbIW!KW/!duqm"`,-02V-SElGo3o\kfDY[_Z].E:5V-jNCqlQ45%I<E\a`FfTe4r0\X@5Lc>->2LM`%,KeP](*/SiaK=Nr/X3SfgA4^2P:_cjG>HnO#R1RC2NmG.PHKM0ijKU]"tT!ZRG<jbE)lt%cilKbf7H^`Sg<HB<(FK4lFa(d'XLhRP"Sujg0BNa*U<cuqj[LptHF??s\(h$^X#N9h4N2q96().A3m,gqu/Ic8s6@J:->`1sL]bJu5O>#0A>HF1>N>T.FUXt%51gd=uC9c>9RauiFdVE4ro"'-+nf8>[F&lO(.LRZH=K@aB\h:f;pPb]R<7OW-/L6:_C:74tV<]l)LeFoPKdgN6RTdpXM5Ks;\F^[VK"S8CNI6M7])H:&Rl.)AP,58Y^8$[PD:PI--5GW?:;7%![@u2m+^:"M7m-Wkcc5%O/i5.qb(XXpcCILMmlg_g9t:r)eogp$?S*R96ah#b=!AYCWjp[<#ZRk(foXhFQnOnf#e&aJ[A*fECrgC3b88Dm`&_jQhsga6E[;/Xop1HIIeA399;X`~>endstream

+endobj

+% 'R314': class PDFStream 

+314 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 4060 >>

+stream

+Gb!;(a`?/pp?jF1"3OVB,ps>M[?or0nflg;bG/1^bXE=+$$A&ddO*Y14't3s=@a"Y5[!A#[O\6Ep'&56n/Mh(jL7SX)^G^&^-]$K/7dGtl3:CoiM*AKkhXe\BA_npMkbVOZ>F+>&Xp_LKha0RB$<uiZ9<=(r#+I.<J'AQ@cjAb"Bh$V^k=pCS/WN*2!OIVNK,Re-+`pd?2[11s%`TA'-Fuig<=B"aqaPJk,U9S=XLPpQL#/n%N$m,)N2/<>cO)dTK-VBf3sTn[cM#YYOR-'&l6]B&Y34c.?GjSmF_S<B>.39Ebt(gfX*IEYkJ/-mKhZf([p2kfIMfd4muc^Xo&8#]Zmd*Nf,*m*K#ZS_SS@$L.G)d*_MU-T[Df"o`!n(UduOp.8<%scoi\?Gj&`Ii:WK6>^W,$"!:mFBgI)$qXB;do1)gCp%cS&E':Kfdphu<PQ@2J/6T@GOpBgfru6YOe)/F+q7pV!$\Z4+$#HN8j)gMn&*is$L-9T)jlPOg1bCR,?Q\J0`<Eh:17\%2qB`_0@U)T1=KL2nAo(6[h+;$;J5XkUaEZt7e#/Wl2_8`b9`6e9kG4h8EFCEO]%8ThmRPadI:=*Ar3@Bo]:c?c/u)qr@s!iGT]`*Z3/j<TP2J#T[3tUNOuE.G2#3=@T#%Tj;ZHae*gEB+V,U+i)He\Md3T3HjNn*`n96a+!F(-#0^-"u`W7l(#KE3t(iHQM/$+CE+_uW'0k%!#)BaKFZ0IH:L/#;'0K.]t)E[7c;"CGo+K7750n;S\)n;.8.hMN<-1o7`P3TE@E5NrR,Zo[oZ:[E^IdEBG:A)&3NPn*?8HG$J%GG\/)AKI]JsOG`:BnuN$/2&[C<d/YVZqa]'nIMG>#A*5$q=Y:&$ga++?c/".L=B]YY?Q86c,Oh!uePAeR6e?QGUVWD<ePF'tThAK+T%7_`Z5\D/(LQ,b1/9UJVsBUDFN!7;kRTiK+H6>agJMOMhJsP=G,XN53/SUc'II,d,LiW!HLhY![5hXN%t1.RW!Z)[3<7-Uh6/BM7cQ`"7,%Dp-)thX84Ap6`iJT[@`_^U_[0X?KcZ"I-U#!<H.,;.uc8<a\AUJEQh*1:L,:66jIU!\4lg4PnD.e>F$iLK?S8%>-:&SFmF9\=S:$q65I]?5J+%DQ&K&H3E0'K%DF,(kS1e/ZF9G%]]oB6;h0LbP75(173K68u)+iNP#pX*(A!\!Kh(W,hAo/p:2C?`qcno$]%J$jdcft9B8L@8,N(AH;u<YpM(3C.p^+Hd/^C#\=OuZ:p,X$%//L)=n.!*]LH_eqXlm+/A9&(A(qZT5lot1;6NQ.kq[ODXi@p'lN7314>2omHbK_P51V1+S(Ye&3SFp1Tt0#:!.\dl.AY#lW7d&AO4S`H12iRt$7V,>C:5>=lbad@@t#,&OsaHm#Td.GQVQ//QMb?3)5cTB(5qn*&ZI"AF*;iEY/^8(0Y^5AmghO5N#Ch!LQRYSV*PmV>k<gYZueC5hKiMZ2=A*sdr9E34l52Q.):Yq(aV-nrA)OD!aU9McQAe9U*pK1?&0*Tp7Rm+7t-"%5M`+$#*g-d&o'-%,^rmh3%@N?&jg\s"5nmK0pVi>gT2ft<K%CZ+hPY$3'Tl$Q:TfKl@Ss_bt92A.n0\;$V]Z:<7QR+oh-"r_,h?/]_%&ZC^ZF((iB15]^p4B.j^#"U@cn7+!Wub67;i`VO-*%(2if%>f*ounJF^=4=6?9X29,bjp-?eF2'D*Nsj;6\@_kQ3@5pr0R$W1Zl]ER*_,B4Po5i(A8)l8*[*.f4BaIp!j)$Ns3M+nfq"h/>kZCGg@qNVfX>dVE>@q&%i1!q>bEWJD;(ftL:^.oCoV^la7"jb-qg9IdV#s(ITO1^DmX#k[%?*W5K$_XN.pp]SrQOsn/aljN[M!U,bm58MbVN:%\qNXQ:RH'`[8h"_ru4Y`V@uQ/;47`jRX6ps7E[?M3c?&B_eNoG8":]Xgr:"4Pj<8=IPfK_J&-r[:9P+\69oZo(;k'alh:)B#/;$f_/QWY9/1jEe,su/1fP[dFZpWhNnQkQHKj<)_JdQphSTR3J;SqO"A36)0=Q;]br+2hdYSi$c@"tf$#l;nPh@,ZY?\DB6$dj5`6Ic?<,rWU*.djRk2POc3VaX+hf+XN'M`4jp3];&..qZ$4VQ(e1>A,8uj1;P]TrKA="o`9mi>!U8T$bF?>eLjc#F)k2HER6gi?,fs,qWY2Lqc=n?jF5k;nS&6dnr"d1MILX8l((ubpRlPVM!Ruh%`pf%``RS3Hj*:le3RX/9&L`4o#FXnT*_ITJd1IFiAEqH>TLJtW`+PUkR)B]&654V^qheqI&n/GBF;*^.<42S\4O(^ADr.KkLfQ"R-!,G7X,/;'t/V]l2V8]:dDm=1+cR81?Y4rO<VYj9^,b)CN;+e<!JkafDV%TgT%;TZ2S\MQkYH*t:BXN;nO,iZ5LJVbi7NFmnak_'YCedV3=rm0P^,_R9/dqPmT@nO;^m#1g>rm+.LBpChfq_Un1+j9K;&s7IaGl[ZS:5sdb%.u"g/[:rQ7L]6JY.dj!qDIpFfu4sQd2-9dXAHV$usAWO]6s'W+G$"fp53i,EnoZMAfof6^+1ZV:NOB/RrrW;2heMdc/b%C2g1qE_P5$q,U-.UTBTb3&QO2S8+U"diiAuqhSaH23J`Q-;fEE@/amI)pMlX94ol<J]4$AO`4k8CA8Wo"'mk5LGe!829%TdKk*f-lUg-423o::KksAElUg0523o::KksAUlUg0523o::KhO_mp#M+qG)K-lIZGZaO"V7m^D/G<[]C%O3:KVAOgnk05^sE6o`;g#(If[DBQ-g^VBp`8Z>P5`\44s.VU/&,!1H57EK-j;9qe%7#rI>cH(rQc428/""%/7BUK]#0&ZUr"3&PBH:5rlB/)W$sL,`j\d[bc6;lhcF,rA>6$Ji)MdhKr\,rA>6$Ji)MdhLN&IUh.I3o-HePE%[V+*G//PdA[!K%_T/@@JK`!c(unN:CLZV?X`LS<b('r#(d!5qapiKn#%GUG=^j"m2&GD2e?gNn(K]4^@^91mUo&p>us5\828pLM?Aao<')#L(i>3$u7SrUs@0";X`&tIiFnE>Ea/3O#DFfGP!'G\DanYm;!]qIUl8*R??l`T[Sg[n@i.lIU8aRG_1gJc7-mUqoNhRO,dlp@uo#8cW%u2E@uH4\O"jY2Ur09>2bHj)eF<bMn[s)s&V"H)r2N/P/U(5F62._^sTPIT2W]oX6p8!W+i\7IEj$GFH46ZCRs2A=TC*sl'f&QD0+^#Zof*6?""F:"a#9KqL)2E]SrZJPP*8dY0?,$&m@Yl?]_*qT#D6')f%/M>?@DtDm&B^7.(-SI1r_,qL4cDh]q,?*:M9L$r;1[-:T<:`no^ffG3Tsa5;&"%JD4&pphK230+F+ki,ZCCiL$BYU@+oFD]>TWqMR-_Ulh]0V]R=qX>:P&["\iofYK_NS-NS)e%9Sdd=354ebdkh+$L4b.n&laGqfbll?fm:#[s.A37*hD6l<oUDVnJ(gS4h?@9>5$':[qO5O3cO(]Wo3%WFCo1N1"4W&lgF),q#O_$'.KI0751FGorHM;\MIh0(rGItJ3F"SanojY>T`)2EjS>:J!6W5ZH&90D"G.ND5BTi#Gj;@atKZ0WnaT9KRq8?IP#g)8%/XsU2NubGJP[o"'B[W:[#A<bV?"gO,F]Kkm8lfE,b*H1*\#VR[8Q*tA.oK+AX(R7h2qC0(6)&A3T,1_IKfrH@h"r8@,mATF8\=h3ZP*;dY,:VF;2f3`#)dA`do)$5jfX9\-.UA",Ue8r4Ap,apG48Y?819NTX/"jgGl'XhIO`oCl>>BL@s^]]`6A+:Y)+uDKb+oB1kAr7KqMcIL;gFmL;'7Ghkg*oE$*$?5Vm`5!'P#*7@Y$FKBfUabD?*PcRD<\a>YtNp`W$LA]t73_IZI^88&bhL11(LfU#h9(AHcrKfQNLm%S:W<$\adX^iB6bSqbCU-:B>N@F2f@1N`_78heZY<Q8k@;FO1A?Tn#QJ[lQq/1f#ueU7s!3.OW8688fc=&\]BqZR6`(2Y<UmrAZp;s0r>u>%CQn~>endstream

+endobj

+% 'R315': class PDFStream 

+315 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2874 >>

+stream

+Gb!SnD0+Gi')nJjr.c;BEc,DgI$#hbT:BuOb?Wi0[;qg5EuuM;P#.>F6]b2f^]&BWOs3?.d#N16AF):a!!8)7B6TtRd"W]mg%o=m"2(/?GHYhe*LJFop+-_dDrA[ho4K0;[p;`NH/LZJ5Jh&:TA+<r=.`Xpd']DVCn<l/<UG)WhjTKo0T3cU/KDe'Bh.&!d?[/uPqCtCG$i&O0:;]4DuZm;r_WRalb53i4get0'Csf,E9*!+PE%p%d.4*K&SZ&Ur)+l>'!Nh8aDrlB/j^`?%Ej#0CemUT(3/\8Xmp*;)_-3UYH?94S::;lLPX.t5U`"4P(h:!6G=!;%tQ1N<uaVko5)YqR.G^CGljHMra>MlVND-d/n>#$s%m["/,d"b3/uR6c@UD))3+nV$ULXPe'eO]/Mue?%O#2;J6.'0'QG&]Qm]FIRK[uQ,*ZlgQQe.>eLOdAbE=F[&Q=Q;OGfu8$9,ufE"04<=^I\"E&E/NijpYVf,WtXkUIB'#JO=0!7.<q?j0.<-tDq4b\H\Ip%J&3&BHg`P&_WPDY+7./NJ[1En"G-'d8?7"IVqb1?#HH=h%lXf4kRO8rpaQ%DI2N<gL>8_+]a5Wb,JI(!=(p<A3>!+)g&M\Ug.>*)KkI[&dhM16]edLj5d@O0kSaR/m>]n>Q1CGF[\Xr<N,%5RW</B-L6L9@A;4P>IW&U6^%Y[M5[H6V!(Q=Unsnnf7CmfD]e.*`STYhk-EqG1OtUJmREXl*tGiV6\$@;cDTJQ?>#)T9HZ'Ot`?X>/H#%;\HI'mc_IJHe\;&A0faZLga8eg[MRB/cloE"J)ou*,9gddA)R;kZMTe7g+iqe>NJ&n\`fLBilY(5oi&\E3?W!k:qQ!UD`GI_T4]>.Q9IWksDpP+O($,<ba'V!W$$KG:`KXYU$emr7+m^;[A*`N95hg."WY<Ud:,Sk#6-\pQm5b@XM6$_L_G7qO?%,^DR8NEfh'A:etb0TbJC](aql4\pU$,849/>bZ2g=4_B@h[8luY-LTTn1gQCB!tD/+as+sU!/$@U,2OFFD$u\\!J;i<8:TATmPj.23r"Tno6@?FBr'dT5o1_DH"D35=X;QZR$n;lF54d`CV`9oaoh^MfZqg:jkmFDM`#mr_!OkBdY4k/"gs,X_a856GV7@(aquZ3oII?4\&Q4#cd\t,eRSKrB=6tCcoD2[Y)A46J\5*>r)"6s%f2B1"lUi7_fn_RL`ejICMktI=RcA$PM:tlo8bCV(HHFc64BjS$H$RIF\Rl"8q1=7NVj%#[eaf9#jMn_HReLbPpBqn_]d$Q-kaV,&Vj>56,]&RY7o5DBDO8^-O321dE*c9`#V#ipjG^`3D*sU1#D+-'k@.(RPJ6S@eSKje%!`Nqhdb`iRCDU)*O["3eORoI6]UJ@3%MW[`0=si,fM0Zcr7>h:Bq*koOaBR-[8T)MMnJ2#]+$U:S^rT52o3!\A^(HC_go35pP/(QleJE)Yp_4e'9^a9u5^H%IfZ"-N>rOHQ%f"=ochH("Ji9O-Ae]:3).0WRf*1XZo(A<\P1KZk3W6UNP5&sd16<HG]:HP6i<<scL]R;Y.g>O^ZCU%4'H-[\j)o,9*UcHM0S"H=bb:'+[AMgEWYZG[pkTdYhX/Id3Xc+4"tCnIdRo)MHgC('l_M9P4?Ci7BNQKN(n^eW];PA/TLUs"^N236YH6>sVXLZ?GJ[EZAAIX:uE!>fOYaV7=NNt]Ts@W6b9E]h,,=Tirh]`^-]gF#D%?D,7JdPG_OFhgr0?,$E'>.D9F""0qp<`VYhs!R;+EcY67**qb:#[q=S`>08[OeQX?>]^mtqFR`meqN87o^L6\0h"9jek0H<(Za;+Z!3OPc`E%Mh(?+o:H`1:7uI,%,L+O9C6(H*4_BrPDtNjYOMR\DSq#._D]_TS1cUQ5*4:Sd%mRh"oho@N6or&!:!VT"3UY65:V4)%Lq9iq?3a3,EUuB8e\&0kVm5[ho8'>,bbU3OdBUI1/s=dUAWS-:lY/"3EatdP;H\Qe>Qpkq)&:[OCCsU6#J58*2ug8C0'.XdR-r:n)S2q8:fJU9ghtD!;$s4;7)%qn#2.J!215aEfgUfHA1c&VArdqT#%qC>7ja`d_kH1OE+8e!IQ0F.Ih"rW!ut]]YBdC+Q^J,Ge/5kpW.0DUSV?[@/(t=:Vdb4h*t._ug0T2(KHN5c[DI2jLddF/AcWT&PX.T.*eDtFN^$SPES,>fORX/T;d"h#WDCNQbOl?rF++)1MC9Q[8q@pk:+UCBM5*m0]4(eU7VS70S;<,#Z-K(4Q;gprLCDQpK%ZpHfkBk>`q.-d/FSX'OEMX[3r-F=^1#Dmgm;cgPt3_d2r*ps"0Val0T=PKJ8CD/!45JGmt9tBeT]DmXsA>pJ'c?>4dW@cA=)7JDh3<iWViOHKq#e#V@7Nq8ku..]D?MQ@iTQPJIYRWOZ^E^&52'`HY^+T/=pXfT$q/T;_6q*rOD3NG45M;6(b[MgP5fZr&EV9Y;240bdOas=Ni]Z]/T2#`9a'/Z"%Pr,$gAqP-FaW#0'6Q_]u;<)>2%2A5/,e]+8k[>H)Xf,Eh'HeXY%[Uq,87%JK+Pg?Q-u&4nM)WZIq,pG*?\fssC;MMf!KN:hE.@StJ\&?%hS?N\Q6Y_:&MDVi=IMR`;m+/!f0Q/$%#]VR+o,o8T>/s9%K<%USR9asn!\2b9o)>3d4jf%t1PL%+E9.rbjKZ"8F@qjA[j16,@^+lNd1?S4(NG=^(HE_C#@($FMQ-1$$h7YB6<I3[g3N`$/i'cNNkWP/6U\'koO^dPd.3O=BeCgb,*UVIaUD^W`IZdr_8\%TEK^)[<A[ru5L)$'+c@CUQJq[c9KpU!N5g\s2\7mPt)/3]9Pub:A8T_i"i;'_Z!gRWA$N~>endstream

+endobj

+% 'R316': class PDFStream 

+316 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2964 >>

+stream

+Gb!;fD/\1M&cNgos'ah=<=5-+8\G>l#PV-R)=@*EB3h]0h%)#V-#H!:1:s=rh64S]?'6BXfqP#OE*u%pq6D["bWPL@XF1rDO)I7X']?09G^Jh1+2E71rm2V$r#bF;q<M+Sm&sb[4rQa!G`r`Re%4tbV-dO"-A0YU7^.=>$:jdTM'h)$4G%hc^@1#t*1pi5GU&Yt@"7eUHN*CCbWio@cZ]/WmI-t<bKksER0:D`bGds[BJkc<e-kRo3+Q307*K.C.Lj-!)69ljJ)Btcn,F"IB74/CXtNNG+=&L;^4n>O>_q1l*=qPh%G+&tBtQt0fA>;-3qHtBj4hHtLP+Q1Fp,8rGeobR-H'QRGWI9.&&8]=1/JAPM$H7!*H.A.n=<0-QA^Gf7)&!$g0j&;C#!U?EV=0`2acIAq]3?49#b%k(kb1JjBRiKEs5gS7D^51)\I'$BpS7Qj*be.DPT;9nZnBoKDXMEZ?ZdM(?Gmq+<*dB0#aj;GahA4=#o>W%Ygf"Ee,=_`&Ior<(8*N[E*Us?`u1FbHaN(DC?KZje-n)""!?%)lA<=%'1t#d/6OA@A,\6B#@#G2j:GQ.TU?^:,Vq!m0t[cN`S(;<![>b8Pn>D#`7LP9aW6!iZeq<05eT=-4uXLcaTFf)@BYU@n(SJ5o0U0$H[R05V8HJ=RZbPSXpC]p5VN"T1\+/:Q1:CXh!<KL9KuP/!:$W+Xnm\fOWSsLdoju2]@1>>IJo6*-bm.-G*C^Wr\D];T**1aI(7A<$Y0+9cRT[.>`:1G??YI0N&f@Nn7ba=(GK-7;,44?d^(/#0qX4J4&X)$c7t>hTbe4=P\$SdAT#BXt8"1J\`O@bG"@\ruGP`(%l5]d'f`uZ$_k/TjZ=d05*M"m)L1&)L3KdjMGrB2m^Y?FI(G%FF#UF64B^5+]HC";he(2a1LbW0cllsX0W+B7^fK0rnrdm]g%q;Q-lm4]9RH6N]E9rRrG1)-t.k3[hM`MBYEks3D58Rb)9P:U\d!Hs"nQ_-Y"UC\d7#DU<KJuDX_7^/4[P0&::Za>&V0h5pR4nbr1.jhnlX3dTfIC,1WO4/=RQC'#cW$>[ghkZUX`%,8SS;n6>QL$N64PCDE1,Bo]_qJh58s2Cp:,%L6OA<9.mTCstt"`.G6Qpf;h06,^j<%OfUL:`J"DN(m]:;D%os7;,OJI^<!u"RSF'RTjL5"o^OAR=g_84%Y<:"1"]6_s-*I9";"]B:e!Po0U17:erFJ@n+1#*lPi^W-V<5Q;3)P2@$OLFQe`?14bSZKP,'HGJo7)!0r6`74OS8Urub)G"TYkQT*@0jMsYk-hR[23pu>egP3W11GO!trUTpQ<t`Ahi_=$0II%D5;urg,U)rr^q^W!.4VRSaV\DbfKe/+[=<LbMH)>[i?YM!b7SSG:Ko-B7I3Y,eM+-atF]coE>OhW/B6'SM<PnRC/.CrnpM\3pl_X;G9N?m-LI$@QL+2#on(hD@+BPIqW.M(O:6(XYS5Suu2ct"[?C#oH/GdFgr'r+(;]cNag!,0Lg,fde_XeR]<2$FP"dAeS_tnl=*QOe`@e\9EGq^.sVpj[f)kag-2=oI9QH[Vfg(gs__0]UrK^GjUrEcgH/L&YhWStc[]@?F9*XkAR0Ym!<qYIufGqeg&E7DC.^&1M2R]7bA]Pq6)@$OE6!l7M]cAGkh)^?G%JJWeYMJ,u%5aa3J<V<OSJDdEDE=nL[>.Bs!KW=(&I]J?:H*[^T\Y`A+;lR:gQo/SA>>]GmQ]MtY#G6:k(T3&&Lh8;5<?(7(9a]/!Whr>@B<<`^Y1UlOG^8(X%CF:LmN`[1#%nlC:MIiQa#5:u7mFbH2"_$dCSB=-S`jL2G=R-Xg[H@A^A8?SBF88$Dm^=t'UO[&4FpVmPI;jjhm`JT#NImV546!E99gc;91=(]I<MeO_njP9Sh\]P'j)2k<DA/1,ad/(A:Y>t!.$\+7+lm!X9OLb>M2@"Lu3JjLk==TXG=GjLgop!jHh*Ir4rBm9QWd5)OufM(Q/>`$8WQ?(g)6ciM`3&R$,;tmX)iqiVa_=MnV-<bj^KSIQ&db7jj\DZa4rK7Dfh+WZgQQ>,jumG!o6:bA;jR/PVX/"m%2V<8EtN"jQRCPR:4-(XMO#O+K#/mBVH0R)dW/EGp<YeRf1Xc#f;r%?e3/&A#3+KY+t*<2`)l;)K.qru6$]jI![kdlZ/60;VC6P*_W6I&ln[_ZjXUhU$(-NXT#m1dZbEPAlLn6n&D=Lt7g^bInH7_P2iMEd'?>0o*C%_2T,].JodFE/GrNVC];R/2$(I0Wn(;8j(]^`Xp(Gc.H@)P>OtR,WY3uF:595r:ho??bZtPLGn1=?ghic=^+fR!^a&7F*?=AW]Ebl[:sK\X]rAZ^-,n9b9^+si0mgYlIK)QbW/<f4Ou#d'dBN=%4f(p7s^Q/m`OQ$/ET#!Qp2&[hbo4,Z&f%]DFpO<<]o=:[eK+AP>7u;6'qB,i7ld.(Ukb,a$nP)M!9.bg7t!,VGrC#h^VH*V@<8M#)o@1.ciuc,Y=+*Bhp.UDC>H4Dj<'V"CDH_:J9mJcGN]dpbAk^[Q6$;`EZfF:-"L@g-r*i$aK!%csC*@02\')]"kA&QqL[d[TQ'XV'e&ics>o"$OQ6FMW]Xp@DfLL<%o2rGl&9ur+>h,3-2G#R@m]>WT]GWNq11t`2`KDoWE%./Wm/P=t,N61m-6#%-`OC$^?unaK(%^X(0-5[F3;5L"PU;EE$5I3*Wr.&G*R1Qj;5VaKbp$Vj#F^-0"7.l/;.IE@cNIX,;Rf@\@LTCFeCCn/%u/D5sh\gR)M)802)"doo7cVuBgtI`:11@m*.NL%Z4n6u"B&0Z4TAcUgRTmSo9OZ)=Q!dg)\.-@#>N%k4A^5u$=dIPoo9s3bk'PG0;H5-6!&9O5&lWBIo!=p$WV7a,Q>6YgR=;RlNQ`T%K+K<,TIJ3GD3%=4E.]2$C4ldOtq]l\V>eF<=b+2ZsI*<~>endstream

+endobj

+% 'R317': class PDFStream 

+317 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2526 >>

+stream

+Gb!;eD/\/e&H6"/s5C18F#Sl^AGIP+0Ha$:Zrke[[>/0mL4PY(S#ms9'P5nnot-u*/B;[LQPLMQ,W6s2a60&+H]E->K0PCplULq>NT'+X#94Q";fFk]_>#<]NupU_@"4a,p7;Mlb6C+WAn0VI1T)4&K21$<Ha%nq#\S:[Ka)AGn%gsba'j31kGK%"X@Gp,m#R`(bNV0@nN.S;A!_[TIm9/>hV>SPi-Io;.;.LM:!JL:Ygu^@3F'LR<\aZAFW&uBSu\\i#i14l9+n'19U3WDrZ$;#:ZX.Vgdi0X+B-A@5\Q8L6DR)rlo=JoJ0a2q/->\sLM:?U/H@.mkls!sQXk;9%Y/L/JWBJ$hJfs;0jo6o_3I^AoG--gUSXS@2Qf:2dd56Fb:gTCH2K&pYCd%&HdHD3Dhnm`_!CZ]6QaLF&4W;3YUcu?^&T#sTnl*Q$Fejj3Z<Vdf!W6?>5/:;4Np3^].4:5-t%jO(a'Ag8a_ft=@f#Il^#`%Gi?fhaH./3e`!Qseq--Q:qdGqnZ>>^VL=T8_*,!)jlZTbR`"$,fn79/*d1q->R<XU)K?Vi>)4"bH%7_1dlD?lP2.3=XRC=7[g<X!OsH9@iI7'=J+W:=h&4SDJE:$FGc1A?;Y`7L_9BluaoDgkBjf]k5M2*!EF4$X:Q[`Qp#EL\\Ns[u10bHk6o,U8i0ME(ME-?<N'`oS:_;9th@eSo:)4Z<`N@?a9\caeoP7"f??Faf)N/RpD<,g^Z`%_>'masKMS15D3O'U>a[sePRZT;8qRNmZ:juH5e"!DNoAO=pWlI_`^=KSHZ+5Qpdl_sq=ZqQ5SH`W<<)J5_:I9Vm+:8gs0&7AG@NJ)_e9Z$e=`(YiMunQq%8.?tU:E+*4*ipt;P,>5\*HsH(sfb/P1I&_cW>iL9<78oBosa,/*V@s[BEM&VB7L=R\JN`?#kf<mTO1/:;6KD;A%@L#7[kTRbJrj'2hML(7K7M\qh<rYmr8d'*64&Q(lA7pKH[@6*!IAd$A4V$`U7."R&p\0Lk8_qC(CW=823\WQSRKQ:<>8D9,Vf+&n3bnB*`%V^VKZ^'0iH[k>r6`X)[!dd:RkD@dDDYg\8]=*=3Ooob9kW0u6"CW7J7r!Y7!VXCHB-<LkDVuhV\a+Gk:QIQYFQ,22mP)N\tAJV>m;rLkC[ZFs$(0rg3VAAZFXh,rt@ZRgB](kAUg)O\mghC)o4uH./(j)t>7e:.c,3-Q70`pu]fuio@?bW*Q&lrS4HC]le#$Zut336W58eGD2"]rC;T^9t;"4,=u5s9N]m_:-.GRYRYEucf/L9tadQ)^gWZ$SB+]PSKPRQ]&5+bR0C=cs[TGZ5PK:RmEG/q[N<HA?%gS%(r6?iTunWn_`.c[&HTF\\U#e,MbNrF/7u<ftW)#*nH7`kFro@Cm_Fe&oXcV2Fa[9Vq-^@dN0oX4L>Q5op`$A!YmP(Q=4Y6HQf5/+S,;'1#OKGeBRH]>gdnc[/06rFe]H:-_nEm_-uYEs;_^(E'X8LUl:\[Q)4_LrXmtFJ]nlp=4>d#kMBIHLp]RjE)eSN_k\S1J3nd8ekR&\I.brCjE6;-T?QoNq]2fUmKt+km%@h&GAh.LsV-DL^O6M:G9K][Y1DpKNS[4Q.B_7W\[Tf\VEL3+b0EtE%Z'3WnQb>f7#%=,:D)%0Cde*BDgN>;tJ0*[9i#PSciK8VkXiD37pkJpF;1-9'g5r[gS9j"UJ%r"V464.18EsYgbMbCit&-@?["o3u#KoJ.tr;#tT79c&^-kYUmOefN6e_e4Zj$r@l-TDBj,hG71gU31'*7Hm7;K(PR2fljIKdph8!]I-as3\(S)>S35dXV052$CN3Yh"-mQ+8dZTQ&94B8=ZPs-,"k^oMQ\OdqA+&QeK_"@=)1J'Rom4BIGSTq>86^HRaA\PG$Mp8:aO][rE6X-qCNZUF^f(16?gdhrPN1U"]<V3%u8mh!`Qr2+K&J:d32bg@g`?U.Tr+SM`AgPfm,G6Z0*n*iFMYbPFiadb!R(@0Q@k&:s5Lm`1DsDd`CG;02(\P/oG9NX'/T8lh`3kb%h?JVR.sDWKa-94R&f_m5h?GE(BCZRh3N1_9ZRJ;(/H6>DE&86EPb%\)#[qQZUM\Gg+&)LW6Q7.oQ.3#,ehi8):;tIl@$adl\79V;J'GaNl[tc`/9;-`I2=\2Gi]WX)UV'pfQ2O0+Jr1"CD/P;1M]ljP-Q%&h(D;Wdk.0rRY0H(dN<K669g4ZQ_jp/,n?om=_-s.>S9el,#u',%"sW#\hg/9F]TG$ieT[Bu=[G_kI7'%1eQm!/cDI;\F,8h4"A@roLK,Nj<'rU8a&*GJ)m*X"57-jRS)??r(/d$D*>4YYE#8;0WV$ln`3@/J_>11)DY/a.@?k..n/Jg;'8"*acL_,!V&e41MZ108SIA6AAY+qO8o`H-$T>7/,3CtdJe-2>)Y&FMdBgi-QJpP%GKrV)$=T(C3Ff5J^Eg]#T?cZ"G6Z:9fj>8PVt%pAc'L_<[OY>fm]'V/gJieugHHLl@Bm]l!Tiq`d!5PbUUKY/E~>endstream

+endobj

+% 'R318': class PDFStream 

+318 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2852 >>

+stream

+Gb!;fgQL;L&q+ths.Lr=P:[4p;AVrp-YI;"?*SGij^DpPWIdZ3_O;``!0k]TrH88g7?&W=C-30ajkE<OJOZ9\h5?_P@#2Q!pNN,.I(t2EY6"tr=KEV^ZS=#f_TTpI-Qh.4TY>h0L+m/c"J7^L5(LhLq2Rn];%QK1p[ecp)RLGPCc7j",(h"GGT#,2*@!J9/Vib\?Gf2cr>$1KK>g(1p:n,p+.=:#\S4bPN_c$`]+(=5k@@2ss'K*B\.57SR7;AUIRnsoSd0]<r'-i0Bn8XSnk6%+GQTt`au-Y+je)tTch3"JE!t)&+QHJnK[i26^Z9)iJE4#oaT.Q[h+!4mqV++0GJe]>i90d(?i/H)5CJ^4.%ISV%T>9WbRi227aZkmA%])B.YXp!E;+9P$dbVEg4J,dLm?O8[]nk-.:@ktEs=gT2/8_ri-D&^9N\B:.rrh?0^N-r?cdGi*CaiU=8d*MnHJjBIH<%,"+CtSPr]ZdjCm1Po>^ac)mec[lA\n"B0l%6OPRnRrJ!J>.(%^N6m.o*i'ugURGs"O$D!q^[fT/H1e;`%?L_,_-K5K\V9']Z"JHDV,"P"O8:a=-Q2)?J$EX#9#Dd>"i(CBC:>-/iac"Ta4.c&Oa:M-lRBL1^Qo<7)=Q#ob@4W=]_/kZ$r)ALMo#a7R9;96XO4,ir"te_:Yd_oBd^lcHR<SqNGp9[0Ym2)h.0f8.5qg@"]g]X!E-u(T,m58;:PZt-7P&'p#!_NmIkN;#hf)i6G9&^>j1tc9!Lrdk+eej<ARYZ.6s_naI8@Y[b1pE_!,DVP)!$S8.9P\6fC5Me>/<'lj>pf?_SHX9.oODBmMBnschMiQ.j--!>AUiDM(U@dlYRX=OXlgZ_9._bL)+R-P8#SmP4PD=AaBj[\<11'\?YhZl^rWQqZ<'(K1#cFacVSi4c>quV6tQOHaj,,8r'mbG*RfVbG^]^TjJ#.(<2Z/m.)\[GV63?#og2OXU9*&GLK\EJ,UaJpPr="kSQ\'\B#r!kK8B[RM],$1?Lr1kW3b*)6K58:7XpSUqCFo7'h.<d$`+18!G_eM'-mJ#>``!qs:eI_?d<lOVgU/7&&iNS:cTZR>K7<pkQ`4jd]eTE_KJ(S21f",T8jq^)/*<Lash'6Ia,[^P1_Dh.l&&&bD^nci3WlZ`dDe;L!*SQKW#V!;/R&0_rpZnl%rd41N(*K*aL!"coLD*uIS:h5#$4mc0T&h$N66V-6r+LDW/dM<H)!41r?=k;*h)qer"=IP?3%dFqo:A'I&A@Xk,T7OqM7U1*;,MVf*t:Zt__Ao1O-bFG.T6nDCpmZc^ZZGLoTpNR_1T*%s_[3gU=>+)[833LC\XY=<6!qgMa=Q(XZKjs!jPcNJnJFoH"3j)f)5ZXa_@WH=(^Q01lYDjbb]t8:gCcE;.B="AU&.Gi(N4^g@N'a2??F=DUlPHSW/!1cnNo@n7.HA_&[\Fubo`;6.WMn5=rQ=`(hfsiOlS"1uNj5R[YSG--EMmk$@2];YNjS.Vj?do36T`-RU=MPh,iGOs.#H\R]$P/dC8K?Xm@9OpQcAbq\DNd@'19J>moq?melKe%b&u<"ha_NCh/O:`Gf[H^PaY&d)UF/=MGt=NU&,tHEO+.ZQbD*gIOA;62a`d</XL]7J#9Xl\9dZI,UtG$eJPqc,K*)IlO7[gnI0ClMWTqk?coTb*/n"H*S-1I!Ll4<YQe6&76i!E3jkbKX@42BqTP<!Nt$;qGf%c2:0*f-@m=JsibRL#!rBFT`$mW9bW?/,(u9P#1Vs@p6u)L+91*"BZ2LHF9+)H0W0SD?539DB`kt,+kH1u`N*8Taf#%8:hVq/Z(\K?N!#00lN6EOnKM:$X9)>IGd5Y[Q)*\)+#A?chP\W?DX*ee\;c$64f'1UorTfAA2]XKN)Et'PFQoN6KtX=U/;HBs<eZhBl#),"][Lu_<GP$(=;"G6X:_?kF=;8E!N8+gBM_W'4fHQqhNIT4?aZHA[^j"Y$dDu@GouAG4#^+uA$Fe.q=nD9YgK5[_P"`.$O+7D#`pn")(NPqi5#j\']8^I<*'JH_[r1JSQ'CPDIL?bd+M(_(-\5oNVE#WWNW.@UXK-YIMg=)7DRphOt2fS"+fDr2H>cm`VMd6=QZ371bX_@X":5FCHNVp#d#jQ\E/'CJIJD)#Hj@A)B3f9O"'u&ih`QaBr$E'.QZppgA>Le0!A@^>V<OQ8?'u/Gg5&s%/d1%?EKL)U1(6]r-8N!l)OoUO:tfF.&E&L09M,dAME&jp-ei[*fWr%KuX4=d31*@:7$-#kA-?IZ#DA,r+dmIH/JB746$2J1]Zl#1>WSo$!/LcI#9[#H)fUS03)`7C&eO```7=[SJe<=2P^&:nb[HQZ@CJ2[_$QA>!j;R<?bqfSuKim&o:l73Jae61IA2R6C(ArU^-2kk'PrB*ba3V+6$[U7L\0m<eot#_/g\#(qH1WJ'tu;5'l;fH6NX\i8QH%j<(446J3I@7\=\)"<uDg(q2_j/["IogOgpP\j[Z;QH&@6hF+0,N);uZd9e.$?o!DeIo6V[,F-TLaCKaW,(K3bkD4i.NE=Gil%=.8<;n=B26Sj*Cf/f?==K4JLa8=d:aTbfh6^Faa5(>Zl&60t:;_[Qc,gh9.Mtt-P0.,UF(q"7jMd:7lGAdSZE;Rg.kS\sP]Bp:6/[cd_-3T8ZP>MZ>[saOV+'fM^>7^'Q\ipW^nKU[@4Pffc63'6r9Q$5VnX@A>qVuHmiPie(KZTkqE"bjS?Ft&eo+0>7ErnrieiRG+Lu6-TpI)n2T0_.bkr(0b<&31kHct_h0gf'aP\(GkJEfnps3\,reA"VFUisg/X^#Gs+D4V;SK16DD1qD"]!TrGl$M$,?#1$~>endstream

+endobj

+% 'R319': class PDFStream 

+319 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2269 >>

+stream

+Gb!;egN)%,&:MkuraEiC:<#akM%lf[.8>-19Un)M17_1r#De%$,UC/*TH3.[]*hq=>II-cDGlNYYsT+]h6Ub?0&Q_!p_ERRP60[?"[)Z.J7&eD'a,Zf@IY7b?9E]/aaXQ?lVRrJ0oI8]F6RrMLI(fr`M6!YNo9j*,IAA2)oZVONF5UK&2=#!mF.(MMeL:rs"\BB&)nt@p]-5MIf"?gqc!C8];sf,j7$F2\_`+ueoPl.g],8(p.p=NG)cF250,djJUnlU5?Yd"!+4jiS;(#(nk9l3B0nTdgd*WGhnFV!YVq(p@<MWl"Vohgqgq`#rr(HhNtb:-0cL?OARRF5>SSrL,8O#D`V*.=-XV^?U5Lea^q"P)\4j\ZPo;5QYX2Iq0[\UM;B^j(2qEfe\4+1RQaoXQW_7-!+2>+#\o3:Q^O0k*;mb0F_Wo8h_B-K<kWZ'Gq"s[i)k<VdHq#hRADSZGo[MDAYT2&WC(2-k=)7hP,t3jh4!W8/A]X%6I&\Rq8G,@ad0]EPcimc,iFGii(lmP@!Q18o1BFi"V8P\jXE]n-L*mq?og0TP*/$:rd.6@>i5cP6;JoA`aYV&0e-_FX<=aAl'o[,1l$++l(\SYh6"p/%.(HHM2VnotAeY)o?]S!;3ucBK3cpR(_41\F!;'VBd"qaZFXmgc2]d&K-bm?Cs8"#K@ZjeAAHogQ,8*;5M8:^<WmB)D;Fn4"2lo(@l)n3u\e)*oVEk!enEfU`CF-!%9$?tEM'Q$j;ro=#O@g;ZMt!$RSU<Q<9q<iRE6XCA<HIUPiur#^A$esP3P:<Gl#aFJh^\<b2@Sr+OpM>klrD?9R:]dcldj3RT0R7u1\'Vpi`\-40<S8,/G=]Km?9p:=]uG(OUHf[TVA=h\^dgUF=6mQQY_.5@bhR41D!%5H"+A*G$G;j.ms8;)qfdAVp.P.;E\Hu:QHg1lVqn9T37:iQ"$UfC`S+W!5'kBr[\GA?lZ8"K@+@ckbBK"M%UJ$Y;gqc*9,*8ToV=J7eOC=lHsLos*nO!?ZSmK_U\tN\'XJt_,%]UT#!%7EP,L1^@E7kK1m@Ms0F)UbLZ&UUPgEu4E,#-1oRaGkpuE\%IL7R:.)p4qOiVkSHU(jZ+RtnnrOe`4eT8S2e5l3/[5I6'$?sqXJ7-$:Ofp=%QSV9E4/!Bf6aA6$9r.,aFl![=o+>,5.L4i$uV7@Rs_%V/1YrCo]7^BCF-iS!rFp#K9bEdB]"ed4k"kspO&r1&)kk.rJe$Ad%b3*(WYuaSnjXR_sK4^Y]l2fraLVR^X7.E5dQ<jE&;B#8[lO@;VKEm<"MF-gV2,SZ\cHK@CI(U-IM1L;"-Hnm^<OobeA;e.6F`:p7>Nl1Nu-eiB[Y;J)BR)Lps!lV;&eBpMmEij68-Pl#msV#&O,NLUSe5klP[aE/TAGe[="qp;L7Lj#^>8QQJWTg>]FY&,E3CP4UhU><bjO%&$4;S!1j'K2$'h*P"AM?pX[mm)XLdM1m5,ep$EfWsA#=V89$>2P"b!D'1^L$uP6!caN#E&emWc`g7W_%=d1C@W-MFMT"CD?O0m)84M6T*d1^X@gF-0Xd+>Pac*CR=m\*sfM4@\I[p][.7DY!Ta*EZ?T52"^J#O*Bl:Mo=p$[?_WbmFI8_k0nN<u-5%X?kJ>QcpmU*-MOMOTX35!U1&X1KoZGCD_o6Q%-F1(R.\8uLN6IKoi;kGrSD7TKMa_6o([UD2T4$8:`n?(!.U7.[mi(.g0T#k4W2#0=WqQS4,g#,S5V(#;GY*E86KHnafG[B9r25Y[/ZG*=.5*]]>YBp:YE0INUPqQCu^*sSZJhoA(@Y#>E9_N&dX3:AtS4l42A\ijIr?2PFF$qXZ^kWS:5/2eaGPq,35gsZhfCldXp.4gPU=*)FXq!TYh**Wo:+FC$k%uCQAu`e#Sk,(.)raN19mTR91a;+BlBXG+BY$FW6kF[P2Mg@UddrZtmXff#5aHK&A3,pEDLkTD86K934F.L;XpkSb&>R?CeCVFZK%Dc25Ep>e<@(F)$?p/\6'G!<^/JiqdB%HgkG,=<,rU='fhg1h5KHhT;doShLsmNYgp@(pjD?sT$'RJRp.>?%=-b&tH<M-./(LRZr\n[t=mO,"lOq_CZ`96C%A(&Oi:H!8Z'C9KJ0WE*qT,M-5F<^e/8S=g%g/)IE2<-6<j_C"He-ur?_=p4&K+G\;]#ESD`"F>#eLAFeLn.&W7l!3fZMkJ)Hl)5J)cHcT4amimO=:J?kImNkPeYq!S'\2RHZ*(bKqk9J]EiN!E]SENr~>endstream

+endobj

+% 'R320': class PDFStream 

+320 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2691 >>

+stream

+Gb!;e>BAQ-&q8/#rkgqR*LR\BX4o#@P*/N!fX6sPB9(;[+;0jaO9@q$[e9+$$h,K9ZKX>_Hc@+r,)O9JpY0U>EhSIWY5.BR!,q"=3d&:3@(lcQlZ?S7!@IEiYJ-B22h/Nm"j_5o4^>=9hh;`Q\E=:S*S9Vnh<S,jeL`]u35^1Ujq5,+K9&knm5T'2Zt8"iUanEFLW;+K'BVNHm=-k*?]'bK*bmKEHR,\\3r:S>PjGcJ:(o3LEKEd)JEM%4@e:aEE6&_(5fOB)>N'W,HHe8L&n7h+`."'W*&J1OZBk"begq9u=NVYOdsFEhTIs.kn7@h</J]Lb4/(9\EcIof9Z";[$BlLDPBZqjV_&HQ@/1EH;%iGU`u;pZJeFmo)SM\IJ5"pLHnhY._rVdh50`6?;HRO>#V&I[RGnHVU=UAS=7>`re4F_2*Qq9^2@b\jcD=_!)DnkH6PX9)UBYV:J14`P,*V<aHN:C3QN#6R^);+->uV6&Y2_P3IPR>,&<Z4gE-(Z@R#7BnjuR\3)XDW=?2"c:IO9sH@R\-"h;tOFj3gMA!$Lh<3fug+iTEa_>ZSmOS?>W?C"rcmIHT`0hDYOI$(:Wb<p2_H&gVjmVHbE&%RdrZUBiUF$t+=tDocYuOO8(+9pfoPV-Z+3X>fKo%34_]f5G$2MS\V):;;e_h#Y5E`,eE+S[G#p?L:c!Z^8#X\.OHtAHpL1Mj;TlE`PIE43J#;G[e@?#*0WV-K:afde381o&AY>_2+bbV8QZ\+TYYn.MheM`!/uCn^"_7T2k[aY7Y?*6-$Y#8nKMmE=4g6q95;cIg;$3=J<ZNMM-2s@U1Hel'A,c.72`RAcA.J*-pQp9G,$GTB!]02j<-9@*p3bi9NraR-#\LgH]Nq!57ebP=Of7lZo)c6n%[3k$2VfAHEC+3uh0B\h;$S0?Mc.9AtLsG\TBp`+.4m*rFOKgV.j(b`)r5o@d,:[]FQPVVNYYKqE]$9rk*D6d5&rNq5$>)`$te9GqYTe'\G!R*l89`<K.j2BN[0=WA)0TpgqK?A55&nE@.:?SY#:Le2eT"dbYqI'ZX@8=3<;_!<O\nO\fdro8<(O:>'.T*JNA[imq-&roY2&#3d1_u'FYZg5CscI.oUi*em<W-P)AU>=ecQTPe3\YM?sAoY&PF$pXLNHDO!pb!$,aU8mr+Y^c/=oV;T+#F>efT4MQRq'L7ee08<C-Gm'ma33u`<bTJRiAmsGhg@FbZV:3)-O@(jhV0l2st']oHL-'c?*sEl#_6uGIfr,k5)70VlSg;a`993XG<9kg]V$-9j'g1a"6%+AM"uWI9:Ne.Hm(sN6GKqs3k\[OEXYTo4>#N5u&%Q=3U]g<r@QgpbtWmC:6DXM5F>+bu%e4f$la4M!MGWWnRK82!#/fVQ&_7mWP5D%/V:K)gZkO@1?F4j"DZjT-^?_^sGb8`>d4pa73\t-<(=(Y,o+p'W"oDRf?^n^XFsCBs,(@fa>u<b(caK/_?2M.AWgrc(a?r=u5O5ZaTbJR]kUi]`)<>k3HE"oY#0Jni^"(f/pW^hC4?XO-ao%i.j^FNMEMXo(S'Ca/Zl0E3^V>e""ol/388eF]Nm,H<AC>;Y.P\``609FNRan[G5Y\'i7^_2:V_0^F]/Kh$TQ.LL4]HDI2j]D,Tg_E$8[&AJ+&ZI4*LiE)+5_9"jAeFp<GGAU5K4>8K6cL'+:j`:i7_3Y'@HmY`BgnF1D5[s*lG0=2Oi,ifAL4PJ<OTeta>"/a@d?G$1-6Kh@eIF;qcJC;qZ:$rm9BG<"12PMV('e5oC)[i\\Mc5aA1`$Kn`c!4VGW35Q[:&RkanW/Al=Tqc(#DFlVg*+6Ubm:;q]@HImSIc#b`_WgOcsOoX%[n^<&A1*0lN)OLS2H%2Cr>%`]=9[.-A8&_S#Rueb_Q&YfaeIB;lW^[<I3`7BH9n4C,@L%jk#qc0Yt49'n:%jc8qp,u$o\=u7CS=GtEI.9=Sf.4fY#o^If\oX^([pd&/_h<Xci_d1'bS\a!pSu(mP>0Qdn5M7ri+eP=3#eSCE/W"i*1La]X@#*Oa`U`^+B]!Mp;X--*bU9ptk+$^',QF$I@1J=jp1k.sp+/+]F`AEoh_[8I/s/m0UI;nUp-#<@M.**2[adVc<"cL]:R7N(mCP*mW+a**.4,t>F.4IKpIK'c-pHh=<ZpV](tFo"Hd;1i*:QdO,?s-_IB#)G5j?]*fEkaT\)/!8Bb+^[^,"/o4KOATDK-%U;6`MqMN*e_O(q-6,(XkM9n:*T/SlIdm\';RfY"]s^`=E)2D)#<Ymm>f3aucH^?bMf?QU64@l*LmG-sQ7T$qVi*NIloO'=:h9s"Sa%'sDL=4T&H(>LF+LjL1,K2oVY;n2VSg*DH>YmM:H6<"U?Q>(WMP^\@WJaor);EqZu!Nd8CkM0P/J1268B!@NX3bgulSK:C[chKuPD%E5tM1;Y0.<?@o0+hPWDF$,GA:-C+6h,Ni'E^1&^_=C.=>"=9L@ng1OiCE?HHurHml_H`qB=I6Xq-q()knRIS`^<bi\pD@Ab.Q\6AW<De^lH6VI,<o2%;jVi7mM`X[M>%72"^+kEm)&fWsNI<9F&Qn;L6c[dGQ'a2fGTJLu7aP;+S08ur0>SgdPhVYr&(27&]!eF67SpcX$@)O%E(\gXKt@$0=l[ba*[Rsl4!hYhG63M-.'qD>tBSKGrF&^\>Z=+:6\B^E\~>endstream

+endobj

+% 'R321': class PDFStream 

+321 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 3044 >>

+stream

+Gb!;fCN&":')`jos'_!BFY;7VX*qVYj>_:#ELSqi[fqZ##e1N!b>o5jP-VFmoll.d?Mh%ZZ&;i=0^P&m%VO(W3AY[]IJaH>cR8sA1P^HeL(Fi&^4^G>N*uVeHoliRifj<NrU&VW$jOOiN6ejp&)f>r57=@e@5o+ArQ?"eC05=0%;(eYbYneb!&*C/[,Wt[e!>FZV/G6;4F7P/5@FID]D[faqc!=6O.4]o_dUpBRb`]YCVmD#$ob:-DHh>\_titT5/+XTqsDG)pL#RiSDo2>UVrl\>_?8_.rV@%3k8WI="O-^'`MROdbAQY`?.2t!PFbRK39p]5D4b^B%eX[1'=f"oeU<4ja"-9,Ol6R0u"A6s%:2'&;`C^)<eId4GClE=aKao*YK&@6=rBnf7;)f7>-OoF/I/")E2@Y[)d.ZT1._Yr;M9oaaus2DOi.7&C5d@gq#=&HV2p"[KDF0"G6\,Q-@J:-&_!*(G3ZjB`;O'GfIC@CVpN(bnH]>bkTi'49$$`(*uDn&T:<XrmI5'iZ>o0KZ&,ej5lJNpS0k_k3MHU+'\UQG[U9N)lGiodoT&rHf=$4S5-1lACR<[mc`DL5@;`F`U:g$MJJUoeiT,5"qo4gJR?,QLRSsHN^EJJ1?s?1c2*N[cTKT6YIf-1*$6N/QBR(%@//ehl:?d)hAr-\rb@HMYm5lrZtH<`.hVqWWU/Lp^Yo%-pArK2cdING\pt'?o.3p?`%VIO(aKPOkE/l(#]u3l;RuIhgK%;:f"jdX(@TNK9VBg],hSs'/JPZ@d,)]tpoQNEf'-ReVqOffI`F1hQC(9h]ZN!Ub4;]B#gl[oG^%/toEYEKS8/\f&j;26f9g!XLfWS;<Z$+nPYm"Z>:*%Id$#d`DI*FW@j5?>KMuiu4g+$`UpLC80olW*f2tcsSVc@Dm_0^fcMj5l[:CVLp^?VL7<skf=siG8oWAIE!3&de.eFu0:(t9=LkX+f[RQ$(YkVj1s2fE-kGYTS4n@u<-AfCeh$_,F1?qPYRqh;8BWnZab1SrCDhi,5P1EdI<D-2aZ.oBo$cdi4,aH<+cDemFC'3?B4rDrYh$I],*^r3M8m5p7aD*0IMWtDXK#mN"gq:'X\\W?K]-o[3>AtZtgjT>7$1</\[rc+Z.#"S8I78F[,I1l7HU+5E-nrs\A[g8ehn=E"_-f51_C:.:]KS\E;]*_*_0A4Q.mH\bqB/DA(.=4Hd[^grD9Eaq9RdF[6h./6RK2>iIT7&05#N(f$sAMhiPe<iN(m671KQ)Z'iXWc;`sOn?$#Vg/U:>dpZBC%Q_n#Chs<l$giT'Y:_4?ki^h#*@<Kg8oli["Y%6<;gRV_S@<WBF%J5pNhB`_=D#!Q,BHA>-2OO2`khMo3,F`'!Z.6P7gpq[5Dcn9HDd)sAWfl*'^ci/)(rpK!)P)SQMrW^9jp.@NI?i6+d!AH_lk]Q?%!;S!82<e2M8[&]=1Qh84TDELH0"j.bipZJd`1nj:;gkZJXAMd](Q2F,;\+EY4Mp#'HCU^.C$M!<*au&HV9PP;lk;b1.8JnP^O8,i_IQ],MBH%#/Lm7b@is(cL(Xe@YiN^,KrfC@4GZe-I!E<(^*a:$OP[0-Xn]VCigU$%3hu\:6.du9nb=iY*?steCmHI$U2SLgXjHoB-)F/K17KuD`G2B6E9In%jqm0+jW"BT\rim]%C2+9%%M6:SFh4dj<tP/N=Rt4=^">G]=nOb-uT';r#c"FB?)Lrof`8m#/s4G;IQ1NANH6[\QQNc)e5'Vi%fNC=KRa;B<Jm\<I?N/iFhT.:/JQYDX[kgNlE$\bHCJ[('+f?S<02lJlR)s*4LY#-d/g9AR.APf*As[X/#p:1f"-Y\*B$.%asJZQ3&bDhYW@BY(E$U?r7?ei@SLL1-ifYnaG^1ae-\G;:]/:08X0l%L>:qoDj$/n;AtZ)'(Q).'4eCg;C2?*"M8m<?X>f!`94..>llcj#ei,5">baZo_&QU(m>Me#MlmC&el4K#J6FNZ@V:dNiH<ha%8of@1eA`#KSQ7NcZT%5\K]1ja%)?Z_S+E.-Ts+jNsZNhCDqn[N/W\,-J>n8b!B>GJA=ada3"!*$54uRsfcK>A^k)8@]cq]PZ18)nFi:Yk)U<&1K=u%+5AO`/k%.Ot-",8\lg:k<fX:ftc6b?6cQ%SZ8#1V#SGnhb0BlRe+!?r+FE#eqA=-YeZC05$d^P&nm?GQERaV*@rOT6sHQ,gqPIHS-&-*=`Pm7_((%H$NR'%=4t>ra3F8Y;kr$,<ea:Rm<7A>ciCr\Xf;J)cM'$-q++-i93D`u%g+@p-Hf:=G5&;C:jW#hO":iQ@m$28H=oRcOY7;G>269D0`o?_KN!BPp$hm%0u)_74h954[<+H;-lbMYEh:;EU,ORJ=sfpI]&]Gg<#u&umV>89UtD/4$k67TJm4,GT.N`SFf2=K@!ikX>f@G`RU>'X/d>\OtEei@:gSCgBp.;e#VjX-&:ic!(Vi.j+#`;OEPSnR*Xe\+='))]4%6O;Y&<NGRL)6_:*V_YF_WCU[d9?pX'`VTVU)W0pBI^"p"5?W8'%@-6.DdCaH?3aHUGPK'frdcSogPq!]>HXoU)4-Yu$fC-O=$>Mc4;s%Cb&_;Caf>MJa1>Q+CbW=oWke'4]\R-qLWXc'aJ*UoX3!m?aC%`t*_aO(XiPrs905<J+L[%m.`sqR;\X)o%dnZiNJb[Ukm:p,f_@gjHLq+=6jWnE537#=eNMfrY^QT"OpD^dKPqAS,$6_^Q2-/_fA?fbpWNM1^S,G1ZN</[fB*n:ALK2`,[jAp%WIRL[LkJmY>iZj&?6otXXb@`lD0_R#1e+VG1A8-,4XW+;P_.Oh9UO(O\g'BYL;DqiRi2M0nRs\ID4r?D#Lg#YK?kece``.a_:6L(,_1)$Q"k.JFFE4TjD8Wkpl^-rl$%#kk>lOG6!4OfkkD%R7t@J`'K/jhBXLa:n.&G+!^pNNV]G\T-10Pap1R%A$j%T1nO@-U<l@dtX9V\e9G1%$J(!j&@J?6i)*QuoDT5!;FOQ_Mr&4pK7"NEI>,934!FEM8+4t7Y?2~>endstream

+endobj

+% 'R322': class PDFStream 

+322 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2616 >>

+stream

+Gb!SmD/\/u')ipps'a8-k7fg!l<X//Nh'L,\929bm/[EK'tKM$9("IHU_MXg^R85fU0_Y7^$EX]Y[LWX3BK=KbVRQr6g3H(aFBs!i+`U;hhMbd@601J+7s"<&T4JL?[^njYe5D2LMf$f%IfdVmmFSjX7(X;V\aL]Y^ZNXXbQL8UL62(^bga!%.H%+V\M_<J<oQkO'TP(\+9g$s+'A.]_p+Rqka/PkC%8<@4u<[c!ucfP9:9<G]kZ?.[$IQ/<Qp]\]C&`%W4Mg:LP\Q&k!4d'J@E[Nc2,:bTW7NYo=6)Tb9(Q,if1#V1da&eM70!@jmkS/ea?U@#A%`UMP"+CM=?"XCrc'<9R%jZAR%4/7TEO>fLl6.;ZX4<^L?Fb\6XrJLdH@#R=DKb++fZTC^LV!81YPho^L.3>=N?[c-1P*1G<d2+d9?._CcNa5K[EAC0k.BVR4]-G_bU%[S+b(:!tfgfT:6@Z_%MKS+?k1#W\VIG_+'3.":WQ/C0LSO"T=mP1b]XPBa_@s:\(Bl?[R3'!pu`OFG*H>SQ08o>%a$>nYB086\OAHu[V<q76ij5IcQgJ=G+?LJ!c_]K0aO!^2W61^pnFnCu7Z,Cu-/l;[_M9srm_G"DBTO"]+8<m4iO`E=q]Z:J^O;1e:+bVIRlI[!i#Ok8B;*d4D!PM#^+E_3%EgkTOV;,O;;0%#'dUmn;\0[P&g5!W;'cX;49F@2dKrR%*'oVD&<2/pmJ+Jo*XV5>$q$'th4B?b8QZjMk#!PY:R..UDCRl:S_l_9&7-hZ(=dBVWEO[GaKk%-AX1Kf"@#c\r4A-`_fu:%m],I,/A=QsC_TJb($hPrM.hrjEn]"uk5a&o>EU'0ZJP1YboBd;FdiOX"A3!t+9*(U/n\s4746j:fKkGaPpCPDC0FYMn>]/MOH`SX>rHhn^m9La>n'cbS2*BCpb^>FY3U_2]3F$!P[.=jth3;&pl%*4.o/O'Z$/Go4F^IUNU^T,,Xqh1XG-1>srl.l8B[RU$%<DAO'M3``hjG[dN2C2@1LIm)i.M'6pM;9).MJm;[[$Vbl/F4:86kbjS[pdI^-65/gjRjLeT#gQ>?:8`h'S[1";DKFIttQlC&92+@4%_=fRTNJbUB$kLUTL>]EibY`oP-t./IBd'm*Tu`s%DMqai,OWZ6/Li0R4]VDl9Gr&VOeo],&RhsRC,ICf@8k(q*X+7Tmem(8*N#O^r-2aMggU-Eh'OQS>;f2h!,R$_ffE>sVr)haX@6K.q=6c7UNfF17,*1P-dHV%2;oLeITLa\Fr+c67L#IEDlPi4[,'tf'D)3H&O7bs/9Q;T%S4"!%'F^/H'P>.mqlI[3M66qD]R/ngo+&1\PN-&49p;<B%1u!en@SV,6n@O>Q>4=bu"\&[mXK/i<rCuPV]kq08j$sh8VeF3O3$t>`9P(RF>.Km\0ZK$Qds/f/mpLhf!bNX@U'CK!ah.\-^.%_dr=qpGZrT2AiP!4(:;G?dmAP0`=d,?=PSpP]$ND^2pD=890Gq5ai<'I.Pp?M?B22/.)og#L*\c4<+\f5Sj]=aQGMGp2EBG_J`tCW<Em8k?0#8le7NL@Fk*okOW$0-"i2uNoIlY38U_#QV@V)ajdC3;\0o3.@A[cJt,,u0;n1_YA]Uu:+`t&"16+s:D_mSOZ8&K4KX)msAZ,`C@@*Eigb]LB_]BI`6NKVnQQJJuhZI]V"BW$9ZXi8dra"CS8[bNhfrre^b)#cND:8l<$)Q20=5@j9QVL;22-Ju64pk+l1[%s&s.SC6t-Rp?rHsG(:$le:og@O9_J$)P)dK!0h3JXCW<k^2pA!"OpYqp2rb>@+qAfV]8'^ZRnSL:m.:P>#G,#ZR&Bq=9@m#!>M2D:sU*5EeBaa7=PG=&4kFiM8ml/T`:kR@=*nb<Zd:,&,q4?Q!>;N<U\=M'41-m7Yhm9"Sf%si`j\``LYq.k<fLV7*joJCgJXbJbJnud0#d0jRtiFp/iO]TTtm5Nd?mp=:@4%EbQVALV:8IW4cQ;Ls/TDFK$9UUen@rojoWXZU[E=%kkm@uT'4GW8&9%<FOWQV]>'aqOW.OIHd_U>9R4e0nj+C/O.bh"9N8nQ`'#s?r/NIp[",LIoM#PuVT1/d_,+jW11:bT#]$BET_TDpd%^uM_^5*sM*<[PY6XF71^^$#1[`Q#K*6\Rc#KN(CkE3rc0cZ.B&eR3R?H;]O#@hVTa-^F,.HiF>'o2M76aor^*[V$I7Lt.I(c1Nb[k:eE,P"!Z@2<C,RX6;6HVJI5<Q5N=COIVc<a`/HFPbnO'dZ6Kf=c7utGVgE5:J0+Q$V$Pl>E5X.Nj1HKg_*uL+6*`,DT41iWH/$%U)N7C^ohk<"Vu4sX(!Cf]SjeL)N9i,mbXL"e4iUH0D7Ink8Cs`Ja.CS_o\V%l38Xq9!'rWL/"r'j6!QZdr>A3ddkJUEMMukY<#kUAeG=,1E#oL]ZmD19b%ndMPUGR4$&V"1Jad0c&jq'Nh5!U/Mu%Q[9/@^Ba9#md,g0<M8Q']dcQ.i;E1F3J[0,([u#YkSJjWa-s.>Hh^@G`NVB/pU:89@*>R$"X7CE%VJ.))jAn_)^+_,h=j[\)oo#iG:0a<*Q1fNu3Gap-H4kSf;^rPh^\S`sR,$'~>endstream

+endobj

+% 'R323': class PDFStream 

+323 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2886 >>

+stream

+Gb!;fD0+L@&cV29s+gOg,pQ97]pH+T)9&m#[8u9TkB8n/5<q?$%P^PF!V.N7qsFM2O$&OeSmo<kUld'5!UN#&GFf$lIXC4$S-&VmJFb]@GWmZZi.Xo3Mmr2%naaXHoAc+s;$ao)9I!fk)Y`16X2^[/)gHf7pFfn3Y$QP'e<s#T=JXl#%Sl'`FQ1f,kXa<QX#i<2]l.?L)_A]Za8]Ut5#i-.luOuQ,KFh'm9i[PIhRFs)Hlum,h9b^7.=I!a.=Pgauq"Ce00bM<0h<k.hN<5dtD]*I3l&QEOCrZAQd5cYuY,5A[3;rA.Zu"&sKM0Rdr#],Pe(/-WB1ao$jA%(Rn,C@[7Ci_-9rNnJW/ej[\.qFOjka]j17clqJMH)o;&Rc!_o^7,Ejg%bQek%=%2-Z@p0;;2K740ClNl+NJVN_dfqaHjMe?ko;#2iN)1^^ELOcKW6?_SN-H'9rE_)@]UM%Mp]U=r^"YQc.2QME30]XQ@Tj^DE:Z/9)t^.5m-qt7H"%=k5=B<VMW+\BE5n6Wq7)6;sC>N`ZLZM9VTo7PWnXL!8U\)n?ItB4&.,C"4khY/VDE3Ei'4u`m(lqp0?`20se8@a<eb[h'>,'eWMN+Kb3L3Y?6qJ^uAU87K/)a7aXW;Yi04i6"Ft5e8+IA3TTNOa+G]%S>gm[,a,eT=n)J2-"B@Ce=:?@?=Z\T`=b'[rlFMNVhkhk+bE@QCrJp>a7UmcC^Dgh&s1cs`E>CUIG)PHilmGPdEdXp2^1Zn=iP$HTb1=cZ`u=<ETt[DI%&V!"r2D=-Hc7-bqgJn"=d&+b,j9^__(%SI9fkaq=5465I:BWfTZD0n>_e8B<'$.*9pEL@&oeJ;P5o4/aWqrI`R%W-kbfH_gG$=U_7kq6R?YQ_H=2oe"/4r(bj0q%tC@,J&?=SoJM@$^VBc5GVJ;nFL:5k&Li$`Y^B4(`_O'(m'[.Ub3c+8e+M)'hIV;kGsFMO[&u^ij?.?9)ge/"XlbAh2$f[Eb7fM9Em27P]UBjIgE:>cmR)/Bk@&I:CHM&,RLDi2>JiiG%^%3/`W4k:"qcTB.nY\=n.'8)`8Q8I--\D?#<!PeY$SMs?0@lgiiohqgI&G_^E)5qh2g^S*]cAA$rQbFU2bNomHcMHh)f^O?dUdmn*22eF4Zh%3;@*,""u-C_o_gj7HQ]2,a_aO5I^NS[B16)'G4MtIdXu\NseD@e$WHO"L-h?@#V]4$''uQ9>ko03mm#&WR91VBfoQ[$5Wu\4*Q&oa8MD^O,.om,/W7pD%%<;7Uut%2_JmUjBE4+1.W90Q25(3E;fcJYo<fM]##mR35nE6FA?mVXL;'FK]U_;fO'9A![b#n_^khHgDY=Z'&R\o$E]f.f88K;XuNgZQ81'$)eD`kna9#e^C?kOQN[,LCKW(0<_jlpl8^BUJ*N:FMbCeGM;2JO;seG_G$kRc?#2Ds&Jpfe-](QOjJlfoo43!@`>o9;9"tWT=lbrbI4BoUGo"Q9>RHq?>\LGWs#fEna+>Db@VWVT1,[#G=t!"SEK9@+<oA]<*^6>'gC=61g5i//<ZhQ@W'VV0G(@#S0YN2:IX$hIRF!D=OH,U9[<IkeN=0!8H\V/^TTT$g)2@H<@;s;Th'ef;Al"E>Ff+cYQ>OoKRBkB,[O$8qQPLV&0T:U9*;8$#L^Y2kCtNM?iH'7V\Y904`akrVoWr+e4%ME7E.h(.B5+bkS@%spP@L2XT0RBU_b+=WC<[med)VX!^UO%9'4eC#-[We+"Cs"QS15ME@'tRs2.p#>UQnFkF5Uf*YD[mmAbK6h.94;jZ/i>1cM2gOmAil2Urg>.0SQj=p/oO*m!K$U9=`(%H#1kq.d@8!;49.V7(rcl;$u?HD<VR4>$=udRbqL63QU[*'"DXh5,JH[";<.6XXjb)^0H.HABaD@(f[gMeqheWI'A>o4VkP7$e/^^c:pX,V)9\XK-Cu$$4cM\nSkAs8+b4EhRK"364(5LMuZi[AmA^n9D4r(5hTVpW.8H'VpK,C=-kM8Ald^\9""!V+=V&Qnd&6gUE0pYjf4-=[6=%5I?>Ro&cR&.k--1e'?<2%97@Z"#on17'!<<2.8$3IM$!-bX;kY!N]V$F8lT]^D^h&$O*Z_(XJN!$BjbbIaIt<[*2TW7nd?n-5BFT*gC515THKM^ahN9id>cn*SSa(Dfb&/\M!a,>ZoG>lq)_k27TA,kk2`40n!Q*[ZVH8pWV7B.Tuij>M(9i$Ku1l1IS[56HJOsqAhoKmO1XghfmLfao7A9rL89d^Rq<C%/@HO(eri,aUV+X;8"HCRP/j`/JCdlL@aq@Q:HpL+P)Ym?d(H4FHhEEda6uJ:V*\<OTXo?c'n+eup]q=?qL+#$;r_S>=o+Z7$1-0M]\3uE'Kj?\BZmA>ga=@N2S6r<"1O=,W>p\\>4qs-#7F<a^IP-YAMn2iCH`d[Dt_t\rE8Qp%k5pSK]l19/>m`-*G-qOd?SU._D<Z'bp#tY=%X>W'pW%e43q&Is,F0h]Z/B;Kd=r2RTQc+'s.52kkn.OnU'h>1O+MNJNhg/AI&6Er\UE4fi=&&i#^.6fm!bp3OP$S2F?MB5D*XIoVqth7Os0-B6g3EJaY(fOGH))659&-bm+41ejmLgbT6G-A#q7,XDP//gpXg'hiASrRiMo,h3*0-GL4ZklfQ6[hnQk+3^@f9\hYUWBA\N>[Gc&*0^4:)S]C2mMHbKg0l^!^,A^rOpcm)7kJOdh6$B#URe'#NR1b7[,,*"$V?"_:[FAuhXBh,.Z(En@.V=2%n`DeT3:qlTcNreI^:to\fQ+=@5WZ,*YCZG6m6%?,7@EpMQ[q>aRZo^#_u1LcbH1WK!p,0K((>\Kq1e/<-&]BXGP#fq-1QNV_FlC61/J9Llo&%E"8<0V?i1^$oPl5~>endstream

+endobj

+% 'R324': class PDFStream 

+324 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2692 >>

+stream

+Gau`UgN)%<&q+ths'abnD_VLuhSd[&f#k,;=XOuk>?c(gL;8n@#f+53"3K?%cflJN"=ZqeD3n1!\L:q6ds\h)oYn'Pi[<l<dmAk?/]9U*a!+9s@O:#R1_u#$ik*2$BCGXTDN7N4,"\N^"Rk]*+,d>_p:Fur*6$#fgc^,kWH!.0/@q3D`1df_*8rX5duC\I6<=Zma0*C>,^CgSIu;30q"e@npO2qtf0aCeanQ0bNpG'(H;:J^pHSH2`Og@QA(=,Rj$j6r:,MSupWAfM.q.bllU!W%o5E4gnaACEOit=02r[U0bs8A4/H%gN/!_[_Te[e?<&l>=&UpL.P@_0Z+!;abegaah1=P?R*ZI5Nij-e0d<MdnEh,h+:$JBBJ:8'kHdAS\1BQR0fSJ]f*.K/E!%5PdF96DC\/7C.]S!!jKokCs<*%oA>cf1!X9,JGV/5O<ptZ<nN.:Sb"lUo$%q=aB$fm5<Y"f4E3ZWZ0i"iODP1>Oo_*YS+*eEnQItX4Be%EtVU+QNT>N]!0F<T7nh\;KieL:tD<NZ[/H3Ot+f06\H6C_AKN?dr0NS97`3tK_FXK3jAE/,>p"cO>pL>G#STM?r%889/FicOrCo8g]dacCeoR3\[b_1+DDKRqFl4K#:J)a67H-j&'Q]nD/#4B%aQ"Cd)K,])1V8,*kR3C])B?>fRamtO@a2UVtmRl&*,kEXmA;(@hcfbF!HOefZM!9'=!iWEJ9\'ZWdaMKl,X91r'Y8MB(eTaMDnOaS>b(9?HQg93!5)guL=PjmH::g^g!/3%F1WNIF_imLoFs:nrS0ClaF%)t5$qb/:$R5+>aS])O.W;^P-,l4l%%o6_SVBjc>hZ0Bb"=:/Y.[jgj:<pmA6CBDGYg*KO<ZnrB>3Q8NQO>T[;TgK<5&FZ#=/G]lC2!>/c`-D&@405";DSX4AJe1m*Tc7S_p?B,YFr/=c!*'1aP/P!JuV&&`q2B'#_[Y>aq"nP6d[[VPml,,InNs7Ei##?#B3^PA0S6\[;n42jGl-^(/icM`#u6n6JCe:>AIB9oY5Bp)jW8c<5:jXBoa2-m#3Bj:P3[)cUjrl.,<6'M=q2.uF%uOJ3+',eMRkAP;@q9F(79,0fXo*\g]f_OPrqO+u'G'TW+=go4LM+s`fg8<p+hD8;6eU6=aMeL4P.Wq1V]J6@RoEV^H<IF%89VcHAZ"mZ_8AHU;hBIfTCI]ah_Ppm[[_-+g/rT[DH;AXI!b.:\)D@Y*S/?+O-UK%Mdg^jrCZ!)\q93d@7%35]PBuqTHIO$(R6m^5OaBPWbk,l(8*XfJQUF,JdfjQH'*\45iYC[D@h9ZnJKS`j&;CjHdFi/n^d.,lpoTG="bc:EF[WL0%4(E2\$#g,O7HQ1hFd:qY1RcMWG^]_9$n(*"`Pqcq71V7o3+a*%.4.I3!Q2k'&S_p0[GFoL-hSM)LXCKkEp"2Z^A[$dZVi'tMeF)gnM!RiUh_,m.[nS$ZMQ6jfB;;C30'l6&Ci"q+daeVJb9RL.+bX<fC*%'h\i\l"%e!se5.t78bXW<r5V_J/G:N6&?8eJcuaZ39*C[;kc1?gln[I_]l#M:QW^3-/C<8IG_0<&pu]';=5:a\BB2>g2Vmg620X@LV'sNFVLN<dIDDhu\:T(m*d%]E+Zbmkl,/FU?J!H25aGcR7Z%Pa<JSl:)jReE)c:eD]7&L5PFYS88)maNcsN<qWHs`\RL<)^)F0T]DKs77'#1EL4,/U1COMrpSi-j@CIM,.\SW92oYfN-'=/8cL')9/#`>MqMi2#@i7eYWKC$j_(Nn)=57Ob0_GH#%L\t-$\^td3gi0<"l_(sIA;A<)DcH4@O4GC)ik'lf,o8KGlniLBmq#MJmrF'5)ihK\d>gRJ<u?\<Ll1.N)P9cI&$k&R)l\(:!tFW`E'h4nI<S5/*u.HG^_Ok/Y>-ZmMcf#1P=b1%_MseTXkHjZO*WH">P')N(\><J*,"u=MFZn#/F(1_eHLHd"#5gP_lunR%#ArNhFU<`-VD/&gXI;)7B^@J9NmXbVajT>)aE"4I]`aE6u;(:W1heS`QZdl-F:IdZ$hQ5G]Z];QIH/)em<>Thb8;01SK[_Q)\ctNptb@.+mr@;'&>[_/9\^Rc@I4EFb]20pbM;W=_nB?tbgsg1q@*nPrklTa[.?crXZ`7_C<?ZQ=9%`9jrkKquK$SnT>$D*VTZ-]?,2(!PO=:$Vj-@Y[![lks)AHngY9+#P9lY(G7cAg:TFR8b:W42hYd&snc@Zrs>H_0;UG!<okA!k*'0W<1p(<0c91L^Q:$4,MbtB?LaDEpd/_N0b";1r>ucA\[@5NB8HT<-![&%nqa]:&B_*Ql3&V3.qa[F"a%Fh0NMc*XcY`0WUk]ik5b;`HO:p[E0X.>[0-[f'Y]W%=1YQTabq6rE5C@7fRr-\+%F^4KLHdTN"bc`Nn'?G)/=nm3,C:#dafLV4fWS)n"(G6RE$`MsCnoQmQlgO*9/;lG.++H1dlJrII'")<@V9dY8[Sk,totdAn"3Rra)GBgiQihT7?q\nd,@>NtZa^BseO(nNm:/'`d-T9!m"%Qduen!%U0K,2]ic7'i)k_;rU"#["W0<O;0B38P^Cf*%F\!-snMuZ4bH`BC3>X]?tl.^*W\EkfB:Y,5KqW(3IM>p:p89-Q?EO7N_*&r+kqJ%sa['.brF2rEWegScY]>&gpk9D=3kKj,/.TL2T~>endstream

+endobj

+% 'R325': class PDFStream 

+325 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 1542 >>

+stream

+Gb!;cgN)%,&:O;3s'\DnElUL8;P^,^V,!Ii1/lea9g<1J5!UB,+TVT^!9MVcG6*ki-/TQK:",6E(L211Sis[k@#U_ns3+)c="4(B2Llp'[")ON-BS32DplOU)ugB$jm`JjOA'0>ZSNZ<.-S[lF;tHm%(CusG\XInBM)l.$u$#65]@XfG;i8gm&h?*O1p?W(`bp=):BW)ocO,+VYfDk^,=AYnr,R>gMl?@\MIf<s.^7FX'e!]VE)9V38'gMrpK8@64cR2S>/@VRD^oZNS_q^P&(@+>jU+mJC,%"FNIp0;H3o.V;Xi)>4Ht?[&O8TW9$VipuH:.%X39FR8LB;QoTmLfuu>:rCNTrH4O\rm(^O8V4aA8Nt/f]K$#(9L3,kpTF8Sdb76p"V>:S+5D,,.%@Z,&>dN5'S?isVE,A_a<\eAnSF)JC0QgAED;gf8-(It/^;I%_J<5_nNa;_Q]r>O+rcb^9%F(3!5<p$"`SgCZ+pC8Jksc8d"^=kEcBQm2Z\XR'kkI=Y`u_/Uj'WUnJ@hZ:3HKFWWiU.HZ1$#O,`]u/H5ZtZ0cEiNq)oRHOG&JFm#[Tu`20-I,/d_4%_*N=&1k>mEb[a#/lZ7tWFl*'%;*OKUL1eXM]E]S"?hA2lbgs=60'd7Fj>M(ag*4XglsE2)O#a3*Z$B_JL%]AeAD6(f#G!.9^=P:-TBf9P$n?eZ;<98nLe5mpkfNRY-'Y,RH[NdN^c``E0M?rV2o6.;TtBSPE1_;?&&$M5s.fS-+51ANP=/D6IJcr9WeiJO.k!:Kk/J5(Tj<X'%Iamgr[&o&;7jTD&tRm&9s-/j!SEX&2^rN>pplG/XP'.F>6q+_Q7;Q<C[<K(j/cYEA]ZqXH!]Rog^os8Xqo&m!#MuB.KiLLt%6$NS8iISm3:%Y&:(41cLCJX.g/1@K]tK1K\XS5V85+r?7'9B?Bo(68V5qa%h'g/HQ,QlSVpR]RiJN&sIF:N.jK&pW"MIPO\[<14uof%pM"5,<ATp]%8^67Ao'G%$XEV;QY=X0NMn6h7kZ1i,sNm4FJ!iIo+jhXLA[We_R3/;`VF\V?=l8OK)TI;kX]3L"I&IKd?0"ZE2G>l]3l'1Kn["Wf?SW[E'JtmAV$^]2P5I5NTkC1NQ@;qA5#\&s:k*$H6Mj7Um)(+kHP-H-!@9C@6E?)QABQ-@NCZ"BnpG&o5RO)QYX:0ha:d,-e)9V@n)ol[YWt8P_KKs1HW.#[T4.9@hWs]E:q[Ok9S-f6#Q;]uZbOJ_\5E$dn:K+6.r_`CaG.YXtKVJ_cn.C::Ia(F?6U;2(io^%:YO^/N@dI\M1\;f)Wi'M+9\PB(9=_]#trgpZG']=%e<qp7KB5l=2XnpIT;^Q;llk)6EW.OO-PS$\G(6)ZO)#f3A%D-\t/a>8hEU[QPIR70(V9Q<Mm&.QMpR4$HFA,\(VGLbcLWdT9#eiuq4Q.7Mb5\njZNJVR^mod4hXC#YY7tRL_:K7A$a9:&+fK=/E6G'.Lp3K^6IYf"BZh@D-7[%*BI+^A(=1CM5X$56fAah.S^u<+:MD\]]~>endstream

+endobj

+% 'R326': class PDFStream 

+326 0 obj

+% page stream

+<< /Filter [ /ASCII85Decode

+ /FlateDecode ]

+ /Length 2069 >>

+stream

+Gb!;fgMYb*&:H4YIi.7CcGJ.9GIqcb[RD!G[[4N$PS[MtD)RQUP#>Qbr=2D%^*]/PMOVIPi/eR34<0qQ6dg]QIVesA8c^P7nE5-;C^3ECYW^0^d78F?HN!,arn>o_^'B[.Kg*5W;/SbI?C"`&hmFIHk-&-#X*3;rBFP"b7OcuuL"4hil7oYneR`*;`"Y7mG7LD:0`".\s$_Ee/:W'#[O/?`9DA.96.ha_pO_@a7CH\dJK#N&L/ou6/$g5">t_T:@G+)@dk#)qi<"=ER?Y):]U6NkaoXa7*mqJ3oF^+B/J!H[o%_5]mf0gP*4Kjs9b8Aj-sZ:!-NtHqKG=kNKU\,>'Nc+sAP=C<7,m*57LFtH4V]XtP"!0-.e#lu!M<aOKo7JtSAk!jrRIh3lSVp"56#K9#<o'\EYfuZ9\4$I"L>tG'Cdn21D]50-00Xo4Q6[+BecMBK:(N%Lrq>(1koNY0<bd1AWeU;5hfu]irrfuL&P/*.'nkD;a<-ql?\oGWY#VoSk8dRUfig2\lC2`1f%eBA]BDWZKlEf,9Vj(O:s)9J7iFcZC\l54'i@fFffI=Ndr_)8?fA)N@'$j2>7M40Y[=0MbL[sQFSsu35]D]@]"l_O6]EKJ0YIE+F1]nO;NI`2uk.cocu0o_MQNdV\.4/TSU,CD:Ob6n<m+e2<W/NIG5_]a1$d.QHakHepnSe?tqM>XQ\Hn@AkbVB'kB/i7nleU:`Es0fmU/a/^4^!A!uAQkMl(>d>W0Jh*`XmbSqd^3u)S2E>bjfll+p4U0`B_aE'JRM53FF<hH_`!a)upcPV(MCP&fBGV5*`E<=A*n(6=Ju9OLrN2'YSd%P7]q-B6L(m&69_V@^`0BlgCk!s2S#2`[J'e3!KV2HU=6kMHWSg1Gj:X$iDaT7l[6pR#J.4E@NX90LX$&s6@.uK\2!70^mot6[.(8ku0,P+@@sd)?LK/!uXS'YPE*+4[%5#_-S,[[Z$^)dU9qLeV<r[]@X\k6u[7NoURTVPIhBMb9gbT"M;K>8Xig4T-H6HEcpD).I\<m]L2oc;KfAM0kCCMqp<P0g]fRm9@27<>UPl!-,7UoQ5iUEMP[g%b;>$/5Nh@ic>XUU!i_cnW*Tb[,jlCiq`KG(3k^oTdZ+-#HS:;+#-'d$#87C+RKpqZNF@6S2CQJ@Oh,T)?t,Ndjj&&u:!8eh;'_'TPb)YP<WP[UhIU(j!a+H/0W?/S%<iA<2]Lb0o:2ois9HGkafI&`qr^:<^i'4K_!74E8?W,(s9_LrP*.em>PB7Z%4j+cO])L\Y4[?5<W?<8W&;Bf'T<%=pDr47IV]>iH<,rt\=;+2RQ+$st'&L2$bY\]5[DEF\"-;`;N.rWap!3Un2I%_/IdmHMSYm;[I.4Yp59))m]e-e+R`G1e(InCa5%1hm\[0F"i.aU*gJ[#$/Uf3:V;G*c2dj:HI7'deX"kiiT*8m:Y/!h#.U6lU.RSQdP$S3]dacKcJ4!"(kXl=SjE(Te?2!n^8V6Y,8+gjsX)cT5)>3pXp.BNsCDE:9QL`u(pA/V`]iO;K6a>KSoD/*`Klb[BS<tA]=>@<Rm3'S"NSQ_r-p;@7O_fA!4X4hM^hti81j`HHGE;[MW:Sg""$Rt%ZcKXnbB9Elhdea/>_Jt=.b?UW-8aJk>kEHTTh]?`u1lg;II[Ngf=,I9]n",R4Sm=`H89u4)ifZ]RLg3^*&Y;$Oj=mE![EB#69W<7\L-)edkT5t&m01S7Zr[^0q7`*\%8N8cZlAg[\B4=F5MPj,Q_h&.r*B`>Cd>L/4*1rbMs%VOnII;:><Q4H7O:l:)OQY6Fm,:BlL)Q;`Xj\T,V`qAdca8Nf0If@aup/lqR*Wk(4G<sQOTuO>]j[Fd(%;/OqmhYWjFr[jLK#q,fVN%rbbKTeCH)>de5e?gp8[]'T1E&>hmHO<#O;[cY*M!W]=*6C(-h$o7TQ6crVV`ateC7iO5MAId1dj-"5@oWkig.A0R0^kZ06EEd$3J4hj-==K"%&Wb"aXc)P9$D(7N*rh1AiQ56KQGKN9'\CE/?F@1H_@n\&D!p)q0AeMYc?LaCA_Wt;'!RC6PAH~>endstream

+endobj

+xref

+0 327

+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

+0000014982 00000 n

+0000015214 00000 n

+0000015444 00000 n

+0000015676 00000 n

+0000015908 00000 n

+0000016138 00000 n

+0000016368 00000 n

+0000016600 00000 n

+0000016832 00000 n

+0000017063 00000 n

+0000017295 00000 n

+0000017525 00000 n

+0000017756 00000 n

+0000017986 00000 n

+0000018218 00000 n

+0000018450 00000 n

+0000018682 00000 n

+0000018914 00000 n

+0000019146 00000 n

+0000019376 00000 n

+0000019608 00000 n

+0000019839 00000 n

+0000020071 00000 n

+0000020303 00000 n

+0000020535 00000 n

+0000020765 00000 n

+0000020998 00000 n

+0000021229 00000 n

+0000021461 00000 n

+0000021693 00000 n

+0000021925 00000 n

+0000022138 00000 n

+0000022876 00000 n

+0000023105 00000 n

+0000023336 00000 n

+0000023567 00000 n

+0000023798 00000 n

+0000024029 00000 n

+0000024259 00000 n

+0000024490 00000 n

+0000024720 00000 n

+0000024952 00000 n

+0000025182 00000 n

+0000025414 00000 n

+0000025646 00000 n

+0000025878 00000 n

+0000026109 00000 n

+0000026340 00000 n

+0000026571 00000 n

+0000026803 00000 n

+0000027035 00000 n

+0000027265 00000 n

+0000027496 00000 n

+0000027727 00000 n

+0000027958 00000 n

+0000028189 00000 n

+0000028421 00000 n

+0000028653 00000 n

+0000028882 00000 n

+0000029114 00000 n

+0000029345 00000 n

+0000029577 00000 n

+0000029808 00000 n

+0000030038 00000 n

+0000030268 00000 n

+0000030498 00000 n

+0000030727 00000 n

+0000030957 00000 n

+0000031187 00000 n

+0000031418 00000 n

+0000031646 00000 n

+0000031877 00000 n

+0000032108 00000 n

+0000032323 00000 n

+0000032992 00000 n

+0000033228 00000 n

+0000033462 00000 n

+0000033697 00000 n

+0000033951 00000 n

+0000034219 00000 n

+0000034464 00000 n

+0000034736 00000 n

+0000035027 00000 n

+0000035304 00000 n

+0000035578 00000 n

+0000035860 00000 n

+0000036139 00000 n

+0000036407 00000 n

+0000036671 00000 n

+0000036928 00000 n

+0000037179 00000 n

+0000037430 00000 n

+0000037727 00000 n

+0000038020 00000 n

+0000038303 00000 n

+0000038619 00000 n

+0000038909 00000 n

+0000039194 00000 n

+0000039483 00000 n

+0000039765 00000 n

+0000040045 00000 n

+0000040337 00000 n

+0000040620 00000 n

+0000040918 00000 n

+0000041202 00000 n

+0000041475 00000 n

+0000042076 00000 n

+0000042373 00000 n

+0000042667 00000 n

+0000042965 00000 n

+0000043283 00000 n

+0000043570 00000 n

+0000043856 00000 n

+0000044119 00000 n

+0000044358 00000 n

+0000044580 00000 n

+0000044758 00000 n

+0000044980 00000 n

+0000045166 00000 n

+0000045385 00000 n

+0000045780 00000 n

+0000046053 00000 n

+0000046343 00000 n

+0000046566 00000 n

+0000046878 00000 n

+0000047119 00000 n

+0000047361 00000 n

+0000047603 00000 n

+0000047845 00000 n

+0000048072 00000 n

+0000048270 00000 n

+0000048510 00000 n

+0000048750 00000 n

+0000048992 00000 n

+0000049234 00000 n

+0000049476 00000 n

+0000049718 00000 n

+0000049958 00000 n

+0000050181 00000 n

+0000050613 00000 n

+0000050836 00000 n

+0000051148 00000 n

+0000051390 00000 n

+0000051624 00000 n

+0000051866 00000 n

+0000052107 00000 n

+0000052349 00000 n

+0000052591 00000 n

+0000052832 00000 n

+0000053056 00000 n

+0000053438 00000 n

+0000053678 00000 n

+0000053917 00000 n

+0000054156 00000 n

+0000054380 00000 n

+0000054706 00000 n

+0000054996 00000 n

+0000055238 00000 n

+0000055476 00000 n

+0000055715 00000 n

+0000055938 00000 n

+0000056280 00000 n

+0000056518 00000 n

+0000056742 00000 n

+0000057064 00000 n

+0000057305 00000 n

+0000057530 00000 n

+0000057852 00000 n

+0000058093 00000 n

+0000058334 00000 n

+0000058575 00000 n

+0000058800 00000 n

+0000059142 00000 n

+0000059367 00000 n

+0000059679 00000 n

+0000059921 00000 n

+0000060162 00000 n

+0000060387 00000 n

+0000060719 00000 n

+0000060960 00000 n

+0000061185 00000 n

+0000061491 00000 n

+0000061781 00000 n

+0000062019 00000 n

+0000062258 00000 n

+0000062495 00000 n

+0000062718 00000 n

+0000063060 00000 n

+0000063298 00000 n

+0000063521 00000 n

+0000063843 00000 n

+0000064083 00000 n

+0000064322 00000 n

+0000064628 00000 n

+0000064903 00000 n

+0000065045 00000 n

+0000065289 00000 n

+0000065418 00000 n

+0000065624 00000 n

+0000065781 00000 n

+0000065953 00000 n

+0000066122 00000 n

+0000066335 00000 n

+0000066506 00000 n

+0000066735 00000 n

+0000066894 00000 n

+0000067074 00000 n

+0000067258 00000 n

+0000067448 00000 n

+0000067630 00000 n

+0000067813 00000 n

+0000067980 00000 n

+0000068166 00000 n

+0000068390 00000 n

+0000068559 00000 n

+0000068728 00000 n

+0000068918 00000 n

+0000069094 00000 n

+0000069285 00000 n

+0000069504 00000 n

+0000069659 00000 n

+0000069836 00000 n

+0000070006 00000 n

+0000070176 00000 n

+0000070339 00000 n

+0000070534 00000 n

+0000070763 00000 n

+0000070921 00000 n

+0000071099 00000 n

+0000071277 00000 n

+0000071454 00000 n

+0000071613 00000 n

+0000071801 00000 n

+0000072028 00000 n

+0000072239 00000 n

+0000072408 00000 n

+0000072587 00000 n

+0000072774 00000 n

+0000072956 00000 n

+0000073128 00000 n

+0000073349 00000 n

+0000073506 00000 n

+0000073691 00000 n

+0000073871 00000 n

+0000074036 00000 n

+0000074251 00000 n

+0000074413 00000 n

+0000074590 00000 n

+0000074758 00000 n

+0000074932 00000 n

+0000075106 00000 n

+0000075282 00000 n

+0000075457 00000 n

+0000075621 00000 n

+0000075846 00000 n

+0000076004 00000 n

+0000076189 00000 n

+0000076363 00000 n

+0000076553 00000 n

+0000076727 00000 n

+0000076942 00000 n

+0000077109 00000 n

+0000077293 00000 n

+0000077477 00000 n

+0000077643 00000 n

+0000077869 00000 n

+0000078044 00000 n

+0000078218 00000 n

+0000078367 00000 n

+0000078552 00000 n

+0000078786 00000 n

+0000078944 00000 n

+0000079132 00000 n

+0000079317 00000 n

+0000079496 00000 n

+0000079733 00000 n

+0000079905 00000 n

+0000080081 00000 n

+0000080251 00000 n

+0000080431 00000 n

+0000080603 00000 n

+0000080827 00000 n

+0000080991 00000 n

+0000081179 00000 n

+0000081367 00000 n

+0000081580 00000 n

+0000081720 00000 n

+0000082060 00000 n

+0000083987 00000 n

+0000085644 00000 n

+0000089104 00000 n

+0000092473 00000 n

+0000095769 00000 n

+0000098441 00000 n

+0000101022 00000 n

+0000103803 00000 n

+0000106574 00000 n

+0000109611 00000 n

+0000113392 00000 n

+0000117597 00000 n

+0000120616 00000 n

+0000123725 00000 n

+0000126396 00000 n

+0000129393 00000 n

+0000131807 00000 n

+0000134643 00000 n

+0000137832 00000 n

+0000140593 00000 n

+0000143624 00000 n

+0000146461 00000 n

+0000148148 00000 n

+trailer

+<< /ID 

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

+ [(\262~\267\007\250\024\326\216\224D*%\324\240\2522) (\262~\267\007\250\024\326\216\224D*%\324\240\2522)] 

+

+ /Info 211 0 R

+ /Root 210 0 R

+ /Size 327 >>

+startxref

+150334

+%%EOF

diff --git a/pdk/docs/compatibility/android-cts-manual-r4.pdf b/pdk/docs/compatibility/android-cts-manual-r4.pdf
new file mode 100644
index 0000000..f16b6f9
--- /dev/null
+++ b/pdk/docs/compatibility/android-cts-manual-r4.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/compatibility_toc.cs b/pdk/docs/compatibility/compatibility_toc.cs
index 5688d14..183c0de 100644
--- a/pdk/docs/compatibility/compatibility_toc.cs
+++ b/pdk/docs/compatibility/compatibility_toc.cs
@@ -7,12 +7,13 @@
 <ul>
   <li><h2>Getting Started</h2><ul>
     <li><a href="<?cs var:toroot ?>compatibility/overview.html">Compatibility Overview</a></li>
-    <li><a href="">Current CDD</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/cts-intro.html">CTS Introduction</a></li>
+    <li><a href="<?cs var:toroot ?>compatibility/cts-development.html">CTS Development</a></li>
   </ul></li>
 
   <li><h2>More Information</h2><ul>
-    <li><a href="<?cs var:toroot ?>downloads/index.html">Downloads</a></li>
+    <li><a href="<?cs var:toroot ?>compatibility/downloads.html">Downloads</a></li>
     <li><a href="<?cs var:toroot ?>faqs.html#compatibility">FAQs</a></li>
     <li><a href="<?cs var:toroot ?>compatibility/contact-us.html">Contact Us</a></li>
   </ul></li>
diff --git a/pdk/docs/compatibility/contact-us.jd b/pdk/docs/compatibility/contact-us.jd
index ba4e887..2aa2aa1 100644
--- a/pdk/docs/compatibility/contact-us.jd
+++ b/pdk/docs/compatibility/contact-us.jd
@@ -7,13 +7,12 @@
 out of any of these options, please first read "Getting the Most from Our
 Lists" on the <a href="{@docRoot}community/index.html">Community page.</a></p>
 
-<h3>Discussion Group</h3>
+<h3>For General Discussion</h3>
 <p>The preferred way to reach us is via the <a
-href="http://groups.google.com/group/android-compatibility">android-compatibility
-mailing list</a>. Use this list for all your compatibility-related questions.
-Please be aware that this is a public forum.</p>
+href="mailto:compatibility@android.com">compatibility@android.com
+address</a>.</p>
 
-<h3>CTS Technical Questions</h3>
+<h3>For CTS Technical Questions</h3>
 <p>If you have specific issues with the Compatibility Test Suite that require
 you to disclose information you'd prefer not to be public, you can contact an
 email address we've set up specifically this purpose: <a
@@ -23,9 +22,9 @@
 list. Note also that this list is for specific technical questions; general
 inquiries will also be directed back to the android-compatibility list.</p>
 
-<h3>Private Inquiries</h3>
+<h3>For Business Inquiries</h3>
 <p>Finally, business inquiries about the compatibility program, including
 requests to use branding elements and so on, can be sent to the address <a
-href="mailto:compatibility@android.com">compatibility@android.com</a>. Like
+href="mailto:android-partnerships@google.com">android-partnerships@google.com</a>. Like
 the CTS address, this address is for specific, private inquiries; general
 questions will be directed back to the android-compatibility list.</p>
diff --git a/pdk/docs/compatibility/cts-development.jd b/pdk/docs/compatibility/cts-development.jd
new file mode 100644
index 0000000..7a2f5af
--- /dev/null
+++ b/pdk/docs/compatibility/cts-development.jd
@@ -0,0 +1,130 @@
+page.title=CTS Development
+doc.type=compatibility
+@jd:body
+
+<h3>Initializing Your Repo Client</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/download.html">instructions</a>
+to get and build the Android source code but specify "-b froyo"
+when issuing the "repo init" command. This assures that your CTS
+changes will be included in the next CTS release and beyond.</p>
+
+<h3>Setting Up Eclipse</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/using-eclipse.html">instructions</a>
+to setup Eclipse but execute the following command to generate the
+.classpath file rather than copying the one from the development
+project:</p>
+
+<pre>
+cd /path/to/android/root
+./cts/development/ide/eclipse/genclasspath.sh &gt; .classpath
+chmod u+w .classpath
+</pre>
+
+<p>This .classpath file will contain both the Android framework
+packages and the CTS packages.</p>
+
+<h3>Building and Running CTS</h3>
+
+<p>Execute the following commands to build CTS and start the interactive
+CTS console:</p>
+
+<pre>
+cd /path/to/android/root
+make cts
+cts
+</pre>
+
+<p>Provide arguments to CTS to immediately start executing a test:</p>
+
+<pre>
+cts start --plan CTS -p android.os.cts.BuildVersionTest
+</pre>
+
+<h3>Writing CTS Tests</h3>
+
+<p>CTS tests use JUnit and the Android testing APIs. Review the
+<a href="http://d.android.com/guide/topics/testing/testing_android.html">Testing
+and Instrumentation</a> tutorial while perusing the existing tests under the
+"cts/tests/tests" directory. You will see that CTS tests mostly follow the same
+conventions used in other Android tests.</p>
+
+<p>Since CTS runs across many production devices, the tests must follow
+these rules:</p>
+
+<ul>
+    <li>Must take into account varying screen sizes, orientations, and
+        keyboard layouts.</li>
+    <li>Only use public API methods. In other words, avoid all classes,
+        methods, and fields that are annotated with the "hide" annotation.</li>
+    <li>Avoid relying upon particular view layouts or depend on the
+        dimensions of assets that may not be on some device.</li>
+    <li>Don't rely upon root privileges.</li>
+</ul>
+
+<h4>Test Naming and Location</h4>
+
+<p>Most CTS test cases target a specific class in the Android API. These tests
+have Java package names with a "cts" suffix like "android.view.cts" and class
+names with the "Test" suffix like "ViewTest." Each test case consists of
+multiple tests, where each test usually exercises a particular API method of
+the API class being tested. Each test is annotated with a @TestTargetNew
+annotation to indicate what API method is being exercised. These tests are
+arranged in a directory structure where tests are grouped into different
+categories like "widgets" and "views."</p>
+
+<p>For example, the CTS test for "android.widget.TextView" is
+"android.widget.cts.TextVietTest" found under the
+"cts/tests/tests/widget/src/android/widget/cts" directory with its
+Java package name as "android.widget.cts" and its class name as
+"TextViewTest." The "TextViewTest" class has a test called "testSetText"
+that exercises the "setText" method and a test named "testSetSingleLine" that
+calls the "setSingleLine" method. Each of those tests have @TestTargetNew
+annotations indicating what they cover.</p>
+
+<p>Some CTS tests do not directly correspond to an API class but are placed in
+the most related package possible. For instance, the CTS test,
+"android.net.cts.ListeningPortsTest," is in the "android.net.cts," because it
+is network related even though there is no "android.net.ListeningPorts" class.
+Thus, use your best judgement when adding new tests and refer to other tests
+as examples.</p>
+
+<h4>New Test Packages</h4>
+
+<p>When adding new tests, there may not be an existing directory to place your
+test. In that case, refer to the example under "cts/tests/tests/example" and
+create a new directory. Furthermore, make sure to add your new package's
+module name from its Android.mk to "CTS_COVERAGE_TEST_CASE_LIST" in
+"cts/CtsTestCaseList.mk." This Makefile is used by "build/core/tasks/cts.mk"
+to glue all the tests together to create the final CTS package.</p>
+
+<h4>Test Stubs and Utilities</h4>
+
+<p>Some tests use additional infrastructure like separate activities
+and various utilities to perform tests. These are located under the
+"cts/tests/src" directory. These stubs aren't separated into separate test
+APKs like the tests, so the "cts/tests/src" directory does not have additional
+top level directories like "widget" or "view." Follow the same principle of
+putting new classes into a package with a name that correlates to the purpose
+of your new class. For instance, a stub activity used for testing OpenGL like
+"GLSurfaceViewStubActivity" belongs in the "android.opengl.cts" package under
+the "cts/tests/src/android/opengl" directory.</p>
+
+<h3>Other Tasks</h3>
+
+<p>Besides adding new tests there are other ways to contribute to CTS:</p>
+
+<ul>
+    <li>Fix or remove tests annotated with BrokenTest and KnownFailure.</li>
+</ul>
+
+<h3>Submitting Your Changes</h3>
+
+<p>Follow the 
+<a href="{@docRoot}source/submit-patches.html">Android
+contributors' workflow</a> to contribute changes to CTS. A reviewer
+will be assigned to your change, and your change should be reviewed shortly!</p>
+
diff --git a/pdk/docs/compatibility/cts-intro.jd b/pdk/docs/compatibility/cts-intro.jd
index f1d2359..5d80a45 100644
--- a/pdk/docs/compatibility/cts-intro.jd
+++ b/pdk/docs/compatibility/cts-intro.jd
@@ -13,10 +13,14 @@
 
 <h3>Workflow</h3>
 <ol>
-<li>Obtain the CTS source code. The CTS is included in the Android source code available from the Android
-Open Source Project. (To get a copy of that source code, <a
-href="{@docRoot}source/download.html">read this page.</a></li>
+<li><a href="{@docRoot}compatibility/downloads.html">Download</a> the CTS.
 <li>Attach at least one device (or emulator) to your machine.</li>
+<li>For CTS 2.1 R2 and beyond, setup your device (or emulator) to run the accessibility tests:
+    <ol>
+        <li>adb install -r android-cts/repository/testcases/CtsDelegatingAccessibilityService.apk</li>
+        <li>On the device, enable Settings &gt; Accessibility &gt; Accessibility &gt; Delegating Accessibility Service</li>
+    </ol>
+</li>
 <li>Launch the CTS. The CTS test harness loads the test plan onto the attached devices. For each test in the test harness:
     <ul>
     <li>The test harness pushes a .apk file to each device, executes the test through instrumentation, and records test results.</li>
diff --git a/pdk/docs/compatibility/downloads.jd b/pdk/docs/compatibility/downloads.jd
new file mode 100644
index 0000000..723d13e
--- /dev/null
+++ b/pdk/docs/compatibility/downloads.jd
@@ -0,0 +1,60 @@
+page.title=Android Compatibility Downloads
+doc.type=compatibility
+@jd:body
+<p>Thanks for your interest in Android Compatibility! The links below allow
+you to access the key documents and information.</p>
+
+<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.
+</p>
+<ul>
+  <li><a href="{@docRoot}compatibility/android-2.3-cdd.pdf">Android 2.3 Compatibility Definition Document (CDD)</a></li>
+  <!-- <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.2_r4-x86.zip">Android 2.2 R4 Compatibility Test Suite (CTS)</a></li> -->
+</ul>
+
+<h2>Android 2.2</h2>
+<p>Android 2.2 is the release of the development milestone code-named
+FroYo. Source code for Android 2.2 is found in the 'froyo' branch in the
+open-source tree.
+</p>
+<ul>
+  <li><a href="{@docRoot}compatibility/android-2.2-cdd.pdf">Android 2.2 Compatibility Definition Document (CDD)</a></li>
+  <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.2_r4-x86.zip">Android 2.2 R4 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 2.1</h2>
+<p>Android 2.1 is the release of the development milestone code-named
+Eclair. Source code for Android 2.1 is found in the 'eclair' branch in the
+open-source tree. Note that for technical reasons, there is no compatibility
+program for Android 2.0 or 2.0.1, and new devices must use Android 2.1.
+</p>
+<ul>
+  <li><a href="{@docRoot}compatibility/android-2.1-cdd.pdf">Android 2.1 Compatibility Definition Document (CDD)</a></li>
+  <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.1_r5-x86.zip">Android 2.1 R5 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 1.6</h2>
+<p>Android 1.6 was the release of the development milestone code-named Donut.
+Android 1.6 was obsoleted by Android 2.1. Source code for Android 1.6 is found
+in the 'donut' branch in the open-source tree.
+<ul>
+  <li><a href="{@docRoot}compatibility/android-1.6-cdd.pdf">Android 1.6 Compatibility Definition Document (CDD)</a></li>
+</ul>
+
+<h2>Compatibility Test Suite Manual</h2>
+<p>The CTS user manual is applicable to any CTS version, but CTS 2.1 R2 and
+beyond require
+<a href="{@docRoot}compatibility/cts-intro.html">additional steps</a>
+to run the accessibility tests.
+<ul>
+  <li><a href="{@docRoot}compatibility/android-cts-manual-r4.pdf">Compatibility Test Suite (CTS) User Manual</a></li>
+</ul>
+
+<h2>Older Android Versions</h2>
+<p>There is no Compatibility Program for older versions of Android, such as Android
+1.5 (known in development as Cupcake). New devices intended to be Android
+compatible must ship with Android 1.6 or later.</p>
diff --git a/pdk/docs/compatibility/index.jd b/pdk/docs/compatibility/index.jd
index 0c39a98..e4e30a8 100644
--- a/pdk/docs/compatibility/index.jd
+++ b/pdk/docs/compatibility/index.jd
@@ -1,17 +1,21 @@
 page.title=Android Compatibility
 doc.type=compatibility
 @jd:body
-<p>Android is an open source product, and anyone can use the source code to build
-devices. The purpose of the Android compatibility program is to help Android
-device implementations remain compatible with all apps.</p>
-<p>A device is considered compatible if existing and new third-party
-applications run correctly on it. Poor device implementations that change APIs
-or alter behaviors will break these apps and so are not compatible. The
-Android compatibility program's aim is to ensure that these APIs are
-consistently implemented across devices.</p>
-<p>The latest version of the Android source code and compatibility program is
-1.6, which roughly corresponded to the Donut branch.  The compatibility
-program for Android 2.x (corresponding to Eclair) is coming soon.</p>
+<p>Android's purpose is to establish an open platform for developers to build
+innovative mobile apps. Three key components work together to realize this
+platform.</p>
+<p>The Android Compatibility Program defines the technical details of Android
+platform and provides tools used by OEMs to ensure that developers’ apps run
+on a variety of devices. The Android SDK provides built-in tools that
+Developers use to clearly state the device features their apps require. And
+Android Market shows apps only to those devices that can properly run
+them.</p>
+<p>These pages describe the Android Compatibility Program and how to get
+access to compatibility information and tools. The latest version of the
+Android source code and compatibility program is 2.3, which 
+corresponded to the Gingerbread branch.</p>
+
+
 <h2>Why build compatible Android devices?</h2>
 <h3>Users want a customizable device.</h3>
 <p>A mobile phone is a highly personal, always-on, always-present gateway to
@@ -20,7 +24,7 @@
 platform for running after-market applications.</p>
 
 <h3>Developers outnumber us all.</h3>
-<p>No device manufacturer can hope to write all the software that anyone could
+<p>No device manufacturer can hope to write all the software that a person could
 conceivably need. We need third-party developers to write the apps users want,
 so the Android Open Source Project aims to make it as easy and open as
 possible for developers to build apps.</p>
@@ -38,30 +42,23 @@
 sure your device is compatible with Android. For more details about the
 Android compatibility program in general, see <a
 href="{@docRoot}compatibility/overview.html">the program overview</a>.</p>
-<p>Building a compatible device is a four-step process:</p>
+<p>Building a compatible device is a three-step process:</p>
 <ol>
-  <li><b>Obtain the Android software stack source code</b><p>This is the
+  <li><b>Obtain the Android software source code</b><p>This is the
   <a href="{@docRoot}source/index.html">source code for the Android
   platform</a>, that you port to your hardware.</p></li>
-  <li><b>Comply with Android Compatibility Definition Document</b><p>
-  This document enumerates the software and the hardware features of
+  <li><b>Comply with Android Compatibility Definition Document (CDD)</b><p>
+  The CDD enumerates the software and hardware requirements of
   a compatible Android device.</p></li>
   <li><b>Pass the Compatibility Test Suite (CTS)</b><p>You can use the CTS
   (included in the Android source code) as an ongoing aid to compatibility
   during the development process.</p></li>
-  <li><b>Submit CTS report</b><p>[Optional] You can also submit your CTS report,
-  so that it can be validated and recorded.</p><p><i>Note:
-  the submission system is currently under construciton, and is not currently
-  available.</i></p></li>
 </ol>
 
-<h2>Benefits of compatibility</h2>
-<p>By submitting a validated CTS report, you receive public recognition of
-your device's compatibility. This also opens up additional options you can
-pursue such as use of the Android branding, access to Android Market, and
-more.</p>
-<p>As a consequence of some legal quirks, we aren't able to offer automatic
-licensing of either the Android Market or branding. To actually obtain access
-to these programs, you will need to <a
-href="{@docRoot}compatibility/contact-us.html">contact us</a> to obtain a
-license.</p>
+<h2>Joining the Ecosystem</h2>
+<p>Once you've built a compatible device, you may wish to include Android
+Market to provide your users access to the third-party app ecosystem.
+Unfortunately, for a variety of legal and business reasons, we aren't able to
+automatically license Android Market to all compatible devices. To inquire
+about access about Android Market, you can <a
+href="{@docRoot}compatibility/contact-us.html">contact us</a></p>
diff --git a/pdk/docs/compatibility/overview.jd b/pdk/docs/compatibility/overview.jd
index 039e2c2..31a4832 100644
--- a/pdk/docs/compatibility/overview.jd
+++ b/pdk/docs/compatibility/overview.jd
@@ -35,11 +35,13 @@
 compatible.</p></li>
 <li><b>Minimize costs and overhead associated with
 compatibility.</b><p>Ensuring compatibility should be easy and inexpensive to
-device manufacturers. The testing tool (CTS) is free and will soon be available
-in open source. CTS is designed to be used for continuous self-testing during
-the device development process to eliminate the cost of changing your workflow
-or sending your device to a third party for testing. Meanwhile, there are no
-required certifications, and thus no corresponding costs and fees.</p></li>
+device manufacturers. The testing tool (CTS) is free, open source, and
+available for <a href="{@docRoot}compatibility/downloads.html">download</a>. 
+CTS is designed to be used for continuous self-testing
+during the device development process to eliminate the cost of changing your
+workflow or sending your device to a third party for testing. Meanwhile, there
+are no required certifications, and thus no corresponding costs and
+fees.</p></li>
 </ul>
 <p>The Android compatibility program consists of three key components:</p>
 <ul>
@@ -76,8 +78,9 @@
 simply examine <a href="">the latest CDD</a>.</p>
 
 <h3>Compatibility Test Suite (CTS)</h3>
-<p>The CTS is a free, commercial-grade test suite, available along with the
-Android source code. The CTS represents the "mechanism" of compatibility.</p>
+<p>The CTS is a free, commercial-grade test suite, available for
+<a href="{@docRoot}compatibility/downloads.html">download</a>.
+The CTS represents the "mechanism" of compatibility.</p>
 <p>The CTS runs on a desktop machine and executes test cases directly on
 attached devices or an emulator. The CTS is a set of unit tests designed to be
 integrated into the daily workflow (such as via a continuous build system) of
diff --git a/pdk/docs/downloads/downloads_toc.cs b/pdk/docs/downloads/downloads_toc.cs
deleted file mode 100644
index 28f43af..0000000
--- a/pdk/docs/downloads/downloads_toc.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-<script type="text/javascript" language="JavaScript">
-<!--
-function nothing() {}
--->
-</script>
-
-<ul>
-  <li><h2>PDK</h2><ul>
-    <li><a href="">PDK 1.6</a></li>
-  </ul></li>
-
-  <li><h2>Compatibility</h2><ul>
-    <li><a href="">Android 1.6</a></li>
-  </ul></li>
-</ul>
-
-<script type="text/javascript">
-<!--
-    buildToggleLists();
-//-->
-</script>
diff --git a/pdk/docs/downloads/index.jd b/pdk/docs/downloads/index.jd
deleted file mode 100644
index b6f5a2f..0000000
--- a/pdk/docs/downloads/index.jd
+++ /dev/null
@@ -1,44 +0,0 @@
-page.title=Downloads
-doc.type=downloads
-doc.hidenav=true
-@jd:body
-<p>This page provides access to various downloads. Note that if you're looking
-for the Android SDK (for application developers), you should visit <a
-href="http://developer.android.com/sdk/index.html">developer.android.com</a>.</p>
-
-<h2>Compatibility</h2>
-<p>The Compatibility Definition Document can be downloaded below. The
-Compatibility Test Suite is available in the open-source tree.</p>
-<table class="download"> 
-  <tr> 
-      <th>Item</th> 
-      <th>File</th> 
-      <th>Size</th> 
-  </tr> 
-  <tr> 
-    <td>Android CDD 2.1</td> 
-    <td><a href="">android-cdd-2.1.pdf</a></td> 
-    <td>23070805 bytes</td> 
-  </tr> 
-  <tr class="alt-color"> 
-    <td>Android CTS 2.1 Manual</td> 
-    <td><a href="">android-cts-manual-2.1.0.pdf</a></td> 
-    <td>23070805 bytes</td> 
-  </tr> 
-  <tr> 
-    <td>Android CDD 1.6</td> 
-    <td><a href="">android-cdd-1.6.pdf</a></td> 
-    <td>23070805 bytes</td> 
-  </tr> 
-  <tr class="alt-color"> 
-    <td>Android CTS 1.6 Manual</td> 
-    <td><a href="">android-cts-manual-1.6.4.pdf</a></td> 
-    <td>23070805 bytes</td> 
-  </tr> 
-</table> 
-<p>For more information on how to build an Android-compatible device, see the
-<a href="{@docRoot}compatibility/index.html">Compatibility</a> page. Note that
-there is no compatibility program for Android 1.5 and earlier. Note also that
-there is no compatibility program for Android 2.0, since it was superceded by
-Android 2.1 after only a few weeks.
-</p>
diff --git a/pdk/docs/faqs.jd b/pdk/docs/faqs.jd
index a55d380..00db026 100644
--- a/pdk/docs/faqs.jd
+++ b/pdk/docs/faqs.jd
@@ -74,8 +74,8 @@
 <p>Finally, Google works on the next version of the Android platform in tandem
   with developing a flagship device. This branch pulls in changes from the
   experimental and stable branches as appropriate.</p>
-<p>You can find more information on this topic at our Branches Releases
-  page.</p>
+<p>You can find more information on this topic at our <a
+href="{@docRoot}source/code-lines.html">Branches and Releases</a> page.</p>
 
 <h3>Why are parts of Android developed in private?</h3>
 <p>It typically takes over a year to bring a device to market, but of course
@@ -86,16 +86,16 @@
 <p>To address this, some parts of the next version of Android including the
   core platform APIs are developed in a private branch. These APIs constitute
   the next version of Android. Our aim is to focus attention on the current
-  stable version of the Android source code, while we refine the next version
-  of the platform using the flagship Android devices. This allows developers
+  stable version of the Android source code, while we create the next version
+  of the platform as driven by flagship Android devices. This allows developers
   and OEMs to focus on a single version without having to track unfinished
-  future work just to keep up.Other parts of the Android system that aren't
+  future work just to keep up. Other parts of the Android system that aren't
   related to application compatibility are developed in the open, however.
   It's our intention to move more of these parts to open development over
   time.</p>
 
 <h3>When are source code releases made?</h3>
-<p>When they are ready. Some parts of Android are developed in the open, and
+<p>When they are ready. Some parts of Android are developed in the open,
   so that source code is always available. Other parts are developed first in
   a private tree, and that source code is released when the next platform
   version is ready.</p>
@@ -143,8 +143,7 @@
   "Android compatible devices" from devices that merely run derivatives of the
   source code. We welcome all uses of the Android source code, but only
   Android compatible devices -- as defined and tested by the Android
-  Compatibility Program -- may call themselves "Android" and participate in
-  the Android ecosystem.</p>
+  Compatibility Program -- may participate in the Android ecosystem.</p>
 
 <h3>How can I contribute to Android?</h3>
 <p>There are a number of ways you can contribute to Android. You can report
@@ -170,8 +169,9 @@
 <p>Once submitted, changes need to be accepted by a designated Approver.
   Approvers are typically Google employees, but the same approvers are
   responsible for all submissions, regardless of origin.</p>
-<p>You can find more information on this topic at the Submitting Patches
-  page.</p>
+<p>You can find more information on this topic at the <a
+   href="{@docRoot}source/submit-patches.html">Submitting Patches</a>
+   page.</p>
 
 <a name="compatibility"></a><h2>Compatibility</h2>
 <h3>What does "compatibility" mean?</h3>
@@ -185,7 +185,7 @@
 <p>In other words, compatibility is a prerequisite to participate in the
   Android apps ecosystem. Anyone is welcome to use the Android source code,
   but if the device isn't compatible, it's not considered part of the Android
-  ecosystem, and irrelevant to developers.</p>
+  ecosystem.</p>
 
 <h3>What is the role of Android Market in compatibility?</h3>
 <p>Devices that are Android compatible may seek to license the Android Market
@@ -200,11 +200,11 @@
   Compatibility Definition Document (CDD) spells out the specific device
   configurations that will be considered compatible.</p>
 <p>For example, though the Android source code could be ported to run on a
-  device that doesn't have a camera, the CDD requires that in order to be
-  compatible, all devices must have a camera. This allows developers to rely
-  on a consistent set of device capabilities when writing their apps.</p>
+  phone that doesn't have a camera, the CDD requires that in order to be
+  compatible, all phones must have a camera. This allows developers to rely
+  on a consistent set of capabilities when writing their apps.</p>
 <p>The CDD will evolve over time to reflect market realities. For instance,
-  the 1.6 CDD only allows cell phones, but the 2.x CDD allows devices to omit
+  the 1.6 CDD only allows cell phones, but the 2.1 CDD allows devices to omit
   telephony hardware, allowing for non-phone devices such as tablet-style
   music players to be compatible. As we make these changes, we will also
   augment Android Market to allow developers to retain control over where
@@ -214,13 +214,10 @@
   devices.</p>
 
 <h3>If my device is compatible, does it automatically have access to Android Market and branding?</h3>
-<p>Android Market is a service operated by Google. For legal and business
-  reasons, Google isn't able to make that service available in all parts of
-  the world. Similarly, Google is unable to license the Android trademark for
-  use in all cases.</p>
-<p>As a result, achieving compatibility does not automatically entitle a
-  device to include Android Market or use the Android name. Device
-  manufacturers should contact Google to obtain access to those tools.</p>
+<p>Android Market is a service operated by Google. Achieving compatibility is
+   a prerequisite for obtaining access to the Android Market software and branding.
+   Device manufacturers should contact Google to obtain access to Android
+   Market.</p>
 
 <h3>If I am not a manufacturer, how can I get Android Market?</h3>
 <p>Android Market is only licensed to handset manufacturers shipping devices.
@@ -229,9 +226,9 @@
 
 <h3>How can I get access to the Google apps for Android, such as Maps?</h3>
 <p>The Google apps for Android, such as YouTube, Google Maps and Navigation,
-  Gmail, and so on are not part of Android, and are licensed separately.
-  Contact android-partnerships@google.com for inquiries related to those
-  apps.</p>
+  Gmail, and so on are Google properties that are not part of Android, and
+  are licensed separately.  Contact android-partnerships@google.com for
+  inquiries related to those apps.</p>
 
 <h3>Is compatibility mandatory?</h3>
 <p>No. The Android Compatibility Program is optional. Since the Android source
@@ -246,7 +243,7 @@
   test a device.</p>
 
 <h3>How long does compatibility take?</h3>
-<p>The process is automatic. The Compatibility Test Suite generates a report
+<p>The process is automated. The Compatibility Test Suite generates a report
   that can be provided to Google to verify compatibility. Eventually we intend
   to provide self-service tools to upload these reports to a public database.</p>
 
@@ -271,12 +268,15 @@
   generally have much effect on third-party apps. As such, device builders are
   free to customize the user interface as much as they like. The Compatibility
   Definition Document does restrict the degree to which OEMs may alter the
-  system user interface for the few areas that do impact third-party apps.</p>
+  system user interface for areas that do impact third-party apps.</p>
 
 <h3>When are compatibility definitions released for new Android versions?</h3>
 <p>Our goal is to release new versions of Android Compatibility Definition
   Documents (CDDs) once the corresponding Android platform version has
-  converged enough to permit it. Since the CDDs</p>
+  converged enough to permit it. While we can't release a final draft of a CDD
+  for an Android software version before the first flagship device ships with
+  that software, final CDDs will always be released after the first device.
+  However, wherever practical we will make draft versions of CDDs available.</p>
 
 <h3>How are device manufacturers' compatibility claims validated?</h3>
 <p>There is no validation process for Android device compatibility. However,
diff --git a/pdk/docs/images/code-lines.png b/pdk/docs/images/code-lines.png
index acfb77b..f86260c 100644
--- a/pdk/docs/images/code-lines.png
+++ b/pdk/docs/images/code-lines.png
Binary files differ
diff --git a/pdk/docs/index.jd b/pdk/docs/index.jd
index 217877d..d8f1739 100644
--- a/pdk/docs/index.jd
+++ b/pdk/docs/index.jd
@@ -1,7 +1,27 @@
 page.title=Welcome to Android
 home=true
 @jd:body
-<div style="float: left; width: 45%; font-size: 1.3em;">
+<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
+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
+href="{@docRoot}compatibility/index.html">visit the Compatibility page.</a>
+</p>
+<p><b>Source Code Available for Android 2.3</b><br/>
+The source code for the Android 2.3 platform and software stack has been
+released! This release allows OEMs to begin preparing Android 2.3 for
+installation on new and existing devices, and allows hobbyists, enthusiasts,
+and researchers to develop custom builds. For information on how to obtain the
+software, 
+<a href="{@docRoot}source/download.html">visit our 'Getting the Source' page.</a>
+</p>
+</div>
+<img style="float: right; padding-right: 1.5em;" src="{@docRoot}images/home-bugdroid.png" alt="Android Mascot"/>
+<div style="font-size: 1.3em;">
   <p>Here you can find the information and source code you need to build an
   Android-compatible device.</p>
   <p>Android is an open-source software stack for mobile devices, and a
@@ -12,51 +32,40 @@
   created Android, and made its source code open.</p>
   <p><a href="{@docRoot}about/index.html">Learn more &raquo;</a></p>
 </div>
-<div style="float: right; width: 35%;">
-<h3 style="padding-top: 0px;">News</h3>
-<p><b>Site redesign</b><br/>
-You're looking at the new and improved source.android.com! We've updated
-the layout and site design, and also added new information. We hope you find
-these improvements helpful.</p>
-<p><b>Introducing the Compatibility Program</b><br/>
-We're pleased to introduce the Android Compatibility Program. We've released
-two tools -- the Compatibility Definition Document and the Compatibility Test
-Suite -- to help device manufacturers build compatible devices. Full details
-of the Compatibility Program will be available in the first quarter of 2010.</p>
-</div>
-<img style="float: right; padding-right: 1.5em;" src="{@docRoot}images/home-bugdroid.png" alt="Android Mascot"/>
 
 <div style="clear: both;"/>
 
 <table border="0" style="border: 0px; margin: 0px; padding: 0px;"><tr><td align="center" style="border: 0px; margin: 0px; padding: 0px;">
 <div class="rebox lil" style="float: left; width: 30%; margin: 1em;"> 
-  <h2 style="color: white; background-color: #95C0D0; border: 0px;">Get Involved</h2> 
+  <h2 style="color: white; background-color: #95C0D0; border: 0px;">Source</h2> 
   <div class="p"> 
-    <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
+    <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
     If you're interested in contributing to the Android source code or helping
-    out with the project in some other way, click here.</p> 
-    <p><a href="{@docRoot}source/index.html">More &raquo;</a></p> 
+    out with the open-source project, our Source pages have the information
+    you need.</p> 
+    <p><a href="{@docRoot}source/index.html">Get Involved &raquo;</a></p> 
   </div> 
 </div> 
 
 <div class="rebox lil" style="float: left; width: 30%; margin: 1em;"> 
-  <h2 style="color: white; background-color: #95C0D0; border: 0px;">Build a Device</h2> 
+  <h2 style="color: white; background-color: #95C0D0; border: 0px;">Porting</h2> 
   <div class="p"> 
-    <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
-    If you're an engineer building a device intended to run the Android
-    software stack, click here to find porting information and tips.</p> 
-    <p><a href="{@docRoot}porting/index.html">More &raquo;</a></p> 
+    <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
+    If you're an engineer building a device
+    intended to run the Android software stack, look at our Porting pages for
+    information and tips.</p> 
+    <p><a href="{@docRoot}porting/index.html">Build a Device &raquo;</a></p> 
   </div> 
 </div> 
 
 <div class="rebox lil" style="float: left; width: 30%; margin: 1em;"> 
   <h2 style="color: white; background-color: #95C0D0; border: 0px;">Compatibility</h2> 
   <div class="p"> 
-    <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
-    If you're an OEM or other organization building an Android device, click
-    here to find out how to ensure that your device is fully compatible, and
-    how to take advantage of the benefits of compatibility.</p> 
-    <p><a href="{@docRoot}compatibility/index.html">More &raquo;</a></p> 
+    <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
+    If you're an organization building an Android device, you'll want to check out our
+    Compatibility pages to find out how to take advantage of the benefits of
+    compatibility.</p> 
+    <p><a href="{@docRoot}compatibility/index.html">Get Compatible &raquo;</a></p> 
   </div> 
 </div> 
 </td></tr></table>
diff --git a/pdk/docs/porting/bluetooth.jd b/pdk/docs/porting/bluetooth.jd
index ceb8683..c792bd2 100755
--- a/pdk/docs/porting/bluetooth.jd
+++ b/pdk/docs/porting/bluetooth.jd
@@ -17,7 +17,8 @@
 </div>
 </div>
 
-<p>Android's Bluetooth stack uses BlueZ version 3.36 for GAP, SDP, and RFCOMM profiles, and is a SIG-qualified Bluetooth 2.0 + EDR host stack.</p>
+<p>Android's Bluetooth stack uses BlueZ for GAP, SDP, and RFCOMM profiles, and
+is a SIG-qualified Bluetooth stack. </p>
 
 <p>Bluez is GPL licensed, so the Android framework interacts with userspace bluez code through D-BUS IPC to avoid proprietary code.</p>
 
@@ -33,7 +34,7 @@
 
 <a name="androidBluetoothPorting"></a><h3>Porting</h3>
 
-<p>BlueZ is Bluetooth 2.0 compatible and should work with any 2.0 chipset. There are two integration points:</p>
+<p>BlueZ is Bluetooth 2.1 compatible and should work with any 2.1 chipset and is backward compatibile with older Bluetooth versions. There are two integration points:</p>
 <p><ul>
 <li>UART driver</li>
 <li>Bluetooth Power On / Off</li>
@@ -67,7 +68,7 @@
 
 <a name="androidBluetoothTroubleshooting"></a><h3>Troubleshooting</h3>
 <p><strong>Debugging</strong></p>
-<p>To debug your bluetooth implementation, start by reading the logs (<code>adb logcat</code>) and look for ERRROR and WARNING messages regarding Bluetooth. 
+<p>To debug your bluetooth implementation, start by reading the logs (<code>adb logcat</code>) and look for ERRROR and WARNING messages regarding Bluetooth.
   Andoird uses Bluez, which comes with some useful debugging tools. The snippet below provides examples in a suggested order:</p>
 <pre>
 hciconfig -a  			# print BT chipset address and features. Useful to check if you can communicate with your BT chipset.
@@ -158,14 +159,79 @@
   <li>QDID B015261: Host stack (SDP, L2CAP, GAP, RFCOMM, SPP, AVCTP, AVRCP, GAVDP, AVDTP, A2DP)</li>
   <li>QDID B015262: EPL for HTC Sapphire (HSP, HFP)</li>
 </ul>
+<h4>Android 2.0/2.1 release (eclair)</h4>
+<h4>Platform features</h4>
+<ul>
+  <li>Based on Bluez 4.47 with Linux Kernel 2.6.29</li>
+  <li>Bluetooth 2.1+EDR host stack</li>
+  <ul>
+    <li>Support for auto-pairing with '0000' devices</li>
+    <li>Support for Simple Secure Pairing</li>
+  </ul>
+  <li>Headset Profile 1.1 in Audio Gateway role</li>
+  <li>Handsfree Profile 1.5 in Audio Gateway role</li>
+  <ul>
+    <li>Three-way calling    </li>
+    <li>Phonebook over AT commands    </li>
+    <li>Volume synchronization</li>
+    <li>eSCO</li>
+    <li>Extensive bug fixes and compatibility improvements</li>
+  </ul>
+  <li>Stereo Bluetooth (A2DP 1.2) in Source role</li>
+  <ul>
+    <li>AVDTP 1.2 in Acceptor and Initiator roles</li>
+    <li>GAVDTP 1.0 in Acceptor and Initiator roles</li>
+    <li>44.1 khz, stereo, software SBC codec</li>
+  </ul>
+  <li>Remote Control (AVRCP 1.0) in Target role</li>
+  <ul>
+    <li>AVCTP 1.3 in Target role</li>
+    <li>play/pause/stop/prev/next</li>
+  </ul>
+  <li> Object Push Profile version 1.1 </li>
+  <ul>
+     <li>Adds ability to transfer pictures, videos</li>
+     <li>Transfer of contacts using vCard is not supported in this release.</li>
+  </ul>
+  <li>Phone Book Address Profile version 1.0</li>
+  <ul>
+    <li>Phone Book Server Equipment (PSE) role supported</li>
+  </ul>
+  <li>Using Java Bluetooth APIs, an Android application can peform the
+  following:</li>
+  <ul>
+   <li>Scan for other Bluetooth devices </li>
+   <li>Query the local Bluetooth adapter for paired Bluetooth devices </li>
+   <li>Establish RFCOMM channels </li>
+   <li>Connect to other devices through service discovery </li>
+   <li>Transfer data to and from other devices </li>
+   <li>Manage multiple connections </li>
+  </ul>
+  <li>Support for Bluetooth enabled car and desk docks</li>
+  <ul>
+   <li>Framework support for routing Phone Call Audio and A2DP streaming using
+   car and desk docks. </li>
+  </ul>
+</ul>
+
+<h4>Android 2.2  release (Froyo)</h4>
+<h4>Platform features</h4>
+<ul>
+  <li>Based on Bluez 4.47 with Linux Kernel 2.6.32</li>
+  <li>No new profiles added.</li>
+  <li>Added ability to share contacts using vCard</li>
+  <li>Added ability to export all contacts - useful to transfer contacts to car kits </li>
+  <li>Improved compatibility with headsets and car kits. </li>
+</ul>
+
 <h5>&nbsp;</h5>
 <h4>Future releases</h4>
 <p>This section offers a rough guide of which features the team is developing for the next release. This feature list may change without notice. It isn't possible to post scheduling advice to the mailing lists.</p>
 <ul>
-  <li>Java Bluetooth API</li>
-  <li>Bluez 4.x with Linux Kernel 2.6.29</li>
   <li>More profiles...</li>
-  <li>Bluetooth 2.1+EDR</li>
+  <li>Improved compatibility with headsets and car kits</li>
+  <li>Bluetooth emulator support</li>
+  <li>Bluetooth Low Energy </li>
 </ul>
 
 <p><strong>Development Notes</strong></p>
@@ -184,10 +250,4 @@
 While not officially supported, you should be able to run <code>dund</code> or <code>pand</code> daemons and, using <code>pppd</code> or <code>iptables</code>, test tethering support. Next steps include plubming the DBUS APIs to these daemons up into the Android Java framework and adding code to setup the network paths via <code>pppd</code> and / or <code>iptables</code>.<br />
   <br />
   </li>
-  <li><strong>Emulator Support</strong><br />
-  The Android emulator does not support Bluetooth at this time and there currently aren't any plans for its support.<br />
-    <br />
-  </li>
-  <li><strong>Bluetooth 2.1 and Simple Pairing Support</strong><br />
-  In order to support these features, Android needs to move to a Bluez 4.x version. This change is not scheduled at this time.</li>
 </ul>
diff --git a/pdk/docs/porting/instrumentation_testing.jd b/pdk/docs/porting/instrumentation_testing.jd
index c3765f4..045291f 100755
--- a/pdk/docs/porting/instrumentation_testing.jd
+++ b/pdk/docs/porting/instrumentation_testing.jd
@@ -335,7 +335,7 @@
 <pre class="prettify">
 public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner {
 
-    @Override
+    &#64;Override
     public TestSuite getAllTests() {
         InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
 
@@ -345,7 +345,7 @@
         return suite;
     }
 
-    @Override
+    &#64;Override
     public ClassLoader getLoader() {
         return FrameworkInstrumentationTestRunner.class.getClassLoader();
     }
@@ -373,7 +373,7 @@
         super("com.example", MyActivity.class);
     }
 
-    @Override
+    &#64;Override
     public void setUp() throws Exception {
       super.setUp();
       mLeftButton = (Button) getActivity().findViewById(R.id.leftButton);
diff --git a/pdk/docs/source/building-dream.jd b/pdk/docs/source/building-dream.jd
index 89392fd..d130524 100644
--- a/pdk/docs/source/building-dream.jd
+++ b/pdk/docs/source/building-dream.jd
@@ -3,10 +3,10 @@
 @jd:body
 <p><i>The information on this page is a bit out of date. We'll update this
 page as soon as we can.</i></p>
-<div>The basic manifest for cupcake (and above) defines which projects are
+<div>The basic manifest for 1.6 defines which projects are
 needed to do a generic build for the emulator or for unlocked Dream devices
 (e.g. the Android Dev Phone 1). You need to have an appropriate device running
-a matching official image.<br><br>To build donut or master for dream (your
+a matching official image.<br><br>To build donut for dream (your
 device needs to be an ADP1 running an official 1.6 system):<br><ol><li>Follow
 the <a href="{@docRoot}source/download.html">normal steps</a>
 to setup repo and check out the sources.
@@ -22,17 +22,6 @@
 </li>
 <li>from this point, the fastboot tool (which is put automatically in your path) can be used to flash a device: boot the device into the bootloader by holding the back key while pressing the power key, and run "fastboot -w flashall".<br></li>
 </ol>
-To build cupcake for dream (your device needs to be an ADP1 running an official 1.5 system):<br><ol><li>Follow the <a href="{@docRoot}source/download.html">normal steps</a>
-to setup repo and check out the sources.
-</li>
-<li>At the root of your source tree, run ". build/envsetup.sh" like you normally would for an emulator build.
-</li>
-<li>Run "make adb" if you don't already have adb in your path.<br></li>
-<li>in vendor/htc/dream-open/ there is a script called "extract-files.sh" that must be run (from that directory) to extract some proprietary binaries from your device (*). You only need to do this once.<br></li>
-<li>run "lunch htc_dream-eng" to specifically configure the build system for dream (the default is the equivalent of "lunch generic-eng", which doesn't contain dream-specific files).<br></li>
-<li>run make from the top of the source tree.
-</li>
-<li>from this point, the fastboot tool (which is put automatically in your path) can be used to flash a device: boot the device into the bootloader by holding the back key while pressing the power key, and run "fastboot -w flashall".<br></li>
-</ol>
-* The Dream device software contains some proprietary binaries.For contractual reasons, these cannot be redistributed to be used directly with the Android Open-Source Project, but the provided script may be used to extract these binaries from your development device so that they can be correctly included in your build.These libraries include the openGL|ES library, the Qualcomm camera library, the HTC Radio Interface Library, etc.
+<p>Note: these instructions work for the sapphire (ADP2) build target, as
+well. Simply replace "dream" with "sapphire" above.</p>
 </div>
diff --git a/pdk/docs/source/code-lines.jd b/pdk/docs/source/code-lines.jd
index 61b400d..5ceb103 100644
--- a/pdk/docs/source/code-lines.jd
+++ b/pdk/docs/source/code-lines.jd
@@ -15,7 +15,7 @@
 <h3>Notes and Explanations</h3>
 <ul>
 <li>A <i>release</i> corresponds to a formal version of the Android platform, such
-as 1.5, 2.0, and so on. Generally speaking, a release of the platform
+as 1.5, 2.1, and so on. Generally speaking, a release of the platform
 corresponds to a version of the <code>SdkVersion</code> field used in
 AndroidManifest.xml files, and defined in <code>frameworks/base/api</code> in
 the source tree.</li>
@@ -23,34 +23,37 @@
 stack is pulling code. These include obvious projects such as the Linux kernel
 and WebKit, but over time we are migrating some of the semi-autonomous
 Android projects (such as Dalvik, the Android SDK tools, Bionic, and so on) to
-work as "upstream" projects. These will be developed entirely in the public
-tree, and snapshots will be periodically pulled into releases.</li>
-<li>The diagram refers to "Eclair" and "Flan"; however, they are simply
+work as "upstream" projects. Generally, these projects are developed entirely in
+the public tree. For some upstream projects, development is done by contributing
+directly to the upstream project itself. See
+<a href="{@docRoot}source/submit-patches.html#upstream-projects">Upstream Projects</a>
+for details. In both cases, snapshots will be periodically pulled into releases.</li>
+<li>The diagram refers to "Eclair" and "FroYo"; however, they are simply
 placeholders, and the diagram actually reflects the overall release and
 branching strategy.</li>
-<li>At all times, the Release code-line (which may actually consist of
+<li>At all times, a release code-line (which may actually consist of
 more than one actual branch in git) is considered the sole canonical source
-code for a given Android platform. OEMs and other groups building devices
-should pull only from a Release branch.</li>
-<li>We will be setting up an "Experimental" code-line to capture changes from
+code for a given Android platform version. OEMs and other groups building devices
+should pull only from a release branch.</li>
+<li>We will set up "experimental" code-lines to capture changes from
 the community, so that they can be iterated on, with an eye toward stability.</li>
-<li>Changes that prove stable will eventually be pulled into a Release
+<li>Changes that prove stable will eventually be pulled into a release
 branch. Note that this will only apply to bug fixes, app improvements, and
 other things that do not affect the APIs of the platform.</li>
-<li>Changes will be pulled into Release branches from upstream projects
-(include the Android "upstream" projects) as necessary.</li>
+<li>Changes will be pulled into release branches from upstream projects
+(including the Android "upstream" projects) as necessary.</li>
 <li>The "n+1"th version (that is, next major version of the framework and
-platform APIs) will be developed by Google internally. (See below for
-details.)</li>
-<li>Changes will be pulled from upstream, Release, and Experimental branches
+platform APIs) will be developed by Google internally. See below for
+details.</li>
+<li>Changes will be pulled from upstream, release, and experimental branches
 into Google's private branch as necessary.</li>
 <li>When the platform APIs for the next version have stabilized and been fully
 tested, Google will cut a release of the next platform version. (This
 specifically refers to a new <code>SdkVersion</code>.) This will also
-correspond to the internal code-line being made a public Release branch, and the
+correspond to the internal code-line being made a public release branch, and the
 new current platform code-line.</li>
-<li>When a new platform version is cut, a corresponding Experimental
-code-line.</li>
+<li>When a new platform version is cut, a corresponding experimental
+code-line will be created at the same time.</li>
 </ul>
 <h3>About Private Code-Lines</h3>
 <p>The source management strategy above includes a code-line that Google will
@@ -62,9 +65,9 @@
 Google retains responsibility for the strategic direction of Android as a
 platform and a product. Our approach is based on focusing on a small number of
 flagship devices to drive features, and secure protections of Android-related
-intellectual property through patents and the like.</p>
+intellectual property.</p>
 <p>As a result, Google frequently has possession of confidential
-information of third parties, and we must refrain from revealing patentable
+information of third parties, and we must refrain from revealing sensitive
 features until we've secured the appropriate protections. Meanwhile, there are
 real risks to the platform arising from having too many platform versions
 extant at once. For these reasons, we have structured the open-source project
diff --git a/pdk/docs/source/code-style.jd b/pdk/docs/source/code-style.jd
index 8b5946e..957ab02 100644
--- a/pdk/docs/source/code-style.jd
+++ b/pdk/docs/source/code-style.jd
@@ -1,7 +1,6 @@
 page.title=Code Style Guidelines for Contributors
 doc.type=source
 @jd:body
-<div>
 <p>The rules below are not guidelines or recommendations, but strict rules.
 Contributions to Android generally <b>will not be accepted if they do not
 adhere to these rules.</b>
@@ -11,425 +10,615 @@
 </h1>
 <p>We follow standard Java coding conventions. We add a few rules:
 </p>
-<ol><li><a href="#exceptionsIgnore">Exceptions</a>
-: Never catch and ignore them without explanation.
-</li>
-<li><a href="#exceptionsAll">Exceptions</a>
-: do not catch generic Exception, except in library code at the root of the stack.
-</li>
-<li><a href="#finalizers">Finalizers</a>
-: generally don't use them.
-</li>
-<li><a href="#imports">Imports</a>
-: Fully qualify imports
-</li>
+<ol><li><a href="#exceptionsIgnore">Exceptions</a>: Never catch and ignore them without explanation.</li>
+<li><a href="#exceptionsAll">Exceptions</a>: do not catch generic Exception, except in library code at the root of the stack.</li>
+<li><a href="#finalizers">Finalizers</a>: generally don't use them.</li>
+<li><a href="#imports">Imports</a>: Fully qualify imports</li>
 </ol>
-<h1><a>Java Library Rules</a>
-</h1>
-<p>There are conventions for using Android's Java libraries and tools. In some cases, the convention has changed in important ways and older code might use a deprecated pattern or library. When working with such code, it's okay to continue the existing style (see <a href="#consistency">Consistency</a>
-). When creating new components never use deprecated libraries.
-</p>
-<h1><a>Java Style Rules</a>
-</h1>
-<p>Programs are much easier to maintain when all files have a consistent style. We follow the standard Java coding style, as defined by Sun in their <a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Code Conventions for the Java Programming Language</a>
-, with a few exceptions and additions. This style guide is comprehensive and detailed and is in common usage in the Java community.
-</p>
-<p>In addition, we enforce the following style rules:
-</p>
-<ol><li><a href="#javadoc">Comments/Javadoc</a>
-: write it; use standard style
-</li>
-<li><a href="#shortmethods">Short methods</a>
-: don't write giant methods
-</li>
-<li>Fields: should either be at the top of the file, or immediately before the methods that use them
-</li>
-<li><a href="#localvariables">Local variables</a>
-: limit the scope
-</li>
-<li><a href="#import_style">Imports</a>
-: android; third party alphabetical; java(x)
-</li>
-<li><a href="#indentation">Indentation</a>
-: 4 spaces, no tabs.
-</li>
-<li><a href="#linelen">Line length</a>
-: 100 columns
-</li>
-<li><a href="#field_names">Field names</a>
-: Non-public, non-static fields start with m. Static fields start s.
-</li>
-<li><a href="#braces">Braces</a>
-: Opening braces don't go on their own line.
-</li>
-<li><a href="#annotations">Annotations</a>
-: Use the standard annotations.
-</li>
-<li><a href="#acronyms">Acronyms are words</a>
-: Treat acronyms as words in names, yielding XmlHttpRequest, getUrl(), etc.
-</li>
-<li><a href="#todo">TODO style</a>
-: "TODO: write this description"
-</li>
-<li><a href="#consistency">Consistency</a>
-: Look at what's around you!
-</li>
-<li><a href="#logging">Logging</a>
-: Be careful with logging. It's expensive.
-</li>
+<h1>Java Library Rules</h1>
+<p>There are conventions for using Android's Java libraries and tools. In some
+cases, the convention has changed in important ways and older code might use a
+deprecated pattern or library. When working with such code, it's okay to
+continue the existing style (see <a href="#consistency">Consistency</a>). When
+creating new components never use deprecated libraries.</p>
+<h1>Java Style Rules</h1>
+<p>Programs are much easier to maintain when all files have a consistent
+style. We follow the standard Java coding style, as defined by Sun in their <a
+href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Code
+Conventions for the Java Programming Language</a>, with a few exceptions and
+additions. This style guide is comprehensive and detailed and is in common
+usage in the Java community.</p>
+<p>In addition, we enforce the following style rules:</p>
+<ol><li><a href="#javadoc">Comments/Javadoc</a>: write it; use standard style</li>
+<li><a href="#shortmethods">Short methods</a>: don't write giant methods</li>
+<li>Fields: should either be at the top of the file, or immediately before the methods that use them</li>
+<li><a href="#localvariables">Local variables</a>: limit the scope</li>
+<li><a href="#import_style">Imports</a>: android; third party alphabetical; java(x)</li>
+<li><a href="#indentation">Indentation</a>: 4 spaces, no tabs.</li>
+<li><a href="#linelen">Line length</a>: 100 columns</li>
+<li><a href="#field_names">Field names</a>: Non-public, non-static fields start with m.</li>
+<li><a href="#braces">Braces</a>: Opening braces don't go on their own line.</li>
+<li><a href="#annotations">Annotations</a>: Use the standard annotations.</li>
+<li><a href="#acronyms">Acronyms are words</a>: Treat acronyms as words in names, yielding XmlHttpRequest, getUrl(), etc.</li>
+<li><a href="#todo">TODO style</a>: "TODO: write this description"</li>
+<li><a href="#consistency">Consistency</a>: Look at what's around you!</li>
+<li><a href="#logging">Logging</a>: Be careful with logging. It's expensive.</li>
 </ol>
-<h1><a>Javatests Style Rules</a>
-</h1>
-<ol><li><a href="#testmethodnames">Naming test methods</a>
-: testMethod_specificCase is ok
-</li>
+<h1>Javatests Style Rules</h1>
+<ol>
+<li><a href="#testmethodnames">Naming test methods</a>: testMethod_specificCase is ok</li>
 </ol>
-<hr><h2>
-Java Language Rules
-</h2>
-<h2><a>Exceptions: do not ignore</a>
-</h2>
-Sometimes it is tempting to write code that completely ignores an exception like this:
-<pre>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>}<br>}<br><br></pre>
-<p>You must never do this. While you may think that your code will never encounter this error condition or that it is not important to handle it, ignoring exceptions like above creates mines in your code for someone else to trip over some day. You must handle every Exception in your code in some principled way. The specific handling varies depending on the case.
-</p>
-<blockquote>Anytime somebody has an empty catch clause they should have a creepy feeling. There are definitely times when it is actually the correct thing to do, but at least you have to think about it. In Java you can't escape the creepy feeling.<br><div>-<a href="http://www.artima.com/intv/solid4.html">James Gosling</a>
-</div>
-</blockquote>
-<p>Acceptable alternatives (in order of preference) are:
-</p>
-<ul><li>Throw the exception up to the caller of your method.
-<pre>void setServerPort(String value) throws NumberFormatException {<br>serverPort = Integer.parseInt(value);<br>}<br><br></pre>
-</li>
+<h2>Java Language Rules</h2>
+<h2><a name="exceptionsIgnore"></a>Exceptions: do not ignore</h2>
+<p>Sometimes it is tempting to write code that completely ignores an exception
+like this:</p>
+<pre>void setServerPort(String value) {
+    try {
+        serverPort = Integer.parseInt(value);
+    } catch (NumberFormatException e) { }
+}</pre>
+<p>You must never do this. While you may think that your code will never
+encounter this error condition or that it is not important to handle it,
+ignoring exceptions like above creates mines in your code for someone else to
+trip over some day. You must handle every Exception in your code in some
+principled way. The specific handling varies depending on the case.</p>
+<blockquote>Anytime somebody has an empty catch clause they should have a
+creepy feeling. There are definitely times when it is actually the correct
+thing to do, but at least you have to think about it. In Java you can't escape
+the creepy feeling.
+-<a href="http://www.artima.com/intv/solid4.html">James
+Gosling</a></blockquote>
+<p>Acceptable alternatives (in order of preference) are:</p>
+<ul>
+<li>Throw the exception up to the caller of your method.
+<pre>void setServerPort(String value) throws NumberFormatException {
+    serverPort = Integer.parseInt(value);
+}</pre></li>
 <li>Throw a new exception that's appropriate to your level of abstraction.
-<pre>void setServerPort(String value) throws ConfigurationException {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>throw new ConfigurationException("Port " + value + " is not valid.");<br>}<br><br></pre>
-</li>
-<li>Handle the error gracefully and substitute an appropriate value in the catch {} block.
-<pre>/** Set port. If value is not a valid number, 80 is substituted. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>serverPort = 80;  // default port for server <br>}<br></pre>
-</li>
-<li>Catch the Exception and throw a new RuntimeException. This is dangerous: only do it if you are positive that if this error occurs, the appropriate thing to do is crash.
-<pre>/** Set port. If value is not a valid number, die. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>throw new RuntimeException("port " + value " is invalid, ", e);<br>}<br></pre>
-Note that the original exception is passed to the constructor for RuntimeException. This wrapped exception paradigm is very useful but only works in Java 1.4. If your code must compile under Java 1.3, you will need to omit the exception that is the cause.<br><br></li>
-<li>Last resort: if you are confident that actually ignoring the exception is appropriate then you may ignore it, but you must also comment why with a good reason:
-<pre>/** If value is not a valid number, original port number is used. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>// Method is documented to just ignore invalid user input.<br>// serverPort will just be unchanged.<br>}<br>}<br></pre>
-</li>
+<pre>void setServerPort(String value) throws ConfigurationException {
+    try {
+        serverPort = Integer.parseInt(value);
+    } catch (NumberFormatException e) {
+        throw new ConfigurationException("Port " + value + " is not valid.");
+    }
+}</pre></li>
+<li>Handle the error gracefully and substitute an appropriate value in the
+catch {} block.
+<pre>/** Set port. If value is not a valid number, 80 is substituted. */
+void setServerPort(String value) {
+    try {
+        serverPort = Integer.parseInt(value);
+    } catch (NumberFormatException e) {
+        serverPort = 80;  // default port for server 
+    }
+}</pre></li>
+<li>Catch the Exception and throw a new RuntimeException. This is dangerous:
+only do it if you are positive that if this error occurs, the appropriate
+thing to do is crash.
+<pre>/** Set port. If value is not a valid number, die. */
+void setServerPort(String value) {
+    try {
+        serverPort = Integer.parseInt(value);
+    } catch (NumberFormatException e) {
+        throw new RuntimeException("port " + value " is invalid, ", e);
+    }
+}</pre>
+Note that the original exception is passed to the constructor for
+RuntimeException.  If your code must compile under Java 1.3, you will need to
+omit the exception that is the cause.</li>
+<li>Last resort: if you are confident that actually ignoring the exception is
+appropriate then you may ignore it, but you must also comment why with a good
+reason:
+<pre>/** If value is not a valid number, original port number is used. */
+void setServerPort(String value) {
+    try {
+        serverPort = Integer.parseInt(value);
+    } catch (NumberFormatException e) {
+        // Method is documented to just ignore invalid user input.
+        // serverPort will just be unchanged.
+    }
+}</pre></li>
 </ul>
-<h2><a>Exceptions: do not catch generic Exception</a>
-</h2>
-Sometimes it is tempting to be lazy when catching exceptions and do something like this:
-<pre>try {<br>someComplicatedIOFunction();        // may throw IOException <br>someComplicatedParsingFunction();   // may throw ParsingException <br>someComplicatedSecurityFunction();  // may throw SecurityException <br>// phew, made it all the way <br>} catch (Exception e) {               // I'll just catch all exceptions <br>handleError();                      // with one generic handler!<br>}<br><br></pre>
-You should not do this. In almost all cases it is inappropriate to catch generic Exception or Throwable, preferably not Throwable, because it includes Error exceptions as well. It is very dangerous. It means that Exceptions you never expected (including RuntimeExceptions like ClassCastException) end up getting caught in application-level error handling. It obscures the failure handling properties of your code. It means if someone adds a new type of Exception in the code you're calling, the compiler won't help you realize you need to handle that error differently. And in most cases you shouldn't be handling different types of exception the same way, anyway.
-<p>There are rare exceptions to this rule: certain test code and top-level code where you want to catch all kinds of errors (to prevent them from showing up in a UI, or to keep a batch job running). In that case you may catch generic Exception (or Throwable) and handle the error appropriately. You should think very carefully before doing this, though, and put in comments explaining why it is safe in this place.
-</p>
-<p>Alternatives to catching generic Exception:
-</p>
-<ul><li>Catch each exception separately as separate catch blocks after a single try. This can be awkward but is still preferable to catching all Exceptions. Beware repeating too much code in the catch blocks.
-</li>
-<li>Refactor your code to have more fine-grained error handling, with multiple try blocks. Split up the IO from the parsing, handle errors separately in each case.
-</li>
-<li>Rethrow the exception. Many times you don't need to catch the exception at this level anyway, just let the method throw it.
-</li>
+<h2><a name="exceptionsAll"></a>Exceptions: do not catch generic Exception</h2>
+<p>Sometimes it is tempting to be lazy when catching exceptions and do
+something like this:</p>
+<pre>try {
+    someComplicatedIOFunction();        // may throw IOException 
+    someComplicatedParsingFunction();   // may throw ParsingException 
+    someComplicatedSecurityFunction();  // may throw SecurityException 
+    // phew, made it all the way 
+} catch (Exception e) {               // I'll just catch all exceptions 
+    handleError();                      // with one generic handler!
+}</pre>
+<p>You should not do this. In almost all cases it is inappropriate to catch
+generic Exception or Throwable, preferably not Throwable, because it includes
+Error exceptions as well. It is very dangerous. It means that Exceptions you
+never expected (including RuntimeExceptions like ClassCastException) end up
+getting caught in application-level error handling. It obscures the failure
+handling properties of your code. It means if someone adds a new type of
+Exception in the code you're calling, the compiler won't help you realize you
+need to handle that error differently. And in most cases you shouldn't be
+handling different types of exception the same way, anyway.</p>
+<p>There are rare exceptions to this rule: certain test code and top-level
+code where you want to catch all kinds of errors (to prevent them from showing
+up in a UI, or to keep a batch job running). In that case you may catch
+generic Exception (or Throwable) and handle the error appropriately. You
+should think very carefully before doing this, though, and put in comments
+explaining why it is safe in this place.</p>
+<p>Alternatives to catching generic Exception:</p>
+<ul>
+<li>Catch each exception separately as separate catch blocks after a single
+try. This can be awkward but is still preferable to catching all Exceptions.
+Beware repeating too much code in the catch blocks.</li>
+<li>Refactor your code to have more fine-grained error handling, with multiple
+try blocks. Split up the IO from the parsing, handle errors separately in each
+case.</li>
+<li>Rethrow the exception. Many times you don't need to catch the exception at
+this level anyway, just let the method throw it.</li>
 </ul>
-Remember: exceptions are your friend! When the compiler complains you're not catching an exception, don't scowl. Smile: the compiler just made it easier for you to catch runtime problems in your code.
-<h2><a>Finalizers</a>
-</h2>
-<p><b>What it is</b>
-: Finalizers are a way to have a chunk of code executed when an object is garbage collected.
-</p>
-<p><b>Pros</b>
-: can be handy for doing cleanup, particularly of external resources.
-</p>
-<p><b>Cons</b>
-: there are no guarantees as to when a finalizer will be called, or even that it will be called at all.
-</p>
-<p><b>Decision</b>
-: we don't use finalizers. In most cases, you can do what you need from a finalizer with good exception handling. If you absolutely need it, define a close() method (or the like) and document exactly when that method needs to be called. See InputStream for an example. In this case it is appropriate but not required to print a short log message from the finalizer, as long as it is not expected to flood the logs.
-</p>
-<p>The one exception is it is OK to write a finalizer if all it does is make calls to X.assertTrue().
-</p>
-<h2><a>Imports</a>
-</h2>
-<h3>
-Wildcards in imports
-</h3>
-<p><b>What it is</b>
-: When you want to use class Bar from package foo,there are two possible ways to import it:
-</p>
-<ol><li>import foo.*;
-</li>
-<li>import foo.Bar;
-</li>
+<p>Remember: exceptions are your friend! When the compiler complains you're
+not catching an exception, don't scowl. Smile: the compiler just made it
+easier for you to catch runtime problems in your code.</p>
+<h2><a name="finalizers"></a>Finalizers</h2>
+<p><b>What it is</b>: Finalizers are a way to have a chunk of code executed
+when an object is garbage collected.</p>
+<p><b>Pros</b>: can be handy for doing cleanup, particularly of external
+resources.</p>
+<p><b>Cons</b>: there are no guarantees as to when a finalizer will be called,
+or even that it will be called at all.</p>
+<p><b>Decision</b>: we don't use finalizers. In most cases, you can do what
+you need from a finalizer with good exception handling. If you absolutely need
+it, define a close() method (or the like) and document exactly when that
+method needs to be called. See InputStream for an example. In this case it is
+appropriate but not required to print a short log message from the finalizer,
+as long as it is not expected to flood the logs.</p>
+<h2><a name="imports"></a>Imports</h2>
+<h3>Wildcards in imports</h3>
+<p><b>What it is</b>: When you want to use class Bar from package foo,there
+are two possible ways to import it:</p>
+<ol>
+<li><code>import foo.*;</code></li>
+<li><code>import foo.Bar;</code></li>
 </ol>
-<p><b>Pros of #1</b>
-: Potentially reduces the number of import statements.
+<p><b>Pros of #1</b>: Potentially reduces the number of import statements.
 </p>
-<p><b>Pros of #2</b>
-: Makes it obvious what classes are actually used. Makes code more readable for maintainers.
-</p>
-<p><b>Decision</b>
-:Use style #2 for importing all Android code. An explicit exception is made for java standard libraries (java.util.*, java.io.*, etc.) and unit test code (junit.framework.*).
-</p>
-<h2><a>Comments/Javadoc</a>
-</h2>
-<p>Every file should have a copyright statement at the top. Then a package statement and import statements should follow, each block separated by a blank line. And then there is the class or interface declaration. In the Javadoc comments, describe what the class or interface does.
-</p>
-<pre>/*<br>* Copyright (C) 2007 The Android Open Source Project <br>*<br>* Licensed under the Apache License, Version 2.0 (the "License");<br>* you may not use this file except in compliance with the License.<br>* You may obtain a copy of the License at <br>*<br>*      http://www.apache.org/licenses/LICENSE-2.0<br>*<br>* Unless required by applicable law or agreed to in writing, software <br>* distributed under the License is distributed on an "AS IS" BASIS,<br>* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br>* See the License for the specific language governing permissions and <br>* limitations under the License.<br>*/<br><br>package com.android.internal.foo;<br><br>import android.os.Blah;<br>import android.view.Yada;<br><br>import java.sql.ResultSet;<br>import java.sql.SQLException;<br><br>/**<br>* Does X and Y and provides an abstraction for Z.<br>*/<br>public class Foo {<br>...<br>}<br></pre>
-<p>Every class and nontrivial public method you write <b>must</b>
-contain a Javadoc comment with at least one sentence describing what the class or method does. This sentence should start with a 3rd person descriptive verb. Examples:
-</p>
-<pre>/** Returns the correctly rounded positive square root of a double value. */<br>static double sqrt(double a) {<br>}<br><br>/**<br>* Constructs a new String by converting the specified array of <br>* bytes using the platform's default character encoding.<br>*/<br>public String(byte[] bytes) {<br>}<br></pre>
-<p>You do not need to write Javadoc for trivial get and set methods such as setFoo() if all your Javadoc would say is "sets Foo". If the method does something more complex (such as enforcing a constraint or having an important side effect), then you must document it. And if it's not obvious what the property "Foo" means, you should document it.
-</p>
-<p>Every method you write, whether public or otherwise, would benefit from Javadoc. Public methods are part of an API and therefore require Javadoc.
-</p>
-Android does not currently enforce a specific style for writing Javadoc comments, but you <b>should</b>
-follow the <a href="http://java.sun.com/j2se/javadoc/writingdoccomments/">Sun Javadoc conventions</a>
-.
-<h2><a>Short methods</a>
-</h2>
-To the extent that it is feasible, methods should be kept small and focused. It is, however, recognized that long methods are sometimes appropriate, so no hard limit is placed on method length. If a method exceeds 40 lines or so, think about whether it can be broken up without harming the structure of the program.
-<h2><a>Local variables</a>
-</h2>
-The scope of local variables should be kept to a minimum (<i>Effective Java</i>
-Item 29). By doing so, you increase the readability and maintainability of your code and reduce the likelihood of error. Each variable should be declared in the innermost block that encloses all uses of the variable.
-<p>Local variables should be declared at the point they are first used. Nearly every local variable declaration should contain an initializer. If you don't yet have enough information to initialize a variable sensibly, you should postpone the declaration until you do.
-</p>
-<p>One exception to this rule concerns try-catch statements. If a variable is initialized with the return value of a method that throws a checked exception, it must be initialized inside a try block. If the value must be used outside of the try block, then it must be declared before the try block, where it cannot yet be sensibly initialized:
-</p>
-<pre>// Instantiate class cl, which represents some sort of Set <br>Set s = null;<br>try {<br>s = (Set) cl.newInstance();<br>} catch(IllegalAccessException e) {<br>throw new IllegalArgumentException(cl + " not accessible");<br>} catch(InstantiationException e) {<br>throw new IllegalArgumentException(cl + " not instantiable");<br>}<br><br>// Exercise the set <br>s.addAll(Arrays.asList(args));<br></pre>
-<p>But even this case can be avoided by encapsulating the try-catch block in a method:
-</p>
-<pre>Set createSet(Class cl) {<br>// Instantiate class cl, which represents some sort of Set <br>try {<br>return (Set) cl.newInstance();<br>} catch(IllegalAccessException e) {<br>throw new IllegalArgumentException(cl + " not accessible");<br>} catch(InstantiationException e) {<br>throw new IllegalArgumentException(cl + " not instantiable");<br>}<br>}<br>...<br>// Exercise the set <br>Set s = createSet(cl);<br>s.addAll(Arrays.asList(args));<br></pre>
-Loop variables should be declared in the for statement itself unless there is a compelling reason to do otherwise:
-<pre>for (int i = 0; i n; i++) {<br>doSomething(i);<br>}<br><br>for (Iterator i = c.iterator(); i.hasNext(); ) {<br>doSomethingElse(i.next());<br>}<br><br><br></pre>
-<h2><a>Imports</a>
-</h2>
-The ordering of import statements is:Android importsImports from third parties (com, junit, net, org)<br>java and javax
-<p>To exactly match the IDE settings, the imports should be:
-</p>
-Alphabetical within each grouping.<br>Capital letters are considered to come before lower case letter (e.g. Z before a).There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).
-<h4>
-Why?
-</h4>
-<p>Originally there was no style requirement on the ordering. This meant that the IDE's were either always changing the ordering, or IDE developers had to disable the automatic import management features and maintain the imports by hand. This was deemed bad. When java-style was asked, the preferred styles were all over the map. It pretty much came down to our needing to "pick an ordering and be consistent." So we chose a style, updated the javaguide and made the IDE's obey it. We expect that as IDE users work on the code, the imports in all of the packages will end up matching this pattern without any extra engineering effort.
-</p>
-<p>The style chosen such that:
-</p>
-The imports people want to look at first tend to be at the top (android)The imports people want to look at least tend to be at the bottom (java)Humans can easily follow the styleThe IDE's can follow the style
-<h3>
-What about static imports?
-</h3>
-The use and location of static imports have been mildly controversial issues. Some people would prefer static imports to be interspersed with the remaining imports, some would prefer them reside above or below all other imports. Additinally, we have not yet come up with a way to make all IDEs use the same ordering.
-<p>Since most people consider this a low priority issue, just use your judgement and please be consistent.
-</p>
+<p><b>Pros of #2</b>: Makes it obvious what classes are actually used. Makes
+code more readable for maintainers. </p>
+<p><b>Decision</b>: Use style #2 for importing all Android code. An explicit
+exception is made for java standard libraries (java.util.*, java.io.*, etc.)
+and unit test code (junit.framework.*).</p>
+<h2><a name="javadoc"></a>Comments/Javadoc</h2>
+<p>Every file should have a copyright statement at the top. Then a package
+statement and import statements should follow, each block separated by a blank
+line. And then there is the class or interface declaration. In the Javadoc
+comments, describe what the class or interface does.</p>
+<pre>/*
+ * 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.
+ */
 
-<h2><a>Indentation</a>
-</h2>
-<p>We use 4 space indents for blocks. We never use tabs. When in doubt, be consistent with code around you.
-</p>
-<p>We use 8 space indents for line wraps, including function calls and assignments. For example, this is correct:
-</p>
-<pre>Instrument i <br>= someLongExpression(that, wouldNotFit, on, one, line);</pre>
-and this is not correct:
-<pre>Instrument i <br>= someLongExpression(that, wouldNotFit, on, one, line);</pre>
-<h2><a>Field Names</a>
-</h2>
-<ul><li>Non-public, non-static field names start with m.
-</li>
-<li>Static field names start with s.
-</li>
-<li>Other fields start with a lower case letter.
-</li>
-<li>Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.
-</li>
+package com.android.internal.foo;
+
+import android.os.Blah;
+import android.view.Yada;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Does X and Y and provides an abstraction for Z.
+ */
+public class Foo {
+    ...
+}</pre>
+<p>Every class and nontrivial public method you write <b>must</b> contain a
+Javadoc comment with at least one sentence describing what the class or method
+does. This sentence should start with a 3rd person descriptive verb.
+Examples:</p>
+<pre>/** Returns the correctly rounded positive square root of a double value. */
+static double sqrt(double a) {
+}
+
+/**
+ * Constructs a new String by converting the specified array of 
+ * bytes using the platform's default character encoding.
+ */
+public String(byte[] bytes) {
+}</pre>
+<p>You do not need to write Javadoc for trivial get and set methods such as
+setFoo() if all your Javadoc would say is "sets Foo". If the method does
+something more complex (such as enforcing a constraint or having an important
+side effect), then you must document it. And if it's not obvious what the
+property "Foo" means, you should document it.</p>
+<p>Every method you write, whether public or otherwise, would benefit from
+Javadoc. Public methods are part of an API and therefore require Javadoc.</p>
+<p>Android does not currently enforce a specific style for writing Javadoc
+comments, but you <b>should</b> follow the <a
+href="http://java.sun.com/j2se/javadoc/writingdoccomments/">Sun Javadoc
+conventions</a>.</p>
+<h2><a name="shortmethods"></a>Short methods</h2>
+<p>To the extent that it is feasible, methods should be kept small and
+focused. It is, however, recognized that long methods are sometimes
+appropriate, so no hard limit is placed on method length. If a method exceeds
+40 lines or so, think about whether it can be broken up without harming the
+structure of the program.</p>
+<h2><a name="localvariables"></a>Local variables</h2>
+<p>The scope of local variables should be kept to a minimum (<i>Effective
+Java</i> Item 29). By doing so, you increase the readability and
+maintainability of your code and reduce the likelihood of error. Each variable
+should be declared in the innermost block that encloses all uses of the
+variable.</p>
+<p>Local variables should be declared at the point they are first used. Nearly
+every local variable declaration should contain an initializer. If you don't
+yet have enough information to initialize a variable sensibly, you should
+postpone the declaration until you do.</p>
+<p>One exception to this rule concerns try-catch statements. If a variable is
+initialized with the return value of a method that throws a checked exception,
+it must be initialized inside a try block. If the value must be used outside
+of the try block, then it must be declared before the try block, where it
+cannot yet be sensibly initialized:</p>
+<pre>// Instantiate class cl, which represents some sort of Set 
+Set s = null;
+try {
+    s = (Set) cl.newInstance();
+} catch(IllegalAccessException e) {
+    throw new IllegalArgumentException(cl + " not accessible");
+} catch(InstantiationException e) {
+    throw new IllegalArgumentException(cl + " not instantiable");
+}
+
+// Exercise the set 
+s.addAll(Arrays.asList(args));</pre>
+<p>But even this case can be avoided by encapsulating the try-catch block in a method:</p>
+<pre>Set createSet(Class cl) {
+    // Instantiate class cl, which represents some sort of Set 
+    try {
+        return (Set) cl.newInstance();
+    } catch(IllegalAccessException e) {
+        throw new IllegalArgumentException(cl + " not accessible");
+    } catch(InstantiationException e) {
+        throw new IllegalArgumentException(cl + " not instantiable");
+    }
+}
+
+...
+
+// Exercise the set 
+Set s = createSet(cl);
+s.addAll(Arrays.asList(args));</pre>
+<p>Loop variables should be declared in the for statement itself unless there
+is a compelling reason to do otherwise:</p>
+<pre>for (int i = 0; i n; i++) {
+    doSomething(i);
+}
+
+for (Iterator i = c.iterator(); i.hasNext(); ) {
+    doSomethingElse(i.next());
+}</pre>
+<h2><a name="import_style"></a>Imports</h2>
+<p>The ordering of import statements is:</p>
+<ol>
+<li>Android imports</li>
+<li>Imports from third parties (com, junit, net, org)</li>
+<li>java and javax</li>
+</ol>
+<p>To exactly match the IDE settings, the imports should be:</p>
+<ul>
+<li>Alphabetical within each grouping.</li>
+<li>Capital letters are considered to come before lower case letter (e.g. Z before a).</li>
+<li>There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).</li>
 </ul>
-<p>For example:
-</p>
-<pre>public class MyClass {<br>public static final int SOME_CONSTANT = 42;<br>public int publicField;<br>private static MyClass sSingleton;<br>int mPackagePrivate;<br>private int mPrivate;<br>protected int mProtected;<br>}</pre>
-<h2><a>Braces</a>
-</h2>
-<p>Braces do not go on their own line; they go on the same line as the code before them. So:
-</p>
-<pre>class MyClass {<br>int func() {<br>if (something) {<br>// ...<br>} else if (somethingElse) {<br>// ...<br>} else {<br>// ...<br>}<br>}<br>}<br></pre>
-<p>We require braces around the statements for a conditional. Except, if the entire conditional (the condition and the body) fit on one line, you may (but are not obligated to) put it all on one line. That is, this is legal:
-</p>
-<pre>if (condition) {<br>body; // ok <br>}<br>if (condition) body; // ok</pre>
-<p>but this is still illegal:
-</p>
-<pre>if (condition)<br>body; // bad <br></pre>
-<h2><a>Line length</a>
-</h2>
-<p>Each line of text in your code should be at most 100 characters long.
-</p>
-<p>There has been lots of discussion about this rule and the decision remains that 100 characters is the maximum.
-</p>
-<p>Exception: if a comment line contains an example command or a literal URL longer than 100 characters, that line may be longer than 100 characters for ease of cut and paste.
-</p>
-<p>Exception: import lines can go over the limit because humans rarely see them. This also simplifies tool writing.
-</p>
-<h2>
-Java 1.5 Annotations
-</h2>
-<p>Annotations should precede other modifiers for the same language element. Simple marker annotations (e.g. @Override) can be listed on the same line with the language element. If there are multiple annotations, or parameterized annotations, they should each be listed one-per-line in alphabetical order.
-</p>
-<p>Android -standard practices for the three predefined annotations in Java 1.5's are:
-</p>
-@DeprecatedThe @Deprecated annotation must be used whenever the use of the annotated element is discouraged. If you use the @Deprecated annotation, you must also have a @deprecated Javadoc tag and it should name an alternate implementation. In addition, remember that a @Deprecated method is <b>still</b>
-supposed to work.
-<p>If you see old code that has a @deprecated Javadoc tag, please add the @Deprecated annotation.
-</p>
-@OverrideThe @Override annotation must be used whenever a method overrides the declaration or implementation from a super-class.
-<p>For example, if you use the {@inheritdocs} Javadoc tag, and derive from a class (not an interface), you must also annotate that the method @Overrides the parent class's method.
-</p>
-@SuppressWarningsThe @SuppressWarnings annotation should only be used under circumstances where it is impossible to eliminate a warning. If a warning passes this "impossible to eliminate" test, the@SuppressWarnings annotation <b>must</b>
-be used, so as to ensure that all warnings reflect actual problems in the code.
-<p>When a @SuppressWarnings annotation is necessary, it must be prefixed with a TODO comment that explains the "impossible to eliminate" condition. This will normally identify an offending class that has an awkward interface. For example:
-</p>
-<pre>// TODO: The third-party class com.third.useful.Utility.rotate() needs generics <br>@SuppressWarnings({"generic-cast"})<br>ListStringblix = Utility.rotate(blax);<br></pre>
-When a @SuppressWarnings annotation is required, the code should be refactored to isolate the software elements where the annotation applies.
-<h2><a>Acronyms in names</a>
-</h2>
-<p>Treat acronyms and abbreviations as words. The names are much more readable:
-</p>
+<h4>Why?</h4>
+<p>Originally there was no style requirement on the ordering. This meant that
+the IDE's were either always changing the ordering, or IDE developers had to
+disable the automatic import management features and maintain the imports by
+hand. This was deemed bad. When java-style was asked, the preferred styles
+were all over the map. It pretty much came down to our needing to "pick an
+ordering and be consistent." So we chose a style, updated the style guide, and
+made the IDEs obey it. We expect that as IDE users work on the code, the
+imports in all of the packages will end up matching this pattern without any
+extra engineering effort.</p>
+<p>The style chosen such that:</p>
+<ul>
+<li>The imports people want to look at first tend to be at the top (android)</li>
+<li>The imports people want to look at least tend to be at the bottom (java)</li>
+<li>Humans can easily follow the style</li>
+<li>The IDE's can follow the style</li>
+</ul>
+<h3>What about static imports?</h3>
+<p>The use and location of static imports have been mildly controversial
+issues. Some people would prefer static imports to be interspersed with the
+remaining imports, some would prefer them reside above or below all other
+imports. Additinally, we have not yet come up with a way to make all IDEs use
+the same ordering.</p>
+<p>Since most people consider this a low priority issue, just use your
+judgement and please be consistent.</p>
 
-<table><tbody><tr><td>Good
-</td>
-<td>Bad
-</td>
-</tr>
-<tr><td>XmlHttpRequest</td>
-<td>XMLHTTPRequest
-</td>
-</tr>
-<tr><td>getCustomerId</td>
-<td>getCustomerID
-</td>
-</tr>
-</tbody>
-</table>
-
-<p>This style rule also applies when an acronym or abbreviation is the entire name:
-</p>
-
-<table><tbody><tr><td>Good
-</td>
-<td>Bad
-</td>
-</tr>
-<tr><td>class Html</td>
-<td>class HTML
-</td>
-</tr>
-<tr><td>String url;</td>
-<td>String URL;
-</td>
-</tr>
-<tr><td>long id;</td>
-<td>long ID;
-</td>
-</tr>
-</tbody>
-</table>
-
-<p>Both the JDK and the Android code bases are very inconsistent with regards to acronyms, therefore, it is virtually impossible to be consistent with the code around you. Bite the bullet, and treat acronyms as words.
-</p>
+<h2><a name="indentation"></a>Indentation</h2>
+<p>We use 4 space indents for blocks. We never use tabs. When in doubt, be
+consistent with code around you.</p>
+<p>We use 8 space indents for line wraps, including function calls and
+assignments. For example, this is correct:</p>
+<pre>Instrument i =
+        someLongExpression(that, wouldNotFit, on, one, line);</pre>
+<p>and this is not correct:</p>
+<pre>Instrument i =
+    someLongExpression(that, wouldNotFit, on, one, line);</pre>
+<h2><a name="field_names"></a>Field Names</h2>
+<ul>
+<li>Non-public, non-static field names start with m.</li>
+<li>Static field names start with s.</li>
+<li>Other fields start with a lower case letter.</li>
+<li>Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.</li>
+</ul>
+<p>For example:</p>
+<pre>public class MyClass {
+    public static final int SOME_CONSTANT = 42;
+    public int publicField;
+    private static MyClass sSingleton;
+    int mPackagePrivate;
+    private int mPrivate;
+    protected int mProtected;
+}</pre>
+<h2><a name="braces"></a>Braces</h2>
+<p>Braces do not go on their own line; they go on the same line as the code
+before them. So:</p>
+<pre>class MyClass {
+    int func() {
+        if (something) {
+            // ...
+        } else if (somethingElse) {
+            // ...
+        } else {
+            // ...
+        }
+    }
+}</pre>
+<p>We require braces around the statements for a conditional. Except, if the
+entire conditional (the condition and the body) fit on one line, you may (but
+are not obligated to) put it all on one line. That is, this is legal:</p>
+<pre>if (condition) {
+    body(); // ok 
+}
+if (condition) body(); // ok</pre>
+<p>but this is still illegal:</p>
+<pre>if (condition)
+    body(); // bad</pre>
+<h2><a name="linelen"></a>Line length</h2>
+<p>Each line of text in your code should be at most 100 characters long.</p>
+<p>There has been lots of discussion about this rule and the decision remains
+that 100 characters is the maximum.</p>
+<p>Exception: if a comment line contains an example command or a literal URL
+longer than 100 characters, that line may be longer than 100 characters for
+ease of cut and paste.</p>
+<p>Exception: import lines can go over the limit because humans rarely see
+them. This also simplifies tool writing.</p>
+<h2><a name="annotations"></a>Java 1.5 Annotations</h2>
+<p>Annotations should precede other modifiers for the same language element.
+Simple marker annotations (e.g. &#64;Override) can be listed on the same line with
+the language element. If there are multiple annotations, or parameterized
+annotations, they should each be listed one-per-line in alphabetical
+order.</p>
+<p>Android -standard practices for the three predefined annotations in Java
+1.5's are:</p>
+<h3>&#64;Deprecated</h3>
+<p>The &#64;Deprecated annotation must be used whenever the use of the annotated
+element is discouraged. If you use the &#64;Deprecated annotation, you must also
+have a &#64;deprecated Javadoc tag and it should name an alternate implementation.
+In addition, remember that a &#64;Deprecated method is <b>still</b> supposed to
+work.</p>
+<p>If you see old code that has a &#64;deprecated Javadoc tag, please add the &#64;Deprecated annotation.</p>
+<h3>&#64;Override</h3>
+<p>The &#64;Override annotation must be used whenever a method overrides the
+declaration or implementation from a super-class.</p>
+<p>For example, if you use the &#64;inheritdocs Javadoc tag, and derive from a
+class (not an interface), you must also annotate that the method &#64;Overrides
+the parent class's method.</p>
+<h3>&#64;SuppressWarnings</h3>
+<p>The &#64;SuppressWarnings annotation should only be used under circumstances
+where it is impossible to eliminate a warning. If a warning passes this
+"impossible to eliminate" test, the &#64;SuppressWarnings annotation <b>must</b> be
+used, so as to ensure that all warnings reflect actual problems in the
+code.</p>
+<p>When a &#64;SuppressWarnings annotation is necessary, it must be prefixed with
+a TODO comment that explains the "impossible to eliminate" condition. This
+will normally identify an offending class that has an awkward interface. For
+example:</p>
+<pre>// TODO: The third-party class com.third.useful.Utility.rotate() needs generics 
+&#64;SuppressWarnings("generic-cast")
+List&lt;String&gt; blix = Utility.rotate(blax);</pre>
+<p>When a &#64;SuppressWarnings annotation is required, the code should be
+refactored to isolate the software elements where the annotation applies.</p>
+<h2><a name="acronyms"></a>Acronyms in names</h2>
+<p>Treat acronyms and abbreviations as words. The names are much more readable:</p>
+<table><tbody>
+<tr><td>Good</td> <td>Bad</td></tr>
+<tr><td>XmlHttpRequest</td> <td>XMLHTTPRequest</td></tr>
+<tr><td>getCustomerId</td> <td>getCustomerID</td></tr>
+</tbody></table>
+<p>This style rule also applies when an acronym or abbreviation is the entire
+name:</p>
+<table><tbody>
+<tr><td>Good</td> <td>Bad</td></tr>
+<tr><td>class Html</td> <td>class HTML</td></tr>
+<tr><td>String url;</td> <td>String URL;</td></tr>
+<tr><td>long id;</td> <td>long ID;</td></tr>
+</tbody></table>
+<p>Both the JDK and the Android code bases are very inconsistent with regards
+to acronyms, therefore, it is virtually impossible to be consistent with the
+code around you. Bite the bullet, and treat acronyms as words.</p>
 <p>For further justifications of this style rule, see <i>Effective Java</i>
-Item 38 and <i>Java Puzzlers</i>
-Number 68.
-</p>
-<h2><a>TODO style</a>
-</h2>
-<p>Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect.
-</p>
-<p>TODOs should include the string TODO in all caps, followed by a colon:
-</p>
-<pre>// TODO: Remove this code after the UrlTable2 has been checked in.<br><br>// TODO: Change this to use a flag instead of a constant.</pre>
-<p>If your TODO is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2005") or a very specific event ("Remove this code after all production mixers understand protocol V7.").
-</p>
-<h2>
-Consistency
-</h2>
-<p>Our parting thought: BE CONSISTENT. If you're editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around their if clauses, you should too. If their comments have little boxes of stars around them, make your comments have little boxes of stars around them too.
-</p>
-<p>The point of having style guidelines is to have a common vocabulary of coding, so people can concentrate on what you're saying, rather than on how you're saying it. We present global style rules here so people know the vocabulary. But local style is also important. If code you add to a a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Try to avoid this.
-</p>
-<h2><a>Logging</a>
-</h2>
-<p>While logging is necessary it has a significantly negative impact on performance and quickly loses its usefulness if it's not kept reasonably terse. The logging facilities provides five different levels of logging. Below are the different levels and when and how they should be used.
-</p>
+Item 38 and <i>Java Puzzlers</i> Number 68.</p>
 
-<ul><li><b>ERROR:</b>
-This level of logging should be used when something fatal has happened, i.e. something that will have user-visible consequences and won't be recoverable without explicitly deleting some data, uninstalling applications, wiping the data partitions or reflashing the entire phone (or worse). This level is always logged. Issues that justify some logging at the ERROR level are typically good candidates to be reported to a statistics-gathering server.
-</li>
+<h2><a name="todo"></a>TODO style</h2>
+<p>Use TODO comments for code that is temporary, a short-term solution, or
+good-enough but not perfect.</p>
+<p>TODOs should include the string TODO in all caps, followed by a colon:</p>
+<pre>// TODO: Remove this code after the UrlTable2 has been checked in.
+
+// TODO: Change this to use a flag instead of a constant.</pre>
+<p>If your TODO is of the form "At a future date do something" make sure that
+you either include a very specific date ("Fix by November 2005") or a very
+specific event ("Remove this code after all production mixers understand
+protocol V7.").</p>
+
+<h2><a name="consistency"></a>Consistency</h2>
+<p>Our parting thought: BE CONSISTENT. If you're editing code, take a few
+minutes to look at the code around you and determine its style. If they use
+spaces around their if clauses, you should too. If their comments have little
+boxes of stars around them, make your comments have little boxes of stars
+around them too.</p>
+<p>The point of having style guidelines is to have a common vocabulary of
+coding, so people can concentrate on what you're saying, rather than on how
+you're saying it. We present global style rules here so people know the
+vocabulary. But local style is also important. If code you add to a a file
+looks drastically different from the existing code around it, it throws
+readers out of their rhythm when they go to read it. Try to avoid this.</p>
+
+<h2><a name="logging"></a>Logging</h2>
+<p>While logging is necessary it has a significantly negative impact on
+performance and quickly loses its usefulness if it's not kept reasonably
+terse. The logging facilities provides five different levels of logging. Below
+are the different levels and when and how they should be used.</p>
+
+<ul>
+<li><b>ERROR:</b>
+This level of logging should be used when something fatal has happened,
+i.e. something that will have user-visible consequences and won't be
+recoverable without explicitly deleting some data, uninstalling applications,
+wiping the data partitions or reflashing the entire phone (or worse). This
+level is always logged. Issues that justify some logging at the ERROR level
+are typically good candidates to be reported to a statistics-gathering
+server.</li>
 <li><b>WARNING:</b>
-This level of logging should used when something serious and unexpected happened, i.e. something that will have user-visible consequences but is likely to be recoverable without data loss by performing some explicit action, ranging from waiting or restarting an app all the way to re-downloading a new version of an application or rebooting the device. This level is always logged. Issues that justify some logging at the WARNING level might also be considered for reporting to a statistics-gathering server.
-</li>
+This level of logging should used when something serious and unexpected
+happened, i.e. something that will have user-visible consequences but is
+likely to be recoverable without data loss by performing some explicit action,
+ranging from waiting or restarting an app all the way to re-downloading a new
+version of an application or rebooting the device. This level is always
+logged. Issues that justify some logging at the WARNING level might also be
+considered for reporting to a statistics-gathering server.</li>
 <li><b>INFORMATIVE:</b>
-This level of logging should used be to note that something interesting to most people happened, i.e. when a situation is detected that is likely to have widespread impact, though isn't necessarily an error. Such a condition should only be logged by a module that reasonably believes that it is the most authoritative in that domain (to avoid duplicate logging by non-authoritative components). This level is always logged.
-</li>
+This level of logging should used be to note that something interesting to
+most people happened, i.e. when a situation is detected that is likely to have
+widespread impact, though isn't necessarily an error. Such a condition should
+only be logged by a module that reasonably believes that it is the most
+authoritative in that domain (to avoid duplicate logging by non-authoritative
+components). This level is always logged.</li>
 <li><b>DEBUG:</b>
-This level of logging should be used to further note what is happening on the device that could be relevant to investigate and debug unexpected behaviors. You should log only what is needed to gather enough information about what is going on about your component. If your debug logs are dominating the log then you probably should be using verbose logging. This level will be logged, even on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if (LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or subcomponent, so that there can exist a possibility to disable all such logging. There must therefore be no active logic in an if (LOCAL_LOG) block. All the string building for the log also needs to be placed inside the if (LOCAL_LOG) block. The logging call should not be re-factored out into a method call if it is going to cause the string building to take place outside of the if (LOCAL_LOG) block. There is some code that still says if (localLOGV). This is considered acceptable as well, although the name is nonstandard.
-</li>
+This level of logging should be used to further note what is happening on the
+device that could be relevant to investigate and debug unexpected behaviors.
+You should log only what is needed to gather enough information about what is
+going on about your component. If your debug logs are dominating the log then
+you probably should be using verbose logging. This level will be logged, even
+on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if
+(LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or
+subcomponent, so that there can exist a possibility to disable all such
+logging. There must therefore be no active logic in an if (LOCAL_LOG) block.
+All the string building for the log also needs to be placed inside the if
+(LOCAL_LOG) block. The logging call should not be re-factored out into a
+method call if it is going to cause the string building to take place outside
+of the if (LOCAL_LOG) block. There is some code that still says if
+(localLOGV). This is considered acceptable as well, although the name is
+nonstandard.</li>
 <li><b>VERBOSE:</b>
-This level of logging should be used for everything else. This level will only be logged on debug builds and should be surrounded by if (LOCAL_LOGV) block (or equivalent) so that it can be compiled out by default. Any string building will be stripped out of release builds and needs to appear inside the if (LOCAL_LOGV) block.
-</li>
+This level of logging should be used for everything else. This level will only
+be logged on debug builds and should be surrounded by if (LOCAL_LOGV) block
+(or equivalent) so that it can be compiled out by default. Any string building
+will be stripped out of release builds and needs to appear inside the if
+(LOCAL_LOGV) block.</li>
 </ul>
-<p><i>Note:</i>
-Within a given module, other than at the VERBOSE level, an error should only be reported once if possible: within a single chain of function calls within a module, only the innermost function should return the error, and callers in the same module should only add some logging if that significantly helps to isolate the issue.
-</p>
-<p><i>Note:</i>
-In a chain of modules, other than at the VERBOSE level, when a lower-level module detects invalid data coming from a higher-level module, the lower-level module should only log this situation to the DEBUG log, and only if logging provides information that is not otherwise available to the caller. Specifically, there is no need to log situations where an exception is thrown (the exception should contain all the relevant information), or where the only information being logged is contained in an error code. This is especially important in the interaction between the framework and applications, and conditions caused by third-party applications that are properly handled by the framework should not trigger logging higher than the DEBUG level. The only situations that should trigger logging at the INFORMATIVE level or higher is when a module or application detects an error at its own level or coming from a lower level.
-</p>
-<p><i>Note:</i>
-When a condition that would normally justify some logging is likely to occur many times, it can be a good idea to implement some rate-limiting mechanism to prevent overflowing the logs with many duplicate copies of the same (or very similar) information.
-</p>
-<p><i>Note:</i>
-Losses of network connectivity are considered common and fully expected and should not be logged gratuitously. A loss of network connectivity that has consequences within an app should be logged at the DEBUG or VERBOSE level (depending on whether the consequences are serious enough and unexpected enough to be logged in a release build).
-</p>
-<p><i>Note:</i>
-A full filesystem on a filesystem that is acceessible to or on behalf of third-party applications should not be logged at a level higher than INFORMATIVE.
-</p>
-<p><i>Note:</i>
-Invalid data coming from any untrusted source (including any file on shared storage, or data coming through just about any network connections) is considered expected and should not trigger any logging at a level higher then DEBUG when it's detected to be invalid (and even then logging should be as limited as possible).
-</p>
-<p><i>Note:</i>
-Keep in mind that the '+' operator, when used on Strings, implicitly creates a StringBuilder with the default buffer size (16 characters) and potentially quite a few other temporary String objects, i.e. that explicitly creating StringBuilders isn't more expensive than relying on the default '+' operator (and can be a lot more efficient in fact). Also keep in mind that code that calls Log.v() is compiled and executed on release builds, including building the strings, even if the logs aren't being read.
-</p>
-<p><i>Note:</i>
-Any logging that is meant to be read by other people and to be available in release builds should be terse without being cryptic, and should be reasonably understandable. This includes all logging up to the DEBUG level.
-</p>
-<p><i>Note:</i>
-When possible, logging should be kept on a single line if it makes sense. Line lengths up to 80 or 100 characters are perfectly acceptable, while lengths longer than about 130 or 160 characters (including the length of the tag) should be avoided if possible.
-</p>
-<p><i>Note:</i>
-Logging that reports successes should never be used at levels higher than VERBOSE.
-</p>
-<p><i>Note:</i>
-Temporary logging that is used to diagnose an issue that's hard to reproduce should be kept at the DEBUG or VERBOSE level, and should be enclosed by if blocks that allow to disable it entirely at compile-time.
-</p>
-<p><i>Note:</i>
-Be careful about security leaks through the log. Private information should be avoided. Information about protected content must definitely be avoided. This is especially important when writing framework code as it's not easy to know in advance what will and will not be private information or protected content.
-</p>
-<p><i>Note:</i>
-System.out.println() (or printf() for native code) should never be used. System.out and System.err get redirected to /dev/null, so your print statements will have no visible effects. However, all the string building that happens for these calls still gets executed.
-</p>
-<p><i>Note:</i>
-<b>The golden rule of logging is that your logs may not unnecessarily push other logs out of the buffer, just as others may not push out yours.</b>
-</p>
-<h2>
-Javatests Style Rules
-</h2>
+<p><i>Note:</i> Within a given module, other than at the VERBOSE level, an
+error should only be reported once if possible: within a single chain of
+function calls within a module, only the innermost function should return the
+error, and callers in the same module should only add some logging if that
+significantly helps to isolate the issue.</p>
+<p><i>Note:</i> In a chain of modules, other than at the VERBOSE level, when a
+lower-level module detects invalid data coming from a higher-level module, the
+lower-level module should only log this situation to the DEBUG log, and only
+if logging provides information that is not otherwise available to the caller.
+Specifically, there is no need to log situations where an exception is thrown
+(the exception should contain all the relevant information), or where the only
+information being logged is contained in an error code. This is especially
+important in the interaction between the framework and applications, and
+conditions caused by third-party applications that are properly handled by the
+framework should not trigger logging higher than the DEBUG level. The only
+situations that should trigger logging at the INFORMATIVE level or higher is
+when a module or application detects an error at its own level or coming from
+a lower level.</p>
+<p><i>Note:</i> When a condition that would normally justify some logging is
+likely to occur many times, it can be a good idea to implement some
+rate-limiting mechanism to prevent overflowing the logs with many duplicate
+copies of the same (or very similar) information.</p>
+<p><i>Note:</i> Losses of network connectivity are considered common and fully
+expected and should not be logged gratuitously. A loss of network connectivity
+that has consequences within an app should be logged at the DEBUG or VERBOSE
+level (depending on whether the consequences are serious enough and unexpected
+enough to be logged in a release build).</p>
+<p><i>Note:</i> A full filesystem on a filesystem that is acceessible to or on
+behalf of third-party applications should not be logged at a level higher than
+INFORMATIVE.</p>
+<p><i>Note:</i> Invalid data coming from any untrusted source (including any
+file on shared storage, or data coming through just about any network
+connections) is considered expected and should not trigger any logging at a
+level higher then DEBUG when it's detected to be invalid (and even then
+logging should be as limited as possible).</p>
+<p><i>Note:</i> Keep in mind that the '+' operator, when used on Strings,
+implicitly creates a StringBuilder with the default buffer size (16
+characters) and potentially quite a few other temporary String objects, i.e.
+that explicitly creating StringBuilders isn't more expensive than relying on
+the default '+' operator (and can be a lot more efficient in fact). Also keep
+in mind that code that calls Log.v() is compiled and executed on release
+builds, including building the strings, even if the logs aren't being
+read.</p>
+<p><i>Note:</i> Any logging that is meant to be read by other people and to be
+available in release builds should be terse without being cryptic, and should
+be reasonably understandable. This includes all logging up to the DEBUG
+level.</p>
+<p><i>Note:</i> When possible, logging should be kept on a single line if it
+makes sense. Line lengths up to 80 or 100 characters are perfectly acceptable,
+while lengths longer than about 130 or 160 characters (including the length of
+the tag) should be avoided if possible.</p>
+<p><i>Note:</i> Logging that reports successes should never be used at levels
+higher than VERBOSE.</p>
+<p><i>Note:</i> Temporary logging that is used to diagnose an issue that's
+hard to reproduce should be kept at the DEBUG or VERBOSE level, and should be
+enclosed by if blocks that allow to disable it entirely at compile-time.</p>
+<p><i>Note:</i> Be careful about security leaks through the log. Private
+information should be avoided. Information about protected content must
+definitely be avoided. This is especially important when writing framework
+code as it's not easy to know in advance what will and will not be private
+information or protected content.</p>
+<p><i>Note:</i> System.out.println() (or printf() for native code) should
+never be used. System.out and System.err get redirected to /dev/null, so your
+print statements will have no visible effects. However, all the string
+building that happens for these calls still gets executed.</p>
+<p><i>Note:</i> <b>The golden rule of logging is that your logs may not
+unnecessarily push other logs out of the buffer, just as others may not push
+out yours.</b></p>
 
-<h2><a>Naming test methods</a>
-</h2>
-<a>When naming test methods, you can use an underscore to seperate what is being tested from the specific case being tested. This style makes it easier to see exactly what cases are being tested.</a>
-<p><a>Example:</a>
-</p>
-<pre><a>testMethod_specificCase1 <br>testMethod_specificCase2</a>
-</pre>
+<h2>Javatests Style Rules</h2>
+<h2><a name="testmethodnames"></a>Naming test methods</h2>
+<p>When naming test methods, you can use an underscore to seperate what is
+being tested from the specific case being tested. This style makes it easier
+to see exactly what cases are being tested.</p>
+<p><a>For example:</a></p>
+<pre>testMethod_specificCase1 testMethod_specificCase2</pre>
 
-<pre><a>void testIsDistinguishable_protanopia() {<br>ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)<br>assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))<br>assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))<br>}</a>
+<pre>void testIsDistinguishable_protanopia() {
+    ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)
+    assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))
+    assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))
+}
 </pre>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/download.jd b/pdk/docs/source/download.jd
index 6679ebc..4d81460 100644
--- a/pdk/docs/source/download.jd
+++ b/pdk/docs/source/download.jd
@@ -1,6 +1,7 @@
 page.title=Get Android Source Code
 doc.type=source
 @jd:body
+<div>
 <div><br>This document describes how to set up your local work environment, how to use Repo to get the Android files, and how to build the files on your machine.<br><br>Related reading:<br></div>
 <ul><li>For an overview of the entire code-review and code-update process, see
 <a href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>
@@ -23,30 +24,21 @@
 The Android build is routinely tested on recent versions of Ubuntu (6.06 and later), but reports of successes or failures on other distributions are welcome.<br><h4>
 Ubuntu Linux (32-bit x86)</h4>
 <div>To set up your Linux development environment, make sure you have the following:</div>
-<div><div><div><ul><li>Required Packages:</li>
+<div><ul><li>Required Packages:</li>
 <ul><li>Git 1.5.4 or newer <span>and the GNU Privacy Guard.<br></span>
 </li>
 </ul>
 </ul>
 </div>
-</div>
-</div>
-</div>
-<div><div><div><div><ul><ul><li>JDK 5.0, update 12 or higher.Java 6 is not supported, because of incompatibilities with @Override.<br></li>
+<div><ul><ul><li>JDK 5.0, update 12 or higher.Java 6 is not supported, because of incompatibilities with @Override.<br></li>
 </ul>
 </ul>
 </div>
-</div>
-</div>
-</div>
-<div><div><div><div><ul><ul><li><span>flex, bison, gperf, libsdl-dev, libesd0-dev, libwxgtk2.6-dev (optional), build-essential, zip, curl.</span>
+<div><ul><ul><li><span>flex, bison, gperf, libsdl-dev, libesd0-dev, libwxgtk2.6-dev (optional), build-essential, zip, curl.</span>
 </li>
 </ul>
 </ul>
 </div>
-</div>
-</div>
-</div>
 <blockquote><span>$ sudo apt-get install</span>
 <span>git-core gnupg</span>
 <span>sun-java5-jdk</span>
@@ -54,14 +46,11 @@
 libwxgtk2.6-dev build-essential zip <span>curl libncurses5-dev zlib1g-dev <br></span>
 </span>
 </blockquote>
-<div><div><div><div><ul><li><span><span>You might also want Valgrind, a tool that will help you find memory leaks, stack corruption, array bounds overflows, etc.</span>
+<div><ul><li><span><span>You might also want Valgrind, a tool that will help you find memory leaks, stack corruption, array bounds overflows, etc.</span>
 </span>
 </li>
 </ul>
 </div>
-</div>
-</div>
-</div>
 <blockquote><div><span>$ sudo apt-get install valgrind <br></span>
 </div>
 </blockquote>
@@ -70,8 +59,7 @@
 8.10) users may need a newer version of libreadline:</li>
 </ul>
 <div>$ sudo apt-get install lib32readline5-dev <br></div>
-</div>
-<div><div><div><div><div><div><h4>
+<div><h4>
 Ubuntu Linux (64-bit x86)</h4>
 This has not been as well tested. Please send success or failure reports to <a href="mailto:android-porting@googlegroups.com">android-porting@googlegroups.com</a>
 .</div>
@@ -86,19 +74,16 @@
 </ul>
 </ul>
 </div>
-</div>
-</div>
-</div>
 <blockquote><span><span>$</span>
 sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl</span>
 sun-java5-jdk <span><span>zlib1g-dev</span>
 </span>
 gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev</blockquote>
-<ul><li>Set the system to use the right version of java by default:<br><br>$sudo update-java-alternatives -sjava-1.5.0-sun <br></li>
+<ul><li>Set the system to use the right version of java by default:<br><br>$ sudo update-java-alternatives -s java-1.5.0-sun <br></li>
 </ul>
 <ul><li>X11: Ubuntu doesn't have packages for the X11 libraries, but that can be worked around with the following command:<br><br>$ sudo ln -s /usr/lib32/libX11.so.6 /usr/lib32/libX11.so <br><br></li>
 </ul>
-<div><div><div><div><div><h4>
+<div><h4>
 Running Linux in a virtual machine</h4>
 If you are running Linux in a virtual machine, you will need at least 1.5GB of RAM and 10GB or more of disk space in order to build the Android tree.<br><h4>
 Other Linux</h4>
@@ -135,42 +120,34 @@
 <li>volume format: case sensitive, journaled</li>
 </ul>
 </li>
-<li>This will create a .dmg file which, once mounted, acts as a drive with the required formatting for Android development. For a disk image named "android.dmg" stored in your home directory, you can add the following to your ~/.bash_profile to mount the image when you execute "mountAndroid":<br><br><div># command to mount the android file image <br>function mountAndroid{ hdiutil attach ~/android.dmg-mountpoint /Volumes/android; }<br></div>
+<li>This will create a .dmg file which, once mounted, acts as a drive with the required formatting for Android development. For a disk image named "android.dmg" stored in your home directory, you can add the following to your ~/.bash_profile to mount the image when you execute "mountAndroid":<br><br><div># command to mount the android file image <br>function mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }<br></div>
 <br>Once mounted, you'll do all your work in the "android" volume. You can eject it (unmount it) just like you would with an external drive.</li>
 </ul>
 </ul>
 </ul>
 <ul></ul>
-To set up your Mac OS development environment, follow these steps:<br><ol><li>Install the XCode version 2.4 or later from <a href="http://developer.apple.com/">http://developer.apple.com</a>. We recommend version 3.0 or newer.<br></li>
+To set up your Mac OS development environment, follow these steps:<br>
+<ol><li>Install the XCode version 2.4 or later from <a href="http://developer.apple.com/">http://developer.apple.com</a>. We recommend version 3.0 or newer.<br></li>
 <li>Install MacPorts. To do this:</li>
-<ol><li>Download the tar file from <a href="http://www.macports.org/">http://www.macports.org/</a> and untar the files.</li>
-<li>Run the following:<span><br>$ ./configure <br></span>
-<span>$</span>
-<span>make <br></span>
-<span>$</span>
-<span>sudo make install</span>
-</li>
-<li>Make sure that /opt/local/bin is in your path before /usr/bin. by running <br>$ echo $PATH <br>If you don't see /opt/local/bin, edit $HOME/.bash_profile and add the line <br>export PATH=/opt/local/bin:$PATH <br>(or the equivalent for other shells) after any other PATH-related lines.<span>To verify that your path is now correct, o</span>
-pen a new terminal and <span>run</span>
-echo $PATH <span>again</span>
-.</li>
-<li>Ask MacPorts to update itself:<br><span></span>
-<span>$</span>
-<span>sudo port selfupdate</span>
-<br></li>
+<ol>
+    <li>Download and run the installer from <a href="http://www.macports.org/install.php">http://www.macports.org/install.php</a></li>
+    <li>Make sure that <code>/opt/local/bin</code> is in your path before <code>/usr/bin</code> by running
+        <div><code>$ echo $PATH</code></div>
+        <div> If you don't see /opt/local/bin, edit <code>$HOME/.bash_profile</code> and add the line <code>export PATH=/opt/local/bin:$PATH</code>
+        after any other PATH-related lines. To verify that your path is now correct, open a new terminal and run <code>echo $PATH</code> again.</div>
+    </li>
 </ol>
-<li>Get the following packages from port:<br>$<span>POSIXLY_CORRECT=1</span>
-sudo port install gmake libsdl git-core gnupg <br><span>If using Mac OS 10.4, also install:<br>$<span>POSIXLY_CORRECT=1</span>
+<li>Get the following packages from port:<br>$ <span>POSIXLY_CORRECT=1</span>
+sudo port install gmake libsdl git-core gnupg <br><span>If using Mac OS 10.4, also install:<br>$ <span>POSIXLY_CORRECT=1</span>
 sudo port install bison <br></span>
 </li>
-<li>Upgrade GNU make to 3.81 or later by running.Mac OS doesn't come with a recent enough version.<br>$ sudo ln -s gmake /opt/local/bin/make <br></li>
+<li>Upgrade GNU make to 3.81 or later by running the following command. (Mac OS doesn't come with a recent enough version.)<br>$ sudo ln -s gmake /opt/local/bin/make <br></li>
 <li>Set an appropriate per-process file descriptor limit. To do this, add the following lines to your <i><span>.bash_profile</span>
 </i>
-file:<br># set the number of open files to be 1024<br>ulimit -S -n 1024</li>
+file:<br># set the number of open files to be 1024<br>$ <span>ulimit -S -n 1024</span><br>
+Note that this may not be necessary; on some systems, the output of "ulimit -S" will show "unlimited". In this case, there is no need to set the limit to 1024.</li>
 </ol>
 </div>
-</div>
-</div>
 <div><br></div>
 <h2>
 Installing Repo <br></h2>
@@ -180,14 +157,13 @@
 .<br></p>
 To install, initialize, and configure Repo, follow these steps:<br><br></div>
 <ol><li><span>Make sure you have a~/bindirectory in your home directory, and check to be sure that this bin directory is in your path:</span>
-<br>$ cd~<br><span><span>$ mkdir bin <br>$ echo $PATH <br></span>
+<br>$ cd ~<br><span><span>$ mkdir bin <br>$ echo $PATH <br></span>
 </span>
 </li>
 <li><span>Download thereposcript and make sure it is executable:</span>
-<br>$ curl http://android.git.kernel.org/repo~/bin/repo <div>$ chmod a+x ~/bin/repo</div>
+<br>$ curl http://android.git.kernel.org/repo &gt;~/bin/repo <div>$ chmod a+x ~/bin/repo</div>
 </li>
 </ol>
-</div>
 <div><p><br></p>
 <h2>
 Initializing a Repo client <br></h2>
@@ -197,7 +173,7 @@
 <span>$ mkdir mydroid</span>
 <br><span>$ cd mydroid</span>
 <br></li>
-<li><span>Runrepo initto bring down the latest version of Repo with all its most recent bug fixes. You must specify a URL for the manifest:</span>
+<li><span>Run "repo init" to bring down the latest version of Repo with all its most recent bug fixes. You must specify a URL for the manifest:</span>
 <br><span>$ repo init</span>
 -u git://android.git.kernel.org/platform/manifest.git</li>
 <ul><li><span>If you would like to check out a branch other than "master", specify it with -b, like:</span>
@@ -238,15 +214,13 @@
 Getting the files</h2>
 <div><span><span>To pull down files to your working directory from the repositories as specified in the default manifest, run</span>
 <br><br>$ repo sync <i><br></i>
-<br><span>For more aboutrepo syncand other Repo commands, see</span>
+<br><span>For more about "repo sync" and other Repo commands, see</span>
 <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>
 <span>.</span>
 <br><br><span>The Android source files will be located in your working
 directory under their project names.</span>
 </span>
 <br></div>
-<span><h2>
-<br></h2>
 <h2>
 Verifying Git Tags</h2>
 <span>Load the following public key into your GnuPG key database.The key is used to sign annotated tags that represent releases.</span>
@@ -300,6 +274,3 @@
 code-review server, see <a href="{@docRoot}source/submit-patches.html">Contribute</a>
 .</span>
 </div>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/git-repo.jd b/pdk/docs/source/git-repo.jd
index 8905780..3abb0e3 100644
--- a/pdk/docs/source/git-repo.jd
+++ b/pdk/docs/source/git-repo.jd
@@ -1,6 +1,7 @@
 page.title=Using Repo and Git
 doc.type=source
 @jd:body
+<div>
 <p>To work with the Android code, you will need to use both Git and Repo.<br></p>
 <ul><li><i>Git</i>
 is an open-source version-control system designed to handle very large projects that are distributed over multiple repositories. In the context of Android, we use Git for local operations such as local branching, commits, diffs, and edits.<br><br></li>
@@ -22,8 +23,8 @@
 In most situations, you can use Git instead of Repo, or mix Repo and Git
 commands to form complex commands. Using Repo for basic across-network
 operations will make your work much simpler, however.
-<br></div>
-<div><div><h2>
+<br>
+<div><h2>
 Task reference <br></h2>
 The task list below shows a summary of how to do common Repo and Git tasks.
 For complete quick-start information and examples, see <a
@@ -316,4 +317,3 @@
 At intervals, you use git commit to save a snapshot of the staged files and a log message that describes the change.<br><br><i>Manifest</i>
 <br>A manifest file that contains a list of repositories and a mapping of where the files from these repositories will be located within your working directory. When you synchronize your files, the files contained in the repositories that are listed in the manifest will be pulled into your working directory.</div>
 </div>
-</div>
diff --git a/pdk/docs/source/index.jd b/pdk/docs/source/index.jd
index 230a0b3..a9acbf4 100644
--- a/pdk/docs/source/index.jd
+++ b/pdk/docs/source/index.jd
@@ -3,7 +3,7 @@
 @jd:body
 <div>
 <p>Thanks for your interest in Android! Here are some ways you can get involved
-and help Google improve Android. For background on the Android project and our
+and help us improve Android. For background on the Android project and our
 goals, check out the <a href="{@docRoot}about/philosophy.html">Project
 Philosophy page</a>.</p>
 
@@ -11,7 +11,7 @@
 <p>One of the easiest and most effective ways you can help improve Android is
 to file bugs. For more information, visit the <a
 href="{@docRoot}source/report-bugs.html">Reporting Bugs</a> page.</p>
-<p>Please note that we can't guarantee that any particular bug can be fixed in
+<p>Please note that we can't guarantee that any particular bug will be fixed in
 any particular release. To see what happens to your bug once you report it,
 read <a href="{@docRoot}source/life-of-a-bug.html">Life of a Bug</a>.</p>
 
@@ -26,8 +26,10 @@
 
 <h2>Contribute to the Code</h2>
 <p>Code is King. We'd love to review any changes you submit, so please check
-out the source, pick a bug or feature, and get coding.</p>
-<p>You can get started with  by learning about the <a
+out the source, pick a bug or feature, and get coding. Note that the smaller
+and more targetted your patch submissions, the easier it will be for us to
+review them.</p>
+<p>You can get started with Android by learning about the <a
 href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>, and by
 learning about <code>git</code>, <code>repo</code>, and other tools using the
 links to the left. If you need help along the way, you can join our <a
diff --git a/pdk/docs/source/licenses.jd b/pdk/docs/source/licenses.jd
index 846a92a..17cebeb 100644
--- a/pdk/docs/source/licenses.jd
+++ b/pdk/docs/source/licenses.jd
@@ -4,18 +4,15 @@
 <div>
 <p>The Android Open Source Project uses a few <a
 href="http://www.opensource.org/">open source initiative</a> approved open
-source licenses to enable availability of source code and to accept
-contributions from individuals and corporations.</p>
+source licenses for our software.</p>
 <h2>Android Open Source Project license</h2>
-<p>The preferred license for the Android Open Source Project is <a
-href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. Apache 2.0
-is a commercial and open source friendly open source license. The majority of
-the Android platform is licensed under the <a
-href="http://www.apache.org/licenses/">Apache 2.0 license</a>. While the
-project will strive to adhere to the preferred license, there may be
-exceptions which will be handled on a case-by-case basis. For example, the
-Linux kernel patches are under the GPLv2 license with system exceptions, which
-can be found on <a
+<p>The preferred license for the Android Open Source Project is the <a
+href="http://www.apache.org/licenses/LICENSE-2.0">Apache Software License,
+2.0</a> ("Apache 2.0"), and the majority of the Android software is licensed
+with Apache 2.0. While the project will strive to adhere to the preferred
+license, there may be exceptions which will be handled on a case-by-case
+basis. For example, the Linux kernel patches are under the GPLv2 license with
+system exceptions, which can be found on <a
 href="http://www.kernel.org/pub/linux/kernel/COPYING">kernel.org</a>.
 </p>
 <h2>Contributor License Grants</h2>
@@ -25,15 +22,15 @@
 href="{@docRoot}source/cla-individual.html">Individual
 Contributor License Grant</a>. The grant can be executed online through the <a
 href="https://review.source.android.com/#settings,agreements">code review
-tool</a>. The agreement clearly defines the terms under which intellectual
-property has been contributed to the Android Open Source Project.This license
+tool</a>. The grant clearly defines the terms under which intellectual
+property has been contributed to the Android Open Source Project. This license
 is for your protection as a contributor as well as the protection of the
 project; it does not change your rights to use your own contributions for any
 other purpose.</p>
 <p>For a <b>corporation</b> (or other entity) that has assigned employees to
 work on the Android Open Source Project, a <a
 href="{@docRoot}source/cla-corporate.html">Corporate
-Contributor License Grant</a> is available. This version of the Grant allows a
+Contributor License Grant</a> is available. This version of the grant allows a
 corporation to authorize contributions submitted by its designated employees
 and to grant copyright and patent licenses. Note that a Corporate Contributor
 License Grant does not remove the need for any developer to sign their own
diff --git a/pdk/docs/source/life-of-a-bug.jd b/pdk/docs/source/life-of-a-bug.jd
index 1d58ae1..5d77f7a 100644
--- a/pdk/docs/source/life-of-a-bug.jd
+++ b/pdk/docs/source/life-of-a-bug.jd
@@ -57,7 +57,7 @@
 which is considered the "master" copy. (For instance, Google maintains one
 such private issue tracker, intended primarily for bugs which contain
 sensitive information which can't be revealed publicly.)</p></li>
-<li><b>Assigned</b><li>Like <code>Unassigned</code>, but the bug has been
+<li><b>Assigned</b><p>Like <code>Unassigned</code>, but the bug has been
 actually assigned to a specific contributor to fix.</p></li>
 </ul>
 <p>Typically, a given bug will start in <code>Unassigned</code>, where it
@@ -77,8 +77,8 @@
 <li><b>Spam</b><p>A kind soul sent us some delicious pork products, that we,
 regrettably, do not want.</p></li>
 <li><b>Question</b><p>Someone mistook the issue tracker for a help forum.
-(This is not as uncommon as one might assume: many users whose native language
-isn't English can make this mistake.)</p></li>
+(This is not as uncommon as you might think: many users whose native language
+isn't English misunderstand the site and make this mistake.)</p></li>
 <li><b>Unreproducible</b><p>An AOSP contributor attempted to reproduce the
 behavior described, and was unable to do so. This sometimes means that the bug
 is legitimate but simply rare or difficult to reproduce, and sometimes means
diff --git a/pdk/docs/source/overview-1.0.jd b/pdk/docs/source/overview-1.0.jd
deleted file mode 100644
index e1b5cd6..0000000
--- a/pdk/docs/source/overview-1.0.jd
+++ /dev/null
@@ -1,157 +0,0 @@
-page.title=Android 1.0 Features
-doc.type=source
-@jd:body
-<div><div><div><div>This page provides a high-level overview of Android 1.0
-features. To see the code itself, you can either use the <a href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can <a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine.<br><br><b>Applications</b>
-<br><br>The Android platform comes with a variety of applications written using the Java programming language:<br><ul><li><i>Home</i>
-displays applications, widgets, and shortcuts. It also supports customizable wall paper.
-</li>
-<li><i>Phone</i>
-supports regular telephony functions as well as call controls, conference calls, supplementary services, and easy integration with <i>Contacts</i>
-.<br></li>
-<li><i>Web Browser</i>
-is a fully featured WebKit-based browser that supports HTML and XHTML.
-</li>
-<li><i>Email</i>
-provides access to email servers commonly found on the Internet and supports POP3, IMAP4, and SMTP.
-</li>
-<li><i>Media Player</i>
-enables managing, importing, and playing back content that has been encoded in various forms.<br></li>
-<li><i>Alarm Clock, Calculator, Calendar, Camera, Contacts, IM, MMS, Settings,</i>
-<i>Voice Dialer</i>
-, and many other applications are also included in this release.<br></li>
-</ul>
-<b>Application framework</b>
-<br><br></div>
-<div>The Android Application Framework has been designed to provide a rich set of APIs for third-party application developers. For more information, visit the <a href="http://developer.android.com/guide/index.html">Android SDK developer guide</a>
-.<b><br></b>
-</div>
-<div></div>
-<div><b>Android runtime</b>
-<b><br><br></b>
-Android applications run on Dalvik, a custom virtual machine (VM) designed for embedded use. The Dalvik VM runs dex executable files, which are typically compiled from source code written in Java.<br><br></div>
-<div>The dex executable format is designed to have these characteristics:<br><ul><li>Efficient on-device storage.
-</li>
-<li>Efficient runtime memory usage.
-</li>
-<li>Ease of interpretation.<br></li>
-</ul>
-Dalvik has the following runtime characteristics:
-<ul><li>Efficient support for multiple concurrent VM processes, including amortized initialization and heavily shared memory.
-</li>
-<li>Optimized interpreter.
-</li>
-<li>Efficient linkage to low-level native code.
-</li>
-<li>A familiar and rich set of core library functionality. For a complete list of supported libraries, see <a href="http://developer.android.com/reference/packages.html">http://developer.android.com/reference/packages.html</a>
-.
-</li>
-<li>Enhanced JDWP support, enabling easier debugging of multiple processes simultaneously.
-</li>
-<li>JNI support.
-</li>
-</ul>
-<b>Native libraries <br></b>
-<br>The Android platform makes use of many native libraries, including:<br><ul><li><i>Bionic</i>
-, a custom libc implementation optimized for embedded systems.
-</li>
-<li>Graphics libraries for 2D and 3D (OpenGL ES 1.0) graphics support.<br></li>
-<li>openCore to provide the bulk of Android's multimedia capability. It includes support for network streaming (HTTP and RTSP), as well as most of the codecs and media file parsers used by the system.<br></li>
-<li>sqlite to support having a lightweight transactional data store.
-</li>
-<li>WebKit library to power Android's WebKit based full web browser.<br></li>
-</ul>
-<br><b>System software</b>
-<b><br></b>
-<br></div>
-<div>About Android's operating system:
-<ul><li>Based on Linux 2.6.25 for ARM.<br></li>
-<li>Platform currently expects ARM V5T or better architecture. Support for earlier architectures could be added, but CPUs without an MMU would be difficult to support.
-</li>
-<li>A set of kernel enhancements are provided to support Android. The patches include alarm, ashmem, binder, power management, low memory killer, kernel degugger, and logger <b>.<br></b>
-</li>
-<li>While the platform is designed to be chipset agnostic, and will run on virtually any ARM-based Linux kernel environment, version 1.0 of the platform has been tested and verified on the MSM 7K chipsets <b>.</b>
-Over time we expect to see support for other major chipsets.
-Kernel patches for MSM based chipsets are also available.
-</li>
-<li>FAT32 file system is supported.
-</li>
-<li>Support for TCP/IP (TCP, UDP, etc).
-</li>
-</ul>
-</div>
-<div>A minimal reference bootloader for the supported chipset is provided. It is capable of booting Linux from RAM, debugger, and NAND Flash.<br></div>
-<div><br>About Android's support for debugging:<br><ul><li>Debugging native code is supported via GDB (GNU Project Debugger) over USB.
-</li>
-<li>Debugging managed code is supported via any JDWP-compatible debugger over USB.
-</li>
-<li>Logging and crash logs supported for debugging.
-</li>
-</ul>
-<b>Supported hardware <br></b>
-<ul><li>The platform will run on almost on any ARM based Linux kernel environment.
-</li>
-<li>The platform requires a minimum of 128 MB of RAM and 256 MB ofFlash memory. AnOEM may want to support more Flash memory to make it possible to download more third-party applications to user devices.<br></li>
-<li>The platform will interface with a baseband radio stack provided externally via a Radio Interface Layer (RIL).
-</li>
-<li>802.11 b/g Wi-Fi
-</li>
-<li>Standard USB interface, including USB 2.0
-</li>
-<li>Bluetooth 2.0 EDR (Enhanced Data Rate)
-</li>
-<li>Camera for still and video capture
-</li>
-<li>Removable storage
-</li>
-</ul>
-<b>Supported display</b>
-<br><ul><li>HVGA resolution <br></li>
-<li>16 bit color depth <br></li>
-<li>Landscape and portrait orientation, including dynamic runtime switching
-</li>
-<li>Finger-based touchscreen navigation
-</li>
-</ul>
-<b>Supported keypads and buttons</b>
-<br><ul><li>QWERTY
-</li>
-<li>5-way navigation
-</li>
-<li>Hardware buttons: Send, End, Home, Back, Menu</li>
-<li>Power button
-</li>
-<li>Volume keys (up and down)
-</li>
-<li>Camera trigger button, including detection for both partial press (to focus) and full press (to actually take a picture)
-</li>
-</ul>
-<b>Supported audio outputs</b>
-<br><ul><li>Audio output via the headphone jack (mono and stereo)
-</li>
-<li>64 kbps Bluetooth audio supported</li>
-</ul>
-<b>Supported notifications</b>
-<br><ul><li>LEDs
-</li>
-<li>Vibration
-</li>
-</ul>
-<b>Supported radio and telephony features <br></b>
-<ul><li>GPRS, EDGE, UMTS, HSDPA
-</li>
-<li>International roaming, SMS, MMS <br></li>
-<li>Emergency call support <br></li>
-<li>Supplementary Services for Telephony, for example call waiting and conference calling <br></li>
-<li>Unstructured Supplementary Service Data (USSD)
-</li>
-<li>Reference Radio Interface Layer (RIL)
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/overview-1.5.jd b/pdk/docs/source/overview-1.5.jd
deleted file mode 100644
index dd74874..0000000
--- a/pdk/docs/source/overview-1.5.jd
+++ /dev/null
@@ -1,198 +0,0 @@
-page.title=Android 1.5 Features
-doc.type=source
-@jd:body
-<h3><b>Release features - Android 1.5</b>
-</h3>
-<div><div><div><div><b>Previous release highlights</b>
-:<a href="{@docRoot}source/overview-1.0.html">Android 1.0</a>
-<br><br>This page provides a high-level overview of the new features added to
-Android 1.5. To see the code itself, you can either use the<a href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can<a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine. You can use<i>repo init -u</i>
-git://android.git.kernel.org/platform/manifest.git<i>-b android-1.5</i>
-to download the source code for Android 1.5.<br><br><b>User interface refinements:</b>
-<br><ul><li>System-wide:
-<ul><li>Refinement of all core UI elements
-</li>
-<li>Animated window transitions (off by default)
-</li>
-<li>Accelerometer-based application rotations
-</li>
-</ul>
-</li>
-<li>UI polish for:
-<ul><li>In-call experience
-</li>
-<li>Contacts, Call log, and Favorites
-</li>
-<li>SMS MMS
-</li>
-<li>Browser
-</li>
-<li>Calendar
-</li>
-<li>Email
-</li>
-<li>Camera Gallery
-</li>
-<li>Application management
-</li>
-</ul>
-</li>
-</ul>
-<div><b><br>Performance improvements:</b>
-<br></div>
-<ul><li>Faster Camera start-up and image capture
-</li>
-<li>Much faster acquisition of GPS location (powered by SUPL AGPS)
-</li>
-<li>Smoother page scrolling in Browser
-</li>
-</ul>
-<br><b>Applications</b>
-<br><ul><li>Camera Gallery
-</li>
-<ul><li>Video recording
-</li>
-<li>Video playback (MPEG-4 3GP formats)
-</li>
-</ul>
-<li>Browser
-</li>
-<ul><li>Updated with latest Webkit browser Squirrelfish Javascript engines
-</li>
-<li>Copy 'n paste in browser
-</li>
-<li>Search within a page
-</li>
-<li>User-selectable text-encoding
-</li>
-<li>UI changes include:
-</li>
-<ul><li>Unified Go and Search box
-</li>
-<li>Tabbed bookmarks/history/most-visited screen
-</li>
-</ul>
-</ul>
-<li>Contacts
-</li>
-<ul><li>Shows user picture for Favorites
-</li>
-<li>Specific date/time stamp for events in call log
-</li>
-<li>One-touch access to a contact card from call log event
-</li>
-</ul>
-</ul>
-<b><br>Application framework</b>
-<br><br></div>
-<div><ul><li>On-screen soft keyboard
-</li>
-<ul><li>Works in both portrait and landscape orientation
-</li>
-<li>Support for user installation of 3rd party keyboards
-</li>
-<li>User dictionary for custom words
-</li>
-</ul>
-<li>Home screen
-</li>
-<ul><li>Widgets
-</li>
-<ul><li>Bundled home screen widgets include: analog clock, calendar, music player, picture frame, and search
-</li>
-</ul>
-<li>Live folders
-</li>
-</ul>
-<li>UI framework
-</li>
-<ul><li>Framework for easier background/UI thread interaction
-</li>
-<li>New SlidingDrawer widget
-</li>
-<li>Horizontal ScrollView widget
-</li>
-</ul>
-<li>Home Screen framework
-</li>
-<ul><li>APIs for creating secure home screen widgets
-</li>
-<li>APIs for populating live folders with custom content
-</li>
-</ul>
-<li>Media framework
-</li>
-<ul><li>Raw audio recording and playback APIs
-</li>
-<li>Interactive MIDI playback engine
-</li>
-<li>Video recording APIs for developers (3GP format)
-</li>
-<li>Video and photo sharing Intents
-</li>
-<li>Media search Intent
-</li>
-</ul>
-<li>Input Method framework
-</li>
-<ul><li>Text prediction engine
-</li>
-<li>Ability to provide downloadable IMEs to users
-</li>
-</ul>
-<li>Speech recognition framework
-</li>
-<ul><li>Support for using speech recognition libraries via Intent
-</li>
-</ul>
-<li>Misc API additions
-</li>
-<ul><li>LocationManager - Applications can get location change updates via Intent
-</li>
-<li>WebView - Touch start/end/move/cancel DOM event support
-</li>
-<li>SensorManager - redesigned sensor APIs
-</li>
-<li>GLSurfaceView - convenience framework for creating OpenGL applications
-</li>
-<li>Broadcast Intent for app update install succeeded - for smoother app upgrade experience
-</li>
-</ul>
-</ul>
-</div>
-<div></div>
-<div><br><b>System software</b>
-<br><br></div>
-<ul><li>New Linux kernel (version 2.6.27)
-</li>
-<li>SD card filesystem auto-checking and repair
-</li>
-<li>SIM Application Toolkit 1.0
-</li>
-</ul>
-<div><b><br>Supported hardware<br></b>
-<ul><li>Bluetooth</li>
-<ul><li>Stereo Bluetooth support (A2DP and AVCRP profiles)
-</li>
-<li>Auto-pairing
-</li>
-<li>Improved handsfree experience
-</li>
-</ul>
-</ul>
-<br><b>Developer tools</b>
-<br></div>
-<div><ul><li>Support for multiple versions of Android in a single SDK installation
-</li>
-<li>Improved JUnit support in ADT
-</li>
-<li>Easier application performance profiling
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/overview.jd b/pdk/docs/source/overview.jd
index 2763c52..5a31018 100644
--- a/pdk/docs/source/overview.jd
+++ b/pdk/docs/source/overview.jd
@@ -1,93 +1,36 @@
-page.title=Android 1.6 Platform Overview
+page.title=Android 2.1 Platform
 doc.type=source
 @jd:body
-<p>This page provides a high-level overview of the new features added to
-Android 1.6. To see the code itself, you can either use the <a
-href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can <a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine. You can use <code>repo init -u
-git://android.git.kernel.org/platform/manifest.git -b android-1.6</code>
-to download the source code for Android 1.6.</p>
-<p><i>Note: platform overview information for Android 2.x has not yet been
-published, since the <a
-href="{@docRoot}compatibility/index.html">Compatibility Program</a> for
-Android 2.x has not yet launched. When the Compatibilty Definition Document
-for 2.x is released, this page will be updated to match.</i></p>
-<p>Information about older Android releases is also available:<ul>
-<li><a href="{@docRoot}source/overview-1.5.html">Android 1.5 Platform Overview</a></li>
-<li><a href="{@docRoot}source/overview-1.0.html">Android 1.0 Platform Overview</a></li>
-</ul></p>
-<h2>User interface refinements</h2>
-<h3>Quick Search Box for Android </h3>
-<p>Android 1.6 includes a redesigned search framework that provides a quick, effective, and consistent way for users to search across multiple sources—such as browser bookmarks history, contacts, and the web—directly from the home screen.
-</p>
-<p><br></p>
-<p>The system constantly learns which search results are more relevant based on what is clicked. So popular contacts or apps that have previously been picked will bubble up to the top when a user types the first few letters of a relevant query.
-</p>
-<p><br></p>
-<p>The search framework also provides developers a way to easily expose relevant content from their applications in Quick Search Box.
-</p>
-<h3>Camera, Camcorder, and Gallery </h3>
-<p>An updated user interface provides an integrated camera, camcorder, and gallery experience. Users can quickly toggle between still and video capture modes. Additionally, the gallery enables users to select multiple photos for deletion.<br></p>
-<p><br></p>
-<p>Android 1.6 also provides a much faster camera experience. Compared to the previous release, launching the camera is now 39% faster, and there is a 28% improvement in the time from completing one shot to the next.
-</p>
-<h3>VPN, 802.1x </h3>
-<p>A new Virtual Private Network (VPN) control panel in Settings allows users to configure and connect to the following types of VPNs:
-</p>
-<ul><li>L2TP/IPSEC pre-shared key based VPN
-  </li>
-<li>L2TP/IPsec certificate based VPN
-  </li>
-<li>L2TP only VPN
-  </li>
-<li>PPTP only VPN
-  </li>
-</ul>
-<h3>Battery usage indicator </h3>
-<p>A new battery usage screen lets users see which apps and services are consuming battery power. If the user determines that a particular service or application is using too much power, they can take action to save the battery by adjusting settings, stopping the application, or uninstalling the application.
-</p>
-<h3>Accessibility </h3>
-<p>Users will be able to download new accessibility services built on the new accessibility framework and enable them in Settings.
-</p>
-<h2>New Platform Technologies </h2>
-<h3>Expanded Search Framework </h3>
-<p>The Android search framework has been redesigned and expanded to provide third-party applications the opportunity to surface content from their applications in Quick Search Box, the global search tool. To do this, developers will need to make their app "searchable" and provide suggestions in response to user queries. To enable application search suggestions, users simply select each application from which they'd like to receive suggestions, under Searchable items in the Search settings.
-</p>
-<h3>Text-to-speech engine</h3>
-<p>Android 1.6 features a multi-lingual speech synthesis engine called Pico. It allows any Android application to "speak" a string of text with an accent that matches the language. The engine supports the following languages: English (American and British accents), French, Italian, German and Spanish. If you're using a T-Mobile G1 or Dream device, you'll need to download the SpeechSynthesis Data Installer from Android Market, which includes the "voices" needed by the text-to-speech engine.
-</p>
-<h3>Gestures </h3>
-<p>A new gestures framework provides application developers with a framework for creating, storing, loading, and recognizing gestures and associating them with specific actions.
-</p>
-<p>Developers can use the new GestureBuilder tool included in the Android 1.6 SDK to generate libraries of gestures to include with their application.
-</p>
-<h3>Accessibility </h3>
-<p>Android 1.6 provides a new accessibility framework. With this framework, developers can create accessibility plugins that respond to user input, such as making a sound when a new window is shown, vibrating when navigating to the top of a list, and providing spoken feedback.
-</p>
-<h3>Expanded support for screen densities and resolutions </h3>
-<p>Android 1.6 adds screen support that enables applications to be rendered properly on different display resolutions and densities. Developers can also specify the types of screens supported by their application.
-</p>
-<h3>Telephony support for CDMA </h3>
-<p>Android 1.6 includes support for CDMA in the telephony stack.
-</p>
-<h3>New version of OpenCore </h3>
-<p>Android 1.6 includes the updated OpenCore 2 media engine, which has:
-</p>
-<ul><li>Support for OpenMAX encoders
-  </li>
-<li>Support for additional audio codecs in AuthorEngine
-  </li>
-<li>Improved buffering model supports shared buffers allocated in the decoder
-  </li>
-</ul>
-<h3>2.6.29 Linux kernel </h3>
-<p>Android 1.6 upgrades the Linux kernel from 2.6.27 to 2.6.29.
-</p>
-<h2>New Framework APIs</h2>
-<p>For a detailed overview of new APIs, see the <a
-href="http://developer.android.com/sdk/android-1.6.html#api-changes">Version
-Notes</a>. For a complete report of all API changes, see the <a
-href="http://developer.android.com/sdk/api_diff/4/changes.html">API
-Differences Report</a>.</p>
+<p>Our sister site, <a
+href="http://developer.android.com/">http://developer.android.com/</a>, 
+includes feature overviews of the various Android platform versions.
+The links below will take you to developer.android.com where you can view this
+information.</p>
+<p>The links below will navigate you away from this site.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.3-highlights.html">Android 2.3</a></h3>
+<p>Android 2.3 corresponded to the "Gingerbread" milestone branch, and has an API level of 9.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.2-highlights.html">Android 2.2</a></h3>
+<p>Android 2.2 corresponded to the "FroYo" milestone branch, and has an API level of 8.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.0-highlights.html">Android 2.1</a></h3>
+<p>Android 2.1 corresponded to the "Eclair" milestone branch, and has an API level of
+7.</p>
+<p>The Eclair branch was also used for 2.0 and 2.0.1; however, both of those
+releases were quickly obsoleted by the version 2.1 Eclair release. As Android
+2.1 includes key bug fixes and improvements not present in 2.0/2.0.1, only
+Android 2.1 should be used for new devices. As there is no compatibility
+program for 2.0 or 2.0.1, the officially compatible Eclair-based release is Android
+2.1. (The linked document refers to Android 2.0, because there were
+no new platform features added in 2.1.)</p>
+<h3><a href="http://developer.android.com/sdk/android-1.6-highlights.html">Android 1.6</a></h3>
+<p>Android 1.6 corresponded to the "Donut" milestone branch, and has an API level of
+4.</p>
+<h3><a href="http://developer.android.com/sdk/android-1.5-highlights.html">Android 1.5</a></h3>
+<p>Android 1.5 corresponded to the "Cupcake" milestone branch, and has an API
+level of 3.</p>
+<h3><a href="http://developer.android.com/sdk/android-1.1.html">Android 1.1</a></h3>
+<p>Android 1.1 has an API level of 2. Android 1.1 was known as
+"Petit Four" internally, though this name was not used officially.</p>
+<h3>Android 1.0</h3>
+<p>was the first release of Android, and has an API
+level of 1. Since it was the first released version of Android, no platform
+highlights were prepared for this release.</p>
diff --git a/pdk/docs/source/report-bugs.jd b/pdk/docs/source/report-bugs.jd
index 138080d..a6e56c6 100644
--- a/pdk/docs/source/report-bugs.jd
+++ b/pdk/docs/source/report-bugs.jd
@@ -77,7 +77,7 @@
 
 public class TestObjectNull extends Activity {
     /** Called when the activity is first created. */
-    @Override
+    &#64;Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         setContentView(R.layout.main);
diff --git a/pdk/docs/source/roles.jd b/pdk/docs/source/roles.jd
index 451c821..f4fb891 100644
--- a/pdk/docs/source/roles.jd
+++ b/pdk/docs/source/roles.jd
@@ -15,22 +15,22 @@
 
 <h2>Contributor</h2>
 <p>A "Contributor" is anyone making contributions to the AOSP source code,
-including both employees of Google or other companies, as well as
-external developers who are contributing to Android on their own behalf.
-There is no distinction between Contributors who are employed by 
-Google, and those who are not: all engineers use the same git/gerrit tools, 
-follow the same code review process, and are subject to the same requirements
-on code style and so on.</p>
+including both employees of Google or other companies, as well as external
+developers who are contributing to Android on their own behalf.  There is no
+distinction between Contributors who are employed by Google, and those who are
+not: all engineers use the same tools (<code>git</code>, <code>repo</code>,
+and <code>gerrit</code>), follow the same code review process, and are subject
+to the same requirements on code style and so on.</p>
 <p/>
 
 <h2>Developer</h2>
 <p>A "Developer" is an engineer writing applications that run on Android
 devices. There is, of course, no difference in skillset between a "Developer"
-and a "Contributor"; AOSP simply uses "Developer" to help identify our audience.
-Since the key purpose of Android is to cultivate an open development platform,
-"Developers" are one of the key customers of the Android platform. As such, we
-talk about them a lot, though this isn't technically a separate role in the
-AOSP <i>per se.</i></p>
+and a "Contributor", but AOSP uses "Developer" to distinguish between
+engineers using the platform and those contributing to it. Developers are
+(along with end users) the "customers" of the platform that the Contributors
+create. As such, we talk about Developers a lot, though this isn't technically
+a separate role in the AOSP <i>per se.</i></p>
 <p/>
 
 <h2>Verifier</h2>
@@ -62,12 +62,12 @@
   releases.</li>
   <li>Designate Verifiers and Approvers for submitted patches.</li>
   <li>Be fair and unbiased while reviewing changes. Accept or reject patches
-  based on technical merit and alignment with the Android platform.</li>
+  based on technical merit and alignment with the Android strategy.</li>
   <li>Review changes in a timely manner and make best efforts to communicate
   when changes are not accepted.</li>
   <li>Optionally maintain a web site for the project for information and
   documents specific to the project.</li>
   <li>Act as a facilitator in resolving technical conflicts.</li>
-  <li>Be the public face for the project and the go-to person for questions
+  <li>Be a public face for the project and the go-to person for questions
   related to the project.</li>
 </ul>
diff --git a/pdk/docs/source/submit-patches.jd b/pdk/docs/source/submit-patches.jd
index 2b7bae1..9e7d9df 100644
--- a/pdk/docs/source/submit-patches.jd
+++ b/pdk/docs/source/submit-patches.jd
@@ -1,6 +1,7 @@
 page.title=Android Contributors' Workflow
 doc.type=source
 @jd:body
+<div>
 <br>This page describes how to record changes to the Android files on your local client, upload those changes to the code-review server, and use Gerrit to track changes.<br><h2>
 Prerequisites</h2>
 Before you follow the instructions on this page, you will need to set up your
@@ -14,6 +15,9 @@
 Open Source community, see <a href="{@docRoot}source/roles.html">Project roles</a>.</li>
 <li>If you plan to contribute code to the Android platform, be sure to read
 the <a href="{@docRoot}source/licenses.html">AOSP's licensing information</a>.</li>
+<li>Note that changes to some of the upstream projects used by Android should be
+made directly to that project, as described in
+<a href="#upstream-projects">Upstream Projects</a>.
 </ul>
 <h2>
 Working with the code</h2>
@@ -129,8 +133,8 @@
 </ul>
 <h3>
 Viewing diffs and comments</h3>
-To open the details of the change within Gerrit, click on the "Id number" or "Subject" of a change. To compare the established code with the updated code, click the file name under "Side-by-side diffs."<br></div>
-<div><h3>
+To open the details of the change within Gerrit, click on the "Id number" or "Subject" of a change. To compare the established code with the updated code, click the file name under "Side-by-side diffs."<br>
+<h3>
 Adding comments</h3>
 Anyone in the community can use Gerrit to add inline comments to code submissions. A good comment will be relevant to the line or section of code to which it is attached in Gerrit. It might be a short and constructive suggestion about how a line of code could be improved, or it might be an explanation from the author about why the code makes sense the way it is.<br><br>To add an inline comment, double-click the relevant line of the code and write your comment in the text box that opens. When you click Save, only you can see your comment.<br><br>To publish your comments so that others using Gerrit will be able to see them, click the Publish Comments button. Your comments will be emailed to all relevant parties for this change, including the change owner, the patch set uploader (if different from the owner), and all current reviewers.<br><br><h3>
 After a submission is approved</h3>
@@ -142,6 +146,27 @@
 .<br><br><h2>
 Using GitWeb to track patch histories</h2>
 To view snapshots of the files that are in the public Android repositories and view file histories, use the <a href="http://android.git.kernel.org/">Android instance of GitWeb</a>
-.<br></div>
-</div>
+.<br>
+<h2><a name="upstream-projects"></a>Upstream Projects</h2>
+Android makes use of a number of other open-source projects, such as the Linux
+kernel and WebKit, as described in
+<a href="{@docRoot}source/code-lines.html">Branches &amp Releases</a>. For the
+upstream projects detailed below, changes should be made directly upstream. Such
+changes will be incorporated into the Android tree as part of the usual process
+of pulling these projects.
+<h3>WebKit</h3>
+All changes to the WebKit project at <code>external/webkit</code> should be made
+upstream at <a href="http://www.webkit.org">http://www.webkit.org</a>. The
+process begins by filing a WebKit bug. This bug should use <code>Android</code>
+for the <code>Platform</code> and <code>OS</code> fields only if the bug is
+specific to Android. Bugs are far more likely to receive the reviewers'
+attention once a proposed fix is added and tests are included. See
+<a href="http://webkit.org/coding/contributing.html">Contributing Code to
+WebKit</a> for details.
+<h3>V8</h3>
+All changes to the V8 project at <code>external/v8</code> should be submitted
+upstream at
+<a href="http://code.google.com/p/v8">http://code.google.com/p/v8</a>. See
+<a href="http://code.google.com/p/v8/wiki/Contributing">Contributing to V8</a>
+for details.
 </div>
diff --git a/pdk/docs/source/using-eclipse.jd b/pdk/docs/source/using-eclipse.jd
index 56df713..660de11 100644
--- a/pdk/docs/source/using-eclipse.jd
+++ b/pdk/docs/source/using-eclipse.jd
@@ -95,58 +95,6 @@
 <p>When you're done, the "source folder" path in the list should look like android/packages/apps/<i>YourAppName</i>
 /src. Depending on which app(s) you include, you may also need to include othersrc/main/java directories under android/dalvik/libcore. Do this if you find you cannot build with the default set.
 </p>
-<h4>
-Eclipse setup to work on developer tools
-</h4>
-<p>To work on Java developer tools, the principle is the same, except you specify /path/to/tool when using the option "Create project from existing source."
-</p>
-<p>Once the project is created, you need to set up the Java Build Path:
-</p>
-<ol><li>Select the project you just created.
-</li>
-<li>Project Properties
-</li>
-<li>Select "Java Build Path" from the left-hand menu.
-</li>
-<li>Choose the "Source" tab.
-</li>
-<li>Expand the single <i>toolname</i>
-/src entry.
-</li>
-<li>Double click the "Excluded: (none)" item.
-</li>
-<li>Add to the excluded (bottom) list: "MakeFile" and "resources/".
-</li>
-<li>Close the dialog.
-</li>
-<li>Back in the "Source" tab, click "Add Folder...", and add <i>toolname</i>
-/src/resources.
-</li>
-<li>Click OK.
-</li>
-</ol>
-<h4>
-Eclipse setup to work on DDMS <br></h4>
-<p>For DDMS, you will need to make a project for
-</p>
-<ol><li>development/tools/ddms/libs/ddmlib
-</li>
-<li>development/tools/ddms/libs/ddmuilib
-</li>
-<li>development/tools/ddms/app
-</li>
-</ol>
-<p>Each project will need to reference the ones before it ("ddmuilib" references "ddmlib", and "app" references both of those). To do this:
-</p>
-<ol><li>Make sure you have all 3 projects defined.
-</li>
-<li>Right click on a project, "Build Path" "Configure Build Path..."
-</li>
-<li>Choose the "Project" tab.
-</li>
-<li>Click "Add..." and check the required projects.
-</li>
-</ol>
 <h2><a>Eclipse formatting</a>
 </h2>
 <p>You can import files in development/ide/eclipse to make Eclipse
@@ -189,15 +137,6 @@
 
 <pre>Ctrl-Shift-o = Organize imports <br>Ctrl-Shift-t = load class by name <br>Ctrl-Shift-r = load non-class resource by name <br>Ctrl-1 = quick fix <br>Ctrl-e = Recently viewed files <br>Ctrl-space = auto complete <br>Shift-Alt-r = refactor:rename <br>Shift-Alt-v = refactor:move <br></pre>
 
-<h2><a>Useful Plugins</a>
-</h2>
-<p>Eclipse has a plugin architecture that enables third parties to extend the IDE. Here are some plugins that make Eclipse easier to use for writing Android software:
-</p>
-
-<ul><li><a href="http://andrei.gmxhome.de/anyedit/">AnyEdit</a>
-- automatically fix whitespace issues when saving files. Can convert tabs to spaces, strip blanks at end-of-line, and ensure the last line of the file has an end-of-line character.
-</li>
-</ul>
 <h2><a>"Eclipse is not working correctly, what should I do?"</a>
 </h2>
 <p>Make sure:
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index e9acbb4..d73fa39 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -37,13 +37,16 @@
 
     <!-- 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" />
     <uses-feature android:name="android.hardware.camera" />
     <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
+    -->
 
     <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. -->
@@ -72,7 +75,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" />
@@ -148,6 +151,22 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".app.ActivityRecreate"
+                android:label="@string/activity_recreate">
+            <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" />
@@ -155,7 +174,8 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".app.SendResult">
+        <activity android:name=".app.SendResult"
+                android:theme="@android:style/Theme.Holo.DialogWhenLarge">
         </activity>
 
         <activity android:name=".app.Forwarding" android:label="@string/activity_forwarding">
@@ -181,9 +201,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" />
@@ -217,6 +240,107 @@
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
+        
+        <!-- Fragment Samples -->
+
+        <activity android:name=".app.FragmentAlertDialog"
+                android:label="@string/fragment_alert_dialog">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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" />
+
+        <activity android:name=".app.FragmentListCursorLoader"
+                android:label="@string/fragment_list_cursor_loader">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.FragmentListArray"
+                android:label="@string/fragment_list_array">
+            <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">
+            <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">
+            <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">
+            <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">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
 
         <!-- Intent Samples -->
 
@@ -227,6 +351,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" />
@@ -360,12 +492,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>
@@ -526,50 +662,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"
@@ -611,10 +703,117 @@
             </intent-filter>
         </activity>
 
+        <!-- Action Bar Samples -->
+        <activity android:name=".app.ActionBarMechanics"
+                  android:label="@string/action_bar_mechanics">
+            <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">
+            <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">
+            <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">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--       PREFERENCE PACKAGE SAMPLES      -->
+        <!-- ************************************* -->
+
+        <activity android:name=".preference.FragmentPreferences"
+                android:label="@string/fragment_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.PreferenceWithHeaders"
+                android:label="@string/preference_with_headers">
+            <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">
+            <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" />
@@ -696,6 +895,109 @@
         </receiver>
 
         <!-- ************************************* -->
+        <!--     ANDROID.ANIMATION PACKAGE SAMPLES         -->
+        <!-- ************************************* -->
+
+        <activity android:name=".animation.AnimationLoading" android:label="Animation/Loading"
+                  android:hardwareAccelerated="false">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
         <!--     ANIMATION PACKAGE SAMPLES         -->
         <!-- ************************************* -->
 
@@ -829,21 +1131,43 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".view.Tabs1" android:label="Views/Tabs/Content By Id">
+        <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"/>
@@ -941,27 +1265,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" />
@@ -1053,63 +1356,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" />
@@ -1151,6 +1454,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" />
@@ -1216,6 +1540,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>
@@ -1319,15 +1651,35 @@
         </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">
+            <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">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -1454,6 +1806,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" />
@@ -1468,6 +1827,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" />
@@ -1475,6 +1866,22 @@
             </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">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <!-- ************************************* -->
         <!--           GRAPHICS SAMPLES            -->
         <!-- ************************************* -->
diff --git a/samples/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/anim/animator.xml
similarity index 66%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/anim/animator.xml
index b6b1b7c..2432f19 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/anim/animator.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -15,8 +14,10 @@
      limitations under the License.
 -->
 
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/anim/color_animator.xml
similarity index 65%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/anim/color_animator.xml
index b6b1b7c..08ca017 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/anim/color_animator.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -15,8 +14,10 @@
      limitations under the License.
 -->
 
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/anim/object_animator.xml
similarity index 65%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/anim/object_animator.xml
index b6b1b7c..863d423 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/anim/object_animator.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -15,8 +14,10 @@
      limitations under the License.
 -->
 
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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-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/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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/layout/action_bar_display_options_custom.xml
similarity index 69%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/layout/action_bar_display_options_custom.xml
index b6b1b7c..b7f5bd9 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/layout/action_bar_display_options_custom.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -14,9 +13,5 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+        android:text="@string/display_options_custom_button" />
diff --git a/samples/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/layout/action_bar_tab_content.xml
similarity index 69%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/layout/action_bar_tab_content.xml
index b6b1b7c..c0aa7fa 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/layout/action_bar_tab_content.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -14,9 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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..9c6e4a3 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"/>
diff --git a/apps/GraphicsLab/res/layout/graphics_lab.xml b/samples/ApiDemos/res/layout/animation_cloning.xml
similarity index 67%
copy from apps/GraphicsLab/res/layout/graphics_lab.xml
copy to samples/ApiDemos/res/layout/animation_cloning.xml
index 7c0e5d9..de51880 100644
--- a/apps/GraphicsLab/res/layout/graphics_lab.xml
+++ b/samples/ApiDemos/res/layout/animation_cloning.xml
@@ -1,25 +1,28 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT 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">        
+    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/apps/GraphicsLab/res/layout/graphics_lab.xml b/samples/ApiDemos/res/layout/animation_custom_evaluator.xml
similarity index 67%
rename from apps/GraphicsLab/res/layout/graphics_lab.xml
rename to samples/ApiDemos/res/layout/animation_custom_evaluator.xml
index 7c0e5d9..0d6285c 100644
--- a/apps/GraphicsLab/res/layout/graphics_lab.xml
+++ b/samples/ApiDemos/res/layout/animation_custom_evaluator.xml
@@ -1,25 +1,28 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT 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">        
+    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/apps/GraphicsLab/res/layout/graphics_lab.xml b/samples/ApiDemos/res/layout/animation_loading.xml
similarity index 67%
copy from apps/GraphicsLab/res/layout/graphics_lab.xml
copy to samples/ApiDemos/res/layout/animation_loading.xml
index 7c0e5d9..de51880 100644
--- a/apps/GraphicsLab/res/layout/graphics_lab.xml
+++ b/samples/ApiDemos/res/layout/animation_loading.xml
@@ -1,25 +1,28 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT 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">        
+    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/apps/GraphicsLab/res/layout/graphics_lab.xml b/samples/ApiDemos/res/layout/animation_multi_property.xml
similarity index 67%
copy from apps/GraphicsLab/res/layout/graphics_lab.xml
copy to samples/ApiDemos/res/layout/animation_multi_property.xml
index 7c0e5d9..de51880 100644
--- a/apps/GraphicsLab/res/layout/graphics_lab.xml
+++ b/samples/ApiDemos/res/layout/animation_multi_property.xml
@@ -1,25 +1,28 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT 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">        
+    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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/layout/bouncing_balls.xml
similarity index 71%
rename from samples/NFCDemo/res/layout/tag_divider.xml
rename to samples/ApiDemos/res/layout/bouncing_balls.xml
index b6b1b7c..e5d7da5 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/layout/bouncing_balls.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -14,9 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<View 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="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+    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..63a2de1 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"
diff --git a/samples/ApiDemos/res/layout/device_admin_sample.xml b/samples/ApiDemos/res/layout/device_admin_sample.xml
index 16b08ce..a7cb0d9 100644
--- a/samples/ApiDemos/res/layout/device_admin_sample.xml
+++ b/samples/ApiDemos/res/layout/device_admin_sample.xml
@@ -15,132 +15,263 @@
 -->
 
 <!-- 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>
+
+        <LinearLayout android:orientation="vertical" android:gravity="center_horizontal"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+
+            <EditText android:id="@+id/proxyhost"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:hint="@string/proxyhost_hint">
+            </EditText>
+
+            <EditText android:id="@+id/proxylist"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:hint="@string/proxylist_hint">
+            </EditText>
+
+            <Button android:id="@+id/set_proxy"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="@string/set_proxy_label">
+            </Button>
+
+        </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..0dd193d
--- /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_4"
+        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_toRightOf="@id/drag_dot_3"
+        dot:legend="Local"
+        dot:localOnly="true"
+        />
+
+    <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_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_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_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_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..c9b87da
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_stack.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">
+
+    <FrameLayout
+            android:id="@+id/simple_fragment"
+            android:layout_width="match_parent"
+            android:layout_height="0px"
+            android:layout_weight="1" />
+            
+    <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/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/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..b7f69ab
--- /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="wrap_content"
+    >
+    <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="match_parent"
+        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..641f6c1
--- /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="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="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/apps/GraphicsLab/res/layout/graphics_lab.xml b/samples/ApiDemos/res/layout/popup_menu_1.xml
similarity index 61%
copy from apps/GraphicsLab/res/layout/graphics_lab.xml
copy to samples/ApiDemos/res/layout/popup_menu_1.xml
index 7c0e5d9..6ddc76e 100644
--- a/apps/GraphicsLab/res/layout/graphics_lab.xml
+++ b/samples/ApiDemos/res/layout/popup_menu_1.xml
@@ -1,25 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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: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">        
+              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/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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/layout/search_view.xml
similarity index 69%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/layout/search_view.xml
index b6b1b7c..4a9f7c0 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/layout/search_view.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -15,8 +14,6 @@
      limitations under the License.
 -->
 
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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/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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/menu/display_options_actions.xml
similarity index 69%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/menu/display_options_actions.xml
index b6b1b7c..7c72de4 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/menu/display_options_actions.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -14,9 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/menu/list_select_menu.xml
similarity index 66%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/menu/list_select_menu.xml
index b6b1b7c..490e3f7 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/menu/list_select_menu.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 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.
@@ -15,8 +14,9 @@
      limitations under the License.
 -->
 
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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/NFCDemo/res/layout/tag_divider.xml b/samples/ApiDemos/res/menu/searchview_in_menu.xml
similarity index 62%
copy from samples/NFCDemo/res/layout/tag_divider.xml
copy to samples/ApiDemos/res/menu/searchview_in_menu.xml
index b6b1b7c..09036a7 100644
--- a/samples/NFCDemo/res/layout/tag_divider.xml
+++ b/samples/ApiDemos/res/menu/searchview_in_menu.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -14,9 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/listDivider"
-/>
\ No newline at end of file
+<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/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..4654d7e 100644
--- a/samples/ApiDemos/res/values/attrs.xml
+++ b/samples/ApiDemos/res/values/attrs.xml
@@ -32,4 +32,17 @@
         <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="localOnly" format="boolean" />
+        <attr name="anr">
+            <enum name="none" value="0" />
+            <enum name="thumbnail" value="1" />
+            <enum name="drop" value="2" />
+        </attr>
+    </declare-styleable>
 </resources>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index e88512f..ae041a6 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,46 @@
     <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_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_list_cursor_loader">App/Fragment/List Cursor Loader</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="activity_menu">App/Activity/Menu</string>
     <string name="open_menu">Open menu</string>
     <string name="close_menu">Close menu</string>
@@ -238,6 +295,12 @@
     <!--  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>
@@ -260,15 +323,24 @@
     <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 +375,10 @@
     <!--  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_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 +400,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 +474,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 +512,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 +589,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>
@@ -482,6 +608,9 @@
     <string name="wipe_all_data">Wipe All Data</string>
     <string name="timeout_hint">Max screen timeout</string>
     <string name="set_timeout_label">Set Timeout</string>
+    <string name="proxyhost_hint">Global proxyhost:port</string>
+    <string name="proxylist_hint">No proxy for domain1,domain2</string>
+    <string name="set_proxy_label">Set Global Proxy</string>
 
     <!-- ============================== -->
     <!--  app/voice recognition examples strings  -->
@@ -491,6 +620,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 +700,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 +749,24 @@
     <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>
+
     <!-- ============================== -->
     <!--  GoogleLogin examples strings  -->
     <!-- ============================== -->
@@ -659,6 +845,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 +1148,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/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..432bbcd 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 />
+        <set-global-proxy />
+        <expire-password />
     </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/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..ca22550
--- /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 RGBEvaluator());
+            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..75c5580
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/FixedGridLayout.java
@@ -0,0 +1,106 @@
+/*
+ * 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
+        setMeasuredDimension(resolveSize(mCellWidth*count, widthMeasureSpec),
+                resolveSize(mCellHeight*count, 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..5d38b03
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java
@@ -0,0 +1,209 @@
+/*
+ * 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);
+        ((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);
+        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..66e424e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.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.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 FixedGridLayout(this);
+        ((FixedGridLayout)container).setCellHeight(50);
+        ((FixedGridLayout)container).setCellWidth(100);
+        container = new LinearLayout(this);
+
+        // 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..a61a582
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarUsage.java
@@ -0,0 +1,95 @@
+/*
+ * 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.OnQueryChangeListener;
+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 OnQueryChangeListener {
+    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.setOnQueryChangeListener(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
+    @Override
+    public boolean onQueryTextChanged(String newText) {
+        newText = newText.isEmpty() ? "" : "Query so far: " + newText;
+        mSearchText.setText(newText);
+        return true;
+    }
+
+    @Override
+    public boolean onSubmitQuery(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/AlertDialogSamples.java b/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
index 6714175..057e20c 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,7 @@
     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 MAX_PROGRESS = 100;
     
@@ -115,6 +116,30 @@
                     }
                 })
                 .create();
+        case DIALOG_YES_NO_ULTRA_LONG_MESSAGE:
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setIcon(R.drawable.alert_dialog_icon)
+                .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)
@@ -277,6 +302,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() {
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/DeviceAdminSample.java b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
index b3fc2f9..06a2c19 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,20 @@
 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.net.InetSocketAddress;
+import java.net.Proxy;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
 
 /**
  * Example of a do-nothing admin class.  When enabled, it lets you control
@@ -48,21 +56,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 +93,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);
     }
 
     /**
@@ -100,6 +142,7 @@
      */
     public static class Controller extends Activity {
         static final int RESULT_ENABLE = 1;
+        private static final long MS_PER_MINUTE = 60*1000;
 
         DevicePolicyManager mDPM;
         ActivityManager mAM;
@@ -115,10 +158,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 +186,15 @@
 
         private EditText mTimeout;
 
+        EditText mProxyHost;
+        EditText mProxyList;
+        Button mProxyButton;
+
+        private EditText mPasswordExpirationTimeout;
+        private Button mPasswordExpirationButton;
+        private TextView mPasswordExpirationStatus;
+        private Button mPasswordExpirationStatusButton;
+
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
@@ -179,6 +240,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 +390,11 @@
             mTimeout = (EditText) findViewById(R.id.timeout);
             mTimeoutButton = (Button) findViewById(R.id.set_timeout);
             mTimeoutButton.setOnClickListener(mSetTimeoutListener);
+
+            mProxyHost = (EditText) findViewById(R.id.proxyhost);
+            mProxyList = (EditText) findViewById(R.id.proxylist);
+            mProxyButton = (Button) findViewById(R.id.set_proxy);
+            mProxyButton.setOnClickListener(mSetProxyListener);
         }
 
         void updateButtonStates() {
@@ -224,6 +404,13 @@
                 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);
@@ -235,6 +422,13 @@
                 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);
@@ -249,6 +443,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 +459,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 +548,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,6 +616,7 @@
         protected void onResume() {
             super.onResume();
             updateButtonStates();
+            updatePasswordExpirationStatus();
         }
 
         @Override
@@ -304,9 +624,9 @@
             switch (requestCode) {
                 case RESULT_ENABLE:
                     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;
             }
@@ -343,7 +663,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 +681,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 +698,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 +742,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 +757,49 @@
                 }
             }
         };
+
+        private OnClickListener mSetProxyListener = new OnClickListener() {
+
+            public void onClick(View v) {
+                boolean active = mDPM.isAdminActive(mDeviceAdminSample);
+                String proxySpec = mProxyHost.getText().toString();
+                String proxyList = mProxyList.getText().toString();
+                Proxy instProxy;
+                List<String> exclList;
+
+                if ((proxySpec.length() == 0) || (proxySpec == null)) {
+                    instProxy = Proxy.NO_PROXY;
+                } else {
+                    String[] proxyComponents = proxySpec.split(":");
+                    if (proxyComponents.length != 2) {
+                        Toast.makeText(Controller.this, "Wrong proxy specification.",
+                                Toast.LENGTH_SHORT).show();
+                        return;
+                    }
+                    instProxy = new Proxy(Proxy.Type.HTTP,
+                            new InetSocketAddress(proxyComponents[0],
+                                    Integer.parseInt(proxyComponents[1])));
+                }
+                if ((proxyList == null) || (proxyList.length() == 0)) {
+                    exclList = null;
+                } else {
+                    String[] listDoms = proxyList.split(",");
+                    if (listDoms.length == 0) {
+                        Toast.makeText(Controller.this, "Wrong exclusion list format.",
+                                Toast.LENGTH_SHORT).show();
+                    }
+                    exclList =  Arrays.asList(listDoms);
+                }
+                if (active) {
+                    mDPM.setGlobalProxy(mDeviceAdminSample, instProxy, exclList);
+                    ComponentName proxyAdmin = mDPM.getGlobalProxyAdmin();
+                    if ((proxyAdmin != null) && (proxyAdmin.equals(mDeviceAdminSample))) {
+                        Toast.makeText(Controller.this, "Global Proxy set by device admin.",
+                                Toast.LENGTH_SHORT).show();
+                    }
+                }
+            }
+        };
+
     }
 }
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..0a6b724 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java
@@ -19,10 +19,17 @@
 // Need the following import to get access to the app resources, since this
 // class is in a sub-package.
 import android.app.Activity;
+import android.content.Intent;
 import android.os.Bundle;
+import android.view.View;
 import android.view.Window;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
 
 import com.example.android.apis.R;
+import com.example.android.apis.app.ForegroundService.Controller;
 
 /**
  * <h3>Dialog Activity</h3>
@@ -50,5 +57,30 @@
         
         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/FragmentContextMenu.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentContextMenu.java
new file mode 100644
index 0000000..185f7a0
--- /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().openTransaction().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..bb2ef8b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialog.java
@@ -0,0 +1,159 @@
+/*
+ * 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().openTransaction();
+        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 light fullscreen theme";
+            case 5: return "STYLE_NORMAL with dark 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;
+            }
+            switch ((mNum-1)%6) {
+                case 4: theme = android.R.style.Theme_Light; break;
+                case 5: theme = android.R.style.Theme; 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..c4d2c00
--- /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().openTransaction();
+            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..9e9661a
--- /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().openTransaction();
+                ft.setCustomAnimations(android.R.anim.animator_fade_in,
+                        android.R.anim.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..f959d00
--- /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().openTransaction().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;
+        int mShownCheckPosition = -1;
+
+        @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);
+                mShownCheckPosition = savedInstanceState.getInt("shownChoice", -1);
+            }
+
+            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);
+            outState.putInt("shownChoice", mShownCheckPosition);
+        }
+
+        @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);
+
+                if (mShownCheckPosition != mCurCheckPosition) {
+                    // If we are not currently showing a fragment for the new
+                    // position, we need to create and install a new one.
+                    DetailsFragment df = DetailsFragment.newInstance(index);
+
+                    // Execute a transaction, replacing any existing fragment
+                    // with this one inside the frame.
+                    FragmentTransaction ft = getFragmentManager().openTransaction();
+                    ft.replace(R.id.details, df);
+                    ft.setTransition(index > mCurCheckPosition
+                            ? FragmentTransaction.TRANSIT_FRAGMENT_NEXT
+                            : FragmentTransaction.TRANSIT_FRAGMENT_PREV);
+                    ft.commit();
+                    mShownCheckPosition = index;
+                }
+
+            } 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;
+        }
+
+        @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[getArguments().getInt("index", 0)]);
+            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..d4aafa1
--- /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().openTransaction().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/FragmentListCursorLoader.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.java
new file mode 100644
index 0000000..ac9bcf0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.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.ListFragment;
+import android.app.LoaderManager;
+import android.content.Context;
+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.view.inputmethod.InputMethodManager;
+import android.widget.ListView;
+import android.widget.SearchView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.SearchView.OnQueryChangeListener;
+
+/**
+ * Demonstration of more complex use if a ListFragment, including showing
+ * an empty view and loading progress.
+ */
+public class FragmentListCursorLoader extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create the list fragment and add it as our sole content.
+        if (findFragmentById(android.R.id.content) == null) {
+            CursorLoaderListFragment list = new CursorLoaderListFragment();
+            openFragmentTransaction().add(android.R.id.content, list).commit();
+        }
+    }
+
+//BEGIN_INCLUDE(fragment_cursor)
+    public static class CursorLoaderListFragment extends ListFragment
+            implements OnQueryChangeListener, 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.setOnQueryChangeListener(this);
+            item.setActionView(sv);
+        }
+
+        @Override public boolean onQueryTextChanged(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 onSubmitQuery(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,
+        };
+
+        @Override 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");
+        }
+
+        @Override 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);
+        }
+
+        @Override 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/FragmentMenu.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentMenu.java
new file mode 100644
index 0000000..9dc223d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentMenu.java
@@ -0,0 +1,116 @@
+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.openTransaction();
+        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().openTransaction();
+        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..d2ef673
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentReceiveResult.java
@@ -0,0 +1,117 @@
+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().openTransaction();
+            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..1879090
--- /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().openTransaction().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.openTransaction().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..6710a2d
--- /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().openTransaction();
+            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().openTransaction();
+        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().getInt("num");
+        }
+
+        /**
+         * 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/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..6fe2d4c 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
@@ -37,47 +37,131 @@
   <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>Fragment</h3>
+<dl>
+  <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="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="FragmentCursorLoader.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="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>Service</h3>
 <dl>
-  <dt><a href="LocalService.html">Local Service Controller and
-        Local Service Binding</a></dt>
+  <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
@@ -126,6 +210,10 @@
 
   <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>
@@ -141,3 +229,12 @@
 </dl>
 
 
+<h3>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..6144224
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.java
@@ -0,0 +1,145 @@
+/**
+ * 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", null, mStyledText));
+    }
+
+    public void pastePlainText(View button) {
+        mClipboard.setPrimaryClip(ClipData.newPlainText("Styled Text", null, 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", null, intent));
+    }
+
+    public void pasteUri(View button) {
+        mClipboard.setPrimaryClip(ClipData.newRawUri("URI", null,
+                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.getItem(0).getText() != null) {
+            mSpinner.setSelection(1);
+            mEditText.setText(clip.getItem(0).getText());
+        } else if (clip.getItem(0).getIntent() != null) {
+            mSpinner.setSelection(2);
+            mEditText.setText(clip.getItem(0).getIntent().toUri(0));
+        } else if (clip.getItem(0).getUri() != null) {
+            mSpinner.setSelection(3);
+            mEditText.setText(clip.getItem(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/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/app/AdvancedPreferences.java b/samples/ApiDemos/src/com/example/android/apis/preference/AdvancedPreferences.java
similarity index 96%
rename from samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java
rename to samples/ApiDemos/src/com/example/android/apis/preference/AdvancedPreferences.java
index 2dbbc45..0328b03 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/AdvancedPreferences.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.preference;
 
 import com.example.android.apis.R;
 
@@ -35,7 +35,7 @@
 
     private CheckBoxPreference mCheckBoxPreference;
     private Handler mHandler = new Handler();
-    
+
     /**
      * This is a simple example of controlling a preference from code.
      */
@@ -44,19 +44,19 @@
             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);
@@ -68,7 +68,7 @@
 
         // Start the force toggle
         mForceCheckBoxRunnable.run();
-        
+
         // Set up a listener whenever a key changes
         getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
     }
@@ -79,7 +79,7 @@
 
         // Unregister the listener whenever a key changes
         getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
-        
+
         mHandler.removeCallbacks(mForceCheckBoxRunnable);
     }
 
@@ -90,5 +90,5 @@
                     + sharedPreferences.getInt(key, 0), Toast.LENGTH_SHORT).show();
         }
     }
-    
+
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java b/samples/ApiDemos/src/com/example/android/apis/preference/DefaultValues.java
similarity index 97%
rename from samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
rename to samples/ApiDemos/src/com/example/android/apis/preference/DefaultValues.java
index 494a2ea..69cf499 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/DefaultValues.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.preference;
 
 import com.example.android.apis.ApiDemosApplication;
 import com.example.android.apis.R;
@@ -46,7 +46,7 @@
     @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..b3cc6a3
--- /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().openTransaction().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/app/LaunchingPreferences.java b/samples/ApiDemos/src/com/example/android/apis/preference/LaunchingPreferences.java
similarity index 96%
rename from samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java
rename to samples/ApiDemos/src/com/example/android/apis/preference/LaunchingPreferences.java
index 4aa1522..066477b 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/LaunchingPreferences.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.preference;
 
 import com.example.android.apis.R;
 
@@ -36,9 +36,9 @@
 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);
@@ -50,33 +50,33 @@
          * 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);
     }
@@ -84,7 +84,7 @@
     @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) {
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java b/samples/ApiDemos/src/com/example/android/apis/preference/MyPreference.java
similarity index 96%
rename from samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java
rename to samples/ApiDemos/src/com/example/android/apis/preference/MyPreference.java
index 967c181..aeb8bf9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/MyPreference.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.preference;
 
 import com.example.android.apis.R;
 
@@ -33,18 +33,18 @@
  */
 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);        
+
+        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) {
@@ -61,14 +61,14 @@
             // 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();
     }
@@ -100,7 +100,7 @@
          * 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
@@ -120,14 +120,14 @@
             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.
@@ -136,10 +136,10 @@
      */
     private static class SavedState extends BaseSavedState {
         int clickCounter;
-        
+
         public SavedState(Parcel source) {
             super(source);
-            
+
             // Restore the click counter
             clickCounter = source.readInt();
         }
@@ -147,7 +147,7 @@
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             super.writeToParcel(dest, flags);
-            
+
             // Save the click counter
             dest.writeInt(clickCounter);
         }
@@ -167,5 +167,5 @@
             }
         };
     }
-    
+
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java b/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceDependencies.java
similarity index 95%
rename from samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
rename to samples/ApiDemos/src/com/example/android/apis/preference/PreferenceDependencies.java
index 27c22de..3aa4e39 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceDependencies.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.preference;
 
 import com.example.android.apis.R;
 
@@ -26,7 +26,7 @@
     @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/app/PreferencesFromCode.java b/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromCode.java
similarity index 96%
rename from samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java
rename to samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromCode.java
index be22b49..8ce6b42 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromCode.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.preference;
 
 import android.content.Intent;
 import android.content.res.TypedArray;
@@ -34,26 +34,26 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        
+
         setPreferenceScreen(createPreferenceHierarchy());
     }
 
     private PreferenceScreen createPreferenceHierarchy() {
         // Root
         PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
-        
-        // Inline preferences 
+
+        // 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);
@@ -66,7 +66,7 @@
         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);
@@ -76,7 +76,7 @@
         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);
@@ -93,19 +93,19 @@
         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)
@@ -113,18 +113,18 @@
         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.
@@ -137,7 +137,7 @@
                         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/preference/PreferencesFromXml.java
similarity index 95%
rename from samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
rename to samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromXml.java
index 63bbac2..868e33c 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
+++ b/samples/ApiDemos/src/com/example/android/apis/preference/PreferencesFromXml.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.preference;
 
 import com.example.android.apis.R;
 
@@ -26,7 +26,7 @@
     @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/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/apps/Term/src/com/android/term/TermPreferences.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java
similarity index 60%
copy from apps/Term/src/com/android/term/TermPreferences.java
copy to samples/ApiDemos/src/com/example/android/apis/view/Controls3.java
index 3102963..407767f 100644
--- a/apps/Term/src/com/android/term/TermPreferences.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java
@@ -14,19 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.term;
+package com.example.android.apis.view;
 
-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);
-    }
-
-}
+public class Controls3 extends Controls1 {}
diff --git a/apps/Term/src/com/android/term/TermPreferences.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java
similarity index 60%
rename from apps/Term/src/com/android/term/TermPreferences.java
rename to samples/ApiDemos/src/com/example/android/apis/view/Controls4.java
index 3102963..3dcf310 100644
--- a/apps/Term/src/com/android/term/TermPreferences.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java
@@ -14,19 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.term;
+package com.example.android.apis.view;
 
-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);
-    }
-
-}
+public class Controls4 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..7e8c076
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.java
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+    @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);
+        dot = (DraggableDot) findViewById(R.id.drag_dot_4);
+        dot.setReportView(text);
+
+        mResultText = (TextView) findViewById(R.id.drag_result_text);
+        mResultText.setOnDragListener(new View.OnDragListener() {
+            @Override
+            public boolean onDrag(View v, DragEvent event) {
+                final int action = event.getAction();
+                if (action == DragEvent.ACTION_DRAG_ENDED) {
+                    final boolean dropped = event.getResult();
+                    mResultText.setText(dropped ? "Dropped!" : "No drop");
+                }
+                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..b715ba1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.java
@@ -0,0 +1,266 @@
+/*
+ * 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;
+    boolean mLocalOnly;
+    CharSequence mLegend;
+
+    static final int ANR_NONE = 0;
+    static final int ANR_THUMBNAIL = 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);
+    }
+
+    // Thumbnail builder that can ANR if desired
+    class ANRThumbBuilder extends DragThumbnailBuilder {
+        boolean mDoAnr;
+
+        public ANRThumbBuilder(View view, boolean doAnr) {
+            super(view);
+            mDoAnr = doAnr;
+        }
+
+        @Override
+        public void onDrawThumbnail(Canvas canvas) {
+            if (mDoAnr) {
+                sleepSixSeconds();
+            }
+            super.onDrawThumbnail(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;
+
+            case R.styleable.DraggableDot_localOnly: {
+                mLocalOnly = a.getBoolean(attr, false);
+            } break;
+            }
+        }
+
+        Log.i(TAG, "DraggableDot @ " + this + " : radius=" + mRadius + " legend='" + mLegend
+                + "' anr=" + mAnrType + " local=" + mLocalOnly);
+
+        setOnLongClickListener(new View.OnLongClickListener() {
+            public boolean onLongClick(View v) {
+                ClipData data = ClipData.newPlainText("dot", null, "Dot : " + v.toString());
+                v.startDrag(data, new ANRThumbBuilder(v, mAnrType == ANR_THUMBNAIL),
+                        mLocalOnly, (Object)v);
+                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.getItem(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/app/PreferenceDependencies.java b/samples/ApiDemos/src/com/example/android/apis/view/Focus5.java
similarity index 72%
copy from samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
copy to samples/ApiDemos/src/com/example/android/apis/view/Focus5.java
index 27c22de..728671c 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Focus5.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,20 +14,18 @@
  * limitations under the License.
  */
 
-package com.example.android.apis.app;
+package com.example.android.apis.view;
 
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
 import com.example.android.apis.R;
 
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-
-public class PreferenceDependencies extends PreferenceActivity {
-
+public class Focus5 extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        
-        addPreferencesFromResource(R.xml.preference_dependencies);
-    }
 
+        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/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/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..d6ad8ed
--- /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.OnQueryChangeListener,
+        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.setOnQueryChangeListener(this);
+        mSearchView.setOnCloseListener(this);
+    }
+
+    public boolean onQueryTextChanged(String newText) {
+        mStatusView.setText("Query = " + newText);
+        return false;
+    }
+
+    public boolean onSubmitQuery(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..a5898ba
--- /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.OnQueryChangeListener {
+
+    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.setOnQueryChangeListener(this);
+        mSearchView.setSubmitButtonEnabled(false);
+        mSearchView.setQueryHint(getString(R.string.cheese_hunt_hint));
+    }
+
+    public boolean onQueryTextChanged(String newText) {
+        if (TextUtils.isEmpty(newText)) {
+            mListView.clearTextFilter();
+        } else {
+            mListView.setFilterText(newText.toString());
+        }
+        return true;
+    }
+
+    public boolean onSubmitQuery(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..0a435c1 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>
 
 
@@ -235,13 +259,21 @@
 
 <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. Theme Light</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. Theme Dark</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. Theme Holographic Light</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. Theme Holographic Dark</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>
 
 <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/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java b/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
index d0c1d43..20e9b9e 100644
--- a/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
+++ b/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
@@ -402,6 +402,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/BrowserPlugin/jni/Android.mk b/samples/BrowserPlugin/jni/Android.mk
index d444bb0..b153e37 100644
--- a/samples/BrowserPlugin/jni/Android.mk
+++ b/samples/BrowserPlugin/jni/Android.mk
@@ -30,7 +30,9 @@
 LOCAL_SRC_FILES := \
 	main.cpp \
 	PluginObject.cpp \
+	RenderingThread.cpp \
 	animation/AnimationPlugin.cpp \
+	animation/AnimationThread.cpp \
 	audio/AudioPlugin.cpp \
 	background/BackgroundPlugin.cpp \
 	form/FormPlugin.cpp \
@@ -52,10 +54,16 @@
 	external/webkit/WebCore/bridge \
 	external/webkit/WebCore/plugins \
 	external/webkit/WebCore/platform/android/JavaVM \
-	external/webkit/WebKit/android/plugins
+	external/webkit/WebKit/android/plugins \
+	external/skia/include/core
 
 LOCAL_SHARED_LIBRARIES := \
-	libnativehelper
+	libnativehelper \
+	libutils \
+	libcutils \
+	libEGL \
+	libGLESv2 \
+	libskia
 
 LOCAL_CFLAGS += -fvisibility=hidden 
 LOCAL_PRELINK_MODULE:=false
diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp
index dd0fbac..16925c8 100644
--- a/samples/BrowserPlugin/jni/PluginObject.cpp
+++ b/samples/BrowserPlugin/jni/PluginObject.cpp
@@ -45,6 +45,10 @@
     return obj->window->height;
 }
 
+SurfaceSubPlugin::~SurfaceSubPlugin() {
+    setContext(NULL);
+}
+
 bool SurfaceSubPlugin::supportsDrawingModel(ANPDrawingModel model) {
     return (model == kSurface_ANPDrawingModel);
 }
diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h
index 0ebed28..e0f4424 100644
--- a/samples/BrowserPlugin/jni/PluginObject.h
+++ b/samples/BrowserPlugin/jni/PluginObject.h
@@ -48,7 +48,7 @@
 public:
     SubPlugin(NPP inst) : m_inst(inst) {}
     virtual ~SubPlugin() {}
-    virtual int16 handleEvent(const ANPEvent* evt) = 0;
+    virtual int16_t handleEvent(const ANPEvent* evt) = 0;
     virtual bool supportsDrawingModel(ANPDrawingModel) = 0;
 
     int getPluginWidth();
@@ -63,7 +63,7 @@
 class SurfaceSubPlugin : public SubPlugin {
 public:
     SurfaceSubPlugin(NPP inst) : SubPlugin(inst) { m_context = NULL; }
-    virtual ~SurfaceSubPlugin() {}
+    virtual ~SurfaceSubPlugin();
     virtual jobject getSurface() = 0;
     virtual bool supportsDrawingModel(ANPDrawingModel);
 
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
index 72a11c9..58999ad 100644
--- a/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
+++ b/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
@@ -33,128 +33,85 @@
 extern ANPCanvasInterfaceV0    gCanvasI;
 extern ANPPaintInterfaceV0     gPaintI;
 extern ANPPathInterfaceV0      gPathI;
+extern ANPSystemInterfaceV0    gSystemI;
 extern ANPWindowInterfaceV0    gWindowI;
 
-static uint16 rnd16(float x, int inset) {
+static uint16_t rnd16(float x, int inset) {
     int ix = (int)roundf(x) + inset;
     if (ix < 0) {
         ix = 0;
     }
-    return static_cast<uint16>(ix);
+    return static_cast<uint16_t>(ix);
 }
 
-static void inval(NPP instance, const ANPRectF& r, bool doAA) {
-    const int inset = doAA ? -1 : 0;
-
-    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 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;
-        }
-    }
-}
 ///////////////////////////////////////////////////////////////////////////////
 
-BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) {
-    m_x = m_y = 0;
-    m_dx = 7 * SCALE;
-    m_dy = 5 * SCALE;
-
-    memset(&m_oval, 0, sizeof(m_oval));
-
-    m_paint = gPaintI.newPaint();
-    gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
-    gPaintI.setColor(m_paint, 0xFFFF0000);
-
+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() {
-    gPaintI.deletePaint(m_paint);
+    m_renderingThread->requestExitAndWait();
+    destroySurface();
 }
 
 bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) {
-    return (model == kBitmap_ANPDrawingModel);
+    return (model == kOpenGL_ANPDrawingModel);
 }
 
-void BallAnimation::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
+jobject BallAnimation::getSurface() {
 
-    // create a canvas
-    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
-
-    // clip the canvas
-    ANPRectF clipR;
-    clipR.left = clip.left;
-    clipR.top = clip.top;
-    clipR.right = clip.right;
-    clipR.bottom = clip.bottom;
-    gCanvasI.clipRect(canvas, &clipR);
-
-    // setup variables
-    PluginObject *obj = (PluginObject*) inst()->pdata;
-    const float OW = 20;
-    const float OH = 20;
-    const int W = obj->window->width;
-    const int H = obj->window->height;
-
-    // paint the canvas (using the path API)
-    gCanvasI.drawColor(canvas, 0xFFFFFFFF);
-    {
-        ANPPath* path = gPathI.newPath();
-
-        float cx = W * 0.5f;
-        float cy = H * 0.5f;
-        gPathI.moveTo(path, 0, 0);
-        gPathI.quadTo(path, cx, cy, W, 0);
-        gPathI.quadTo(path, cx, cy, W, H);
-        gPathI.quadTo(path, cx, cy, 0, H);
-        gPathI.quadTo(path, cx, cy, 0, 0);
-
-        gPaintI.setColor(m_paint, 0xFF0000FF);
-        gCanvasI.drawPath(canvas, path, m_paint);
-
-        ANPRectF bounds;
-        memset(&bounds, 0, sizeof(bounds));
-        gPathI.getBounds(path, &bounds);
-        gPathI.deletePath(path);
+    if (m_surface) {
+        return m_surface;
     }
 
-    // draw the oval
-    inval(inst(), m_oval, true);  // inval the old
-    m_oval.left = m_x;
-    m_oval.top = m_y;
-    m_oval.right = m_x + OW;
-    m_oval.bottom = m_y + OH;
-    inval(inst(), m_oval, true);  // inval the new
-    gPaintI.setColor(m_paint, 0xFFFF0000);
-    gCanvasI.drawOval(canvas, &m_oval, m_paint);
+    // 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;
+    }
 
-    // update the coordinates of the oval
-    bounce(&m_x, &m_dx, obj->window->width - OW);
-    bounce(&m_y, &m_dy, obj->window->height - OH);
+    const char* className = "com.android.sampleplugin.AnimationSurface";
+    jclass fullScreenClass = gSystemI.loadJavaClass(inst(), className);
 
-    // delete the canvas
-    gCanvasI.deleteCanvas(canvas);
+    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() {
@@ -173,23 +130,32 @@
     gWindowI.clearVisibleRects(instance);
 }
 
-int16 BallAnimation::handleEvent(const ANPEvent* evt) {
+int16_t BallAnimation::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);
+                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:
-                    break;   // unknown drawing model
+                    return 0;   // unknown drawing model
             }
         case kTouch_ANPEventType:
              if (kDown_ANPTouchAction == evt->data.touch.action) {
                  showEntirePluginOnScreen();
              }
-             return 1;
+            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;
     }
diff --git a/samples/BrowserPlugin/jni/animation/AnimationPlugin.h b/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
index ef2a3f54..870b67c 100644
--- a/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
+++ b/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008, The Android Open Source Project
+ * 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
@@ -24,29 +24,25 @@
  */
 
 #include "PluginObject.h"
+#include "AnimationThread.h"
 
 #ifndef pluginGraphics__DEFINED
 #define pluginGraphics__DEFINED
 
-class BallAnimation : public SubPlugin {
+class BallAnimation : public SurfaceSubPlugin {
 public:
     BallAnimation(NPP inst);
     virtual ~BallAnimation();
     virtual bool supportsDrawingModel(ANPDrawingModel);
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
+
+    virtual jobject getSurface();
 private:
-    void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
     void showEntirePluginOnScreen();
+    void destroySurface();
 
-    float m_x;
-    float m_y;
-    float m_dx;
-    float m_dy;
-
-    ANPRectF    m_oval;
-    ANPPaint*   m_paint;
-
-    static const float SCALE = 0.1;
+    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
index 9731f19..8defef4 100644
--- a/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp
+++ b/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp
@@ -44,12 +44,12 @@
     browser->invalidaterect(instance, NULL);
 }
 
-static uint16 rnd16(float x, int inset) {
+static uint16_t rnd16(float x, int inset) {
     int ix = (int)roundf(x) + inset;
     if (ix < 0) {
         ix = 0;
     }
-    return static_cast<uint16>(ix);
+    return static_cast<uint16_t>(ix);
 }
 
 static void inval(NPP instance, const ANPRectF& r, bool doAA) {
@@ -272,7 +272,7 @@
     return (input == m_activeRect) ? m_paintActiveRect : m_paintRect;
 }
 
-int16 AudioPlugin::handleEvent(const ANPEvent* evt) {
+int16_t AudioPlugin::handleEvent(const ANPEvent* evt) {
     NPP instance = this->inst();
 
     switch (evt->eventType) {
diff --git a/samples/BrowserPlugin/jni/audio/AudioPlugin.h b/samples/BrowserPlugin/jni/audio/AudioPlugin.h
index 129d33a..0f88a92 100644
--- a/samples/BrowserPlugin/jni/audio/AudioPlugin.h
+++ b/samples/BrowserPlugin/jni/audio/AudioPlugin.h
@@ -42,7 +42,7 @@
     AudioPlugin(NPP inst);
     virtual ~AudioPlugin();
     virtual bool supportsDrawingModel(ANPDrawingModel);
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
 private:
     void draw(ANPCanvas*);
     void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
index f749639..515acbe 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
@@ -179,7 +179,7 @@
     gSurfaceI.unlock(env, m_surface);
 }
 
-int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) {
+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());
@@ -233,10 +233,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #define TIMER_INTERVAL     50
-static void timer_oneshot(NPP instance, uint32 timerID);
-static void timer_repeat(NPP instance, uint32 timerID);
-static void timer_neverfires(NPP instance, uint32 timerID);
-static void timer_latency(NPP instance, uint32 timerID);
+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();
@@ -255,18 +255,18 @@
     browser->scheduletimer(instance, TIMER_INTERVAL, true, timer_latency);
     mStartTime = mPrevTime = getMSecs();
     // test unschedule immediately
-    uint32 id = browser->scheduletimer(instance, 100, false, timer_neverfires);
+    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 timerID) {
+static void timer_oneshot(NPP instance, uint32_t timerID) {
     gLogI.log(kDebug_ANPLogType, "-------- oneshot timer\n");
 }
 
-static void timer_repeat(NPP instance, uint32 timerID) {
+static void timer_repeat(NPP instance, uint32_t timerID) {
     BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
 
     gLogI.log(kDebug_ANPLogType, "-------- repeat timer %d\n",
@@ -276,11 +276,11 @@
     }
 }
 
-static void timer_neverfires(NPP instance, uint32 timerID) {
+static void timer_neverfires(NPP instance, uint32_t timerID) {
     gLogI.log(kError_ANPLogType, "-------- timer_neverfires!!!\n");
 }
 
-static void timer_latency(NPP instance, uint32 timerID) {
+static void timer_latency(NPP instance, uint32_t timerID) {
     BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
 
     obj->mTimerLatencyCurrentCount += 1;
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
index ebd77d1..e0b0597 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
@@ -32,7 +32,7 @@
 public:
     BackgroundPlugin(NPP inst);
     virtual ~BackgroundPlugin();
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
     virtual jobject getSurface();
 
     // Timer Testing Variables
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.cpp b/samples/BrowserPlugin/jni/form/FormPlugin.cpp
index 5a536d9..110afaa 100644
--- a/samples/BrowserPlugin/jni/form/FormPlugin.cpp
+++ b/samples/BrowserPlugin/jni/form/FormPlugin.cpp
@@ -43,12 +43,12 @@
     browser->invalidaterect(instance, NULL);
 }
 
-static uint16 rnd16(float x, int inset) {
+static uint16_t rnd16(float x, int inset) {
     int ix = (int)roundf(x) + inset;
     if (ix < 0) {
         ix = 0;
     }
-    return static_cast<uint16>(ix);
+    return static_cast<uint16_t>(ix);
 }
 
 static void inval(NPP instance, const ANPRectF& r, bool doAA) {
@@ -199,7 +199,7 @@
     }
 }
 
-int16 FormPlugin::handleEvent(const ANPEvent* evt) {
+int16_t FormPlugin::handleEvent(const ANPEvent* evt) {
     NPP instance = this->inst();
 
     switch (evt->eventType) {
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.h b/samples/BrowserPlugin/jni/form/FormPlugin.h
index 041ffb8..9f985a3 100644
--- a/samples/BrowserPlugin/jni/form/FormPlugin.h
+++ b/samples/BrowserPlugin/jni/form/FormPlugin.h
@@ -39,7 +39,7 @@
     FormPlugin(NPP inst);
     virtual ~FormPlugin();
     virtual bool supportsDrawingModel(ANPDrawingModel);
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
 private:
     void draw(ANPCanvas*);
     void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
diff --git a/samples/BrowserPlugin/jni/main.cpp b/samples/BrowserPlugin/jni/main.cpp
index 3e8fee7..a2dd667 100644
--- a/samples/BrowserPlugin/jni/main.cpp
+++ b/samples/BrowserPlugin/jni/main.cpp
@@ -41,19 +41,19 @@
 
 #define EXPORT __attribute__((visibility("default")))
 
-NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
+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* stype);
+        NPBool seekable, uint16_t* stype);
 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
-int32   NPP_WriteReady(NPP instance, NPStream* stream);
-int32   NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
+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   NPP_HandleEvent(NPP instance, void* event);
+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);
@@ -77,6 +77,7 @@
 ANPSystemInterfaceV0        gSystemI;
 ANPTypefaceInterfaceV0      gTypefaceI;
 ANPWindowInterfaceV0        gWindowI;
+ANPOpenGLInterfaceV0        gOpenGLI;
 
 #define ARRAY_COUNT(array)      (sizeof(array) / sizeof(array[0]))
 #define DEBUG_PLUGIN_EVENTS     0
@@ -125,6 +126,7 @@
         { kSystemInterfaceV0_ANPGetValue,       sizeof(gSystemI),   &gSystemI },
         { kTypefaceInterfaceV0_ANPGetValue,     sizeof(gTypefaceI), &gTypefaceI },
         { kWindowInterfaceV0_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;
@@ -151,7 +153,7 @@
     return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
 }
 
-NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc,
                 char* argn[], char* argv[], NPSavedData* saved)
 {
 
@@ -162,6 +164,7 @@
     if (browser->version >= 14) {
         instance->pdata = browser->createobject (instance, getPluginClass());
         obj = static_cast<PluginObject*>(instance->pdata);
+        obj->pluginType = 0;
     }
     /* END: STANDARD PLUGIN FRAMEWORK */
 
@@ -176,6 +179,9 @@
             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;
         }
@@ -228,7 +234,6 @@
                 obj->pluginType = kVideo_PluginType;
                 obj->activePlugin = new VideoPlugin(instance);
             }
-            gLogI.log(kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
             break;
         }
     }
@@ -240,6 +245,8 @@
         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);
@@ -247,7 +254,7 @@
     }
 
     // if the plugin uses the surface drawing model then set the java context
-    if (model == kSurface_ANPDrawingModel) {
+    if (model == kSurface_ANPDrawingModel || model == kOpenGL_ANPDrawingModel) {
         SurfaceSubPlugin* surfacePlugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
 
         jobject context;
@@ -290,7 +297,7 @@
     return NPERR_NO_ERROR;
 }
 
-NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
 {
     *stype = NP_ASFILEONLY;
     return NPERR_NO_ERROR;
@@ -301,12 +308,12 @@
     return NPERR_NO_ERROR;
 }
 
-int32 NPP_WriteReady(NPP instance, NPStream* stream)
+int32_t NPP_WriteReady(NPP instance, NPStream* stream)
 {
     return 0;
 }
 
-int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
+int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer)
 {
     return 0;
 }
@@ -319,7 +326,7 @@
 {
 }
 
-int16 NPP_HandleEvent(NPP instance, void* event)
+int16_t NPP_HandleEvent(NPP instance, void* event)
 {
     PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
     const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
@@ -434,7 +441,8 @@
         PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
         if (obj && obj->activePlugin) {
 
-            if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
+            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();
diff --git a/samples/BrowserPlugin/jni/main.h b/samples/BrowserPlugin/jni/main.h
index 66629e6..ebfb4b2 100644
--- a/samples/BrowserPlugin/jni/main.h
+++ b/samples/BrowserPlugin/jni/main.h
@@ -27,6 +27,7 @@
 #include <npfunctions.h>
 #include <npruntime.h>
 #include "android_npapi.h"
+#include "ANPOpenGL_npapi.h"
 #include "ANPSurface_npapi.h"
 #include "ANPSystem_npapi.h"
 
diff --git a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp
index 99667a4..01d9a79 100644
--- a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp
+++ b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp
@@ -43,12 +43,12 @@
     browser->invalidaterect(instance, NULL);
 }
 
-static uint16 rnd16(float x, int inset) {
+static uint16_t rnd16(float x, int inset) {
     int ix = (int)roundf(x) + inset;
     if (ix < 0) {
         ix = 0;
     }
-    return static_cast<uint16>(ix);
+    return static_cast<uint16_t>(ix);
 }
 
 static void inval(NPP instance, const ANPRectF& r, bool doAA) {
@@ -163,7 +163,7 @@
     return (input == m_activeNav) ? m_paintActive : m_paintDisabled;
 }
 
-int16 NavigationPlugin::handleEvent(const ANPEvent* evt) {
+int16_t NavigationPlugin::handleEvent(const ANPEvent* evt) {
     NPP instance = this->inst();
 
     switch (evt->eventType) {
diff --git a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h
index ca12ae7..c2044bb 100644
--- a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h
+++ b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h
@@ -33,7 +33,7 @@
 	NavigationPlugin(NPP inst);
     virtual ~NavigationPlugin();
     virtual bool supportsDrawingModel(ANPDrawingModel);
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
 private:
     void draw(ANPCanvas*);
     void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
index 71b9f24..abe6805 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
@@ -273,7 +273,7 @@
     }
 }
 
-int16 PaintPlugin::handleEvent(const ANPEvent* evt) {
+int16_t PaintPlugin::handleEvent(const ANPEvent* evt) {
     switch (evt->eventType) {
         case kTouch_ANPEventType: {
             float x = (float) evt->data.touch.x;
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.h b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
index 035e51b..ffdf624 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.h
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
@@ -33,7 +33,7 @@
 public:
     PaintPlugin(NPP inst);
     virtual ~PaintPlugin();
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
     virtual jobject getSurface();
 
 private:
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
index f24295b..bf3ab76 100644
--- a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
@@ -103,7 +103,7 @@
     }
 }
 
-int16 VideoPlugin::handleEvent(const ANPEvent* evt) {
+int16_t VideoPlugin::handleEvent(const ANPEvent* evt) {
     switch (evt->eventType) {
         case kLifecycle_ANPEventType: {
             switch (evt->data.lifecycle.action) {
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.h b/samples/BrowserPlugin/jni/video/VideoPlugin.h
index 701e2d0..fb15386 100644
--- a/samples/BrowserPlugin/jni/video/VideoPlugin.h
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.h
@@ -32,7 +32,7 @@
 public:
     VideoPlugin(NPP inst);
     virtual ~VideoPlugin();
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
     virtual jobject getSurface();
 
 private:
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/NFCDemo/Android.mk b/samples/CorpApp/Android.mk
similarity index 75%
rename from samples/NFCDemo/Android.mk
rename to samples/CorpApp/Android.mk
index 60815a2..37b98b0 100644
--- a/samples/NFCDemo/Android.mk
+++ b/samples/CorpApp/Android.mk
@@ -1,14 +1,12 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_STATIC_JAVA_LIBRARIES := guava
+LOCAL_MODULE_TAGS := samples
 
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := NFCDemo
+LOCAL_PACKAGE_NAME := CorpApp
 
 LOCAL_SDK_VERSION := current
 
@@ -16,3 +14,4 @@
 
 # Use the following include to make our test apk.
 include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/samples/CorpApp/AndroidManifest.xml b/samples/CorpApp/AndroidManifest.xml
new file mode 100644
index 0000000..22a3375
--- /dev/null
+++ b/samples/CorpApp/AndroidManifest.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.
+-->
+
+<!-- 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.corpapp">
+    <application android:label="CorporateDeviceAdminDemoApp">
+        <activity android:name="CorpAppActivity"
+                  android:label="@string/corp_app_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <receiver android:name=".app.CorpDeviceAdmin"
+                android:label="@string/corp_app_admin"
+                android:description="@string/corp_device_admin_description"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.corp_device_admin"
+                       android:resource="@xml/corp_device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/samples/CorpApp/res/layout/corp_app_activity.xml b/samples/CorpApp/res/layout/corp_app_activity.xml
new file mode 100644
index 0000000..e21e734
--- /dev/null
+++ b/samples/CorpApp/res/layout/corp_app_activity.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<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:gravity="center_horizontal"
+        android:layout_width="match_parent" android:layout_height="match_parent">
+
+        <TextView android:id="@+id/status_text"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:paddingBottom="4dip"
+            android:text="@string/corp_app_status_waiting_text"/>
+
+        <Button android:id="@+id/set_button"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="@string/corp_app_set_button_text"/>
+
+    </LinearLayout>
+</ScrollView>
+
diff --git a/samples/CorpApp/res/values/strings.xml b/samples/CorpApp/res/values/strings.xml
new file mode 100644
index 0000000..18ef549
--- /dev/null
+++ b/samples/CorpApp/res/values/strings.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.
+-->
+
+<resources>
+
+    <string name="corp_app_title_text">Corporate Demo App</string>
+    <string name="corp_app_set_button_text">Set Corp Global Proxy</string>
+    <string name="corp_app_status_success_text">Global Proxy successfully set</string>
+    <string name="corp_app_status_failed_text">Global Proxy could not be set.</string>
+    <string name="corp_app_status_waiting_text">Waiting to set Global Proxy...</string>
+    <string name="corp_app_proxy_name">proxy.corpapp.com:8080</string>
+    <string name="corp_app_proxy_excl_list">google.com,youtube.com</string>
+    <string name="corp_app_activity">Sample Corp App Activity</string>
+    <string name="corp_app_admin">Sample Corp App Device Admin</string>
+    <string name="corp_device_admin_description">Corporate device admin sample demo</string>
+
+</resources>
diff --git a/apps/Term/res/values/styles.xml b/samples/CorpApp/res/xml/corp_device_admin.xml
similarity index 68%
rename from apps/Term/res/values/styles.xml
rename to samples/CorpApp/res/xml/corp_device_admin.xml
index 0e59f4a..f464b60 100644
--- a/apps/Term/res/values/styles.xml
+++ b/samples/CorpApp/res/xml/corp_device_admin.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.
@@ -14,10 +14,11 @@
      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>
+<!-- BEGIN_INCLUDE(meta_data) -->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-policies>
+        <set-global-proxy />
+    </uses-policies>
+</device-admin>
+<!-- END_INCLUDE(meta_data) -->
 
diff --git a/samples/CorpApp/src/com/example/android/corpapp/CorpAppActivity.java b/samples/CorpApp/src/com/example/android/corpapp/CorpAppActivity.java
new file mode 100644
index 0000000..968fb55
--- /dev/null
+++ b/samples/CorpApp/src/com/example/android/corpapp/CorpAppActivity.java
@@ -0,0 +1,114 @@
+/*
+ * 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.corpapp;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A minimal Globl Proxy-setting corp app  application.
+ */
+public class CorpAppActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+
+    Button mSetButton;
+    TextView mStatusText;
+    String mProxyName;
+    String mProxyExclList;
+    String mSuccess;
+    String mFailure;
+
+    DevicePolicyManager mDPM;
+    ActivityManager mAM;
+    ComponentName mCorpDeviceAdmin;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mAM = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
+        mCorpDeviceAdmin = new ComponentName(CorpAppActivity.this, CorpDeviceAdmin.class);
+
+        // Set the layout for this activity.  You can find it
+        // in res/layout/corp_app_activity.xml
+        setContentView(R.layout.corp_app_activity);
+
+        mSetButton = (Button)findViewById(R.id.set_button);
+        mSetButton.setOnClickListener(mSetListener);
+        mStatusText = (Button)findViewById(R.id.status_text);
+
+        boolean active = mDPM.isAdminActive(mCorpDeviceAdmin);
+        mSetButton.setEnabled(active);
+        mProxyName = getResources().getString(R.string.corp_app_proxy_name);
+        mProxyExclList = getResources().getString(R.string.corp_app_proxy_excl_list);
+        mSuccess = getResources().getString(R.string.corp_app_status_success_text);
+        mFailure = getResources().getString(R.string.corp_app_status_failed_text);
+    }
+    
+    private OnClickListener mSetListener = new OnClickListener() {
+        public void onClick(View v) {
+            String[] proxyComponents = mProxyName.split(":");
+            if (proxyComponents.length != 2) {
+                Toast.makeText(CorpAppActivity.this, "Wrong proxy specification.",
+                        Toast.LENGTH_SHORT).show();
+                return;
+            }
+            Proxy instProxy = new Proxy(Proxy.Type.HTTP,
+                    new InetSocketAddress(proxyComponents[0],
+                            Integer.parseInt(proxyComponents[1])));
+            String[] listDoms = mProxyExclList.split(",");
+            if (listDoms.length == 0) {
+                Toast.makeText(CorpAppActivity.this, "Wrong exclusion list format.",
+                        Toast.LENGTH_SHORT).show();
+            }
+            List<String> exclList =  Arrays.asList(listDoms);
+            boolean active = mDPM.isAdminActive(mCorpDeviceAdmin);
+            if (active) {
+                mDPM.setGlobalProxy(mCorpDeviceAdmin, instProxy, exclList);
+                ComponentName proxyAdmin = mDPM.getGlobalProxyAdmin();
+                if ((proxyAdmin != null) && (proxyAdmin.equals(mCorpDeviceAdmin))) {
+                    Toast.makeText(CorpAppActivity.this, "Global Proxy set by device admin.",
+                            Toast.LENGTH_SHORT).show();
+                    mStatusText.setText(mSuccess);
+                } else {
+                    Toast.makeText(CorpAppActivity.this, "Failed to set Global Proxy.",
+                            Toast.LENGTH_SHORT).show();
+                    mStatusText.setText(mFailure);
+                }
+            }
+        }
+    };
+
+}
+
diff --git a/samples/CorpApp/src/com/example/android/corpapp/CorpDeviceAdmin.java b/samples/CorpApp/src/com/example/android/corpapp/CorpDeviceAdmin.java
new file mode 100644
index 0000000..f1a83d6
--- /dev/null
+++ b/samples/CorpApp/src/com/example/android/corpapp/CorpDeviceAdmin.java
@@ -0,0 +1,64 @@
+/*
+ * 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.corpapp;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.widget.Toast;
+
+public class CorpDeviceAdmin extends DeviceAdminReceiver {
+
+    static SharedPreferences getSamplePreferences(Context context) {
+        return context.getSharedPreferences(DeviceAdminReceiver.class.getName(), 0);
+    }
+
+    void showToast(Context context, CharSequence msg) {
+        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+    }
+
+    @Override
+    public void onEnabled(Context context, Intent intent) {
+        showToast(context, "Sample Corp Device Admin: enabled");
+    }
+
+    @Override
+    public CharSequence onDisableRequested(Context context, Intent intent) {
+        return "Sample Corp Device Admin: disable requested";
+    }
+
+    @Override
+    public void onDisabled(Context context, Intent intent) {
+        showToast(context, "Sample Corp Device Admin: disabled");
+    }
+
+    @Override
+    public void onPasswordChanged(Context context, Intent intent) {
+        showToast(context, "Sample Corp Device Admin: pw changed");
+    }
+
+    @Override
+    public void onPasswordFailed(Context context, Intent intent) {
+        showToast(context, "Sample Corp Device Admin: pw failed");
+    }
+
+    @Override
+    public void onPasswordSucceeded(Context context, Intent intent) {
+        showToast(context, "Sample Corp Device Admin: pw succeeded");
+    }
+}
diff --git a/samples/NFCDemo/AndroidManifest.xml b/samples/NFCDemo/AndroidManifest.xml
deleted file mode 100644
index 044690b..0000000
--- a/samples/NFCDemo/AndroidManifest.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- 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.nfc"
->
-    <uses-permission android:name="android.permission.NFC" />
-    <uses-permission android:name="android.permission.CALL_PHONE" />
-    <application
-        android:icon="@drawable/icon"
-        android:label="@string/app_name"
-    >
-    <activity android:name=".simulator.FakeTagsActivity"
-        android:theme="@android:style/Theme.NoTitleBar">
-        <intent-filter>
-            <action android:name="android.intent.action.MAIN" />
-            <category android:name="android.intent.category.LAUNCHER" />
-        </intent-filter>
-    </activity>
-        <activity android:name="TagViewer"
-            android:theme="@android:style/Theme.NoTitleBar"
-        >
-            <intent-filter>
-                <action android:name="android.nfc.action.TAG_DISCOVERED"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-        </activity>
-    </application>
-    <uses-sdk android:minSdkVersion="9" />
-    <uses-feature android:name="android.hardware.nfc" android:required="true" />
-</manifest>
diff --git a/samples/NFCDemo/_index.html b/samples/NFCDemo/_index.html
deleted file mode 100644
index d1c53f1..0000000
--- a/samples/NFCDemo/_index.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<p>
-  Near-field Communication or NFC is a standard defined by the
-  <a href=http://www.nfc-forum.org/home>NFC Forum
-  </a>.
-  NFC Data Exchange Format (NDEF) defines a common data format between NFC-compliant devices and tags.
-  This demo application shows how to read a NDEF Tags using using Android 2.3 SDK APIs.
-  The NFC Tags consist of data encoded in NDEF Message format specified by NFC Forum Type 2 Specification.
-  Each NDEF message consists of one or more NDEF Records.
-
-  You need a NFC compliant device and a NFC compliant Tag to use this sample app. Or else, you could use
-  the FakeTagsActivity displayed at launch of this sample app, to generate fake Tag broadcasts from the emulator.
-</p>
-
-<p>The application includes:
-</p>
-  <ul>
-    <li>
-      <a href="src/com/example/android/nfc/TagViewer.html">
-        <code>TagViewer
-        </code>
-      </a>
-      &mdash; an
-      <code>Activity
-      </code> that handles a broadcast of a new tag that the device
-      just discovered, parses it, and displays its record contents in a
-      <code>ListActivity
-      </code>
-    </li>
-    <li>
-      <a href="src/com/example/android/nfc/NdefMessageParser.html">
-        <code> NdefMessageParser
-        </code>
-      </a>
-      &mdash; parses the record type of records within the NDEF message.
-    </li>
-    <li>
-      <a href="src/com/example/android/nfc/record/ParsedNdefRecord.html">
-        <code>ParsedNdefRecord
-        </code>
-      </a>
-      &mdash; an interface implemented by all parsed NdefRecord types.
-    </li>
-    <li>
-      <a href="src/com/example/android/nfc/record/SmartPoster.html">
-        <code>SmartPoster
-        </code>
-      </a>
-      &mdash; a representation of an NFC Forum Smart Poster Record Type.
-    </li>
-    <li>
-      <a href="src/com/example/android/nfc/record/TextRecord.html">
-        <code>TextRecord
-        </code>
-      </a>
-      &mdash; a representation of an NFC Forum Text Record Type.
-    </li>
-    <li>
-      <a href="src/com/example/android/nfc/record/UriRecord.html">
-        <code>UriRecord
-        </code>
-      </a>
-      &mdash; a representation of an NFC Forum Uri Record Type.
-    </li>
-    <li>
-      <a href="src/com/example/android/nfc/simulator/FakeTagsActivity.html">
-        <code>FakeTagsActivity
-        </code>
-      </a>
-      &mdash; A activity that launches tags as if they had been scanned.
-      This is useful if you don't have access to NFC enabled device or tag.
-    </li>
-    <li>
-      <a href="src/com/example/android/nfc/simulator/MockNdefMessages.html">
-        <code>MockNdefMessages
-        </code>
-      </a>
-      &mdash; this class provides a list of fake NFC Ndef format Tags.
-    </li>
-
-  </ul>
-<p>If you are developing an application that uses the NFC API, remember that the feature
-  is supported only on Android 2.3 (API level 9) and higher versions of the platform. Also,
-  among devices running Android 2.3 (API level 9) or higher, not all devices will offer NFC
-  support. To ensure that your application can only be installed on devices that are capable
-  of supporting NFC, remember to add the following to the application's manifest before
-  publishing to Android Market:
-</p>
-<ul>
-  <li>
-    <code>&lt;uses-sdk android:minSdkVersion="9" /&gt;
-    </code>,
-    which indicates to Android Market and the platform that your application requires
-    Android 2.3 or higher. For more information, see
-    <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>
-<p>To control how Android Market filters your application
-  from devices that do not support NFC, remember to add the following to the application's manifest
-  <ul>
-    <li>
-      <code>&lt;uses-feature android:name="android.hardware.nfc" /&gt;
-      </code>,
-      which tells Android Market that your application uses the NFC API. The declaration
-      should include an
-      <code>android:required
-      </code> attribute that indicates whether you want
-      Android Market to filter the application from devices that do not offer NFC support. Other
-      <code>&lt;uses-feature&gt;
-      </code> declarations may also be needed, depending on your
-      implementation. For more information, see the documentation for the
-      <a href="../../../guide/topics/manifest/uses-feature-element.html">
-        <code>&lt;uses-feature&gt;
-        </code>
-      </a> element.
-    </li>
-  </ul>
-<p>For more information about using the NFC API, see the
-  <a href="../../../reference/android/nfc/package-summary.html">
-    <code>android.nfc</code>
-    </a>
-   documentation.
-</p>
-<img alt="" src="../images/NfcDemo.png"/>
diff --git a/samples/NFCDemo/res/drawable/icon.png b/samples/NFCDemo/res/drawable/icon.png
deleted file mode 100644
index a07c69f..0000000
--- a/samples/NFCDemo/res/drawable/icon.png
+++ /dev/null
Binary files differ
diff --git a/samples/NFCDemo/res/layout/tag_text.xml b/samples/NFCDemo/res/layout/tag_text.xml
deleted file mode 100644
index 59cbbfb..0000000
--- a/samples/NFCDemo/res/layout/tag_text.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/text"
-    android:layout_width="match_parent"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:layout_height="wrap_content"
-    android:padding="4dip"
-    android:textAppearance="?android:attr/textAppearanceMedium"
-    android:maxLines="5"
-    android:ellipsize="end"
-    android:gravity="center_vertical"
-/>
\ No newline at end of file
diff --git a/samples/NFCDemo/res/layout/tag_viewer.xml b/samples/NFCDemo/res/layout/tag_viewer.xml
deleted file mode 100644
index a429ef9..0000000
--- a/samples/NFCDemo/res/layout/tag_viewer.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent" android:layout_height="match_parent"
-    android:orientation="vertical">
-    <!-- Title -->
-    <TextView android:id="@+id/title" android:layout_width="wrap_content"
-        android:layout_height="wrap_content" android:singleLine="true"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textStyle="bold" android:shadowColor="#BB000000"
-        android:shadowRadius="2.75" android:gravity="center_vertical" />
-    <!-- Content -->
-    <ScrollView android:layout_width="match_parent"
-        android:layout_height="0dip" android:layout_weight="1">
-        <LinearLayout android:id="@+id/list" android:layout_width="match_parent"
-            android:layout_height="wrap_content" android:orientation="vertical" />
-    </ScrollView>
-</LinearLayout>
\ No newline at end of file
diff --git a/samples/NFCDemo/res/raw/discovered_tag_notification.ogg b/samples/NFCDemo/res/raw/discovered_tag_notification.ogg
deleted file mode 100755
index 7bf5df7..0000000
--- a/samples/NFCDemo/res/raw/discovered_tag_notification.ogg
+++ /dev/null
Binary files differ
diff --git a/samples/NFCDemo/src/com/example/android/nfc/NdefMessageParser.java b/samples/NFCDemo/src/com/example/android/nfc/NdefMessageParser.java
deleted file mode 100644
index 7372810..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/NdefMessageParser.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.nfc;
-
-import android.nfc.NdefMessage;
-import android.nfc.NdefRecord;
-
-import com.example.android.nfc.record.ParsedNdefRecord;
-import com.example.android.nfc.record.SmartPoster;
-import com.example.android.nfc.record.TextRecord;
-import com.example.android.nfc.record.UriRecord;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility class for creating {@link ParsedNdefMessage}s.
- */
-public class NdefMessageParser {
-
-    // Utility class
-    private NdefMessageParser() {
-
-    }
-
-    /** Parse an NdefMessage */
-    public static List<ParsedNdefRecord> parse(NdefMessage message) {
-        return getRecords(message.getRecords());
-    }
-
-    public static List<ParsedNdefRecord> getRecords(NdefRecord[] records) {
-        List<ParsedNdefRecord> elements = new ArrayList<ParsedNdefRecord>();
-        for (NdefRecord record : records) {
-            if (UriRecord.isUri(record)) {
-                elements.add(UriRecord.parse(record));
-            } else if (TextRecord.isText(record)) {
-                elements.add(TextRecord.parse(record));
-            } else if (SmartPoster.isPoster(record)) {
-                elements.add(SmartPoster.parse(record));
-            }
-        }
-        return elements;
-    }
-}
diff --git a/samples/NFCDemo/src/com/example/android/nfc/TagViewer.java b/samples/NFCDemo/src/com/example/android/nfc/TagViewer.java
deleted file mode 100644
index 01dc0bd..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/TagViewer.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.example.android.nfc;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.nfc.NdefMessage;
-import android.nfc.NdefRecord;
-import android.nfc.NfcAdapter;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.example.android.nfc.record.ParsedNdefRecord;
-
-import java.util.List;
-
-/**
- * An {@link Activity} which handles a broadcast of a new tag that the device
- * just discovered.
- */
-public class TagViewer extends Activity {
-
-    static final String TAG = "ViewTag";
-
-    /**
-     * This activity will finish itself in this amount of time if the user
-     * doesn't do anything.
-     */
-    static final int ACTIVITY_TIMEOUT_MS = 1 * 1000;
-
-    TextView mTitle;
-
-    LinearLayout mTagContent;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.tag_viewer);
-        mTagContent = (LinearLayout) findViewById(R.id.list);
-        mTitle = (TextView) findViewById(R.id.title);
-        resolveIntent(getIntent());
-    }
-
-    void resolveIntent(Intent intent) {
-        // Parse the intent
-        String action = intent.getAction();
-        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
-            // When a tag is discovered we send it to the service to be save. We
-            // include a PendingIntent for the service to call back onto. This
-            // will cause this activity to be restarted with onNewIntent(). At
-            // that time we read it from the database and view it.
-            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
-            NdefMessage[] msgs;
-            if (rawMsgs != null) {
-                msgs = new NdefMessage[rawMsgs.length];
-                for (int i = 0; i < rawMsgs.length; i++) {
-                    msgs[i] = (NdefMessage) rawMsgs[i];
-                }
-            } else {
-                // Unknown tag type
-                byte[] empty = new byte[] {};
-                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
-                NdefMessage msg = new NdefMessage(new NdefRecord[] {record});
-                msgs = new NdefMessage[] {msg};
-            }
-            // Setup the views
-            setTitle(R.string.title_scanned_tag);
-            buildTagViews(msgs);
-        } else {
-            Log.e(TAG, "Unknown intent " + intent);
-            finish();
-            return;
-        }
-    }
-
-    void buildTagViews(NdefMessage[] msgs) {
-        if (msgs == null || msgs.length == 0) {
-            return;
-        }
-        LayoutInflater inflater = LayoutInflater.from(this);
-        LinearLayout content = mTagContent;
-        // Clear out any old views in the content area, for example if you scan
-        // two tags in a row.
-        content.removeAllViews();
-        // Parse the first message in the list
-        // Build views for all of the sub records
-        List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]);
-        final int size = records.size();
-        for (int i = 0; i < size; i++) {
-            ParsedNdefRecord record = records.get(i);
-            content.addView(record.getView(this, inflater, content, i));
-            inflater.inflate(R.layout.tag_divider, content, true);
-        }
-    }
-
-    @Override
-    public void onNewIntent(Intent intent) {
-        setIntent(intent);
-        resolveIntent(intent);
-    }
-
-    @Override
-    public void setTitle(CharSequence title) {
-        mTitle.setText(title);
-    }
-}
diff --git a/samples/NFCDemo/src/com/example/android/nfc/record/ParsedNdefRecord.java b/samples/NFCDemo/src/com/example/android/nfc/record/ParsedNdefRecord.java
deleted file mode 100644
index b706ae8..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/record/ParsedNdefRecord.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.nfc.record;
-
-import android.app.Activity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-
-public interface ParsedNdefRecord {
-
-    /**
-     * Returns a view to display this record.
-     */
-    public View getView(Activity activity, LayoutInflater inflater, ViewGroup parent,
-            int offset);
-
-}
diff --git a/samples/NFCDemo/src/com/example/android/nfc/record/SmartPoster.java b/samples/NFCDemo/src/com/example/android/nfc/record/SmartPoster.java
deleted file mode 100644
index f86d3ef..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/record/SmartPoster.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.example.android.nfc.record;
-
-import android.app.Activity;
-import android.nfc.FormatException;
-import android.nfc.NdefMessage;
-import android.nfc.NdefRecord;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.LinearLayout;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-import com.example.android.nfc.NdefMessageParser;
-import com.example.android.nfc.R;
-
-import java.util.Arrays;
-import java.util.NoSuchElementException;
-
-/**
- * A representation of an NFC Forum "Smart Poster".
- */
-public class SmartPoster implements ParsedNdefRecord {
-
-    /**
-     * NFC Forum Smart Poster Record Type Definition section 3.2.1.
-     *
-     * "The Title record for the service (there can be many of these in
-     * different languages, but a language MUST NOT be repeated). This record is
-     * optional."
-     */
-    private final TextRecord mTitleRecord;
-
-    /**
-     * NFC Forum Smart Poster Record Type Definition section 3.2.1.
-     *
-     * "The URI record. This is the core of the Smart Poster, and all other
-     * records are just metadata about this record. There MUST be one URI record
-     * and there MUST NOT be more than one."
-     */
-    private final UriRecord mUriRecord;
-
-    /**
-     * NFC Forum Smart Poster Record Type Definition section 3.2.1.
-     *
-     * "The Action record. This record describes how the service should be
-     * treated. For example, the action may indicate that the device should save
-     * the URI as a bookmark or open a browser. The Action record is optional.
-     * If it does not exist, the device may decide what to do with the service.
-     * If the action record exists, it should be treated as a strong suggestion;
-     * the UI designer may ignore it, but doing so will induce a different user
-     * experience from device to device."
-     */
-    private final RecommendedAction mAction;
-
-    /**
-     * NFC Forum Smart Poster Record Type Definition section 3.2.1.
-     *
-     * "The Type record. If the URI references an external entity (e.g., via a
-     * URL), the Type record may be used to declare the MIME type of the entity.
-     * This can be used to tell the mobile device what kind of an object it can
-     * expect before it opens the connection. The Type record is optional."
-     */
-    private final String mType;
-
-    private SmartPoster(UriRecord uri, TextRecord title, RecommendedAction action, String type) {
-        mUriRecord = Preconditions.checkNotNull(uri);
-        mTitleRecord = title;
-        mAction = Preconditions.checkNotNull(action);
-        mType = type;
-    }
-
-    public UriRecord getUriRecord() {
-        return mUriRecord;
-    }
-
-    /**
-     * Returns the title of the smart poster. This may be {@code null}.
-     */
-    public TextRecord getTitle() {
-        return mTitleRecord;
-    }
-
-    public static SmartPoster parse(NdefRecord record) {
-        Preconditions.checkArgument(record.getTnf() == NdefRecord.TNF_WELL_KNOWN);
-        Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.RTD_SMART_POSTER));
-        try {
-            NdefMessage subRecords = new NdefMessage(record.getPayload());
-            return parse(subRecords.getRecords());
-        } catch (FormatException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    public static SmartPoster parse(NdefRecord[] recordsRaw) {
-        try {
-            Iterable<ParsedNdefRecord> records = NdefMessageParser.getRecords(recordsRaw);
-            UriRecord uri = Iterables.getOnlyElement(Iterables.filter(records, UriRecord.class));
-            TextRecord title = getFirstIfExists(records, TextRecord.class);
-            RecommendedAction action = parseRecommendedAction(recordsRaw);
-            String type = parseType(recordsRaw);
-            return new SmartPoster(uri, title, action, type);
-        } catch (NoSuchElementException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    public static boolean isPoster(NdefRecord record) {
-        try {
-            parse(record);
-            return true;
-        } catch (IllegalArgumentException e) {
-            return false;
-        }
-    }
-
-    public View getView(Activity activity, LayoutInflater inflater, ViewGroup parent, int offset) {
-        if (mTitleRecord != null) {
-            // Build a container to hold the title and the URI
-            LinearLayout container = new LinearLayout(activity);
-            container.setOrientation(LinearLayout.VERTICAL);
-            container.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.WRAP_CONTENT));
-            container.addView(mTitleRecord.getView(activity, inflater, container, offset));
-            inflater.inflate(R.layout.tag_divider, container);
-            container.addView(mUriRecord.getView(activity, inflater, container, offset));
-            return container;
-        } else {
-            // Just a URI, return a view for it directly
-            return mUriRecord.getView(activity, inflater, parent, offset);
-        }
-    }
-
-    /**
-     * Returns the first element of {@code elements} which is an instance of
-     * {@code type}, or {@code null} if no such element exists.
-     */
-    private static <T> T getFirstIfExists(Iterable<?> elements, Class<T> type) {
-        Iterable<T> filtered = Iterables.filter(elements, type);
-        T instance = null;
-        if (!Iterables.isEmpty(filtered)) {
-            instance = Iterables.get(filtered, 0);
-        }
-        return instance;
-    }
-
-    private enum RecommendedAction {
-        UNKNOWN((byte) -1), DO_ACTION((byte) 0), SAVE_FOR_LATER((byte) 1), OPEN_FOR_EDITING(
-            (byte) 2);
-
-        private static final ImmutableMap<Byte, RecommendedAction> LOOKUP;
-        static {
-            ImmutableMap.Builder<Byte, RecommendedAction> builder = ImmutableMap.builder();
-            for (RecommendedAction action : RecommendedAction.values()) {
-                builder.put(action.getByte(), action);
-            }
-            LOOKUP = builder.build();
-        }
-
-        private final byte mAction;
-
-        private RecommendedAction(byte val) {
-            this.mAction = val;
-        }
-
-        private byte getByte() {
-            return mAction;
-        }
-    }
-
-    private static NdefRecord getByType(byte[] type, NdefRecord[] records) {
-        for (NdefRecord record : records) {
-            if (Arrays.equals(type, record.getType())) {
-                return record;
-            }
-        }
-        return null;
-    }
-
-    private static final byte[] ACTION_RECORD_TYPE = new byte[] {'a', 'c', 't'};
-
-    private static RecommendedAction parseRecommendedAction(NdefRecord[] records) {
-        NdefRecord record = getByType(ACTION_RECORD_TYPE, records);
-        if (record == null) {
-            return RecommendedAction.UNKNOWN;
-        }
-        byte action = record.getPayload()[0];
-        if (RecommendedAction.LOOKUP.containsKey(action)) {
-            return RecommendedAction.LOOKUP.get(action);
-        }
-        return RecommendedAction.UNKNOWN;
-    }
-
-    private static final byte[] TYPE_TYPE = new byte[] {'t'};
-
-    private static String parseType(NdefRecord[] records) {
-        NdefRecord type = getByType(TYPE_TYPE, records);
-        if (type == null) {
-            return null;
-        }
-        return new String(type.getPayload(), Charsets.UTF_8);
-    }
-}
diff --git a/samples/NFCDemo/src/com/example/android/nfc/record/TextRecord.java b/samples/NFCDemo/src/com/example/android/nfc/record/TextRecord.java
deleted file mode 100644
index 8041cca..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/record/TextRecord.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.nfc.record;
-
-import android.app.Activity;
-import android.nfc.NdefRecord;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.google.common.base.Preconditions;
-
-import com.example.android.nfc.R;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-
-/**
- * An NFC Text Record
- */
-public class TextRecord implements ParsedNdefRecord {
-
-    /** ISO/IANA language code */
-    private final String mLanguageCode;
-
-    private final String mText;
-
-    private TextRecord(String languageCode, String text) {
-        mLanguageCode = Preconditions.checkNotNull(languageCode);
-        mText = Preconditions.checkNotNull(text);
-    }
-
-    public View getView(Activity activity, LayoutInflater inflater, ViewGroup parent, int offset) {
-        TextView text = (TextView) inflater.inflate(R.layout.tag_text, parent, false);
-        text.setText(mText);
-        return text;
-    }
-
-    public String getText() {
-        return mText;
-    }
-
-    /**
-     * Returns the ISO/IANA language code associated with this text element.
-     */
-    public String getLanguageCode() {
-        return mLanguageCode;
-    }
-
-    // TODO: deal with text fields which span multiple NdefRecords
-    public static TextRecord parse(NdefRecord record) {
-        Preconditions.checkArgument(record.getTnf() == NdefRecord.TNF_WELL_KNOWN);
-        Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.RTD_TEXT));
-        try {
-            byte[] payload = record.getPayload();
-            /*
-             * payload[0] contains the "Status Byte Encodings" field, per the
-             * NFC Forum "Text Record Type Definition" section 3.2.1.
-             *
-             * bit7 is the Text Encoding Field.
-             *
-             * if (Bit_7 == 0): The text is encoded in UTF-8 if (Bit_7 == 1):
-             * The text is encoded in UTF16
-             *
-             * Bit_6 is reserved for future use and must be set to zero.
-             *
-             * Bits 5 to 0 are the length of the IANA language code.
-             */
-            String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
-            int languageCodeLength = payload[0] & 0077;
-            String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
-            String text =
-                new String(payload, languageCodeLength + 1,
-                    payload.length - languageCodeLength - 1, textEncoding);
-            return new TextRecord(languageCode, text);
-        } catch (UnsupportedEncodingException e) {
-            // should never happen unless we get a malformed tag.
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    public static boolean isText(NdefRecord record) {
-        try {
-            parse(record);
-            return true;
-        } catch (IllegalArgumentException e) {
-            return false;
-        }
-    }
-}
diff --git a/samples/NFCDemo/src/com/example/android/nfc/record/UriRecord.java b/samples/NFCDemo/src/com/example/android/nfc/record/UriRecord.java
deleted file mode 100644
index 452ebb2..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/record/UriRecord.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.example.android.nfc.record;
-
-import android.app.Activity;
-import android.net.Uri;
-import android.nfc.NdefRecord;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.primitives.Bytes;
-
-import com.example.android.nfc.R;
-
-import java.nio.charset.Charset;
-import java.util.Arrays;
-
-/**
- * A parsed record containing a Uri.
- */
-public class UriRecord implements ParsedNdefRecord {
-
-    private static final String TAG = "UriRecord";
-
-    public static final String RECORD_TYPE = "UriRecord";
-
-    /**
-     * NFC Forum "URI Record Type Definition"
-     *
-     * This is a mapping of "URI Identifier Codes" to URI string prefixes,
-     * per section 3.2.2 of the NFC Forum URI Record Type Definition document.
-     */
-    private static final BiMap<Byte, String> URI_PREFIX_MAP = ImmutableBiMap.<Byte, String>builder()
-            .put((byte) 0x00, "")
-            .put((byte) 0x01, "http://www.")
-            .put((byte) 0x02, "https://www.")
-            .put((byte) 0x03, "http://")
-            .put((byte) 0x04, "https://")
-            .put((byte) 0x05, "tel:")
-            .put((byte) 0x06, "mailto:")
-            .put((byte) 0x07, "ftp://anonymous:anonymous@")
-            .put((byte) 0x08, "ftp://ftp.")
-            .put((byte) 0x09, "ftps://")
-            .put((byte) 0x0A, "sftp://")
-            .put((byte) 0x0B, "smb://")
-            .put((byte) 0x0C, "nfs://")
-            .put((byte) 0x0D, "ftp://")
-            .put((byte) 0x0E, "dav://")
-            .put((byte) 0x0F, "news:")
-            .put((byte) 0x10, "telnet://")
-            .put((byte) 0x11, "imap:")
-            .put((byte) 0x12, "rtsp://")
-            .put((byte) 0x13, "urn:")
-            .put((byte) 0x14, "pop:")
-            .put((byte) 0x15, "sip:")
-            .put((byte) 0x16, "sips:")
-            .put((byte) 0x17, "tftp:")
-            .put((byte) 0x18, "btspp://")
-            .put((byte) 0x19, "btl2cap://")
-            .put((byte) 0x1A, "btgoep://")
-            .put((byte) 0x1B, "tcpobex://")
-            .put((byte) 0x1C, "irdaobex://")
-            .put((byte) 0x1D, "file://")
-            .put((byte) 0x1E, "urn:epc:id:")
-            .put((byte) 0x1F, "urn:epc:tag:")
-            .put((byte) 0x20, "urn:epc:pat:")
-            .put((byte) 0x21, "urn:epc:raw:")
-            .put((byte) 0x22, "urn:epc:")
-            .put((byte) 0x23, "urn:nfc:")
-            .build();
-
-    private final Uri mUri;
-
-    private UriRecord(Uri uri) {
-        this.mUri = Preconditions.checkNotNull(uri);
-    }
-
-    public View getView(Activity activity, LayoutInflater inflater, ViewGroup parent, int offset) {
-        TextView text = (TextView) inflater.inflate(R.layout.tag_text, parent, false);
-        text.setText(mUri.toString());
-        return text;
-    }
-
-    public Uri getUri() {
-        return mUri;
-    }
-
-    /**
-     * Convert {@link android.nfc.NdefRecord} into a {@link android.net.Uri}.
-     * This will handle both TNF_WELL_KNOWN / RTD_URI and TNF_ABSOLUTE_URI.
-     *
-     * @throws IllegalArgumentException if the NdefRecord is not a record
-     *         containing a URI.
-     */
-    public static UriRecord parse(NdefRecord record) {
-        short tnf = record.getTnf();
-        if (tnf == NdefRecord.TNF_WELL_KNOWN) {
-            return parseWellKnown(record);
-        } else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) {
-            return parseAbsolute(record);
-        }
-        throw new IllegalArgumentException("Unknown TNF " + tnf);
-    }
-
-    /** Parse and absolute URI record */
-    private static UriRecord parseAbsolute(NdefRecord record) {
-        byte[] payload = record.getPayload();
-        Uri uri = Uri.parse(new String(payload, Charset.forName("UTF-8")));
-        return new UriRecord(uri);
-    }
-
-    /** Parse an well known URI record */
-    private static UriRecord parseWellKnown(NdefRecord record) {
-        Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.RTD_URI));
-        byte[] payload = record.getPayload();
-        /*
-         * payload[0] contains the URI Identifier Code, per the
-         * NFC Forum "URI Record Type Definition" section 3.2.2.
-         *
-         * payload[1]...payload[payload.length - 1] contains the rest of
-         * the URI.
-         */
-        String prefix = URI_PREFIX_MAP.get(payload[0]);
-        byte[] fullUri =
-            Bytes.concat(prefix.getBytes(Charset.forName("UTF-8")), Arrays.copyOfRange(payload, 1,
-                payload.length));
-        Uri uri = Uri.parse(new String(fullUri, Charset.forName("UTF-8")));
-        return new UriRecord(uri);
-    }
-
-    public static boolean isUri(NdefRecord record) {
-        try {
-            parse(record);
-            return true;
-        } catch (IllegalArgumentException e) {
-            return false;
-        }
-    }
-
-    private static final byte[] EMPTY = new byte[0];
-}
diff --git a/samples/NFCDemo/src/com/example/android/nfc/simulator/FakeTagsActivity.java b/samples/NFCDemo/src/com/example/android/nfc/simulator/FakeTagsActivity.java
deleted file mode 100644
index 313bab4..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/simulator/FakeTagsActivity.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.example.android.nfc.simulator;
-
-import android.app.ListActivity;
-import android.content.Intent;
-import android.nfc.NdefMessage;
-import android.nfc.NdefRecord;
-import android.nfc.NfcAdapter;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import com.google.common.primitives.Bytes;
-
-import java.nio.charset.Charset;
-import java.util.Locale;
-
-/**
- * A activity that launches tags as if they had been scanned.
- */
-public class FakeTagsActivity extends ListActivity {
-
-    static final String TAG = "FakeTagsActivity";
-
-    static final byte[] UID = new byte[] {0x05, 0x00, 0x03, 0x08};
-
-    ArrayAdapter<TagDescription> mAdapter;
-
-    public static NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
-        Preconditions.checkNotNull(text);
-        Preconditions.checkNotNull(locale);
-        final byte[] langBytes = locale.getLanguage().getBytes(Charsets.US_ASCII);
-        final Charset utfEncoding = encodeInUtf8 ? Charsets.UTF_8 : Charset.forName("UTF-16");
-        final byte[] textBytes = text.getBytes(utfEncoding);
-        final int utfBit = encodeInUtf8 ? 0 : (1 << 7);
-        final char status = (char) (utfBit + langBytes.length);
-        final byte[] data = Bytes.concat(new byte[] {(byte) status}, langBytes, textBytes);
-        return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
-    }
-
-    public static NdefRecord newMimeRecord(String type, byte[] data) {
-        Preconditions.checkNotNull(type);
-        Preconditions.checkNotNull(data);
-        final byte[] typeBytes = type.getBytes(Charsets.US_ASCII);
-        return new NdefRecord(NdefRecord.TNF_MIME_MEDIA, typeBytes, new byte[0], data);
-    }
-
-    static final class TagDescription {
-
-        public String title;
-
-        public NdefMessage[] msgs;
-
-        public TagDescription(String title, byte[] bytes) {
-            this.title = title;
-            try {
-                msgs = new NdefMessage[] {new NdefMessage(bytes)};
-            } catch (final Exception e) {
-                throw new RuntimeException("Failed to create tag description", e);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return title;
-        }
-    }
-
-    @Override
-    public void onCreate(Bundle savedState) {
-        super.onCreate(savedState);
-        final ArrayAdapter<TagDescription> adapter = new ArrayAdapter<TagDescription>(
-            this, android.R.layout.simple_list_item_1, android.R.id.text1);
-        adapter.add(
-            new TagDescription("Broadcast NFC Text Tag", MockNdefMessages.ENGLISH_PLAIN_TEXT));
-        adapter.add(new TagDescription(
-            "Broadcast NFC SmartPoster URL & text", MockNdefMessages.SMART_POSTER_URL_AND_TEXT));
-        adapter.add(new TagDescription(
-            "Broadcast NFC SmartPoster URL", MockNdefMessages.SMART_POSTER_URL_NO_TEXT));
-        setListAdapter(adapter);
-        mAdapter = adapter;
-    }
-
-    @Override
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        final TagDescription description = mAdapter.getItem(position);
-        final Intent intent = new Intent(NfcAdapter.ACTION_TAG_DISCOVERED);
-        intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, description.msgs);
-        startActivity(intent);
-    }
-}
diff --git a/samples/NFCDemo/src/com/example/android/nfc/simulator/MockNdefMessages.java b/samples/NFCDemo/src/com/example/android/nfc/simulator/MockNdefMessages.java
deleted file mode 100644
index 52a122f..0000000
--- a/samples/NFCDemo/src/com/example/android/nfc/simulator/MockNdefMessages.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.example.android.nfc.simulator;
-
-/**
- * This class provides a list of fake NFC Ndef format Tags.
- */
-public class MockNdefMessages {
-
-    /**
-     * A Smart Poster containing a URL and no text.
-     */
-    public static final byte[] SMART_POSTER_URL_NO_TEXT =
-        new byte[] {(byte) 0xd1, (byte) 0x02, (byte) 0x0f, (byte) 0x53, (byte) 0x70, (byte) 0xd1,
-            (byte) 0x01, (byte) 0x0b, (byte) 0x55, (byte) 0x01, (byte) 0x67, (byte) 0x6f,
-            (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63,
-            (byte) 0x6f, (byte) 0x6d};
-
-    /**
-     * A plain text tag in english.
-     */
-    public static final byte[] ENGLISH_PLAIN_TEXT =
-        new byte[] {(byte) 0xd1, (byte) 0x01, (byte) 0x1c, (byte) 0x54, (byte) 0x02, (byte) 0x65,
-            (byte) 0x6e, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x20,
-            (byte) 0x72, (byte) 0x61, (byte) 0x6e, (byte) 0x64, (byte) 0x6f, (byte) 0x6d,
-            (byte) 0x20, (byte) 0x65, (byte) 0x6e, (byte) 0x67, (byte) 0x6c, (byte) 0x69,
-            (byte) 0x73, (byte) 0x68, (byte) 0x20, (byte) 0x74, (byte) 0x65, (byte) 0x78,
-            (byte) 0x74, (byte) 0x2e};
-
-    /**
-     * Smart Poster containing a URL and Text.
-     */
-    public static final byte[] SMART_POSTER_URL_AND_TEXT =
-        new byte[] {(byte) 0xd1, (byte) 0x02, (byte) 0x1c, (byte) 0x53, (byte) 0x70, (byte) 0x91,
-            (byte) 0x01, (byte) 0x09, (byte) 0x54, (byte) 0x02, (byte) 0x65, (byte) 0x6e,
-            (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65,
-            (byte) 0x51, (byte) 0x01, (byte) 0x0b, (byte) 0x55, (byte) 0x01, (byte) 0x67,
-            (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
-            (byte) 0x63, (byte) 0x6f, (byte) 0x6d};
-
-    /**
-     * All the mock Ndef tags.
-     */
-    public static final byte[][] ALL_MOCK_MESSAGES =
-        new byte[][] {SMART_POSTER_URL_NO_TEXT, ENGLISH_PLAIN_TEXT, SMART_POSTER_URL_AND_TEXT};
-}
diff --git a/samples/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
index 83e5732..ddf4818 100644
--- a/samples/NotePad/AndroidManifest.xml
+++ b/samples/NotePad/AndroidManifest.xml
@@ -22,15 +22,17 @@
 <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="Froyo" />
     <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 +52,27 @@
         </activity>
 
         <activity android:name="NoteEditor"
-            android:theme="@android:style/Theme.Light"
-            android:configChanges="keyboardHidden|orientation">
+            android:theme="@android:style/Theme.Light.Holo"
+            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 +81,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 a54ea9d..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 78222ea..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..ce385a6 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="always" />
+    <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="always" />
 </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..a3b8b38 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.getItem(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..8f0b2cb 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,123 @@
         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
+                    null,                               // icon 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/NotePadTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
similarity index 91%
rename from samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
rename to samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
index 80f71d2..6a66ebb 100644
--- a/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
@@ -17,19 +17,18 @@
 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> {
+public class NotePadActivityTest extends ActivityInstrumentationTestCase2<NotesList> {
 
     /**
      * Creates an {@link ActivityInstrumentationTestCase2} for the {@link NotesList} activity.
      */
-    public NotePadTest() {
+    public NotePadActivityTest() {
         super(NotesList.class);
     }
 
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/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/XmlAdapters/Android.mk b/samples/XmlAdapters/Android.mk
new file mode 100644
index 0000000..3224bbe
--- /dev/null
+++ b/samples/XmlAdapters/Android.mk
@@ -0,0 +1,17 @@
+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 := XmlAdaptersSample
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+# XXX These APIs are not yet available in the platform.
+#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/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..973fe4b
--- /dev/null
+++ b/samples/XmlAdapters/res/layout/contacts_list.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.
+-->
+
+ 
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <ListView
+        android:id="@android:id/list"
+        android:adapter="@xml/contacts"
+        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/NFCDemo/res/values/strings.xml b/samples/XmlAdapters/res/values/strings.xml
similarity index 62%
rename from samples/NFCDemo/res/values/strings.xml
rename to samples/XmlAdapters/res/values/strings.xml
index 251d2f6..1ae158e 100644
--- a/samples/NFCDemo/res/values/strings.xml
+++ b/samples/XmlAdapters/res/values/strings.xml
@@ -4,25 +4,23 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-
+  
           http://www.apache.org/licenses/LICENSE-2.0
-
+  
      Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
+     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">
-
-    <!-- The title of the NFC tag application -->
-    <string name="app_name">NFCDemo</string>
-
-    <!-- The title for the activity that shows a tag that was just scanned -->
-    <string name="title_scanned_tag">New tag collected</string>
-
-    <!-- Heading for the text of the content in the "my tag" feature. -->
-    <string name="tag_text">Text</string>
+    <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..02cfbca
--- /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"
+  android:uri="content://com.android.contacts/contacts"
+  android:selection="has_phone_number=1"
+  android:layout="@layout/contact_item">
+
+  <bind android:from="display_name" android:to="@id/name" android:as="string" />
+    <bind android:from="starred" android:to="@id/star" android:as="drawable">
+        <map android:fromValue="0" android:toValue="@android:drawable/star_big_off" />
+        <map android:fromValue="1" android:toValue="@android:drawable/star_big_on" />
+    </bind>
+    <bind android:from="_id" android:to="@id/name"
+          android:as="com.example.android.xmladapters.ContactPhotoBinder" />
+
+</cursor-adapter>
diff --git a/samples/NFCDemo/res/values/strings.xml b/samples/XmlAdapters/res/xml/photos.xml
similarity index 60%
copy from samples/NFCDemo/res/values/strings.xml
copy to samples/XmlAdapters/res/xml/photos.xml
index 251d2f6..a62e62e 100644
--- a/samples/NFCDemo/res/values/strings.xml
+++ b/samples/XmlAdapters/res/xml/photos.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,15 +14,12 @@
      limitations under the License.
 -->
 
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<cursor-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+    android:selection="/feed/entry"
+    android:layout="@layout/photo_item">
 
-    <!-- The title of the NFC tag application -->
-    <string name="app_name">NFCDemo</string>
+    <bind android:from="/summary" android:to="@id/title" android:as="string" />
+    <bind android:from="/media:group/media:thumbnail\@url" android:to="@id/photo"
+      android:as="com.example.android.xmladapters.UrlImageBinder" />
 
-    <!-- The title for the activity that shows a tag that was just scanned -->
-    <string name="title_scanned_tag">New tag collected</string>
-
-    <!-- Heading for the text of the content in the "my tag" feature. -->
-    <string name="tag_text">Text</string>
-
-</resources>
+</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..a5f09f11
--- /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"
+    android:selection="/rss/channel/item"
+    android:layout="@layout/rss_feed_item">
+
+    <bind android:from="/title" android:to="@id/title" android:as="string" />
+    <bind android:from="/media:content@url" android:to="@id/image"
+      android:as="com.example.android.xmladapters.UrlImageBinder"/>
+    <bind android:from="/media:description" android:to="@id/description" android:as="string" />
+    <bind android:from="/guid" android:to="@id/item_layout" android:as="tag" />
+    <bind android:from="/pubDate" android:to="@id/date" android:as="string">
+       <transform android:withExpression="Published on {/pubDate}." />
+    </bind>
+
+</cursor-adapter>
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..a5d556f
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/ContactPhotoBinder.java
@@ -0,0 +1,97 @@
+/*
+ * 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.Adapters;
+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..bf5ab58
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/ContactsListActivity.java
@@ -0,0 +1,35 @@
+/*
+ * 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);
+    }
+}
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..1da151d
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/PhotosListActivity.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.app.ListActivity;
+import android.net.Uri;
+import android.os.Bundle;
+import android.widget.Adapters;
+
+/**
+ * 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..fb3e4c1
--- /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.Adapters;
+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..33b1e8e
--- /dev/null
+++ b/samples/XmlAdapters/src/com/example/android/xmladapters/UrlImageBinder.java
@@ -0,0 +1,48 @@
+/*
+ * 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.Adapters;
+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 2afedc5..36e6131 100644
--- a/samples/source.properties
+++ b/samples/source.properties
@@ -1,5 +1,4 @@
 Pkg.UserSrc=false
 Pkg.Revision=1
 AndroidVersion.ApiLevel=9
-#AndroidVersion.CodeName=gingerbread
-
+AndroidVersion.CodeName=Froyo
diff --git a/sdk/doc_source.properties b/sdk/doc_source.properties
index 4418853..9b85b82 100644
--- a/sdk/doc_source.properties
+++ b/sdk/doc_source.properties
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
 Pkg.Revision=1
-AndroidVersion.ApiLevel=9
-#AndroidVersion.CodeName=
+AndroidVersion.ApiLevel=8
+AndroidVersion.CodeName=Froyo
 
diff --git a/sdk/platform_source.properties b/sdk/platform_source.properties
index 6dadea5..5134b61 100644
--- a/sdk/platform_source.properties
+++ b/sdk/platform_source.properties
@@ -1,6 +1,6 @@
-Pkg.Desc=Android SDK Platform 2.3_r1
+Pkg.Desc=Android SDK Platform 2.x_r1
 Pkg.UserSrc=false
-Platform.Version=2.3
+Platform.Version=2.x
 Pkg.Revision=1
-AndroidVersion.ApiLevel=9
-#AndroidVersion.CodeName=
+AndroidVersion.ApiLevel=8
+AndroidVersion.CodeName=Froyo
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/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 f83d32d..de0b272 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -218,6 +218,13 @@
     coverage_target="framework"
     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"
@@ -395,12 +402,14 @@
 <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"
@@ -499,6 +508,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/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%
rename from apps/GraphicsLab/MODULE_LICENSE_APACHE2
rename 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/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..62238f0
--- /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.monkey property"
+  adb_command shell setprop ro.monkey 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");
-    }
-}