am d5e77d5e: am 3ceb9b53: Merge "Update OBB sample to revised API" into gingerbread

Merge commit 'd5e77d5e56aa584e2bf21349f3d11918a15d594c'

* commit 'd5e77d5e56aa584e2bf21349f3d11918a15d594c':
  Update OBB sample to revised API
diff --git a/apps/Development/AndroidManifest.xml b/apps/Development/AndroidManifest.xml
index c809554..827b57a 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" />
@@ -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/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/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/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/build/sdk.atree b/build/sdk.atree
index 3765929..5893bdf 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -166,6 +166,7 @@
 development/samples/VoiceRecognitionService  samples/${PLATFORM_NAME}/VoiceRecognitionService
 development/samples/TicTacToeLib             samples/${PLATFORM_NAME}/TicTacToeLib
 development/samples/TicTacToeMain            samples/${PLATFORM_NAME}/TicTacToeMain
+development/samples/XmlAdapters              samples/${PLATFORM_NAME}/XmlAdapters
 development/samples/CrossCompatibility       samples/${PLATFORM_NAME}/CrossCompatibility
 
 # NOTICE files are copied by build/core/Makefile from sdk.git
diff --git a/build/tools/windows_sdk.mk b/build/tools/windows_sdk.mk
index 9609160..057f1fc 100644
--- a/build/tools/windows_sdk.mk
+++ b/build/tools/windows_sdk.mk
@@ -38,7 +38,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/host/windows/usb/android_winusb.inf b/host/windows/usb/android_winusb.inf
index b2daf89..331ed6d 100755
--- a/host/windows/usb/android_winusb.inf
+++ b/host/windows/usb/android_winusb.inf
@@ -38,14 +38,31 @@
 %CompositeAdbInterface%     = USB_Install, USB\VID_22B8&PID_41DB&MI_01

 ;

 ;Google NexusOne

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_0D02
+%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_0D02

 %CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_0D02&MI_01

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4E11
-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E12&MI_01
+%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4E11

+%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E12&MI_01

 %CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E22&MI_01

-;
-; Dell's Mini5
-%CompositeAdbInterface%     = USB_Install, USB\VID_413C&PID_B007&MI_01
+;

+; Dell's Mini5

+%SingleAdbInterface%        = USB_Install, USB\VID_413C&PID_B007

+%CompositeAdbInterface%     = USB_Install, USB\VID_413C&PID_B007&MI_01

+;

+; Samsung SPH-M900, GT-I5700, SCH-R880

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_681C

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_681C&MI_01

+; Samsung GT-I7500

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_6601

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_6601&MI_01

+; Samsung GT-I5500

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_6882

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_6882&MI_01

+; Samsung SHW-M100S

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_6850

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_6850&MI_01

+; Samsung SHW-M110S

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_681D

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_681D&MI_01

 

 [Google.NTamd64]

 ; HTC Dream

@@ -61,13 +78,30 @@
 ;

 ;Google NexusOne

 %SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_0D02

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_0D02&MI_01
+%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_0D02&MI_01

 %SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4E11

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E12&MI_01
+%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E12&MI_01

 %CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E22&MI_01

-;
-; Dell's Mini5
-%CompositeAdbInterface%     = USB_Install, USB\VID_413C&PID_B007&MI_01
+;

+; Dell's Mini5

+%SingleAdbInterface%        = USB_Install, USB\VID_413C&PID_B007

+%CompositeAdbInterface%     = USB_Install, USB\VID_413C&PID_B007&MI_01

+;

+; Samsung SPH-M900, GT-I5700, SCH-R880

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_681C

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_681C&MI_01

+; Samsung GT-I7500

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_6601

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_6601&MI_01

+; Samsung GT-I5500

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_6882

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_6882&MI_01

+; Samsung SHW-M100S

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_6850

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_6850&MI_01

+; Samsung SHW-M110S

+%SingleAdbInterface%        = USB_Install, USB\VID_04E8&PID_681D

+%CompositeAdbInterface%     = USB_Install, USB\VID_04E8&PID_681D&MI_01

 

 [USB_Install]

 Include = winusb.inf

diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index 1994220..759960a 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -28,7 +28,6 @@
 	<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"/>
@@ -36,6 +35,7 @@
 	<classpathentry kind="src" path="frameworks/base/core/java"/>
 	<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
 	<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 +51,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 +69,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,22 +78,28 @@
 	<classpathentry kind="src" path="out/target/common/obj/APPS/CalendarProvider_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/ContactsProvider_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/Email_intermediates/src/src"/>
+	<classpathentry kind="src" path="out/target/common/obj/APPS/Launcher2_intermediates/src/renderscript/src"/>
+	<classpathentry kind="src" path="out/target/common/obj/APPS/MediaProvider_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/Music_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/Phone_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/QuickSearchBox_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/location/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/renderscript/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/voip/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/vpn/java"/>
 	<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..b65156d
--- /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>Currently the only permitted value for
+<code>android.os.Build.VERSION.RELEASE</code> for Android 2.2 is the string
+"2.2".</p>
+<ul>
+<li>2.2</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-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..5a64082 100644
--- a/pdk/docs/compatibility/compatibility_toc.cs
+++ b/pdk/docs/compatibility/compatibility_toc.cs
@@ -7,12 +7,12 @@
 <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.2-cdd.pdf">Current CDD</a></li>
     <li><a href="<?cs var:toroot ?>compatibility/cts-intro.html">CTS Introduction</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-intro.jd b/pdk/docs/compatibility/cts-intro.jd
index f1d2359..f158ca8 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 > Accessibility > Accessibility > 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..953c868
--- /dev/null
+++ b/pdk/docs/compatibility/downloads.jd
@@ -0,0 +1,48 @@
+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.2</h2>
+<p>Android 2.2 is the release of the development milestone code-named
+FroYo. Android 2.2 is the current version of Android. 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_r3-x86.zip">Android 2.2 R3 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..3664693 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.2, which roughly
+corresponded to the FroYo 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..4786ed5 100644
--- a/pdk/docs/index.jd
+++ b/pdk/docs/index.jd
@@ -1,7 +1,22 @@
 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 Tools for Android 2.2</b><br/>
+The compatibility tools for Android 2.2 have been published. This includes the
+Compatibility Definition Document for Android 2.2, and the Compatibility Test
+Suite version 2.2 r1. With these tools, device manufacturers can finalize
+builds of Android 2.2 for new and existing devices. For more information,
+<a href="{@docRoot}compatibility/index.html">visit the Compatibility page.</a>
+</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.</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 +27,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 329deff..c786bdc 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>
@@ -298,6 +272,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..7cb593c 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>
+<p><i>Note: this page will be updated to cover Android 2.2 when the
+formal compatibility program for Android 2.2 is launched, which will occur in
+the near future.</i></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/Alarm/AndroidManifest.xml b/samples/Alarm/AndroidManifest.xml
new file mode 100644
index 0000000..6a7a831
--- /dev/null
+++ b/samples/Alarm/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?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.
+-->
+
+<!--
+    Declares the contents of this Android application. The xmlns:android
+    attribute brings in the Android platform namespace, and the
+    "package" attribute provides a unique name for the application.
+    If you use this file as a template in your own application, you must change
+    the package name from "com.example.android" to one that you own or have
+    control over.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.newalarm"
+    android:versionCode="2"
+    android:versionName="2.0">
+    <!--
+        Declares the application, its icon, and its visible label
+     -->
+    <application
+        android:icon="@drawable/icon"
+        android:label="@string/app_name">
+        <!--
+            Declares the activity's class name and visible label. The leading "." indicates
+            that the name should be preceded by the application's Android package name.
+         -->
+        <activity
+            android:name=".AlarmActivity"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <service
+            android:name=".AlarmService"
+            android:label="@string/alarm_service"
+            android:process="com.example.android.newalarm">
+        </service>
+    </application>
+    <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
+</manifest>
diff --git a/samples/Alarm/_index.html b/samples/Alarm/_index.html
new file mode 100644
index 0000000..dff51ce
--- /dev/null
+++ b/samples/Alarm/_index.html
@@ -0,0 +1,29 @@
+<p>
+    This sample is a revised version of the AlarmService functionality included in the
+    ApiDemos sample application. It is used as the application under test
+    for the <a href="../AlarmServiceTest/index.html">Alarm Service Test</a>
+    sample test application.
+</p>
+<p>
+    This application demonstrates a simple Android service that is started when needed by
+    <code>Context.startService(Intent)</code> and stops itself when its work is done. You can
+    use this type of service to move long-running or periodic tasks into the background. For
+    example, you could use this type of service to perform data synchronization.
+</p>
+<p>
+    In the sample, the service simply runs for 15 seconds and then stops itself. The wait is
+    implemented in a separate thread that uses a thread-safe object. This illustrates how to
+    set up a service that runs multiple threads that depend on one or more objects that must be
+    made thread-safe.
+</p>
+<p>
+    The application also contains the <code>AlarmActivity</code> activity that is a client of the
+    service. You use the activity to control when the service starts and stops. By default, the
+    activity fires off the service every thirty seconds. In effect, the service starts after
+    thirty seconds, runs for 15 seconds, stops, and then runs again automatically in another
+    15 seconds. You also use the client to stop this cycle.
+</p>
+<p>
+    The test application <a href="tests/index.html">AlarmServiceTest</a>
+    shows you how to set up a test of this service.
+</p>
diff --git a/samples/Alarm/res/drawable/icon.png b/samples/Alarm/res/drawable/icon.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/samples/Alarm/res/drawable/icon.png
Binary files differ
diff --git a/samples/Alarm/res/drawable/stat_sample.png b/samples/Alarm/res/drawable/stat_sample.png
new file mode 100755
index 0000000..6c9ba0a
--- /dev/null
+++ b/samples/Alarm/res/drawable/stat_sample.png
Binary files differ
diff --git a/samples/Alarm/res/layout/main.xml b/samples/Alarm/res/layout/main.xml
new file mode 100644
index 0000000..3d79e2b
--- /dev/null
+++ b/samples/Alarm/res/layout/main.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.
+-->
+
+<!-- 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="fill_parent"
+    android:layout_height="fill_parent">
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/alarm_service"/>
+    <Button android:id="@+id/start_alarm"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/start_alarm_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/stop_alarm"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/stop_alarm_service" />
+</LinearLayout>
+
diff --git a/samples/Alarm/res/values/strings.xml b/samples/Alarm/res/values/strings.xml
new file mode 100644
index 0000000..18a34cc
--- /dev/null
+++ b/samples/Alarm/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <string name="app_name">Alarm</string>
+    <string name="alarm_service">
+        This shows how to schedule a repeating alarm that starts a service.</string>
+    <string name="start_alarm_service">Start Alarm Service</string>
+    <string name="stop_alarm_service">Stop Alarm Service</string>
+    <string name="repeating_started">
+        Repeating timer started. Starts AlarmService every 30 seconds.</string>
+    <string name="alarm_service_started">The sample service is running.</string>
+    <string name="alarm_service_label">Sample Alarm Service</string>
+    <string name="alarm_service_finished">The sample service is no longer running.</string>
+    <string name="repeating_stopped">
+        Repeating timer stopped. AlarmService will no longer be started.</string>
+</resources>
diff --git a/samples/Alarm/src/com/example/android/newalarm/AlarmActivity.java b/samples/Alarm/src/com/example/android/newalarm/AlarmActivity.java
new file mode 100644
index 0000000..d26507d
--- /dev/null
+++ b/samples/Alarm/src/com/example/android/newalarm/AlarmActivity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.newalarm;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+/**
+ * This is the activity that controls AlarmService.
+ * <p>
+ * When the user clicks the "Start Alarm Service" button, it triggers a repeating countdown
+ * timer. Every thirty seconds, the timer starts AlarmService, which then runs for 15 seconds
+ * and shuts itself down.
+ * </p>
+ * <p>
+ * When the user clicks the "Stop Alarm Service" button, it stops the countdown timer.
+ * </p>
+ */
+
+public class AlarmActivity extends Activity {
+    // 30 seconds in milliseconds
+    private static final long THIRTY_SECONDS_MILLIS = 30 * 1000;
+
+    // An intent for AlarmService, to trigger it as if the Activity called startService().
+    private PendingIntent mAlarmSender;
+
+    // Contains a handle to the system alarm service
+    private AlarmManager mAlarmManager;
+
+    /**
+     * This method is called when Android starts the activity. It initializes the UI.
+     * <p>
+     * This method is automatically called when Android starts the Activity
+     * </p>
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create a PendingIntent to trigger a startService() for AlarmService
+        mAlarmSender = PendingIntent.getService(  // set up an intent for a call to a service
+            AlarmActivity.this,  // the current context
+            0,  // request code (not used)
+            new Intent(AlarmActivity.this, AlarmService.class),  // A new Service intent
+            0   // flags (none are required for a service)
+        );
+
+        // Creates the main view
+        setContentView(R.layout.main);
+
+        // Finds the button that starts the repeating countdown timer
+        Button button = (Button)findViewById(R.id.start_alarm);
+
+        // Sets the listener for the start button
+        button.setOnClickListener(mStartAlarmListener);
+
+        // Finds the button that stops countdown timer
+        button = (Button)findViewById(R.id.stop_alarm);
+
+        // Sets the listener for the stop button
+        button.setOnClickListener(mStopAlarmListener);
+
+        // Gets the handle to the system alarm service
+        mAlarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
+    }
+
+    // Creates a new anonymous click listener for the start button. It starts the repeating
+    //  countdown timer.
+    private OnClickListener mStartAlarmListener = new OnClickListener() {
+        // Sets the callback for when the button is clicked
+        public void onClick(View v) {
+
+            // Sets the time when the alarm will first go off
+            // The Android AlarmManager uses this form of the current time.
+            long firstAlarmTime = SystemClock.elapsedRealtime();
+
+            // Sets a repeating countdown timer that triggers AlarmService
+            mAlarmManager.setRepeating(
+                AlarmManager.ELAPSED_REALTIME_WAKEUP, // based on time since last wake up
+                firstAlarmTime,  // sends the first alarm immediately
+                THIRTY_SECONDS_MILLIS,  // repeats every thirty seconds
+                mAlarmSender  // when the alarm goes off, sends this Intent
+            );
+
+            // Notifies the user that the repeating countdown timer has been started
+            Toast.makeText(
+                AlarmActivity.this,  //  the current context
+                R.string.repeating_started,  // the message to display
+                Toast.LENGTH_LONG  // how long to display the message
+            ).show();  // show the message on the screen
+        }
+    };
+
+    // Creates a new anonymous click listener for the stop button. It shuts off the repeating
+    // countdown timer.
+    private OnClickListener mStopAlarmListener = new OnClickListener() {
+        // Sets the callback for when the button is clicked
+        public void onClick(View v) {
+
+            // Cancels the repeating countdown timer
+            mAlarmManager.cancel(mAlarmSender);
+
+            // Notifies the user that the repeating countdown timer has been stopped
+            Toast.makeText(
+                AlarmActivity.this,  //  the current context
+                R.string.repeating_stopped,  // the message to display
+                Toast.LENGTH_LONG  // how long to display the message
+            ).show(); // display the message
+        }
+    };
+}
diff --git a/samples/Alarm/src/com/example/android/newalarm/AlarmService.java b/samples/Alarm/src/com/example/android/newalarm/AlarmService.java
new file mode 100644
index 0000000..1f88206
--- /dev/null
+++ b/samples/Alarm/src/com/example/android/newalarm/AlarmService.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.newalarm;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.widget.Toast;
+
+/**
+ * <p>
+ * This class implements a service. The service is started by AlarmActivity, which contains a
+ * repeating countdown timer that sends a PendingIntent. The user starts and stops the timer with
+ * buttons in the UI.
+ * </p>
+ * <p>
+ * When this service is started, it creates a Runnable and starts it in a new Thread. The
+ * Runnable does a synchronized lock on the service's Binder object for 15 seconds, then issues
+ * a stopSelf(). The net effect is a new worker thread that takes 15 seconds to run and then
+ * shuts down the entire service. The activity restarts the service after 15 more seconds, when the
+ * countdown timer triggers again.
+ * </p>
+ * <p>
+ * This service is provided as the service under test for the sample test application
+ * AlarmServiceTest.
+ * </p>
+ * <p>
+ * Note: Since this sample is based on the Android 1.5 platform, it does not implement
+ * onStartCommand. See the Javadoc for android.app.Service for more details.
+ * </p>
+ */
+public class AlarmService extends Service {
+    // Defines a label for the thread that this service starts
+    private static final String ALARM_SERVICE_THREAD = "AlarmService";
+
+    // Defines 15 seconds
+    public static final long WAIT_TIME_SECONDS = 15;
+
+    // Define the number of milliseconds in one second
+    public static final long MILLISECS_PER_SEC = 1000;
+
+    /*
+     * For testing purposes, the following variables are defined as fields and set to
+     * package visibility.
+     */
+
+    // The NotificationManager used to send notifications to the status bar.
+    NotificationManager mNotificationManager;
+
+    // An Intent that displays the client if the user clicks the notification.
+    PendingIntent mContentIntent;
+
+    // A Notification to send to the Notification Manager when the service is started.
+    Notification mNotification;
+
+    // A Binder, used as the lock object for the worker thread.
+    IBinder mBinder = new AlarmBinder();
+
+    // A Thread object that will run the background task
+    Thread mWorkThread;
+
+    // The Runnable that is the service's "task". This illustrates how a service is used to
+    // offload work from a client.
+    Runnable mWorkTask = new Runnable() {
+        public void run() {
+            // Sets the wait time to 15 seconds, simulating a 15-second background task.
+            long waitTime = System.currentTimeMillis() + WAIT_TIME_SECONDS * MILLISECS_PER_SEC;
+
+            // Puts the wait in a while loop to ensure that it actually waited 15 seconds.
+            // This covers the situation where an interrupt might have overridden the wait.
+            while (System.currentTimeMillis() < waitTime) {
+                // Waits for 15 seconds or interruption
+                synchronized (mBinder) {
+                    try {
+                        // Waits for 15 seconds or until an interrupt triggers an exception.
+                        // If an interrupt occurs, the wait is recalculated to ensure a net
+                        // wait of 15 seconds.
+                        mBinder.wait(waitTime - System.currentTimeMillis());
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+            // Stops the current service. In response, Android calls onDestroy().
+            stopSelf();
+        }
+    };
+
+    /**
+     *  Makes a full concrete subclass of Binder, rather than doing it in line, for readability.
+     */
+    public class AlarmBinder extends Binder {
+        // Constructor. Calls the super constructor to set up the instance.
+        public AlarmBinder() {
+            super();
+        }
+
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+            throws RemoteException {
+
+            // Call the parent method with the arguments passed in
+            return super.onTransact(code, data, reply, flags);
+        }
+    }
+
+    /**
+     * Initializes the service when it is first started by a call to startService() or
+     * bindService().
+     */
+    @Override
+    public void onCreate() {
+        // Gets a handle to the system mNotification service.
+        mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+        // Updates the status bar to indicate that this service is running.
+        showNotification();
+
+        // Creates a new thread. A new thread is used so that the service's work doesn't block
+        // anything on the calling client's thread. By default, a service runs in the same
+        // process and thread as the client that starts it.
+        mWorkThread = new Thread(
+            null,  // threadgroup (in this case, null)
+            mWorkTask, // the Runnable that will run in this thread
+            ALARM_SERVICE_THREAD
+        );
+        // Starts the thread
+        mWorkThread.start();
+    }
+
+    /**
+     * Stops the service in response to the stopSelf() issued when the wait is over. Other
+     * clients that use this service could stop it by issuing a stopService() or a stopSelf() on
+     * the service object.
+     */
+    @Override
+    public void onDestroy() {
+        // Cancels the status bar mNotification based on its ID, which is set in showNotification().
+        mNotificationManager.cancel(R.string.alarm_service_started);
+
+        // Sends a notification to the screen.
+        Toast.makeText(
+            this,  // the current context
+            R.string.alarm_service_finished,  // the message to show
+            Toast.LENGTH_LONG   // how long to keep the message on the screen
+        ).show();  // show the text
+    }
+
+    // Returns the service's binder object to clients that issue onBind().
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    /**
+     * Displays a notification in the status bar that this service is running. This method
+     * also creates an Intent for the AlarmActivity client and attaches it to the notification
+     * line. If the user clicks the line in the expanded status window, the Intent triggers
+     * AlarmActivity.
+     */
+    private void showNotification() {
+        // Sets the text to use for the status bar and status list views.
+        CharSequence notificationText = getText(R.string.alarm_service_started);
+
+        // Sets the icon, status bar text, and display time for the mNotification.
+        mNotification = new Notification(
+            R.drawable.stat_sample,  // the status icon
+            notificationText, // the status text
+            System.currentTimeMillis()  // the time stamp
+        );
+
+        // Sets up the Intent that starts AlarmActivity
+        mContentIntent = PendingIntent.getActivity(
+            this,  // Start the Activity in the current context
+            0,   // not used
+            new Intent(this, AlarmActivity.class),  // A new Intent for AlarmActivity
+            0  // Use an existing activity instance if available
+        );
+
+        // Creates a new content view for the mNotification. The view appears when the user
+        // shows the expanded status window.
+        mNotification.setLatestEventInfo(
+            this,  //  Put the content view in the current context
+            getText(R.string.alarm_service_label),  // The text to use as the label of the entry
+            notificationText,  // The text to use as the contents of the entry
+            mContentIntent  // The intent to send when the entry is clicked
+        );
+
+        // Sets a unique ID for the notification and sends it to NotificationManager to be
+        // displayed. The ID is the integer marker for the notification string, which is
+        // guaranteed to be unique within the entire application.
+        mNotificationManager.notify(
+            R.string.alarm_service_started,  // unique id for the mNotification
+            mNotification   // the mNotification object
+        );
+    }
+}
diff --git a/samples/Alarm/tests/AndroidManifest.xml b/samples/Alarm/tests/AndroidManifest.xml
new file mode 100644
index 0000000..8688920
--- /dev/null
+++ b/samples/Alarm/tests/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?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 test package. The xmlns:android
+    attribute brings in the Android platform namespace, and the
+    "package" attribute provides a unique name for the package.
+    If you use this file as a template in your own test package, you must change
+    the package name from "com.example.android" to one that you own or have
+    control over.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.newalarm.test"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <!--
+        Must use the application element to include the uses-library element.
+     -->
+    <application>
+        <!--
+            Tells Android to include this library in the test package's class loader.
+            The test runner is not included by default in a manifest file.
+        -->
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <!--
+        Specifies that the test package requires API platform level 3 (Android 1.5) or above.
+        The installer will not install this package onto a device or emulator that is running an
+        older platform version.
+     -->
+    <uses-sdk android:minSdkVersion="3" />
+    <!--
+        Declares the instrumentation for this application. The instrumentation class is
+        specified by the "name" attribute, and must name a subclass of
+        android.app.Instrumentation. The application that is run by the instrumentation object is
+        specified by the "targetPackage" attribute.
+     -->
+    <instrumentation
+        android:targetPackage="com.example.android.newalarm"
+        android:name="android.test.InstrumentationTestRunner" />
+</manifest>
diff --git a/samples/Alarm/tests/_index.html b/samples/Alarm/tests/_index.html
new file mode 100644
index 0000000..614125d
--- /dev/null
+++ b/samples/Alarm/tests/_index.html
@@ -0,0 +1,50 @@
+<p>
+    This sample is the test application for the <a href="../Alarm/index.html">Alarm</a>
+    sample application. It tests the application's <code>AlarmService</code> service.
+</p>
+<p>
+    The test application uses the
+    <a href="../../../reference/android/test/ServiceTestCase.html">
+    <code>ServiceTestCase</code></a>  test case class,
+    which extends the JUnit <a href="../../../reference/junit/framework/TestCase.html">
+    <code>TestCase</code></a> class. The test runner is
+    <a href="../../../reference/android/test/InstrumentationTestRunner.html">
+    <code>InstrumentationTestRunner</code></a>.
+</p>
+<p>
+    The application shows how to set up a test application project,
+    how to create the <a href="AndroidManifest.html"><code>AndroidManifest.xml</code></a>
+    file for a test application, and how to set up a test case class for a service. The
+    test case class, <a href="src/com/android/example/newalarm/ServiceAlarmTest.html">
+    <code>AlarmServiceTest</code></a>, contains tests that demonstrate the following
+    Android test patterns:
+</p>
+    <ul>
+        <li>
+            Test setup: The <code>setUp()</code> method re-initializes the state of the
+            service under test before each test is run.
+        </li>
+        <li>
+            Service start: The <code>Service.testServiceCreate()</code> test confirms that the
+            service starts correctly and initializes the variables it needs to provide its
+            services.
+        </li>
+    </ul>
+<p>
+    The <a href="AndroidManifest.html">manifest</a> declares an <code>&lt;instrumentation&gt;</code>
+    element that links the test application with the application under test. Specifically, the
+    element's <code>android:name</code> attribute specifies <code>InstrumentationTestRunner</code>
+    as the instrumentation to use. The <code>android:targetPackage</code> attribute specifies
+    <code>com.android.example.newalarm</code> as the name of the Android package that contains the
+    service under test.
+</p>
+<p class="note">
+    <strong>Note:</strong> <code>AlarmServiceTest.java</code> uses the Java package name
+    <code>com.example.android.newalarm</code>, which is the same package used by service under
+    test, <code>AlarmService.java</code>. This allows the test class to access members in the
+    service under test that are defined with package visibility. To prevent conflicts, though,
+    the generated java file <code>R.java</code> for <code>AlarmServiceTest</code> uses the
+    Java package name <code>com.example.android.newalarm.test</code>. For the same reason, the
+    Android package name for the test application (specified in the manifest file), is
+    <code>com.example.android.newalarm.test</code>.
+</p>
diff --git a/samples/Alarm/tests/src/com/example/android/newalarm/AlarmServiceTest.java b/samples/Alarm/tests/src/com/example/android/newalarm/AlarmServiceTest.java
new file mode 100644
index 0000000..4d6c7ad
--- /dev/null
+++ b/samples/Alarm/tests/src/com/example/android/newalarm/AlarmServiceTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.newalarm;
+
+import android.content.Intent;
+import android.test.ServiceTestCase;
+import com.example.android.newalarm.AlarmService;
+
+/**
+ * Test class for the Alarm sample test package. This test class tests the AlarmService
+ * service component.
+ */
+public class AlarmServiceTest extends ServiceTestCase<AlarmService> {
+    // Contains an Intent used to start the service
+    Intent mStartServiceIntent;
+
+    // Contains a handle to the system alarm service
+    AlarmService mService;
+
+    /**
+     * Constructor for the test class. Test classes that are run by InstrumentationTestRunner
+     * must provide a constructor with no arguments that calls the base class constructor as its
+     * first statement.
+     */
+    public AlarmServiceTest() {
+        super(AlarmService.class);
+    }
+
+    /*
+     * Sets up the test fixture. This method is called before each test
+     */
+    @Override
+    protected void setUp() throws Exception {
+
+        super.setUp();
+
+        // Sets up an intent to start the service under test
+        mStartServiceIntent = new Intent(this.getSystemContext(),AlarmService.class);
+    }
+
+    /**
+     * Cleans up the test fixture
+     * Called after each test method. If you override the method, call super.tearDown() as the
+     * last statement in your override.
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        // Always call the super constructor when overriding tearDown()
+        super.tearDown();
+    }
+
+    /**
+     * Tests the service's onCreate() method. Starts the service using startService(Intent)
+     */
+    public void testServiceCreate() {
+        // Starts the service under test
+        this.startService(mStartServiceIntent);
+
+        // Gets a handle to the service under test.
+        mService = this.getService();
+
+        // Asserts that the Notification Manager was created in the service under test.
+        assertNotNull(mService.mNotificationManager);
+
+        // Asserts that the PendingIntent for the expanded status window was created
+        assertNotNull(mService.mContentIntent);
+
+        // Asserts that the notification was created
+        assertNotNull(mService.mNotification);
+    }
+
+}
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 8163265..d0d80eb 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -34,13 +34,15 @@
 
     <!-- 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">
 
         <!-- This is how we can request a library but still allow the app
              to be installed if it doesn't exist. -->
@@ -214,6 +216,106 @@
                 <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.FragmentAnim"
+                android:label="@string/fragment_anim">
+            <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 -->
 
@@ -523,50 +625,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"
@@ -608,10 +666,100 @@
             </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>
+
+        <!-- ************************************* -->
+        <!--       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" />
@@ -686,6 +834,109 @@
         </receiver>
 
         <!-- ************************************* -->
+        <!--     ANDROID.ANIMATION PACKAGE SAMPLES         -->
+        <!-- ************************************* -->
+
+        <activity android:name=".animation.AnimationLoading" android:label="Animation/Loading">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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">
+            <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         -->
         <!-- ************************************* -->
 
@@ -1043,63 +1294,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" />
@@ -1141,6 +1392,20 @@
             </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.ExpandableList1" android:label="Views/Expandable Lists/1. Custom Adapter">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1206,6 +1471,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>
@@ -1309,15 +1582,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.Light.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.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" />
@@ -1458,6 +1751,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" />
@@ -1465,6 +1790,13 @@
             </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>
+
         <!-- ************************************* -->
         <!--           GRAPHICS SAMPLES            -->
         <!-- ************************************* -->
diff --git a/samples/ApiDemos/res/anim/animator.xml b/samples/ApiDemos/res/anim/animator.xml
new file mode 100644
index 0000000..2432f19
--- /dev/null
+++ b/samples/ApiDemos/res/anim/animator.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="1000"
+    android:valueFrom="1"
+    android:valueTo="0"
+    android:valueType="floatType"
+    android:repeatCount="1"
+    android:repeatMode="reverse"/>
diff --git a/samples/ApiDemos/res/anim/animator_set.xml b/samples/ApiDemos/res/anim/animator_set.xml
new file mode 100644
index 0000000..1358de4
--- /dev/null
+++ b/samples/ApiDemos/res/anim/animator_set.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.
+-->
+
+<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:valueFrom="0"
+        android:valueTo="400"
+        android:valueType="floatType"
+        android:propertyName="y"
+        android:repeatCount="1"
+        android:repeatMode="reverse"/>
+</set>
diff --git a/samples/ApiDemos/res/anim/object_animator.xml b/samples/ApiDemos/res/anim/object_animator.xml
new file mode 100644
index 0000000..ea84aa7
--- /dev/null
+++ b/samples/ApiDemos/res/anim/object_animator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="1000"
+    android:valueFrom="0"
+    android:valueTo="200"
+    android:valueType="floatType"
+    android:propertyName="y"
+    android:repeatCount="1"
+    android:repeatMode="reverse"/>
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..5c512f0
--- /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" />
+
+    <fragment class="com.example.android.apis.app.FragmentLayout$DetailsFragment"
+            android:id="@+id/details" android:layout_weight="1"
+            android:layout_width="0px" android:layout_height="match_parent" />
+    
+</LinearLayout>
+<!-- END_INCLUDE(layout) -->
diff --git a/samples/ApiDemos/res/layout/animation_cloning.xml b/samples/ApiDemos/res/layout/animation_cloning.xml
new file mode 100644
index 0000000..f49c5b0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_cloning.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Run"
+        android:id="@+id/startButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_custom_evaluator.xml b/samples/ApiDemos/res/layout/animation_custom_evaluator.xml
new file mode 100644
index 0000000..fd033f6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_custom_evaluator.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Play"
+        android:id="@+id/startButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_loading.xml b/samples/ApiDemos/res/layout/animation_loading.xml
new file mode 100644
index 0000000..f49c5b0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_loading.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    >
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Run"
+        android:id="@+id/startButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_multi_property.xml b/samples/ApiDemos/res/layout/animation_multi_property.xml
new file mode 100644
index 0000000..f49c5b0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_multi_property.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_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..b2ae536
--- /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="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_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..3507fc1
--- /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="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_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="fill_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..42856d2
--- /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="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_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..f289b5b
--- /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="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_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="fill_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="fill_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/bouncing_balls.xml b/samples/ApiDemos/res/layout/bouncing_balls.xml
new file mode 100644
index 0000000..c0de071
--- /dev/null
+++ b/samples/ApiDemos/res/layout/bouncing_balls.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_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 2827c01..0036742 100644
--- a/samples/ApiDemos/res/layout/device_admin_sample.xml
+++ b/samples/ApiDemos/res/layout/device_admin_sample.xml
@@ -15,126 +15,224 @@
 -->
 
 <!-- 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"
+                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>
+
+        </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>
-
-    <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>
-
-    </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/fragment_anim.xml b/samples/ApiDemos/res/layout/fragment_anim.xml
new file mode 100644
index 0000000..8bec894
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_anim.xml
@@ -0,0 +1,54 @@
+<?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">
+
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:gravity="center_vertical" android:layout_weight="1"
+        android:layout_width="wrap_content" android:layout_height="wrap_content">
+
+        <fragment android:name="com.example.android.apis.app.FragmentAnim$FirstFragment"
+                android:id="@+id/fragment1" android:layout_weight="1"
+                android:layout_width="0px" android:layout_height="wrap_content" />
+
+        <Button android:id="@+id/frag1hide"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="Hide">
+        </Button>
+    
+    </LinearLayout>
+    
+    <LinearLayout android:orientation="horizontal" android:padding="4dip"
+        android:gravity="center_vertical" android:layout_weight="1"
+        android:layout_width="wrap_content" android:layout_height="wrap_content">
+
+        <fragment android:name="com.example.android.apis.app.FragmentAnim$SecondFragment"
+                android:id="@+id/fragment2" android:layout_weight="1"
+                android:layout_width="0px" android:layout_height="wrap_content" />
+
+        <Button android:id="@+id/frag2hide"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="Hide">
+        </Button>
+    
+    </LinearLayout>
+    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/fragment_context_menu.xml b/samples/ApiDemos/res/layout/fragment_context_menu.xml
new file mode 100644
index 0000000..8f2c044
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_context_menu.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="wrap_content"
+    android:padding="8dp">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        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..e03f64f
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_dialog.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.
+-->
+
+<!-- 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: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..eb95e14
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_dialog_or_activity.xml
@@ -0,0 +1,62 @@
+<?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: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: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_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..b2d3c52
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_menu.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<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: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..e9a9a43
--- /dev/null
+++ b/samples/ApiDemos/res/layout/fragment_retain_instance.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<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: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..8239ef0 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="fill_parent"
+ android:layout_height="fill_parent">
+<Gallery  android:id="@+id/gallery"
+android:layout_width="fill_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/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..6c7fe38
--- /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="fill_parent"
+    android:layout_height="wrap_content"
+    android:id="@+id/parent"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_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="fill_parent"
+        android:layout_height="fill_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..e6f31c4
--- /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="fill_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="fill_parent"
+        android:layout_height="fill_parent"
+        android:id="@+id/horizontalContainer"
+        android:animateLayoutChanges="true"
+        />
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="wrap_content"
+        android:layout_height="fill_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..f9ccf62
--- /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="fill_parent"
+    android:layout_height="wrap_content"
+    android:id="@+id/parent"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_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/samples/ApiDemos/res/layout/popup_menu_1.xml b/samples/ApiDemos/res/layout/popup_menu_1.xml
new file mode 100644
index 0000000..6ddc76e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/popup_menu_1.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <Button android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:onClick="onPopupButtonClick"
+            android:text="@string/popup_menu_button" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/rotating_list.xml b/samples/ApiDemos/res/layout/rotating_list.xml
new file mode 100644
index 0000000..057af92
--- /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="fill_parent"
+    android:layout_height="fill_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..9feba98
--- /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="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container"
+    android:splitMotionEvents="true"
+    >
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_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="fill_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="fill_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/translationY"
+        />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_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="fill_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="fill_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="fill_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="fill_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/rotationZ"
+        />
+    </LinearLayout>
+    <Button
+        android:layout_width="200dip"
+        android:layout_height="150dip"
+        android:layout_marginLeft="50dip"
+        android:layout_marginTop="50dip"
+        android:text="Rotating Button"
+        android:id="@+id/rotatingButton"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/search_view.xml b/samples/ApiDemos/res/layout/search_view.xml
new file mode 100644
index 0000000..4a9f7c0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/search_view.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<SearchView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"/>
diff --git a/samples/ApiDemos/res/layout/searchview_actionbar.xml b/samples/ApiDemos/res/layout/searchview_actionbar.xml
new file mode 100644
index 0000000..37736cd
--- /dev/null
+++ b/samples/ApiDemos/res/layout/searchview_actionbar.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+    <Button
+            android:id="@+id/open_button"
+            android:text="@string/open_search"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+        />
+
+    <Button
+            android:id="@+id/close_button"
+            android:text="@string/close_search"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+        />
+
+    <TextView
+            android:id="@+id/status_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/searchview_filter.xml b/samples/ApiDemos/res/layout/searchview_filter.xml
new file mode 100644
index 0000000..e72c17e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/searchview_filter.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+    <SearchView
+            android:id="@+id/search_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+    <ListView
+            android:id="@+id/list_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/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/menu/actions.xml b/samples/ApiDemos/res/menu/actions.xml
new file mode 100644
index 0000000..d148ac9
--- /dev/null
+++ b/samples/ApiDemos/res/menu/actions.xml
@@ -0,0 +1,44 @@
+<?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:onClick="onSearch" />
+    <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_zoom"
+          android:icon="@android:drawable/ic_menu_zoom"
+          android:title="@string/action_bar_zoom"
+          android:showAsAction="ifRoom">
+        <menu>
+            <item android:id="@+id/action_save"
+                  android:icon="@android:drawable/ic_menu_save"
+                  android:title="@string/action_bar_save"
+                  android:showAsAction="ifRoom" />
+        </menu>
+    </item>
+</menu>
diff --git a/samples/ApiDemos/res/menu/list_select_menu.xml b/samples/ApiDemos/res/menu/list_select_menu.xml
new file mode 100644
index 0000000..490e3f7
--- /dev/null
+++ b/samples/ApiDemos/res/menu/list_select_menu.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/share"
+          android:title="@string/share"
+          android:icon="@android:drawable/ic_menu_share"
+          android:showAsAction="always" />
+</menu>
diff --git a/samples/ApiDemos/res/menu/popup.xml b/samples/ApiDemos/res/menu/popup.xml
new file mode 100644
index 0000000..fc0e3b4
--- /dev/null
+++ b/samples/ApiDemos/res/menu/popup.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/search"
+          android:icon="@android:drawable/ic_menu_search"
+          android:title="@string/popup_menu_search" />
+    <item android:id="@+id/add"
+          android:icon="@android:drawable/ic_menu_add"
+          android:title="@string/popup_menu_add" />
+    <item android:id="@+id/edit"
+          android:icon="@android:drawable/ic_menu_edit"
+          android:title="@string/popup_menu_edit">
+        <menu>
+            <item android:id="@+id/share"
+                  android:icon="@android:drawable/ic_menu_share"
+                  android:title="@string/popup_menu_share" />
+        </menu>
+    </item>
+</menu>
diff --git a/samples/ApiDemos/res/menu/searchview_in_menu.xml b/samples/ApiDemos/res/menu/searchview_in_menu.xml
new file mode 100644
index 0000000..09036a7
--- /dev/null
+++ b/samples/ApiDemos/res/menu/searchview_in_menu.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_search"
+          android:title="@string/action_bar_search"
+          android:icon="@android:drawable/ic_menu_search"
+          android:showAsAction="always"
+          android:actionViewClass="android.widget.SearchView" />
+</menu>
diff --git a/samples/ApiDemos/res/values/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/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 21cf980..77c634a 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -89,6 +89,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_anim">App/Fragment/Anim</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 +278,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,7 +306,7 @@
     <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     -->
     <!-- ============================== -->
@@ -363,12 +409,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 +447,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 +524,13 @@
     <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="set_password">Set Password</string>
     <string name="password_hint">Password</string>
     <string name="reset_password">Reset Password</string>
@@ -481,6 +539,9 @@
     <string name="wipe_data">Wipe 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  -->
@@ -490,6 +551,20 @@
     <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_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_zoom">Zoom</string>
+    <string name="action_bar_save">Save</string>
+
     <!-- ============================ -->
     <!--  graphics examples strings  -->
     <!-- ============================ -->
@@ -535,6 +610,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.
@@ -578,6 +659,18 @@
     <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>
     <!-- ============================== -->
     <!--  GoogleLogin examples strings  -->
     <!-- ============================== -->
@@ -954,4 +1047,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..7b75513 100644
--- a/samples/ApiDemos/res/xml/device_admin_sample.xml
+++ b/samples/ApiDemos/res/xml/device_admin_sample.xml
@@ -22,6 +22,7 @@
         <reset-password />
         <force-lock />
         <wipe-data />
+        <set-global-proxy />
     </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..71d2460
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationCloning.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 = new ObjectAnimator(500, balls.get(0), "y",
+                        0f, getHeight() - balls.get(0).getHeight());
+                ObjectAnimator anim2 = anim1.clone();
+                anim2.setTarget(balls.get(1));
+                anim1.addUpdateListener(this);
+
+                ShapeHolder ball2 = balls.get(2);
+                ObjectAnimator animDown = new ObjectAnimator(500, ball2, "y",
+                        0f, getHeight() - ball2.getHeight());
+                animDown.setInterpolator(new AccelerateInterpolator());
+                ObjectAnimator animUp = new ObjectAnimator(500, ball2, "y",
+                        getHeight() - ball2.getHeight(), 0f);
+                animDown.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..f2ef3d3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 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() {
+
+            @Override
+            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(100, 0);
+            addBall(250, 0);
+            addBall(400, 0);
+        }
+
+        private void createAnimation() {
+            if (animation == null) {
+                ObjectAnimator anim =
+                        (ObjectAnimator) AnimatorInflater.
+                                loadAnimator(getApplicationContext(), R.anim.object_animator);
+                anim.addUpdateListener(this);
+                anim.setTarget(balls.get(0));
+
+                ValueAnimator fader =
+                        (ValueAnimator) AnimatorInflater.loadAnimator(getApplicationContext(),
+                        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(getApplicationContext(),
+                        R.anim.animator_set);
+                seq.setTarget(balls.get(2));
+
+                animation = new AnimatorSet();
+                ((AnimatorSet) animation).playTogether(anim, fader, seq);
+            }
+        }
+
+        public void startAnimation() {
+            createAnimation();
+            animation.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();
+            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..8307d60
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationSeeking.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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() {
+
+            @Override
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+
+        mSeekBar = (SeekBar) findViewById(R.id.seekBar);
+        mSeekBar.setMax(DURATION);
+        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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 = new ObjectAnimator(1500, ball, "y",
+                        ball.getY(), getHeight() - BALL_SIZE);
+                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);
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            balls.remove(((ObjectAnimator)animation).getTarget());
+
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+        }
+
+        @Override
+        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..650f350
--- /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 = new ObjectAnimator(1500, ball, "y",
+                        ball.getY(), getHeight() - 50f);
+                yAnim.setRepeatCount(0);
+                yAnim.setRepeatMode(ValueAnimator.REVERSE);
+                yAnim.setInterpolator(new AccelerateInterpolator(2f));
+                yAnim.addUpdateListener(this);
+                yAnim.addListener(this);
+
+                ObjectAnimator xAnim = new ObjectAnimator(1000, ball, "x",
+                        ball.getX(), ball.getX() + 300);
+                xAnim.setStartDelay(0);
+                xAnim.setRepeatCount(0);
+                xAnim.setRepeatMode(ValueAnimator.REVERSE);
+                xAnim.setInterpolator(new AccelerateInterpolator(2f));
+
+                ObjectAnimator alphaAnim = new ObjectAnimator(1000, ball, "alpha", 1f, .5f);
+                AnimatorSet alphaSeq = new AnimatorSet();
+                alphaSeq.play(alphaAnim);
+
+                animation = new AnimatorSet();
+                ((AnimatorSet) animation).playTogether(yAnim, xAnim);
+                //((AnimatorSet) animation).play(alphaSeq).after(500);
+                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..3ffe24a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.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.graphics.drawable.shapes.RectShape;
+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 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;
+
+        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+        AnimatorSet animation = null;
+
+        public MyAnimationView(Context context) {
+            super(context);
+
+            // Create a colored background
+            ShapeDrawable background = new ShapeDrawable(new RectShape());
+            setBackgroundDrawable(background);
+            Paint paint = background.getPaint();
+            paint.setColor(RED);
+
+            // Animate background color
+            ValueAnimator colorAnim = new ObjectAnimator(3000, paint, "color", BLUE);
+            colorAnim.setEvaluator(new RGBEvaluator());
+            colorAnim.setRepeatCount(ValueAnimator.INFINITE);
+            colorAnim.setRepeatMode(ValueAnimator.REVERSE);
+            colorAnim.addUpdateListener(this); // forces invalidation to get the redraw
+            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 = new ObjectAnimator(duration, newBall, "y", startY, endY);
+            bounceAnim.setInterpolator(new AccelerateInterpolator());
+            ValueAnimator squashAnim1 = new ObjectAnimator(duration/4, newBall, "x", newBall.getX(),
+                    newBall.getX() - 25f);
+            squashAnim1.setRepeatCount(1);
+            squashAnim1.setRepeatMode(ValueAnimator.REVERSE);
+            squashAnim1.setInterpolator(new DecelerateInterpolator());
+            ValueAnimator squashAnim2 = new ObjectAnimator(duration/4, newBall, "width", newBall.getWidth(),
+                    newBall.getWidth() + 50);
+            squashAnim2.setRepeatCount(1);
+            squashAnim2.setRepeatMode(ValueAnimator.REVERSE);
+            squashAnim2.setInterpolator(new DecelerateInterpolator());
+            ValueAnimator stretchAnim1 = new ObjectAnimator(duration/4, newBall, "y", endY,
+                    endY + 25f);
+            stretchAnim1.setRepeatCount(1);
+            stretchAnim1.setInterpolator(new DecelerateInterpolator());
+            stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);
+            ValueAnimator stretchAnim2 = new ObjectAnimator(duration/4, newBall, "height",
+                    newBall.getHeight(), newBall.getHeight() - 25);
+            stretchAnim2.setRepeatCount(1);
+            stretchAnim2.setInterpolator(new DecelerateInterpolator());
+            stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);
+            ValueAnimator bounceBackAnim = new ObjectAnimator(duration, newBall, "y", endY,
+                    startY);
+            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 = new ObjectAnimator(250, newBall, "alpha", 1f, 0f);
+            fadeAnim.addListener(this);
+
+            // 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();
+            }
+        }
+
+        public void onAnimationUpdate(ValueAnimator animation) {
+            invalidate();
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            balls.remove(((ObjectAnimator)animation).getTarget());
+
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+        }
+    }
+}
\ 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..d1018c9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/CustomEvaluator.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.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() {
+
+            @Override
+            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 {
+        @Override
+        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 = new ObjectAnimator(1500, ballHolder, "xY",
+                        endXY);
+                bounceAnim.setEvaluator(new XYEvaluator());
+                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..203f2c7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.widget.LinearLayout;
+import com.example.android.apis.R;
+
+import android.animation.AnimatorListenerAdapter;
+import android.animation.Keyframe;
+import android.animation.LayoutTransition;
+import android.animation.PropertyValuesHolder;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+
+/**
+ * This application demonstrates how to use LayoutTransition to automate transition animations
+ * as items are removed from or added to a container.
+ */
+public class LayoutAnimations extends Activity {
+
+    private int numButtons = 1;
+    ViewGroup container = null;
+    Animator defaultAppearingAnim, defaultDisappearingAnim;
+    Animator defaultChangingAppearingAnim, defaultChangingDisappearingAnim;
+    Animator customAppearingAnim, customDisappearingAnim;
+    Animator customChangingAppearingAnim, customChangingDisappearingAnim;
+    Animator currentAppearingAnim, currentDisappearingAnim;
+    Animator currentChangingAppearingAnim, currentChangingDisappearingAnim;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.layout_animations);
+
+        container = new FixedGridLayout(this);
+        ((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<Integer> pvhLeft =
+                new PropertyValuesHolder<Integer>("left", 0, 1);
+        PropertyValuesHolder<Integer> pvhTop =
+                new PropertyValuesHolder<Integer>("top", 0, 1);
+        PropertyValuesHolder<Integer> pvhRight =
+                new PropertyValuesHolder<Integer>("right", 0, 1);
+        PropertyValuesHolder<Integer> pvhBottom =
+                new PropertyValuesHolder<Integer>("bottom", 0, 1);
+        PropertyValuesHolder<Float> pvhScaleX =
+                new PropertyValuesHolder<Float>("scaleX", 1f, 0f, 1f);
+        PropertyValuesHolder<Float> pvhScaleY =
+                new PropertyValuesHolder<Float>("scaleY", 1f, 0f, 1f);
+        customChangingAppearingAnim =
+                new ObjectAnimator(transition.getDuration(LayoutTransition.CHANGE_APPEARING),
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX, pvhScaleY);
+        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 = new Keyframe(0f, 0f);
+        Keyframe kf1 = new Keyframe(.9999f, 360f);
+        Keyframe kf2 = new Keyframe(1f, 0f);
+        PropertyValuesHolder<Keyframe> pvhRotation =
+                new PropertyValuesHolder<Keyframe>("rotation", kf0, kf1, kf2);
+        customChangingDisappearingAnim =
+                new ObjectAnimator(transition.getDuration(LayoutTransition.CHANGE_DISAPPEARING),
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation);
+        customChangingDisappearingAnim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotation(0f);
+            }
+        });
+
+        // Adding
+        customAppearingAnim =
+                new ObjectAnimator<Float>(transition.getDuration(LayoutTransition.APPEARING),
+                        null, "rotationY", 90f, 0f);
+        customAppearingAnim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator anim) {
+                View view = (View) ((ObjectAnimator) anim).getTarget();
+                view.setRotationY(0f);
+            }
+        });
+
+        // Removing
+        customDisappearingAnim =
+                new ObjectAnimator<Float>(transition.getDuration(LayoutTransition.DISAPPEARING),
+                        null, "rotationX", 0f, 90f);
+        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..81d3469
--- /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(getApplicationContext());
+                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(getApplicationContext());
+                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..9f311b1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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<Integer> pvhLeft =
+                new PropertyValuesHolder<Integer>("left", 0, 1);
+        PropertyValuesHolder<Integer> pvhTop =
+                new PropertyValuesHolder<Integer>("top", 0, 1);
+        PropertyValuesHolder<Integer> pvhRight =
+                new PropertyValuesHolder<Integer>("right", 0, 1);
+        PropertyValuesHolder<Integer> pvhBottom =
+                new PropertyValuesHolder<Integer>("bottom", 0, 1);
+        PropertyValuesHolder<Float> pvhScaleX =
+                new PropertyValuesHolder<Float>("scaleX", 1f, 0f, 1f);
+        PropertyValuesHolder<Float> pvhScaleY =
+                new PropertyValuesHolder<Float>("scaleY", 1f, 0f, 1f);
+        final ObjectAnimator changeIn =
+                new ObjectAnimator(transition.getDuration(LayoutTransition.CHANGE_APPEARING),
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX, pvhScaleY);
+        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 = new Keyframe(0f, 0f);
+        Keyframe kf1 = new Keyframe(.9999f, 360f);
+        Keyframe kf2 = new Keyframe(1f, 0f);
+        PropertyValuesHolder<Keyframe> pvhRotation =
+                new PropertyValuesHolder<Keyframe>("rotation", kf0, kf1, kf2);
+        final ObjectAnimator changeOut =
+                new ObjectAnimator(transition.getDuration(LayoutTransition.CHANGE_DISAPPEARING),
+                        this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation);
+        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<Float> animIn =
+                new ObjectAnimator<Float>(transition.getDuration(LayoutTransition.APPEARING),
+                        null, "rotationY", 90f, 0f);
+        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<Float> animOut =
+                new ObjectAnimator<Float>(transition.getDuration(LayoutTransition.DISAPPEARING),
+                        null, "rotationX", 0f, 90f);
+        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..5212781
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ListFlipper.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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() {
+
+            @Override
+            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 = new ObjectAnimator(500, visibleList, "rotationY", 0f, 90f);
+        visToInvis.setInterpolator(accelerator);
+        final ObjectAnimator invisToVis = new ObjectAnimator(500, invisibleList, "rotationY", -90f, 0f);
+        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..0ba012f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 = new ObjectAnimator(DURATION, ball, "y",
+                        ball.getY(), getHeight() - BALL_SIZE);
+                yBouncer.setInterpolator(new BounceInterpolator());
+                yBouncer.addUpdateListener(this);
+
+                ball = balls.get(1);
+                PropertyValuesHolder pvhY = new PropertyValuesHolder("y", ball.getY(),
+                        getHeight() - BALL_SIZE);
+                PropertyValuesHolder pvhAlpha = new PropertyValuesHolder("alpha", 1.0f,
+                        0f);
+                ObjectAnimator yAlphaBouncer = new ObjectAnimator(DURATION/2, ball, pvhY, pvhAlpha);
+                yAlphaBouncer.setInterpolator(new AccelerateInterpolator());
+                yAlphaBouncer.setRepeatCount(1);
+                yAlphaBouncer.setRepeatMode(ValueAnimator.REVERSE);
+
+
+                ball = balls.get(2);
+                PropertyValuesHolder pvhW = new PropertyValuesHolder("width", ball.getWidth(),
+                        ball.getWidth() * 2);
+                PropertyValuesHolder pvhH = new PropertyValuesHolder("height", ball.getHeight(),
+                        ball.getHeight() * 2);
+                PropertyValuesHolder pvTX = new PropertyValuesHolder("x", ball.getX(), ball.getX() - BALL_SIZE/2f);
+                PropertyValuesHolder pvTY = new PropertyValuesHolder("y", 0f, ball.getY(), ball.getY() - BALL_SIZE/2f);
+                ObjectAnimator whxyBouncer = new ObjectAnimator(DURATION/2, ball, pvhW, pvhH,
+                        pvTX, pvTY);
+                whxyBouncer.setRepeatCount(1);
+                whxyBouncer.setRepeatMode(ValueAnimator.REVERSE);
+
+                ball = balls.get(3);
+                pvhY = new PropertyValuesHolder("y", ball.getY(),
+                        getHeight() - BALL_SIZE);
+                float ballX = ball.getX();
+                Keyframe kf0 = new Keyframe(0f, ballX);
+                Keyframe kf1 = new Keyframe(.5f, ballX + 100f);
+                Keyframe kf2 = new Keyframe(1f, ballX + 50f);
+                PropertyValuesHolder pvhX = new PropertyValuesHolder("x", kf0, kf1, kf2);
+                ObjectAnimator yxBouncer = new ObjectAnimator(DURATION/2, ball, pvhY, pvhX);
+                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..13f3b89
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ReversingAnimation.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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() {
+
+            @Override
+            public void onClick(View v) {
+                animView.startAnimation();
+            }
+        });
+
+        Button reverser = (Button) findViewById(R.id.reverseButton);
+        reverser.setOnClickListener(new View.OnClickListener() {
+
+            @Override
+            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 = new ObjectAnimator(1500, ball, "y",
+                        ball.getY(), getHeight() - 50f);
+                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..22f88d3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ShapeHolder.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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) {
+        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/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/ActionBarUsage.java b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarUsage.java
new file mode 100644
index 0000000..9657558
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ActionBarUsage.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.app;
+
+import android.app.Activity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.Toast;
+
+import com.example.android.apis.R;
+
+/**
+ * This demonstrates idiomatic usage of the Action Bar. The theme Theme.WithActionBar
+ * is specified for this activity in AndroidManifest.xml 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 {
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.actions, menu);
+        return true;
+    }
+
+    @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 onSearch(MenuItem item) {
+        Toast.makeText(this, "Searching...", Toast.LENGTH_SHORT).show();
+    }
+}
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 f7ee2d7..e6cbc9b 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
@@ -42,6 +42,11 @@
 import android.widget.Toast;
 import android.widget.AdapterView.OnItemSelectedListener;
 
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.util.Arrays;
+import java.util.List;
+
 /**
  * Example of a do-nothing admin class.  When enabled, it lets you control
  * some of its policy and reports when there is interesting activity.
@@ -54,6 +59,13 @@
 
     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_MAX_FAILED_PW = "max_failed_pw";
 
     void showToast(Context context, CharSequence msg) {
@@ -115,10 +127,18 @@
             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;
@@ -133,6 +153,10 @@
 
         private EditText mTimeout;
 
+        EditText mProxyHost;
+        EditText mProxyList;
+        Button mProxyButton;
+
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
@@ -178,6 +202,97 @@
                     }
                 }
             });
+            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) {
+                    }
+                }
+            });
             mSetPasswordButton = (Button)findViewById(R.id.set_password);
             mSetPasswordButton.setOnClickListener(mSetPasswordListener);
 
@@ -212,6 +327,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() {
@@ -221,6 +341,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);
@@ -231,6 +358,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);
@@ -244,6 +378,13 @@
             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 int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
 
             for (int i=0; i<mPasswordQualityValues.length; i++) {
@@ -252,6 +393,13 @@
                 }
             }
             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));
             mMaxFailedPw.setText(Integer.toString(maxFailedPw));
         }
 
@@ -260,12 +408,26 @@
             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 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);
             }
         }
@@ -282,6 +444,48 @@
             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 setMaxFailedPw(int length) {
             SharedPreferences prefs = getSamplePreferences(this);
             prefs.edit().putInt(PREF_MAX_FAILED_PW, length).commit();
@@ -424,5 +628,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/FragmentAlertDialog.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.java
new file mode 100644
index 0000000..abf9731
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+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/FragmentAnim.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentAnim.java
new file mode 100644
index 0000000..42345a0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentAnim.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstration of animations when changing fragment states.
+ */
+public class FragmentAnim extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_anim);
+
+        addShowHideListener(R.id.frag1hide, findFragmentById(R.id.fragment1));
+        addShowHideListener(R.id.frag2hide, 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 = openFragmentTransaction();
+                ft.setCustomAnimations(android.R.anim.animator_fade_in,
+                        android.R.anim.animator_fade_out);
+                if (fragment.isHidden()) {
+                    button.setAnimation(AnimationUtils.loadAnimation(
+                            FragmentAnim.this, android.R.anim.slide_in_left));
+                    ft.show(fragment);
+                } else {
+                    button.setAnimation(AnimationUtils.loadAnimation(
+                            FragmentAnim.this, android.R.anim.slide_out_right));
+                    ft.hide(fragment);
+                }
+                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/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/FragmentLayout.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
new file mode 100644
index 0000000..a63685e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.ListFragment;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.util.Log;
+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();
+                getFragmentManager().openTransaction().add(android.R.id.content, details).commit();
+                details.setText(getIntent().getIntExtra("text", -1));
+            }
+        }
+    }
+//END_INCLUDE(details_activity)
+
+//BEGIN_INCLUDE(titles)
+    public static class TitlesFragment extends ListFragment {
+        DetailsFragment mDetails;
+        int mCurCheckPosition = 0;
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            // Populate list with our static array of titles.
+            setListAdapter(new ArrayAdapter<String>(getActivity(),
+                    android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES));
+
+            // Restore last state for checked position.
+            if (savedInstanceState != null) {
+                mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
+            }
+
+            // If we are showing details in the screen, set up the list to highlight.
+            mDetails = (DetailsFragment)getFragmentManager().findFragmentById(R.id.details);
+            if (mDetails != null && mDetails.isInLayout()) {
+                getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+                getListView().setItemChecked(mCurCheckPosition, true);
+                mDetails.setText(mCurCheckPosition);
+            }
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            outState.putInt("curChoice", mCurCheckPosition);
+        }
+
+        @Override
+        public void onListItemClick(ListView l, View v, int position, long id) {
+            mCurCheckPosition = position;
+
+            if (mDetails != null && mDetails.isVisible()) {
+                // If the activity has a fragment to display the dialog,
+                // point it to what the user has selected.
+                mDetails.setText(position);
+                getListView().setItemChecked(position, true);
+            } 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("text", position);
+                startActivity(intent);
+            }
+        }
+    }
+//END_INCLUDE(titles)
+
+//BEGIN_INCLUDE(details)
+    public static class DetailsFragment extends Fragment {
+        int mDisplayedText = -1;
+        TextView mText;
+
+        public void setText(int id) {
+            mDisplayedText = id;
+            if (mText != null && id >= 0) {
+                mText.setText(Shakespeare.DIALOGUE[id]);
+            }
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            if (savedInstanceState != null) {
+                mDisplayedText = savedInstanceState.getInt("text", -1);
+            }
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            outState.putInt("text", mDisplayedText);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            ScrollView scroller = new ScrollView(getActivity());
+            mText = new TextView(getActivity());
+            int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    4, getActivity().getResources().getDisplayMetrics());
+            mText.setPadding(padding, padding, padding, padding);
+            scroller.addView(mText);
+            if (mDisplayedText >= 0) {
+                mText.setText(Shakespeare.DIALOGUE[mDisplayedText]);
+            }
+            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..c095692
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.os.Bundle;
+import android.provider.ContactsContract.Contacts;
+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.ListAdapter;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+
+/**
+ * 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();
+        }
+    }
+
+    public static class CursorLoaderListFragment extends ListFragment
+            implements LoaderManager.LoaderCallbacks<Cursor> {
+        MenuItem mSearchMenu;
+        
+        @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);
+            
+            // 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) {
+            mSearchMenu = menu.add("Search");
+            mSearchMenu.setIcon(R.drawable.magnifying_glass);
+            mSearchMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+            if (item == mSearchMenu) {
+                InputMethodManager imm = (InputMethodManager)getActivity()
+                        .getSystemService(Context.INPUT_METHOD_SERVICE);
+                imm.showSoftInput(getActivity().getCurrentFocus(), 0);
+                return true;
+            } else {
+                return super.onOptionsItemSelected(item);
+            }
+        }
+
+        @Override
+        public void onListItemClick(ListView l, View v, int position, long id) {
+            Log.i("FragmentComplexList", "Item clicked: " + id);
+        }
+
+        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) {
+            String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+                    + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+                    + Contacts.DISPLAY_NAME + " != '' ))";
+            return new CursorLoader(getActivity(), Contacts.CONTENT_URI,
+                    CONTACTS_SUMMARY_PROJECTION, select, null,
+                    Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
+        }
+
+        @Override
+        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+            ListAdapter adapter = new SimpleCursorAdapter(getActivity(),
+                    android.R.layout.simple_list_item_2, data, 
+                            new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, 
+                            new int[] { android.R.id.text1, android.R.id.text2 });
+            setListAdapter(adapter);
+        }
+    }
+}
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..2aa9a12
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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);
+            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..f30a7c1 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);
@@ -97,9 +78,18 @@
         // 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 +98,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/content/ClipboardSample.java b/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.java
new file mode 100644
index 0000000..e369ca9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.java
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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() {
+        @Override
+        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.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/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/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java
new file mode 100644
index 0000000..407767f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls3.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+public class Controls3 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java
new file mode 100644
index 0000000..3dcf310
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls4.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+public class Controls4 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
index b6cce29..8b2cb43 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
@@ -17,71 +17,122 @@
 package com.example.android.apis.view;
 
 import android.app.ExpandableListActivity;
+import android.content.AsyncQueryHandler;
+import android.content.ContentUris;
 import android.content.Context;
 import android.database.Cursor;
+import android.net.Uri;
 import android.os.Bundle;
-import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.widget.ExpandableListAdapter;
+import android.provider.ContactsContract.Contacts;
+import android.widget.CursorTreeAdapter;
 import android.widget.SimpleCursorTreeAdapter;
 
 /**
  * Demonstrates expandable lists backed by Cursors
  */
 public class ExpandableList2 extends ExpandableListActivity {
-    private static final int COLUMN_CONTACT_ID = 0;
 
-    private static final String[] CONTACT_PROJECTION = new String[] {
+    private static final String[] CONTACTS_PROJECTION = new String[] {
         Contacts._ID,
         Contacts.DISPLAY_NAME
     };
+    private static final int GROUP_ID_COLUMN_INDEX = 0;
 
-    private static final String[] PHONE_PROJECTION = new String[] {
-        Phone._ID,
-        Phone.CONTACT_ID,
-        Phone.NUMBER
+    private static final String[] PHONE_NUMBER_PROJECTION = new String[] {
+            Phone._ID,
+            Phone.NUMBER
     };
 
-    private ExpandableListAdapter mAdapter;
+    private static final int TOKEN_GROUP = 0;
+    private static final int TOKEN_CHILD = 1;
 
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+    private static final class QueryHandler extends AsyncQueryHandler {
+        private CursorTreeAdapter mAdapter;
 
-        // Query for people
-        Cursor groupCursor = managedQuery(Contacts.CONTENT_URI,
-                CONTACT_PROJECTION, null, null, null);
+        public QueryHandler(Context context, CursorTreeAdapter adapter) {
+            super(context.getContentResolver());
+            this.mAdapter = adapter;
+        }
 
-        // Set up our adapter
-        mAdapter = new MyExpandableListAdapter(groupCursor,
-                this,
-                android.R.layout.simple_expandable_list_item_1,
-                android.R.layout.simple_expandable_list_item_1,
-                new String[] {Contacts.DISPLAY_NAME}, // Name for group layouts
-                new int[] {android.R.id.text1},
-                new String[] {Phone.NUMBER}, // Number for child layouts
-                new int[] {android.R.id.text1});
-        setListAdapter(mAdapter);
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            switch (token) {
+            case TOKEN_GROUP:
+                mAdapter.setGroupCursor(cursor);
+                break;
+
+            case TOKEN_CHILD:
+                int groupPosition = (Integer) cookie;
+                mAdapter.setChildrenCursor(groupPosition, cursor);
+                break;
+            }
+        }
     }
 
     public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
 
-        public MyExpandableListAdapter(Cursor cursor, Context context, int groupLayout,
+        // Note that the constructor does not take a Cursor. This is done to avoid querying the 
+        // database on the main thread.
+        public MyExpandableListAdapter(Context context, int groupLayout,
                 int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
                 int[] childrenTo) {
-            super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
+
+            super(context, null, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
                     childrenTo);
         }
 
         @Override
         protected Cursor getChildrenCursor(Cursor groupCursor) {
-            int contactId = groupCursor.getInt(COLUMN_CONTACT_ID);
-            // The returned Cursor MUST be managed by us, so we use Activity's helper
-            // functionality to manage it for us.
-            return managedQuery(Phone.CONTENT_URI,
-                    PHONE_PROJECTION,
-                    Phone.CONTACT_ID + " = " + contactId,
-                    null, null);
+            // Given the group, we return a cursor for all the children within that group 
+
+            // Return a cursor that points to this contact's phone numbers
+            Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();
+            ContentUris.appendId(builder, groupCursor.getLong(GROUP_ID_COLUMN_INDEX));
+            builder.appendEncodedPath(Contacts.Data.CONTENT_DIRECTORY);
+            Uri phoneNumbersUri = builder.build();
+
+            mQueryHandler.startQuery(TOKEN_CHILD, groupCursor.getPosition(), phoneNumbersUri, 
+                    PHONE_NUMBER_PROJECTION, Phone.MIMETYPE + "=?", 
+                    new String[] { Phone.CONTENT_ITEM_TYPE }, null);
+
+            return null;
         }
     }
-}
\ No newline at end of file
+
+    private QueryHandler mQueryHandler;
+    private CursorTreeAdapter mAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Set up our adapter
+        mAdapter = new MyExpandableListAdapter(
+                this,
+                android.R.layout.simple_expandable_list_item_1,
+                android.R.layout.simple_expandable_list_item_1,
+                new String[] { Contacts.DISPLAY_NAME }, // Name for group layouts
+                new int[] { android.R.id.text1 },
+                new String[] { Phone.NUMBER }, // Number for child layouts
+                new int[] { android.R.id.text1 });
+
+        setListAdapter(mAdapter);
+
+        mQueryHandler = new QueryHandler(this, mAdapter);
+
+        // Query for people
+        mQueryHandler.startQuery(TOKEN_GROUP, null, Contacts.CONTENT_URI, CONTACTS_PROJECTION, 
+                Contacts.HAS_PHONE_NUMBER + "=1", null, null);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        // Null out the group cursor. This will cause the group cursor and all of the child cursors
+        // to be closed.
+        mAdapter.changeCursor(null);
+        mAdapter = null;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/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..81c2079
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List15.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.
+ */
+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");
+            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) {
+            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/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..67d6e3c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RotatingButton.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.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() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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() {
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            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..39e75de
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SplitTouchView.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.Gravity;
+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() {
+        @Override
+        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/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/_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/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h
index 0ebed28..296749a 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();
diff --git a/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp b/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
index 72a11c9..6e93fb6 100644
--- a/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
+++ b/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
@@ -35,12 +35,12 @@
 extern ANPPathInterfaceV0      gPathI;
 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) {
@@ -173,7 +173,7 @@
     gWindowI.clearVisibleRects(instance);
 }
 
-int16 BallAnimation::handleEvent(const ANPEvent* evt) {
+int16_t BallAnimation::handleEvent(const ANPEvent* evt) {
     NPP instance = this->inst();
 
     switch (evt->eventType) {
diff --git a/samples/BrowserPlugin/jni/animation/AnimationPlugin.h b/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
index ef2a3f54..4a5b4e8 100644
--- a/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
+++ b/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
@@ -33,7 +33,7 @@
     BallAnimation(NPP inst);
     virtual ~BallAnimation();
     virtual bool supportsDrawingModel(ANPDrawingModel);
-    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual int16_t handleEvent(const ANPEvent* evt);
 private:
     void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
     void showEntirePluginOnScreen();
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..07bae66 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);
@@ -151,7 +151,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)
 {
 
@@ -290,7 +290,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 +301,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 +319,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);
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/CorpApp/Android.mk b/samples/CorpApp/Android.mk
new file mode 100644
index 0000000..37b98b0
--- /dev/null
+++ b/samples/CorpApp/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 := CorpApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/samples/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/samples/CorpApp/res/xml/corp_device_admin.xml b/samples/CorpApp/res/xml/corp_device_admin.xml
new file mode 100644
index 0000000..f464b60
--- /dev/null
+++ b/samples/CorpApp/res/xml/corp_device_admin.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+
+<!-- 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/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
index 04f4dbe..82fcead 100644
--- a/samples/NotePad/AndroidManifest.xml
+++ b/samples/NotePad/AndroidManifest.xml
@@ -27,7 +27,9 @@
     >
         <provider android:name="NotePadProvider"
             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">
             <intent-filter>
@@ -65,9 +67,12 @@
             </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>
@@ -110,6 +115,6 @@
 
     </application>
 
-    <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
+    <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"/>
 </manifest>
 
diff --git a/samples/NotePad/res/values/strings.xml b/samples/NotePad/res/values/strings.xml
index 168db92..43be4dd 100644
--- a/samples/NotePad/res/values/strings.xml
+++ b/samples/NotePad/res/values/strings.xml
@@ -15,8 +15,10 @@
 -->
 
 <resources>
+    <string name="menu_copy">Copy</string>
     <string name="menu_delete">Delete</string>
     <string name="menu_insert">Add note</string>
+    <string name="menu_paste">Paste</string>
     <string name="menu_revert">Revert</string>
     <string name="menu_discard">Discard</string>
 
diff --git a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
index e45efd8..da85974 100644
--- a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
+++ b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
@@ -16,10 +16,13 @@
 
 package com.example.android.notepad;
 
-import com.example.android.notepad.NotePad.Notes;
+import com.example.android.notepad.NotePad;
 
 import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.ClipData;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -36,35 +39,50 @@
 import android.widget.EditText;
 
 /**
- * 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 = "Notes";
 
-    /**
-     * 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[] {
-            Notes._ID, // 0
-            Notes.NOTE, // 1
+    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 */
+    // The index of the note column
     private static final int COLUMN_INDEX_NOTE = 1;
-    
-    // This is our state data that is stored when freezing.
+
+    // The index of the title column
+    private static final int COLUMN_INDEX_TITLE = 2;
+
+    // A label for the saved state of the activity
     private static final String ORIGINAL_CONTENT = "origContent";
 
-    // Identifiers for our menu items.
+    // Menu item identifiers
     private static final int REVERT_ID = Menu.FIRST;
     private static final int DISCARD_ID = Menu.FIRST + 1;
     private static final int DELETE_ID = Menu.FIRST + 2;
 
-    // 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;
+    private static final int STATE_PASTE = 2;
 
+    // Global mutable variables
     private int mState;
     private boolean mNoteOnly = false;
     private Uri mUri;
@@ -73,129 +91,235 @@
     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()));
 
+            // For a paste, initializes the data from clipboard.
+            if (Intent.ACTION_PASTE.equals(action)) {
+
+                // Does the paste
+                performPaste();
+                // Switches the state to PASTE. The title can not be modified.
+                mState = STATE_PASTE;
+            }
+
+        // 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
+        // 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);
+        /*
+         * 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)
+        );
 
-        // 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) {
-            // 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) {
+
+                // Sets the title to Edit for edits
                 setTitle(getText(R.string.title_edit));
-            } else if (mState == STATE_INSERT) {
+
+            // Sets the title to "create" for inserts and pastes
+            } else if (mState == STATE_INSERT || mState == STATE_PASTE) {
                 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.
+            /*
+             * 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.
             String note = mCursor.getString(COLUMN_INDEX_NOTE);
             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
@@ -203,126 +327,322 @@
         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 else, so make sure their current
-        // changes are safely saved away in the provider.  We don't need
-        // to do this if only editing.
+        /*
+         * 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) {
+
+            // Get the current note text.
             String text = mText.getText().toString();
             int length = text.length();
 
-            // If this activity is finished, and there is no text, then we
-            // do something a little special: 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 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) && !mNoteOnly) {
                 setResult(RESULT_CANCELED);
                 deleteNote();
 
-            // Get out updates into the provider.
+                /*
+                 * 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 {
-                ContentValues values = new ContentValues();
 
-                // This stuff is only done when working with a full-fledged note.
-                if (!mNoteOnly) {
-                    // Bump the modification time to now.
-                    values.put(Notes.MODIFIED_DATE, System.currentTimeMillis());
-
-                    // If we are creating a new note, then we want to also create
-                    // an initial title for it.
-                    if (mState == STATE_INSERT) {
-                        String title = text.substring(0, Math.min(30, length));
-                        if (length > 30) {
-                            int lastSpace = title.lastIndexOf(' ');
-                            if (lastSpace > 0) {
-                                title = title.substring(0, lastSpace);
-                            }
-                        }
-                        values.put(Notes.TITLE, title);
-                    }
-                }
-
-                // Write our text back into the provider.
-                values.put(Notes.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.
-                getContentResolver().update(mUri, values, null, null);
+                // Creates a map to contain the new values for the columns
+                updateNote(text, null, !mNoteOnly);
             }
         }
     }
 
+    /**
+     * 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) {
         super.onCreateOptionsMenu(menu);
 
-        // Build the menus that are shown when editing.
+        // Builds the menus that are shown when editing. These are 'revert' to undo changes, and
+        // 'delete' to delete the note.
         if (mState == STATE_EDIT) {
+
+            // Adds the 'revert' menu item, and sets its shortcut to numeric 0, letter 'r' and its
+            // icon to the Android standard revert icon.
             menu.add(0, REVERT_ID, 0, R.string.menu_revert)
                     .setShortcut('0', 'r')
                     .setIcon(android.R.drawable.ic_menu_revert);
             if (!mNoteOnly) {
+
+                // Adds the 'delete' menu item, and sets its shortcut to numeric 1, letter 'd'
+                // and its icon to the Android standard delete icon
                 menu.add(0, DELETE_ID, 0, R.string.menu_delete)
                         .setShortcut('1', 'd')
                         .setIcon(android.R.drawable.ic_menu_delete);
             }
 
-        // Build the menus that are shown when inserting.
+        // Builds the menus that are shown when inserting. The only option is 'Discard' to throw
+        // away the new note.
         } else {
             menu.add(0, DISCARD_ID, 0, R.string.menu_discard)
                     .setShortcut('0', 'd')
                     .setIcon(android.R.drawable.ic_menu_delete);
         }
 
-        // If we are working on a full note, then 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.
+        /*
+         * Appends menu items for any Activity declarations that implement an alternative action
+         * for this Activity's MIME type, one menu item for each Activity.
+         */
         if (!mNoteOnly) {
+
+            // Makes a new Intent with the URI data passed to this Activity
             Intent intent = new Intent(null, getIntent().getData());
+
+            // Adds the ALTERNATIVE category to the Intent.
             intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
-            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
-                    new ComponentName(this, NoteEditor.class), null, intent, 0, null);
+
+            /*
+             * Constructs a new ComponentName object that represents the current Activity.
+             */
+            ComponentName component = new ComponentName(
+                this,
+                NoteEditor.class);
+
+            /*
+             * In the ALTERNATIVE menu group, adds an option for each Activity that is registered to
+             * handle this Activity's MIME type. The Intent describes what type of items should be
+             * added to the menu; in this case, Activity declarations with category ALTERNATIVE.
+             */
+            menu.addIntentOptions(
+                Menu.CATEGORY_ALTERNATIVE,  // The menu group to add the items to.
+                Menu.NONE,                  // No unique ID is needed.
+                Menu.NONE,                  // No ordering is needed.
+                component,                  // The current Activity object's component name
+                null,                       // No specific items need to be placed first.
+                intent,                     // The intent containing the type of items to add.
+                Menu.NONE,                  // No flags are necessary.
+                null                        // No need to generate an array of menu items.
+            );
         }
 
+        // The method returns TRUE, so that further menu processing is not done.
         return true;
     }
 
+    /**
+     * 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.
+
+        // Chooses the action to perform
         switch (item.getItemId()) {
+
+        // Deletes the note and close the Activity.
         case DELETE_ID:
-            deleteNote();
-            finish();
-            break;
+        deleteNote();
+        finish();
+        break;
+
+        // Discards the new note.
         case DISCARD_ID:
-            cancelNote();
-            break;
+        cancelNote();
+        break;
+
+        // Discards any changes to an edited note.
         case REVERT_ID:
-            cancelNote();
-            break;
+        cancelNote();
+        break;
         }
+
+        // Continues with processing the menu item. In effect, if the item was an alternative
+        // action, this invokes the Activity for that action.
         return super.onOptionsItemSelected(item);
     }
 
+//BEGIN_INCLUDE(paste)
     /**
-     * Take care of canceling work on a note.  Deletes the note if we
-     * had created it, otherwise reverts to the original text.
+     * A helper method that replaces the note's data with the contents of the clipboard.
+     */
+    private final void performPaste() {
+
+        // 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()) {
+                        text = orig.getString(COLUMN_INDEX_NOTE);
+                        title = orig.getString(COLUMN_INDEX_TITLE);
+                    }
+
+                    // Closes the cursor.
+                    orig.close();
+                }
+            }
+
+            // 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, true);
+        }
+    }
+//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
+     * @param updateTitle <em>true</em> if the title should be updated. This also updates the
+     * modification timestamp to the current time.
+     */
+    private final void updateNote(String text, String title, boolean updateTitle) {
+
+        // Sets up a map to contain values to be updated in the provider.
+        ContentValues values = new ContentValues();
+
+        // If updateTitle is true, sets the modification date/time stamp to now.
+        if (updateTitle) {
+            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);
+                        }
+                    }
+                }
+
+                // 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.
+            );
+
+
+    }
+
+    /**
+     * 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
         if (mCursor != null) {
             if (mState == STATE_EDIT) {
                 // Put the original note text back into the database
                 mCursor.close();
                 mCursor = null;
                 ContentValues values = new ContentValues();
-                values.put(Notes.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 25be23e..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.google.provider.NotePad";
 
     // This class cannot be instantiated
-    private NotePad() {}
-    
+    private NotePad() {
+    }
+
     /**
-     * Notes table
+     * Notes table contract
      */
     public static final class Notes implements BaseColumns {
+
         // This class cannot be instantiated
         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 58cdc8f..4595a80 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.Notes;
+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,725 @@
 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";
 
+    /**
+     * The database that the provider uses as its underlying data store
+     */
     private static final String DATABASE_NAME = "note_pad.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;
 
     /**
-     * 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 + " ("
-                    + Notes._ID + " INTEGER PRIMARY KEY,"
-                    + Notes.TITLE + " TEXT,"
-                    + Notes.NOTE + " TEXT,"
-                    + Notes.CREATED_DATE + " INTEGER,"
-                    + Notes.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(Notes._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 = NotePad.Notes.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 Notes.CONTENT_TYPE;
+    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
+            throws FileNotFoundException {
 
-        case NOTE_ID:
-            return Notes.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(NotePad.Notes.CREATED_DATE) == false) {
-            values.put(NotePad.Notes.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(NotePad.Notes.MODIFIED_DATE) == false) {
-            values.put(NotePad.Notes.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(NotePad.Notes.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(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
+            values.put(NotePad.Notes.COLUMN_NAME_TITLE, r.getString(android.R.string.untitled));
         }
 
-        if (values.containsKey(NotePad.Notes.NOTE) == false) {
-            values.put(NotePad.Notes.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, Notes.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(NotePad.Notes.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();
+
         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, Notes._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:
+                // From the incoming URI, get the note ID
+                String noteId = uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION);
+
+                // If no where clause was passed in, uses the note ID column name
+                // for a column and the note ID for a value.
+                if (TextUtils.isEmpty(where)) {
+                    where = NotePad.Notes._ID + " = ?";
+                    whereArgs[0] = noteId;
+
+                } else {
+
+                    /*
+                     * If where clause columns were passed in, appends the note ID column name to
+                     * the list of columns using a replaceable parameter. This works even if the
+                     * other columns have actual values.
+                     */
+                    // Appends the note ID column name as an AND condition using a replaceable
+                    // parameter.
+                    where = where + " AND " + NotePad.Notes._ID + " = ?";
+
+                    // Appends the note ID value to the end of the where clause values.
+                    whereArgs[whereArgs.length] = noteId;
+                }
+
+                // Performs the delete.
+                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;
+
+            // 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;
+
+        // 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, Notes._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);
+
+                // If no where clause was passed in, uses the note ID column name
+                // for a column and the note ID for a value.
+                if (TextUtils.isEmpty(where)) {
+                    where = NotePad.Notes._ID + " = " + noteId;
+
+                    // If where clause columns were passed in, appends the note ID to the where
+                    // clause
+                } else {
+
+                    /*
+                     * Prepends the note ID column name to the search criteria. This handles two
+                     * cases: a) whereArgs contains values b) whereArgs is null.
+                     *
+                     */
+                    where = NotePad.Notes._ID + " = " + noteId +  " 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.
+                    where,                    // The where clause column names. May contain
+                                              // 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(Notes._ID, Notes._ID);
-        sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);
-        sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);
-        sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE);
-        sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE);
-
-        // Support for Live Folders.
-        sLiveFolderProjectionMap = new HashMap<String, String>();
-        sLiveFolderProjectionMap.put(LiveFolders._ID, Notes._ID + " AS " +
-                LiveFolders._ID);
-        sLiveFolderProjectionMap.put(LiveFolders.NAME, Notes.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 ceaaa3c..6229dd2 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotesList.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotesList.java
@@ -16,11 +16,14 @@
 
 package com.example.android.notepad;
 
-import com.example.android.notepad.NotePad.Notes;
+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;
@@ -37,79 +40,209 @@
 
 /**
  * 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 NotePadProvider}
+ * 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";
 
     // Menu item ids
     public static final int MENU_ITEM_DELETE = Menu.FIRST;
-    public static final int MENU_ITEM_INSERT = Menu.FIRST + 1;
+    public static final int MENU_ITEM_COPY = Menu.FIRST + 1;
+    public static final int MENU_ITEM_INSERT = Menu.FIRST + 2;
+    public static final int MENU_ITEM_PASTE = Menu.FIRST + 3;
 
     /**
-     * The columns we are interested in from the database
+     * The columns needed by the cursor adapter
      */
     private static final String[] PROJECTION = new String[] {
-            Notes._ID, // 0
-            Notes.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;
-    
+
+    private MenuItem mPasteItem;
+
+    /**
+     * 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(Notes.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,
-                Notes.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[] { Notes.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) {
+
+        // The parent method creates the default method with the standard system items.
         super.onCreateOptionsMenu(menu);
 
-        // This is our one standard application action -- inserting a
-        // new note into the list.
-        menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
-                .setShortcut('3', 'a')
-                .setIcon(android.R.drawable.ic_menu_add);
+        // Adds an Insert menu item
+        MenuItem menuItem = menu.add(
+            Menu.NONE,                    // No menu group.
+            MENU_ITEM_INSERT,             // Unique ID for this item.
+            Menu.NONE,                    // No order within the group.
+            R.string.menu_insert          // Displayed text for the menu item.
+        );
 
-        // Generate any additional actions that can be performed on the
+        // Sets keyboard shortcuts for the menu item, either "3" or "a";
+        menuItem.setShortcut('3', 'a');
+
+        // Sets the icon for the menu item
+        menuItem.setIcon(android.R.drawable.ic_menu_add);
+
+        // 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.
+        mPasteItem = menu.add(
+                Menu.NONE,                // No menu group.
+                MENU_ITEM_PASTE,          // A unique ID for this item
+                Menu.NONE,                // No menu order
+                R.string.menu_paste       // The displayed text
+        ).setShortcut('4', 'p');          // Set the keyboard shortcuts for this new item.
+
+        // Generates 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
         // our menu with their own actions.
+
+        /* Creates a new Intent with the same incoming data and no defined action.
+         * It also sets its category to ALTERNATIVE. This prepares the Intent as a place
+         * to group alternative options in the menu.
+         */
         Intent intent = new Intent(null, getIntent().getData());
         intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
-        menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
-                new ComponentName(this, NotesList.class), null, intent, 0, null);
 
+        /* Creates a ComponentName from the current Context and this Activity object's
+         * class object.
+         */
+        ComponentName component = new ComponentName(this, NotesList.class);
+
+        /*
+         * Adds any other activities that want to be alternatives for this view. In effect,
+         * any application can add itself as an alternative on the options menu.
+         */
+        menu.addIntentOptions(
+            Menu.CATEGORY_ALTERNATIVE,   // Add the options to the Alternatives group
+            Menu.NONE,                   // Do not use a unique ID
+            Menu.NONE,                   // No need to order the options
+            component,                   // The ComponentName of the Activity making the request.
+                                         // This Activity is excluded from the list of alternatives.
+            null,                        // No specific items are listed first.
+            intent,                      // The Intent to resolve to, in effect, an Intent listing
+                                         // the alternatives
+            Menu.NONE,                   // no flags are needed
+            null                         // Since no specifics were used, so a menu item array is
+                                         // not needed.
+        );
+
+        // Returns true so that the menu is displayed.
         return true;
     }
 
     @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);
+
+        // 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
@@ -118,97 +251,296 @@
         // 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());
 
-            // Build menu...  always starts with the EDIT action...
+            // 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];
 
-            // ... is followed by whatever other actions are available...
+            // 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);
-            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
-                    items);
 
-            // Give a shortcut to the edit action.
-            if (items[0] != null) {
-                items[0].setShortcut('1', 'e');
+
+            /*
+             * 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);
             }
-        } else {
-            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) {
+
+        // Gets the ID of the selected item
         switch (item.getItemId()) {
+
+        // If the menu item is Insert
         case MENU_ITEM_INSERT:
-            // Launch activity to insert a new item
+
+            /*
+             * 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;
+
+        // If the menu item is Paste
+        case MENU_ITEM_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;
         }
+
+        // If the menu item selected is not Insert or Paste, then this calls the regular
+        // processing to handle the item.
         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;
         }
 
-        // Setup the menu header
+        // Sets the menu header to be the title of the selected note.
         menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
 
-        // Add a menu item to delete the note
-        menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete);
+        // Adds a menu item to copy the note to the context menu
+        menu.add(
+            Menu.NONE,          // No grouping is needed for this menu
+            MENU_ITEM_COPY,     // A unique ID for this menu item.
+            Menu.NONE,          // No ordering is necessary in this menu
+            R.string.menu_copy  // The resource ID for the string to display for this item.
+        );
+
+        // Adds a menu item to delete the note to the context menu
+        menu.add(
+            Menu.NONE,            // No grouping is needed for this menu
+            MENU_ITEM_DELETE,     // A unique ID for this menu item.
+            Menu.NONE,            // No ordering is necessary in this menu
+            R.string.menu_delete  // The resource ID for the string to display for this item.
+        );
     }
-        
+
+    /**
+     * 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;
         }
 
+        /*
+         * Gets the menu item's ID and compares it to known actions. The only actions that are
+         * implemented are COPY and DELETE (set in onCreateContextMenu()).
+         */
         switch (item.getItemId()) {
+
+            // Deletes the selected note
             case MENU_ITEM_DELETE: {
-                // Delete the note that the context menu is for
+
+                // Appends the selected note's ID to the URI sent with the incoming Intent.
                 Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
-                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;
             }
+
+//BEGIN_INCLUDE(copy)
+            // Copies the selected note to the clipboard
+            case MENU_ITEM_COPY: {
+
+                // Gets a handle to the clipboard service.
+                ClipboardManager clipboard = (ClipboardManager)
+                        getSystemService(Context.CLIPBOARD_SERVICE);
+
+                // Appends the selected note's ID to the URI sent with the incoming Intent.
+                Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
+
+                // 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)
         }
         return false;
     }
 
+    /**
+     * 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) {
+
+        // 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.
+
+            // 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
+
+            // 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 50d38e5..02c933d 100644
--- a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
+++ b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
@@ -16,7 +16,7 @@
 
 package com.example.android.notepad;
 
-import com.example.android.notepad.NotePad.Notes;
+import com.example.android.notepad.NotePad;
 
 import android.app.Activity;
 import android.content.ContentValues;
@@ -28,8 +28,13 @@
 import android.widget.EditText;
 
 /**
- * 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 {
 
@@ -38,78 +43,139 @@
      */
     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[] {
             NotePad.Notes._ID, // 0
-            NotePad.Notes.TITLE, // 1
+            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.
+         */
+        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.
+        );
 
-        // Set up click handlers for the text field and button
+        // Gets the View ID for the EditText box
         mText = (EditText) this.findViewById(R.id.title);
-        mText.setOnClickListener(this);
-        
+
+        // Sets up a listener for the OK button. Gets the Button by its ID, then sets its
+        // onClickListener to this Activity.
         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(Notes.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.
+            );
         }
     }
 
+    /**
+     * This method is called when the user clicks anywhere in the title text box.
+     *
+     * It calls finish(), which immediately triggers the onPause() method in this Activity. In
+     * turn, onPause() saves the text currently in the title text box to the note.
+     */
     public void onClick(View v) {
-        // When the user clicks, just finish this activity.
-        // onPause will be called, and we save our data there.
+
+        // Calls finish to force the Activity to shut down. In the lifecycle, this forces a call to
+        // onPause(), which saves the work the user has done.
         finish();
     }
 }
diff --git a/samples/NotePad/src/com/google/provider/NotePad.java b/samples/NotePad/src/com/google/provider/NotePad.java
deleted file mode 100644
index f8de69b..0000000
--- a/samples/NotePad/src/com/google/provider/NotePad.java
+++ /dev/null
@@ -1,65 +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.google.provider;
-
-import android.net.Uri;
-import android.provider.BaseColumns;
-
-/**
- * Convenience definitions for NotePadProvider
- */
-public final class NotePad {
-    /**
-     * Notes table
-     */
-    public static final class Notes implements BaseColumns {
-        /**
-         * The content:// style URL for this table
-         */
-        public static final Uri CONTENT_URI
-                = Uri.parse("content://com.google.provider.NotePad/notes");
-
-        /**
-         * The default sort order for this table
-         */
-        public static final String DEFAULT_SORT_ORDER = "modified DESC";
-
-        /**
-         * The title of the note
-         * <P>Type: TEXT</P>
-         */
-        public static final String TITLE = "title";
-
-        /**
-         * The note itself
-         * <P>Type: TEXT</P>
-         */
-        public static final String NOTE = "note";
-
-        /**
-         * The timestamp for when the note was created
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String CREATED_DATE = "created";
-
-        /**
-         * The timestamp for when the note was last modified
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String MODIFIED_DATE = "modified";
-    }
-}
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/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 86%
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..c8acdf0 100644
--- a/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
@@ -24,13 +24,13 @@
  * 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() {
-        super(NotesList.class);
+    public NotePadActivityTest() {
+        super("com.example.android.notepad.test",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..4790e42
--- /dev/null
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadProviderTest.java
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.test.ProviderTestCase2;
+import android.test.mock.MockContentResolver;
+
+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();
+
+    /*
+     * 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 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..24a3327
--- /dev/null
+++ b/samples/XmlAdapters/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := XmlAdaptersSample
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/XmlAdapters/AndroidManifest.xml b/samples/XmlAdapters/AndroidManifest.xml
new file mode 100644
index 0000000..e4ac4d8
--- /dev/null
+++ b/samples/XmlAdapters/AndroidManifest.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.xmladapters">
+    
+    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+
+    <application android:label="@string/app_name">
+        <activity android:name="ContactsListActivity"
+                  android:label="@string/contacts_list_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="PhotosListActivity"
+                  android:label="@string/photos_list_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="RssReaderActivity"
+                  android:label="@string/rss_reader_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <provider android:name="android.content.XmlDocumentProvider"
+           android:authorities="xmldocument" />
+
+    </application>
+
+</manifest>
+
diff --git a/samples/XmlAdapters/_index.html b/samples/XmlAdapters/_index.html
new file mode 100644
index 0000000..2ca3608
--- /dev/null
+++ b/samples/XmlAdapters/_index.html
@@ -0,0 +1,31 @@
+<p>This sample demonstrates the use of XML adapters.</p>
+
+<p>An XML Adapter is an XML file which defines the bindings between the data
+retrieved from a
+<a href="../../../reference/android/content/ContentProvider.html"><code>ContentProvider</code></a>
+and the different views of a layout. They are provided by the
+<a href="../../../reference/android/widget/Adapters.html"><code>Adapters</code></a>
+class.</p>
+
+Three list activities are provided which illustrate this:
+<ul>
+  <li><a href="src/com/example/android/xmladapters/ContactsListActivity.html"><strong>
+  ContactsListActivity</strong></a> uses the device's Contacts provider as its input source.
+  Contacts with a phone number are displayed, their photo being retrieved by a dedicated
+  <a href="src/com/example/android/xmladapters/ContactPhotoBinder.html"><code>ContactPhotoBinder
+  </code></a>.</li>
+
+  <li><a href="src/com/example/android/xmladapters/PhotosListActivity.html"><strong>
+  PhotosListActivity</strong></a> retrieves an RSS photo feed and displays the images and their
+  titles. The images are downloaded from the URL found in the feed using the
+  <a href="src/com/example/android/xmladapters/ImageDownloader.html"><code>ImageDownloader</code>
+  </a> helper class.</li>
+
+  <li><a href="src/com/example/android/xmladapters/RssReaderActivity.html"><strong>
+  RssReaderActivity</strong></a> also displays items extracted from an RSS feed. An additional
+  <a href="src/com/example/android/xmladapters/UrlIntentListener.html"><code>UrlIntentListener
+  </code></a> is used to open a browser when one of the news item is tapped.</li>
+</ul>
+
+<img alt="XmlPhotosAdapter" src="../images/XmlPhotosAdapter.png" />
+<img alt="XmlRssReader" src="../images/XmlRssReader.png" />
diff --git a/samples/XmlAdapters/res/drawable-hdpi/ic_contact_picture.png b/samples/XmlAdapters/res/drawable-hdpi/ic_contact_picture.png
new file mode 100644
index 0000000..a60565a
--- /dev/null
+++ b/samples/XmlAdapters/res/drawable-hdpi/ic_contact_picture.png
Binary files differ
diff --git a/samples/XmlAdapters/res/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/XmlAdapters/res/values/strings.xml b/samples/XmlAdapters/res/values/strings.xml
new file mode 100644
index 0000000..1ae158e
--- /dev/null
+++ b/samples/XmlAdapters/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASI
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">Xml Adapters</string>
+    <string name="contacts_list_activity">Xml Contacts Adapter</string>
+    <string name="photos_list_activity">Xml Photos Adapter</string>
+    <string name="rss_reader_activity">Xml RSS Reader</string>
+    <string name="no_contacts">No contacts available</string>
+    <string name="no_photos">Loading photos...</string>
+    <string name="no_rss_feed">Loading RSS feed...</string>
+
+</resources>
diff --git a/samples/XmlAdapters/res/xml/contacts.xml b/samples/XmlAdapters/res/xml/contacts.xml
new file mode 100644
index 0000000..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/XmlAdapters/res/xml/photos.xml b/samples/XmlAdapters/res/xml/photos.xml
new file mode 100644
index 0000000..a62e62e
--- /dev/null
+++ b/samples/XmlAdapters/res/xml/photos.xml
@@ -0,0 +1,25 @@
+<?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="/feed/entry"
+    android:layout="@layout/photo_item">
+
+    <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" />
+
+</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 96c520a..9b85b82 100644
--- a/samples/source.properties
+++ b/samples/source.properties
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
 Pkg.Revision=1
 AndroidVersion.ApiLevel=8
-#AndroidVersion.CodeName=
+AndroidVersion.CodeName=Froyo
 
diff --git a/sdk/doc_source.properties b/sdk/doc_source.properties
index 69d50d3..9b85b82 100644
--- a/sdk/doc_source.properties
+++ b/sdk/doc_source.properties
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
 Pkg.Revision=1
 AndroidVersion.ApiLevel=8
-AndroidVersion.CodeName=gingerbread
+AndroidVersion.CodeName=Froyo
 
diff --git a/sdk/platform_source.properties b/sdk/platform_source.properties
index 7abd7a3..5134b61 100644
--- a/sdk/platform_source.properties
+++ b/sdk/platform_source.properties
@@ -3,4 +3,4 @@
 Platform.Version=2.x
 Pkg.Revision=1
 AndroidVersion.ApiLevel=8
-AndroidVersion.CodeName=gingerbread
+AndroidVersion.CodeName=Froyo
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..3209574 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -395,7 +395,8 @@
 <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"
@@ -499,6 +500,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/tools/elftree/MODULE_LICENSE_APACHE2 b/tools/elftree/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/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/src/com/android/tools/dict/BigramDictionary.java b/tools/makedict/src/com/android/tools/dict/BigramDictionary.java
new file mode 100644
index 0000000..35115bf
--- /dev/null
+++ b/tools/makedict/src/com/android/tools/dict/BigramDictionary.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * Helper for MakeBinaryDictionary
+ * Deals with all the bigram data
+ */
+public class BigramDictionary {
+
+    /*
+     * Must match the values in the client side which is located in dictionary.cpp & dictionary.h
+     * Changing these values will generate totally different structure which must be also reflected
+     * on the client side.
+     */
+    public static final int FLAG_BIGRAM_READ = 0x80;
+    public static final int FLAG_BIGRAM_CHILDEXIST = 0x40;
+    public static final int FLAG_BIGRAM_CONTINUED = 0x80;
+    public static final int FLAG_BIGRAM_FREQ = 0x7F;
+
+    public static final int FOR_REVERSE_LOOKUPALL = -99;
+
+    public ArrayList<String> mBigramToFill = new ArrayList<String>();
+    public ArrayList<Integer> mBigramToFillAddress = new ArrayList<Integer>();
+
+    public HashMap<String, Bigram> mBi;
+
+    public boolean mHasBigram;
+
+    public BigramDictionary(String bigramSrcFilename, boolean hasBigram) {
+        mHasBigram = hasBigram;
+        loadBigram(bigramSrcFilename);
+    }
+
+    private void loadBigram(String filename) {
+        mBi = new HashMap<String, Bigram>();
+        if (!mHasBigram) {
+            System.out.println("Number of bigrams = " + Bigram.sBigramNum);
+            return;
+        }
+        try {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            parser.parse(new File(filename), new DefaultHandler() {
+                String w1 = null;
+                boolean inWord1 = false;
+                boolean inWord2 = false;
+                int freq = 0, counter = 0;
+                Bigram tempBigram = null;
+
+                @Override
+                public void startElement(String uri, String localName,
+                        String qName, Attributes attributes) {
+                    if (qName.equals("bi")) {
+                        inWord1 = true;
+                        w1 = attributes.getValue(0);
+                        int count = Integer.parseInt(attributes.getValue(1));
+                        tempBigram = new Bigram(count);
+                        counter = 0;
+                    } else if (qName.equals("w")) {
+                        inWord2 = true;
+                        String word2 = attributes.getValue(0);
+                        int freq = Integer.parseInt(attributes.getValue(1));
+                        tempBigram.setWord2(counter, word2, freq);
+                        counter++;
+                        Bigram.sBigramNum++;
+                    }
+                }
+
+                @Override
+                public void endElement(String uri, String localName,
+                        String qName) {
+                    if (inWord2) {
+                        inWord2 = false;
+                    } else if (inWord1) {
+                        inWord1 = false;
+                        mBi.put(w1, tempBigram);
+                    }
+                }
+            });
+        } catch (Exception ioe) {
+            System.err.println("Exception in parsing bigram\n" + ioe);
+            ioe.printStackTrace();
+        }
+        System.out.println("Number of bigrams = " + Bigram.sBigramNum);
+    }
+
+    byte[] writeBigrams(byte[] dict, Map<String, Integer> mDictionary) {
+        for (int i = 0; i < mBigramToFill.size(); i++) {
+            String w1 = mBigramToFill.get(i);
+            int address = mBigramToFillAddress.get(i);
+
+            Bigram temp = mBi.get(w1);
+            int word2Count = temp.count;
+            int j4;
+            for (int j = 0; j < word2Count; j++) {
+                if (!mDictionary.containsKey(temp.word2[j])) {
+                    System.out.println("Not in dictionary: " + temp.word2[j]);
+                    System.exit(0);
+                } else {
+                    j4 = (j * 4);
+                    int addressOfWord2 = mDictionary.get(temp.word2[j]);
+                    dict[address + j4 + 0] = (byte) (((addressOfWord2 & 0x3F0000) >> 16)
+                            | FLAG_BIGRAM_READ);
+                    dict[address + j4 + 1] = (byte) ((addressOfWord2 & 0x00FF00) >> 8);
+                    dict[address + j4 + 2] = (byte) ((addressOfWord2 & 0x0000FF));
+
+                    if (j == (word2Count - 1)) {
+                        dict[address + j4 + 3] = (byte) (temp.freq[j] & FLAG_BIGRAM_FREQ);
+                    } else {
+                        dict[address + j4 + 3] = (byte) ((temp.freq[j] & FLAG_BIGRAM_FREQ)
+                                | FLAG_BIGRAM_CONTINUED);
+                    }
+                }
+            }
+        }
+
+        return dict;
+    }
+
+    void reverseLookupAll(Map<String, Integer> mDictionary, byte[] dict) {
+        Set<String> st = mDictionary.keySet();
+        for (String s : st) {
+            searchForTerminalNode(mDictionary.get(s), FOR_REVERSE_LOOKUPALL, dict);
+        }
+    }
+
+    void searchForTerminalNode(int bigramAddress, int frequency, byte[] dict) {
+        StringBuilder sb = new StringBuilder(48);
+        int pos;
+        boolean found = false;
+        int followDownBranchAddress = 2;
+        char followingChar = ' ';
+        int depth = 0;
+        int totalLoopCount = 0;
+
+        while (!found) {
+            boolean followDownAddressSearchStop = false;
+            boolean firstAddress = true;
+            boolean haveToSearchAll = true;
+
+            if (depth > 0) {
+                sb.append(followingChar);
+            }
+            pos = followDownBranchAddress; // pos start at count
+            int count = dict[pos] & 0xFF;
+            pos++;
+            for (int i = 0; i < count; i++) {
+                totalLoopCount++;
+                // pos at data
+                pos++;
+                // pos now at flag
+                if (!MakeBinaryDictionary.getFirstBitOfByte(pos, dict)) { // non-terminal
+                    if (!followDownAddressSearchStop) {
+                        int addr = MakeBinaryDictionary.get22BitAddress(pos, dict);
+                        if (addr > bigramAddress) {
+                            followDownAddressSearchStop = true;
+                            if (firstAddress) {
+                                firstAddress = false;
+                                haveToSearchAll = true;
+                            } else if (!haveToSearchAll) {
+                                break;
+                            }
+                        } else {
+                            followDownBranchAddress = addr;
+                            followingChar = (char) (0xFF & dict[pos-1]);
+                            if(firstAddress) {
+                                firstAddress = false;
+                                haveToSearchAll = false;
+                            }
+                        }
+                    }
+                    pos += 3;
+                } else if (MakeBinaryDictionary.getFirstBitOfByte(pos, dict)) { // terminal
+                    // found !!
+                    if (bigramAddress == (pos-1)) {
+                        sb.append((char) (0xFF & dict[pos-1]));
+                        found = true;
+                        break;
+                    }
+
+                    // address + freq (4 byte)
+                    if (MakeBinaryDictionary.getSecondBitOfByte(pos, dict)) {
+                        if (!followDownAddressSearchStop) {
+                            int addr = MakeBinaryDictionary.get22BitAddress(pos, dict);
+                            if (addr > bigramAddress) {
+                                followDownAddressSearchStop = true;
+                                if (firstAddress) {
+                                    firstAddress = false;
+                                    haveToSearchAll = true;
+                                } else if (!haveToSearchAll) {
+                                    break;
+                                }
+                            } else {
+                                followDownBranchAddress = addr;
+                                followingChar = (char) (0xFF & dict[pos-1]);
+                                if(firstAddress) {
+                                    firstAddress = false;
+                                    haveToSearchAll = true;
+                                }
+                            }
+                        }
+                        pos += 4;
+                    } else { // freq only (2 byte)
+                        pos += 2;
+                    }
+                    // skipping bigram
+                    int bigramExist = (dict[pos] & FLAG_BIGRAM_READ);
+                    if (bigramExist > 0) {
+                        int nextBigramExist = 1;
+                        while (nextBigramExist > 0) {
+                            pos += 3;
+                            nextBigramExist = (dict[pos++] & FLAG_BIGRAM_CONTINUED);
+                        }
+                    } else {
+                        pos++;
+                    }
+                }
+            }
+            depth++;
+            if (followDownBranchAddress == 2) {
+                System.out.println("ERROR!!! Cannot find bigram!!");
+                System.exit(0);
+            }
+        }
+
+        if (frequency == FOR_REVERSE_LOOKUPALL) {
+            System.out.println("Reverse: " + sb.toString() + " (" + bigramAddress + ")"
+                    + "   Loop: " + totalLoopCount);
+        } else {
+            System.out.println("   bigram: " + sb.toString() + " (" + bigramAddress + ") freq: "
+                    + frequency + "   Loop: " + totalLoopCount);
+        }
+    }
+
+    static class Bigram {
+        String[] word2;
+        int[] freq;
+        int count;
+        static int sBigramNum = 0;
+
+        String getSecondWord(int i) {
+            return word2[i];
+        }
+
+        int getFrequency(int i) {
+            return (freq[i] == 0) ? 1 : freq[i];
+        }
+
+        void setWord2(int index, String word2, int freq) {
+            this.word2[index] = word2;
+            this.freq[index] = freq;
+        }
+
+        public Bigram(int word2Count) {
+            count = word2Count;
+            word2 = new String[word2Count];
+            freq = new int[word2Count];
+        }
+    }
+}
diff --git a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
index 77a6401..ca6de56 100755
--- a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
+++ b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
@@ -19,15 +19,11 @@
 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.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -36,10 +32,18 @@
 import javax.xml.parsers.SAXParserFactory;
 
 /**
- * Compresses a list of words and frequencies into a tree structured binary dictionary.
+ * Compresses a list of words, frequencies, and bigram data
+ * into a tree structured binary dictionary.
+ * Dictionary Version: 200 (may contain bigrams)
+ *  Version number started from 200 rather than 1 because we wanted to prevent number of roots in
+ *  any old dictionaries being mistaken as the version number. There is not a chance that there
+ *  will be more than 200 roots. Version number should be increased when there is structural change
+ *  in the data. There is no need to increase the version when only the words in the data changes.
  */
 public class MakeBinaryDictionary {
 
+    private static final int VERSION_NUM = 200;
+
     public static final int ALPHA_SIZE = 256;
 
     public static final String TAG_WORD = "w";
@@ -48,13 +52,23 @@
     private static final int FLAG_ADDRESS_MASK  = 0x400000;
     private static final int FLAG_TERMINAL_MASK = 0x800000;
     private static final int ADDRESS_MASK = 0x3FFFFF;
-    
+
+    /**
+     * Unit for this variable is in bytes
+     * If destination file name is main.dict and file limit causes dictionary to be separated into
+     * multiple file, it will generate main0.dict, main1.dict, and so forth.
+     */
+    private static int sOutputFileSize;
+    private static boolean sSplitOutput;
+
     public static final CharNode EMPTY_NODE = new CharNode();
 
     List<CharNode> roots;
     Map<String, Integer> mDictionary;
     int mWordCount;
-    
+
+    BigramDictionary bigramDict;
+
     static class CharNode {
         char data;
         int freq;
@@ -68,29 +82,59 @@
     }
 
     public static void usage() {
-        System.err.println("Usage: makedict <src.xml> <dest.dict>");
+        System.err.println("Usage: makedict -s <src_dict.xml> [-b <src_bigram.xml>] "
+                + "-d <dest.dict> [--size filesize]");
         System.exit(-1);
     }
     
     public static void main(String[] args) {
-        if (args.length < 2) {
-            usage();
+        int checkSource = -1;
+        int checkBigram = -1;
+        int checkDest = -1;
+        int checkFileSize = -1;
+        for (int i = 0; i < args.length; i+=2) {
+            if (args[i].equals("-s")) checkSource = (i + 1);
+            if (args[i].equals("-b")) checkBigram = (i + 1);
+            if (args[i].equals("-d")) checkDest = (i + 1);
+            if (args[i].equals("--size")) checkFileSize = (i + 1);
+        }
+        if (checkFileSize >= 0) {
+            sSplitOutput = true;
+            sOutputFileSize = Integer.parseInt(args[checkFileSize]);
         } else {
-            new MakeBinaryDictionary(args[0], args[1]);
+            sSplitOutput = false;
+        }
+        if (checkDest >= 0 && !args[checkDest].endsWith(".dict")) {
+            System.err.println("Error: Dictionary output file extension should be \".dict\"");
+            usage();
+        } else if (checkSource >= 0 && checkBigram >= 0 && checkDest >= 0 &&
+                ((!sSplitOutput && args.length == 6) || (sSplitOutput && args.length == 8))) {
+            new MakeBinaryDictionary(args[checkSource], args[checkBigram], args[checkDest]);
+        } else if (checkSource >= 0 && checkDest >= 0 &&
+                ((!sSplitOutput && args.length == 4) || (sSplitOutput && args.length == 6))) {
+            new MakeBinaryDictionary(args[checkSource], null, args[checkDest]);
+        } else {
+            usage();
         }
     }
 
-    public MakeBinaryDictionary(String srcFilename, String destFilename) {
+    public MakeBinaryDictionary(String srcFilename, String bigramSrcFilename, String destFilename){
+        System.out.println("Generating dictionary version " + VERSION_NUM);
+        bigramDict = new BigramDictionary(bigramSrcFilename, (bigramSrcFilename != null));
         populateDictionary(srcFilename);
         writeToDict(destFilename);
-        // Enable the code below to verify that the generated tree is traversable.
+
+        // Enable the code below to verify that the generated tree is traversable
+        // and bigram data is stored correctly.
         if (false) {
-            traverseDict(0, new char[32], 0);
+            bigramDict.reverseLookupAll(mDictionary, dict);
+            traverseDict(2, new char[32], 0);
         }
     }
-    
+
     private void populateDictionary(String filename) {
         roots = new ArrayList<CharNode>();
+        mDictionary = new HashMap<String, Integer>();
         try {
             SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
             parser.parse(new File(filename), new DefaultHandler() {
@@ -205,8 +249,11 @@
     private void addCount(int count) {
         dict[dictSize++] = (byte) (0xFF & count);
     }
-    
-    private void addNode(CharNode node) {
+
+    private void addNode(CharNode node, String word1) {
+        if (node.terminal) { // store address of each word1
+            mDictionary.put(word1, dictSize);
+        }
         int charData = 0xFFFF & node.data;
         if (charData > 254) {
             dict[dictSize++] = (byte) 255;
@@ -226,6 +273,15 @@
         if (node.terminal) {
             byte freq = (byte) (0xFF & node.freq);
             dict[dictSize++] = freq;
+            // bigram
+            if (bigramDict.mBi.containsKey(word1)) {
+                int count = bigramDict.mBi.get(word1).count;
+                bigramDict.mBigramToFill.add(word1);
+                bigramDict.mBigramToFillAddress.add(dictSize);
+                dictSize += (4 * count);
+            } else {
+                dict[dictSize++] = (byte) (0x00);
+            }
         }
     }
 
@@ -255,24 +311,27 @@
         }
     }
 
-    void writeWordsRec(List<CharNode> children) {
+    void writeWordsRec(List<CharNode> children, StringBuilder word) {
         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);
+            word.append(children.get(j).data);
+            addNode(node, word.toString());
+            word.deleteCharAt(word.length()-1);
         }
         for (int j = 0; j < childCount; j++) {
             CharNode node = children.get(j);
             int nodeAddress = childrenAddresses[j];
             int cacheDictSize = dictSize;
-            writeWordsRec(node.children);
+            word.append(children.get(j).data);
+            writeWordsRec(node.children, word);
+            word.deleteCharAt(word.length()-1);
             updateNodeAddress(nodeAddress, node, node.children != null
                     ? cacheDictSize : 0);
         }
@@ -284,12 +343,40 @@
                                           // < 1MB in most cases, as there is a limit in the
                                           // resource size in apks.
         dictSize = 0;
-        writeWordsRec(roots);
+
+        dict[dictSize++] = (byte) (0xFF & VERSION_NUM); // version info
+        dict[dictSize++] = (byte) (0xFF & (bigramDict.mHasBigram ? 1 : 0));
+
+        StringBuilder word = new StringBuilder(48);
+        writeWordsRec(roots, word);
+        dict = bigramDict.writeBigrams(dict, mDictionary);
         System.out.println("Dict Size = " + dictSize);
+        if (!sSplitOutput) {
+            sOutputFileSize = dictSize;
+        }
         try {
-            FileOutputStream fos = new FileOutputStream(dictFilename);
-            fos.write(dict, 0, dictSize);
-            fos.close();
+            int currentLoc = 0;
+            int i = 0;
+            int extension = dictFilename.indexOf(".dict");
+            String filename = dictFilename.substring(0, extension);
+            while (dictSize > 0) {
+                FileOutputStream fos;
+                if (sSplitOutput) {
+                    fos = new FileOutputStream(filename + i + ".dict");
+                } else {
+                    fos = new FileOutputStream(filename + ".dict");
+                }
+                if (dictSize > sOutputFileSize) {
+                    fos.write(dict, currentLoc, sOutputFileSize);
+                    dictSize -= sOutputFileSize;
+                    currentLoc += sOutputFileSize;
+                } else {
+                    fos.write(dict, currentLoc, dictSize);
+                    dictSize = 0;
+                }
+                fos.close();
+                i++;
+            }
         } catch (IOException ioe) {
             System.err.println("Error writing dict file:" + ioe);
         }
@@ -299,24 +386,36 @@
         int count = dict[pos++] & 0xFF;
         for (int i = 0; i < count; i++) {
             char c = (char) (dict[pos++] & 0xFF);
-            if (c == 0xFF) {
+            if (c == 0xFF) { // two byte character
                 c = (char) (((dict[pos] & 0xFF) << 8) | (dict[pos+1] & 0xFF));
                 pos += 2;
             }
             word[depth] = c;
-            boolean terminal = (dict[pos] & 0x80) > 0;
+            boolean terminal = getFirstBitOfByte(pos, dict);
             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;
+            if ((dict[pos] & (FLAG_ADDRESS_MASK >> 16)) > 0) { // address check
+                address = get22BitAddress(pos, dict);
+                pos += 3;
+            } else {
+                pos += 1;
             }
-            pos++;
             if (terminal) {
                 showWord(word, depth + 1, dict[pos] & 0xFF);
                 pos++;
+
+                int bigramExist = (dict[pos] & bigramDict.FLAG_BIGRAM_READ);
+                if (bigramExist > 0) {
+                    int nextBigramExist = 1;
+                    while (nextBigramExist > 0) {
+                        int bigramAddress = get22BitAddress(pos, dict);
+                        pos += 3;
+                        int frequency = (bigramDict.FLAG_BIGRAM_FREQ & dict[pos]);
+                        bigramDict.searchForTerminalNode(bigramAddress, frequency, dict);
+                        nextBigramExist = (dict[pos++] & bigramDict.FLAG_BIGRAM_CONTINUED);
+                    }
+                } else {
+                    pos++;
+                }
             }
             if (address != 0) {
                 traverseDict(address, word, depth + 1);
@@ -327,4 +426,18 @@
     void showWord(char[] word, int size, int freq) {
         System.out.print(new String(word, 0, size) + " " + freq + "\n");
     }
+
+    static int get22BitAddress(int pos, byte[] dict) {
+        return ((dict[pos + 0] & 0x3F) << 16)
+                | ((dict[pos + 1] & 0xFF) << 8)
+                | ((dict[pos + 2] & 0xFF));
+    }
+
+    static boolean getFirstBitOfByte(int pos, byte[] dict) {
+        return (dict[pos] & 0x80) > 0;
+    }
+
+    static boolean getSecondBitOfByte(int pos, byte[] dict) {
+        return (dict[pos] & 0x40) > 0;
+    }
 }