am 17b152d9: am 60880978: am fe32c3ad: Adjust tags format in _index.jd files.

* commit '17b152d9a273987645fa97b0df00a35378efc85a':
  Adjust tags format in _index.jd files.
diff --git a/apps/Development/res/layout/connectivity.xml b/apps/Development/res/layout/connectivity.xml
index 2df645c..53f1ed7 100644
--- a/apps/Development/res/layout/connectivity.xml
+++ b/apps/Development/res/layout/connectivity.xml
@@ -213,6 +213,33 @@
 
     <LinearLayout
       android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/startTdls"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/start_tdls" />
+        <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/mac_tdls" />
+        <EditText android:id="@+id/sc_ip_mac"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:minEms="10" />
+        <Button android:id="@+id/stopTdls"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/stop_tdls" />
+    </LinearLayout>
+
+    <!-- divider line -->
+    <View android:background="#FFFFFFFF"
+      android:layout_width="match_parent"
+      android:layout_height="3dip" />
+
+    <LinearLayout
+      android:orientation="horizontal"
       android:paddingTop="4dip"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index b7ed5e1..ced7b72 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -34,6 +34,10 @@
     <string name="scan_cycles">Scan Cycles: </string>
     <string name="disconnect">Disconnect</string>
 
+    <string name="start_tdls">Start TDLS</string>
+    <string name="stop_tdls">Stop TDLS</string>
+    <string name="mac_tdls"> IP/MAC: </string>
+
     <string name="start_mms">Start MMS</string>
     <string name="stop_mms">Stop MMS</string>
     <string name="start_hipri">Start HiPri</string>
diff --git a/apps/Development/src/com/android/development/Connectivity.java b/apps/Development/src/com/android/development/Connectivity.java
index 95487dc..7d4491b 100644
--- a/apps/Development/src/com/android/development/Connectivity.java
+++ b/apps/Development/src/com/android/development/Connectivity.java
@@ -117,6 +117,8 @@
     private long mTotalScanTime = 0;
     private long mTotalScanCount = 0;
 
+    private String mTdlsAddr = null;
+
     private WifiManager mWm;
     private PowerManager mPm;
     private ConnectivityManager mCm;
@@ -235,6 +237,7 @@
                     unregisterReceiver(mScanRecv);
                     mScanButton.setText(GET_SCAN_RES);
                 } else {
+                    Log.d(TAG, "Scan: START " + mScanCur);
                     mStartTime = SystemClock.elapsedRealtime();
                     mWm.startScan();
                 }
@@ -289,6 +292,9 @@
         mIntentFilter = new IntentFilter();
         mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
 
+        findViewById(R.id.startTdls).setOnClickListener(mClickListener);
+        findViewById(R.id.stopTdls).setOnClickListener(mClickListener);
+
         findViewById(R.id.start_mms).setOnClickListener(mClickListener);
         findViewById(R.id.stop_mms).setOnClickListener(mClickListener);
         findViewById(R.id.start_hipri).setOnClickListener(mClickListener);
@@ -338,6 +344,12 @@
                 case R.id.startScan:
                     onStartScanCycle();
                     break;
+                case R.id.startTdls:
+                    onStartTdls();
+                    break;
+                case R.id.stopTdls:
+                    onStopTdls();
+                    break;
                 case R.id.start_mms:
                     mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                             Phone.FEATURE_ENABLE_MMS);
@@ -469,6 +481,7 @@
                 mWm.disconnect();
             mTotalScanTime = 0;
             mTotalScanCount = 0;
+            Log.d(TAG, "Scan: START " + mScanCur);
             mStartTime = SystemClock.elapsedRealtime();
             mWm.startScan();
         } else {
@@ -485,6 +498,30 @@
         }
     }
 
+    private void onStartTdls() {
+        mTdlsAddr = ((EditText)findViewById(R.id.sc_ip_mac)).getText().toString();
+        Log.d(TAG, "TDLS: START " + mTdlsAddr);
+        InetAddress inetAddress = null;
+        try {
+            inetAddress = InetAddress.getByName(mTdlsAddr);
+            mWm.setTdlsEnabled(inetAddress, true);
+        } catch (Exception e) {
+            mWm.setTdlsEnabledWithMacAddress(mTdlsAddr, true);
+        }
+    }
+
+    private void onStopTdls() {
+        if (mTdlsAddr == null) return;
+        Log.d(TAG, "TDLS: STOP " + mTdlsAddr);
+        InetAddress inetAddress = null;
+        try {
+            inetAddress = InetAddress.getByName(mTdlsAddr);
+            mWm.setTdlsEnabled(inetAddress, false);
+        } catch (Exception e) {
+            mWm.setTdlsEnabledWithMacAddress(mTdlsAddr, false);
+        }
+    }
+
     private void onAddDefaultRoute() {
         try {
             mNetd.addRoute("eth0", new RouteInfo(null,
diff --git a/apps/SettingInjectorSample/Android.mk b/apps/SettingInjectorSample/Android.mk
new file mode 100644
index 0000000..8cc0c5e
--- /dev/null
+++ b/apps/SettingInjectorSample/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := SettingInjectorSample
+
+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/apps/SettingInjectorSample/AndroidManifest.xml b/apps/SettingInjectorSample/AndroidManifest.xml
new file mode 100644
index 0000000..ef8f838
--- /dev/null
+++ b/apps/SettingInjectorSample/AndroidManifest.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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.injector">
+    <application android:label="My Setting Activity!">
+        <activity android:name="MySettingActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <service android:name="com.example.android.injector.MyInjectorService" >
+            <intent-filter>
+                <action android:name="android.location.SettingInjectorService" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.location.SettingInjectorService"
+                android:resource="@xml/my_injected_location_setting" />
+        </service>
+
+        <service android:name="com.example.android.injector.DisabledInjectorService" >
+            <intent-filter>
+                <action android:name="android.location.SettingInjectorService" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.location.SettingInjectorService"
+                android:resource="@xml/disabled_injected_location_setting" />
+        </service>
+
+        <service android:name="com.example.android.injector.FailingInjectorService" >
+            <intent-filter>
+                <action android:name="android.location.SettingInjectorService" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.location.SettingInjectorService"
+                android:resource="@xml/failing_injected_location_setting" />
+        </service>
+
+        <service android:name="com.example.android.injector.SlowInjectorService" >
+            <intent-filter>
+                <action android:name="android.location.SettingInjectorService" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.location.SettingInjectorService"
+                android:resource="@xml/slow_injected_location_setting" />
+        </service>
+
+        <service android:name="com.example.android.injector.UpdatingInjectorService" >
+            <intent-filter>
+                <action android:name="android.location.SettingInjectorService" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.location.SettingInjectorService"
+                android:resource="@xml/updating_injected_location_setting" />
+        </service>
+
+    </application>
+</manifest>
diff --git a/apps/SettingInjectorSample/res/drawable-hdpi/ic_launcher.png b/apps/SettingInjectorSample/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..c1b44cc
--- /dev/null
+++ b/apps/SettingInjectorSample/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/apps/SettingInjectorSample/res/drawable-hdpi/ic_my_injected_setting.png b/apps/SettingInjectorSample/res/drawable-hdpi/ic_my_injected_setting.png
new file mode 100644
index 0000000..053b527
--- /dev/null
+++ b/apps/SettingInjectorSample/res/drawable-hdpi/ic_my_injected_setting.png
Binary files differ
diff --git a/apps/SettingInjectorSample/res/drawable-mdpi/ic_launcher.png b/apps/SettingInjectorSample/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..a1bf709
--- /dev/null
+++ b/apps/SettingInjectorSample/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/apps/SettingInjectorSample/res/drawable-mdpi/ic_my_injected_setting.png b/apps/SettingInjectorSample/res/drawable-mdpi/ic_my_injected_setting.png
new file mode 100644
index 0000000..7fe282f
--- /dev/null
+++ b/apps/SettingInjectorSample/res/drawable-mdpi/ic_my_injected_setting.png
Binary files differ
diff --git a/apps/SettingInjectorSample/res/drawable-xhdpi/ic_launcher.png b/apps/SettingInjectorSample/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..a1bf709
--- /dev/null
+++ b/apps/SettingInjectorSample/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/apps/SettingInjectorSample/res/drawable-xhdpi/ic_my_injected_setting.png b/apps/SettingInjectorSample/res/drawable-xhdpi/ic_my_injected_setting.png
new file mode 100644
index 0000000..a625b3a
--- /dev/null
+++ b/apps/SettingInjectorSample/res/drawable-xhdpi/ic_my_injected_setting.png
Binary files differ
diff --git a/apps/SettingInjectorSample/res/drawable-xxhdpi/ic_launcher.png b/apps/SettingInjectorSample/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b7df51b
--- /dev/null
+++ b/apps/SettingInjectorSample/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/apps/SettingInjectorSample/res/layout/my_setting_activity.xml b/apps/SettingInjectorSample/res/layout/my_setting_activity.xml
new file mode 100644
index 0000000..4703a35
--- /dev/null
+++ b/apps/SettingInjectorSample/res/layout/my_setting_activity.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+
+<EditText xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:textSize="18sp"
+    android:autoText="true"
+    android:capitalize="sentences"
+    android:text="@string/my_setting_activity_text" />
+
diff --git a/apps/SettingInjectorSample/res/values/strings.xml b/apps/SettingInjectorSample/res/values/strings.xml
new file mode 100644
index 0000000..6657499
--- /dev/null
+++ b/apps/SettingInjectorSample/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="my_setting_activity_text">Hello, World!</string>
+
+    <string name="my_injected_setting_label">Injected setting</string>
+    <string name="disabled_setting_label">Disabled injected setting</string>
+    <string name="failing_setting_label">Failing injected setting</string>
+    <string name="slow_setting_label">Slow injected setting</string>
+    <string name="updating_setting_label">Updating injected setting</string>
+
+</resources>
diff --git a/apps/SettingInjectorSample/res/xml/disabled_injected_location_setting.xml b/apps/SettingInjectorSample/res/xml/disabled_injected_location_setting.xml
new file mode 100644
index 0000000..86e7d2d
--- /dev/null
+++ b/apps/SettingInjectorSample/res/xml/disabled_injected_location_setting.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/disabled_setting_label"
+    android:icon="@drawable/ic_launcher"
+    android:settingsActivity="com.example.android.injector.MySettingActivity"
+/>
diff --git a/apps/SettingInjectorSample/res/xml/failing_injected_location_setting.xml b/apps/SettingInjectorSample/res/xml/failing_injected_location_setting.xml
new file mode 100644
index 0000000..ae68d9d
--- /dev/null
+++ b/apps/SettingInjectorSample/res/xml/failing_injected_location_setting.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/failing_setting_label"
+    android:icon="@drawable/ic_launcher"
+    android:settingsActivity="com.example.android.injector.MySettingActivity"
+/>
diff --git a/apps/SettingInjectorSample/res/xml/my_injected_location_setting.xml b/apps/SettingInjectorSample/res/xml/my_injected_location_setting.xml
new file mode 100644
index 0000000..716cf39
--- /dev/null
+++ b/apps/SettingInjectorSample/res/xml/my_injected_location_setting.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/my_injected_setting_label"
+    android:icon="@drawable/ic_my_injected_setting"
+    android:settingsActivity="com.example.android.injector.MySettingActivity"
+/>
diff --git a/apps/SettingInjectorSample/res/xml/slow_injected_location_setting.xml b/apps/SettingInjectorSample/res/xml/slow_injected_location_setting.xml
new file mode 100644
index 0000000..f902cf3
--- /dev/null
+++ b/apps/SettingInjectorSample/res/xml/slow_injected_location_setting.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/slow_setting_label"
+    android:icon="@drawable/ic_launcher"
+    android:settingsActivity="com.example.android.injector.MySettingActivity"
+/>
diff --git a/apps/SettingInjectorSample/res/xml/updating_injected_location_setting.xml b/apps/SettingInjectorSample/res/xml/updating_injected_location_setting.xml
new file mode 100644
index 0000000..0e16125
--- /dev/null
+++ b/apps/SettingInjectorSample/res/xml/updating_injected_location_setting.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/updating_setting_label"
+    android:icon="@drawable/ic_launcher"
+    android:settingsActivity="com.example.android.injector.MySettingActivity"
+/>
diff --git a/apps/SettingInjectorSample/src/com/example/android/injector/DisabledInjectorService.java b/apps/SettingInjectorSample/src/com/example/android/injector/DisabledInjectorService.java
new file mode 100644
index 0000000..c122639
--- /dev/null
+++ b/apps/SettingInjectorSample/src/com/example/android/injector/DisabledInjectorService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.injector;
+
+import android.location.SettingInjectorService;
+import android.util.Log;
+
+/**
+ * Receiver that returns the status disabled for an injected setting.
+ */
+public class DisabledInjectorService extends SettingInjectorService {
+
+    private static final String TAG = "DisabledInjectorService";
+
+    public DisabledInjectorService() {
+        super(TAG);
+    }
+
+    @Override
+    protected String onGetSummary() {
+        try {
+            // Simulate a delay while reading the setting from disk
+            Thread.sleep(500);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "", e);
+        }
+        return null;
+    }
+
+    @Override
+    protected boolean onGetEnabled() {
+        return false;
+    }
+}
diff --git a/apps/SettingInjectorSample/src/com/example/android/injector/FailingInjectorService.java b/apps/SettingInjectorSample/src/com/example/android/injector/FailingInjectorService.java
new file mode 100644
index 0000000..bdd15eb
--- /dev/null
+++ b/apps/SettingInjectorSample/src/com/example/android/injector/FailingInjectorService.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.injector;
+
+import android.location.SettingInjectorService;
+import android.util.Log;
+
+/**
+ * Receiver that returns the status of the injected setting.
+ */
+public class FailingInjectorService extends SettingInjectorService {
+
+    private static final String TAG = "FailingInjectorService";
+
+    /**
+     * Whether to actually throw an exception here. Pretty disruptive when true, because it causes
+     * a "Unfortunately, My Setting Activity! has stopped" dialog to appear and also blocks the
+     * update of other settings from this app. So only set true when need to test the handling
+     * of the exception.
+     */
+    private static final boolean ACTUALLY_THROW = false;
+
+    public FailingInjectorService() {
+        super(TAG);
+    }
+
+    @Override
+    protected String onGetSummary() {
+        try {
+            // Simulate a delay while reading the setting from disk
+            Thread.sleep(100);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "", e);
+        }
+
+        if (ACTUALLY_THROW) {
+            throw new RuntimeException("Simulated failure reading setting");
+        }
+        return "Decided not to throw exception after all";
+    }
+
+    @Override
+    protected boolean onGetEnabled() {
+        return false;
+    }
+}
diff --git a/apps/SettingInjectorSample/src/com/example/android/injector/MyInjectorService.java b/apps/SettingInjectorSample/src/com/example/android/injector/MyInjectorService.java
new file mode 100644
index 0000000..8797d69
--- /dev/null
+++ b/apps/SettingInjectorSample/src/com/example/android/injector/MyInjectorService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.injector;
+
+import android.location.SettingInjectorService;
+import android.util.Log;
+
+/**
+ * Receiver that returns the status of the injected setting.
+ */
+public class MyInjectorService extends SettingInjectorService {
+
+    private static final String TAG = "MyInjectorService";
+
+    public MyInjectorService() {
+        super(TAG);
+    }
+
+    @Override
+    protected String onGetSummary() {
+        try {
+            // Simulate a delay while reading the setting from disk
+            Thread.sleep(500);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "", e);
+        }
+        return "Example status value";
+    }
+
+    @Override
+    protected boolean onGetEnabled() {
+        return true;
+    }
+}
diff --git a/apps/SettingInjectorSample/src/com/example/android/injector/MySettingActivity.java b/apps/SettingInjectorSample/src/com/example/android/injector/MySettingActivity.java
new file mode 100644
index 0000000..1e5e048
--- /dev/null
+++ b/apps/SettingInjectorSample/src/com/example/android/injector/MySettingActivity.java
@@ -0,0 +1,41 @@
+/*
+ * 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.injector;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+
+/**
+ * A minimal "Hello, World!" application.
+ */
+public class MySettingActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Set the layout for this activity.  You can find it
+        // in res/layout/my_setting_activity.xml
+        View view = getLayoutInflater().inflate(R.layout.my_setting_activity, null);
+        setContentView(view);
+    }
+}
+
diff --git a/apps/SettingInjectorSample/src/com/example/android/injector/SlowInjectorService.java b/apps/SettingInjectorSample/src/com/example/android/injector/SlowInjectorService.java
new file mode 100644
index 0000000..7cb32c9
--- /dev/null
+++ b/apps/SettingInjectorSample/src/com/example/android/injector/SlowInjectorService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.injector;
+
+import android.location.SettingInjectorService;
+import android.util.Log;
+
+/**
+ * Receiver that returns the status of the injected setting.
+ */
+public class SlowInjectorService extends SettingInjectorService {
+
+    private static final String TAG = "SlowInjectorService";
+
+    public SlowInjectorService() {
+        super(TAG);
+    }
+
+    @Override
+    protected String onGetSummary() {
+        try {
+            // Simulate a delay while reading the setting from disk
+            Thread.sleep(5000);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "", e);
+        }
+        return "Dang that took a long time!";
+    }
+
+    @Override
+    protected boolean onGetEnabled() {
+        return true;
+    }
+}
diff --git a/apps/SettingInjectorSample/src/com/example/android/injector/UpdatingInjectorService.java b/apps/SettingInjectorSample/src/com/example/android/injector/UpdatingInjectorService.java
new file mode 100644
index 0000000..3db619a
--- /dev/null
+++ b/apps/SettingInjectorSample/src/com/example/android/injector/UpdatingInjectorService.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.injector;
+
+import android.content.Intent;
+import android.location.SettingInjectorService;
+import android.util.Log;
+
+/**
+ * Receiver that returns a constantly-updating status for an injected setting.
+ */
+public class UpdatingInjectorService extends SettingInjectorService {
+
+    private static final String TAG = "UpdatingInjectorService";
+
+    public UpdatingInjectorService() {
+        super(TAG);
+    }
+
+    @Override
+    protected String onGetSummary() {
+        // Every time it asks for our status, we tell it the setting has just changed. This will
+        // test the handling of races where we're getting many UPDATE_INTENT broadcasts in a short
+        // period of time
+        Intent intent = new Intent(ACTION_INJECTED_SETTING_CHANGED);
+        sendBroadcast(intent);
+        Log.d(TAG, "Broadcasting: " + intent);
+        return String.valueOf(System.currentTimeMillis());
+    }
+
+    @Override
+    protected boolean onGetEnabled() {
+        return true;
+    }
+}
diff --git a/build/windows_sdk_whitelist.mk b/build/windows_sdk_whitelist.mk
index 8d6ac8f..f2f4d8e 100644
--- a/build/windows_sdk_whitelist.mk
+++ b/build/windows_sdk_whitelist.mk
@@ -54,6 +54,7 @@
 	system/core/liblog \
 	system/core/libsparse \
 	system/core/libzipfile \
+	system/core/libutils \
 	system/extras/ext4_utils
 
 # -----
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
index 89679a1..e41a069 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
@@ -139,7 +139,8 @@
         int viewId = Integer.parseInt(viewString);
         int connectionId = sUiTestAutomationBridge.getConnectionId();
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
-        return client.findAccessibilityNodeInfoByAccessibilityId(connectionId, windowId, viewId, 0);
+        return client.findAccessibilityNodeInfoByAccessibilityId(connectionId, windowId, viewId,
+                false, 0);
     }
 
     private static AccessibilityNodeInfo getNodeByViewId(String viewId) throws MonkeyViewException {
diff --git a/host/windows/usb/android_winusb.inf b/host/windows/usb/android_winusb.inf
index f26a75c..8dbfe09 100755
--- a/host/windows/usb/android_winusb.inf
+++ b/host/windows/usb/android_winusb.inf
@@ -6,7 +6,7 @@
 Class               = AndroidUsbDeviceClass

 ClassGuid           = {3F966BD9-FA04-4ec5-991C-D326973B5128}

 Provider            = %ProviderName%

-DriverVer           = 08/27/2012,7.0.0000.00001

+DriverVer           = 07/09/2013,8.0.0000.00000

 CatalogFile.NTx86   = androidwinusb86.cat

 CatalogFile.NTamd64 = androidwinusba64.cat

 

@@ -38,8 +38,6 @@
 

 ;Google Nexus 7

 %SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_4E40

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4E41

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E42

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

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

 

@@ -49,12 +47,8 @@
 

 ;Google Nexus (generic)

 %SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_4EE0

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4EE1

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4EE2

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

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4EE3

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4EE4&MI_01

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4EE5

+%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4EE4&MI_02

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

 

 

@@ -74,8 +68,6 @@
 

 ;Google Nexus 7

 %SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_4E40

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4E41

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E42

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

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

 

@@ -85,12 +77,8 @@
 

 ;Google Nexus (generic)

 %SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_4EE0

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4EE1

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4EE2

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

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4EE3

-%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4EE4&MI_01

-%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_4EE5

+%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4EE4&MI_02

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

 

 [USB_Install]

diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index bfbd04e..678e817 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -16,6 +16,7 @@
 	<classpathentry kind="src" path="packages/apps/Gallery2/src_pd"/>
 	<classpathentry kind="src" path="packages/apps/Gallery2/gallerycommon/src"/>
 	<classpathentry kind="src" path="packages/apps/HTMLViewer/src"/>
+	<classpathentry kind="src" path="packages/apps/InCallUI/src"/>
 	<classpathentry kind="src" path="packages/apps/Launcher2/src"/>
 	<classpathentry kind="src" path="packages/apps/Mms/src"/>
 	<classpathentry kind="src" path="packages/apps/Nfc/src"/>
@@ -38,6 +39,8 @@
 	<classpathentry kind="src" path="packages/screensavers/Basic/src"/>
 	<classpathentry kind="src" path="packages/screensavers/PhotoTable/src"/>
 	<classpathentry kind="src" path="packages/screensavers/WebView/src"/>
+	<classpathentry kind="src" path="packages/services/Telephony/src"/>
+	<classpathentry kind="src" path="packages/services/Telephony/common/src"/>
 	<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"/>
@@ -50,6 +53,7 @@
 	<classpathentry kind="src" path="frameworks/base/location/java"/>
 	<classpathentry kind="src" path="frameworks/base/location/lib/java"/>
 	<classpathentry kind="src" path="frameworks/base/media/java"/>
+	<classpathentry kind="src" path="frameworks/base/media/tests/MediaFrameworkTest/src"/>
 	<classpathentry kind="src" path="frameworks/base/media/mca/effect/java"/>
 	<classpathentry kind="src" path="frameworks/base/media/mca/filterfw/java"/>
 	<classpathentry kind="src" path="frameworks/base/media/mca/filterpacks/java"/>
@@ -111,21 +115,25 @@
 	<classpathentry kind="src" path="out/target/common/obj/APPS/SystemUI_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/android-common-carousel_intermediates/src/renderscript/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/com.android.emailcommon_intermediates/src/src"/>
-	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java"/>
-	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/keystore/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/telephony/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/framework-base_intermediates/src/core/java"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/keystore/java"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/location/java"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/media/java"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/telephony/java"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/wifi/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/NfcLogTags_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/services_intermediates/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/src/src/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/voip-common_intermediates/src/src/java"/>
 	<classpathentry kind="src" path="out/target/common/R"/>
+	<classpathentry kind="src" path="pdk/apps/TestingCamera2/src"/>
 	<classpathentry kind="src" path="external/apache-http/src"/>
 	<classpathentry kind="src" path="external/bouncycastle/bcprov/src/main/java"/>
 	<classpathentry kind="src" path="external/guava/guava/src"/>
+	<classpathentry kind="src" path="external/hamcrest/src"/>
+	<classpathentry kind="src" path="external/junit/src"/>
 	<classpathentry kind="src" path="external/libphonenumber/java/src"/>
+	<classpathentry kind="src" path="external/mockito/src"/>
 	<classpathentry kind="src" path="external/mp4parser/isoparser/src/main/java"/>
 	<classpathentry kind="src" path="external/nist-sip/java"/>
 	<classpathentry kind="src" path="external/tagsoup/src"/>
diff --git a/ide/eclipse/README.importing-to-eclipse.txt b/ide/eclipse/README.importing-to-eclipse.txt
index dffa0ab..c98bf52 100644
--- a/ide/eclipse/README.importing-to-eclipse.txt
+++ b/ide/eclipse/README.importing-to-eclipse.txt
@@ -1,6 +1,33 @@
+(Java)
+
 To import the formatter, go to the preferences, section Java > Code Style >
 formatter, then click on import and choose
 development/ide/eclipse/android-formatting.xml
 
 To import the import order, to go into Java > Code Style > Organize Import,
 then click on import and choose development/ide/eclipse/android.importorder
+
+(C++)
+
+To import the include paths, go to Project > Properties > C/C++ General >
+Paths and Symbols, then click on "Includes" and then click on "Import Settings".
+Choose development/ide/eclipse/android-include-paths.xml and hit Finish.
+You will need to re-index for the changes to get picked up (right click project
+in Package Explorer, then Index > Rebuild).
+
+To import the symbols, go to Project > Properties > C/C++ General >
+Paths and Symbols, then click on "Symbols" and then click on "Import Settings".
+Choose development/ide/eclipse/android-symbols.xml and hit Finish.
+You will need to re-index for the changes to get picked up (right click project
+in Package Explorer, then Index > Rebuild).
+
+In addition, you will need to add some include files (no way to import this
+from an XML file) by hand. Go to Project > Properties > C/C++ General >
+Paths and Symbols, then click on "Include Files" and click on "Add". Check
+"Add to all configurations" and "Add to all languages". Repeat for these files:
+
+    ${ProjDirPath}/build/core/combo/include/arch/linux-arm/AndroidConfig.h
+
+If you are having trouble seeing the "Include Files" tab, you will need to
+enable it in the global preference panel under "C/C++" /
+"Property Pages Settings".
diff --git a/ide/eclipse/android-include-paths.xml b/ide/eclipse/android-include-paths.xml
index be188bd..4487fa4 100644
--- a/ide/eclipse/android-include-paths.xml
+++ b/ide/eclipse/android-include-paths.xml
@@ -31,6 +31,7 @@
 <includepath>${ProjDirPath}/system/core/include/arch/linux-arm</includepath>
 <includepath>${ProjDirPath}/dalvik/libnativehelper/include</includepath>
 <includepath>${ProjDirPath}/dalvik/libnativehelper/include/nativehelper</includepath>
+<includepath>${ProjDirPath}/system/media/camera/include</includepath>
 
 </language>
 <language name="GNU C++">
@@ -60,6 +61,7 @@
 <includepath>${ProjDirPath}/system/core/include/arch/linux-arm</includepath>
 <includepath>${ProjDirPath}/dalvik/libnativehelper/include</includepath>
 <includepath>${ProjDirPath}/dalvik/libnativehelper/include/nativehelper</includepath>
+<includepath>${ProjDirPath}/system/media/camera/include</includepath>
 
 </language>
 <language name="GNU C">
@@ -89,6 +91,7 @@
 <includepath>${ProjDirPath}/system/core/include/arch/linux-arm</includepath>
 <includepath>${ProjDirPath}/dalvik/libnativehelper/include</includepath>
 <includepath>${ProjDirPath}/dalvik/libnativehelper/include/nativehelper</includepath>
+<includepath>${ProjDirPath}/system/media/camera/include</includepath>
 
 </language>
 </section>
diff --git a/ide/intellij/codestyles/AndroidStyle.xml b/ide/intellij/codestyles/AndroidStyle.xml
index cd6beb4..672c4e5 100644
--- a/ide/intellij/codestyles/AndroidStyle.xml
+++ b/ide/intellij/codestyles/AndroidStyle.xml
@@ -9,40 +9,49 @@
       <option name="SMART_TABS" value="false" />
       <option name="LABEL_INDENT_SIZE" value="0" />
       <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+      <option name="USE_RELATIVE_INDENTS" value="false" />
     </value>
   </option>
-  <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
-  <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
-  <option name="ALIGN_MULTILINE_FOR" value="false" />
-  <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
-  <option name="BLANK_LINES_AROUND_FIELD" value="1" />
-  <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
   <option name="FIELD_NAME_PREFIX" value="m" />
   <option name="STATIC_FIELD_NAME_PREFIX" value="m" />
-  <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
-  <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
+  <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
+  <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
   <option name="IMPORT_LAYOUT_TABLE">
     <value>
-      <package name="com.google" withSubpackages="true" />
+      <package name="com.google" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="com" withSubpackages="true" />
+      <package name="com" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="junit" withSubpackages="true" />
+      <package name="junit" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="net" withSubpackages="true" />
+      <package name="net" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="org" withSubpackages="true" />
+      <package name="org" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="android" withSubpackages="true" />
+      <package name="android" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="java" withSubpackages="true" />
+      <package name="java" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="javax" withSubpackages="true" />
+      <package name="javax" withSubpackages="true" static="false" />
       <emptyLine />
-      <package name="" withSubpackages="true" />
+      <package name="" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="" withSubpackages="true" static="true" />
     </value>
   </option>
   <option name="RIGHT_MARGIN" value="100" />
+  <option name="JD_P_AT_EMPTY_LINES" value="false" />
+  <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
+  <option name="JD_KEEP_EMPTY_PARAMETER" value="false" />
+  <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" />
+  <option name="JD_KEEP_EMPTY_RETURN" value="false" />
+  <option name="JD_PRESERVE_LINE_FEEDS" value="true" />
+  <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
+  <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
+  <option name="BLANK_LINES_AROUND_FIELD" value="1" />
+  <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
+  <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+  <option name="ALIGN_MULTILINE_FOR" value="false" />
   <option name="CALL_PARAMETERS_WRAP" value="1" />
   <option name="METHOD_PARAMETERS_WRAP" value="1" />
   <option name="EXTENDS_LIST_WRAP" value="1" />
@@ -63,9 +72,104 @@
   <option name="DOWHILE_BRACE_FORCE" value="3" />
   <option name="WHILE_BRACE_FORCE" value="3" />
   <option name="FOR_BRACE_FORCE" value="3" />
-  <option name="JD_P_AT_EMPTY_LINES" value="false" />
-  <option name="JD_KEEP_EMPTY_PARAMETER" value="false" />
-  <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" />
-  <option name="JD_KEEP_EMPTY_RETURN" value="false" />
+  <ADDITIONAL_INDENT_OPTIONS fileType="css">
+    <option name="INDENT_SIZE" value="4" />
+    <option name="CONTINUATION_INDENT_SIZE" value="8" />
+    <option name="TAB_SIZE" value="4" />
+    <option name="USE_TAB_CHARACTER" value="false" />
+    <option name="SMART_TABS" value="false" />
+    <option name="LABEL_INDENT_SIZE" value="0" />
+    <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+    <option name="USE_RELATIVE_INDENTS" value="false" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <ADDITIONAL_INDENT_OPTIONS fileType="java">
+    <option name="INDENT_SIZE" value="4" />
+    <option name="CONTINUATION_INDENT_SIZE" value="8" />
+    <option name="TAB_SIZE" value="8" />
+    <option name="USE_TAB_CHARACTER" value="false" />
+    <option name="SMART_TABS" value="false" />
+    <option name="LABEL_INDENT_SIZE" value="0" />
+    <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+    <option name="USE_RELATIVE_INDENTS" value="false" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <ADDITIONAL_INDENT_OPTIONS fileType="js">
+    <option name="INDENT_SIZE" value="4" />
+    <option name="CONTINUATION_INDENT_SIZE" value="4" />
+    <option name="TAB_SIZE" value="4" />
+    <option name="USE_TAB_CHARACTER" value="false" />
+    <option name="SMART_TABS" value="false" />
+    <option name="LABEL_INDENT_SIZE" value="0" />
+    <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+    <option name="USE_RELATIVE_INDENTS" value="false" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <ADDITIONAL_INDENT_OPTIONS fileType="jsp">
+    <option name="INDENT_SIZE" value="4" />
+    <option name="CONTINUATION_INDENT_SIZE" value="8" />
+    <option name="TAB_SIZE" value="4" />
+    <option name="USE_TAB_CHARACTER" value="false" />
+    <option name="SMART_TABS" value="false" />
+    <option name="LABEL_INDENT_SIZE" value="0" />
+    <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+    <option name="USE_RELATIVE_INDENTS" value="false" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <ADDITIONAL_INDENT_OPTIONS fileType="sql">
+    <option name="INDENT_SIZE" value="2" />
+    <option name="CONTINUATION_INDENT_SIZE" value="8" />
+    <option name="TAB_SIZE" value="4" />
+    <option name="USE_TAB_CHARACTER" value="false" />
+    <option name="SMART_TABS" value="false" />
+    <option name="LABEL_INDENT_SIZE" value="0" />
+    <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+    <option name="USE_RELATIVE_INDENTS" value="false" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <ADDITIONAL_INDENT_OPTIONS fileType="xml">
+    <option name="INDENT_SIZE" value="4" />
+    <option name="CONTINUATION_INDENT_SIZE" value="8" />
+    <option name="TAB_SIZE" value="4" />
+    <option name="USE_TAB_CHARACTER" value="false" />
+    <option name="SMART_TABS" value="false" />
+    <option name="LABEL_INDENT_SIZE" value="0" />
+    <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+    <option name="USE_RELATIVE_INDENTS" value="false" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <ADDITIONAL_INDENT_OPTIONS fileType="yml">
+    <option name="INDENT_SIZE" value="2" />
+    <option name="CONTINUATION_INDENT_SIZE" value="8" />
+    <option name="TAB_SIZE" value="4" />
+    <option name="USE_TAB_CHARACTER" value="false" />
+    <option name="SMART_TABS" value="false" />
+    <option name="LABEL_INDENT_SIZE" value="0" />
+    <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+    <option name="USE_RELATIVE_INDENTS" value="false" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <codeStyleSettings language="JavaScript">
+    <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
+    <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
+    <option name="BLANK_LINES_AROUND_FIELD" value="1" />
+    <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
+    <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+    <option name="ALIGN_MULTILINE_FOR" value="false" />
+    <option name="CALL_PARAMETERS_WRAP" value="1" />
+    <option name="METHOD_PARAMETERS_WRAP" value="1" />
+    <option name="EXTENDS_LIST_WRAP" value="1" />
+    <option name="THROWS_LIST_WRAP" value="1" />
+    <option name="EXTENDS_KEYWORD_WRAP" value="1" />
+    <option name="THROWS_KEYWORD_WRAP" value="1" />
+    <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
+    <option name="BINARY_OPERATION_WRAP" value="1" />
+    <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+    <option name="TERNARY_OPERATION_WRAP" value="1" />
+    <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
+    <option name="FOR_STATEMENT_WRAP" value="1" />
+    <option name="ARRAY_INITIALIZER_WRAP" value="1" />
+    <option name="ASSIGNMENT_WRAP" value="1" />
+    <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
+    <option name="WRAP_COMMENTS" value="true" />
+    <option name="IF_BRACE_FORCE" value="3" />
+    <option name="DOWHILE_BRACE_FORCE" value="3" />
+    <option name="WHILE_BRACE_FORCE" value="3" />
+    <option name="FOR_BRACE_FORCE" value="3" />
+    <option name="PARENT_SETTINGS_INSTALLED" value="true" />
+  </codeStyleSettings>
 </code_scheme>
 
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 34464a0..bbb01b4 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -643,6 +643,11 @@
             </intent-filter>
         </activity>
 
+        <!-- Stub for memory testing. -->
+
+        <receiver android:name=".app.DoNothing"
+                android:process=":empty" android:exported="true" />
+
         <!-- ============================ -->
         <!--  Accessibility examples      -->
         <!-- ============================ -->
@@ -990,16 +995,6 @@
             </intent-filter>
         </activity>
 
-        <!-- Accessibility Samples -->
-        <activity android:name=".accessibility.AccessibilityNodeProviderActivity"
-                android:label="@string/accessibility_node_provider"
-                android:enabled="@bool/atLeastIceCreamSandwich">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
         <!-- Application Updating Samples -->
 
 <!-- BEGIN_INCLUDE(app_update_declaration) -->
@@ -1010,6 +1005,13 @@
         </receiver>
 <!-- END_INCLUDE(app_update_declaration) -->
 
+        <receiver android:name=".app.AppUpdateSspReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.PACKAGE_REPLACED" />
+                <data android:scheme="package" android:ssp="com.example.android.apis" />
+            </intent-filter>
+        </receiver>
+
         <!-- ************************************* -->
         <!--       PREFERENCE PACKAGE SAMPLES      -->
         <!-- ************************************* -->
@@ -1117,6 +1119,16 @@
             </intent-filter>
         </activity>
 
+        <!--
+        <activity android:name=".content.TextUndoActivity" android:label="@string/activity_text_undo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+                <category android:name="android.intent.category.EMBED" />
+            </intent-filter>
+        </activity>
+        -->
+
         <activity android:name=".content.ResourcesLayoutReference"
                 android:label="@string/activity_resources_layout_reference">
             <intent-filter>
@@ -1242,7 +1254,6 @@
 
         <activity android:name=".animation.AnimationLoading"
                 android:label="Animation/Loading"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1252,7 +1263,6 @@
 
         <activity android:name=".animation.AnimationCloning"
                 android:label="Animation/Cloning"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1262,7 +1272,6 @@
 
         <activity android:name=".animation.AnimationSeeking"
                 android:label="Animation/Seeking"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1272,7 +1281,6 @@
 
         <activity android:name=".animation.AnimatorEvents"
                 android:label="Animation/Events"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1282,7 +1290,6 @@
 
         <activity android:name=".animation.BouncingBalls"
                 android:label="Animation/Bouncing Balls"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1292,7 +1299,6 @@
 
         <activity android:name=".animation.CustomEvaluator"
                 android:label="Animation/Custom Evaluator"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1311,7 +1317,6 @@
 
         <activity android:name=".animation.ReversingAnimation"
                 android:label="Animation/Reversing"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1321,7 +1326,6 @@
 
         <activity android:name=".animation.MultiPropertyAnimation"
                 android:label="Animation/Multiple Properties"
-                android:hardwareAccelerated="false"
                 android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1348,8 +1352,17 @@
         </activity>
 
         <activity android:name=".animation.LayoutAnimationsByDefault"
-                android:label="Animation/Default Layout Animations"
-                android:enabled="@bool/atLeastHoneycomb">
+                  android:label="Animation/Default Layout Animations"
+                  android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.Transitions"
+                  android:label="Animation/Simple Transitions"
+                  android:enabled="@bool/atLeastHoneycomb">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
diff --git a/samples/ApiDemos/res/layout/accessibility_node_provider.xml b/samples/ApiDemos/res/layout/accessibility_node_provider.xml
deleted file mode 100644
index cc10c9c..0000000
--- a/samples/ApiDemos/res/layout/accessibility_node_provider.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="50dip"
-        android:text="@string/accessibility_node_provider_instructions">
-    </TextView>
-
-    <view
-        class="com.example.android.apis.accessibility.AccessibilityNodeProviderActivity$VirtualSubtreeRootView"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" >
-    </view>
-
-</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/intents.xml b/samples/ApiDemos/res/layout/intents.xml
index aed709d..e301b0b 100644
--- a/samples/ApiDemos/res/layout/intents.xml
+++ b/samples/ApiDemos/res/layout/intents.xml
@@ -17,7 +17,8 @@
 <!-- Demonstrates launching various intents.
      See corresponding Java code com.example.android.apis.app.Intents.java. -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+<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">
 
@@ -29,9 +30,22 @@
 
     <Button android:id="@+id/get_music"
         android:layout_width="wrap_content" android:layout_height="wrap_content" 
-        android:text="@string/get_music">
+        android:text="@string/get_music"
+        android:onClick="onGetMusic">
         <requestFocus />
     </Button>
 
+    <Button android:id="@+id/get_image"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/get_image"
+        android:onClick="onGetImage">
+    </Button>
+
+    <Button android:id="@+id/get_stream"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/get_stream"
+        android:onClick="onGetStream">
+    </Button>
+
 </LinearLayout>
 
diff --git a/samples/ApiDemos/res/layout/text_undo.xml b/samples/ApiDemos/res/layout/text_undo.xml
new file mode 100644
index 0000000..f7d74e8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/text_undo.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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 saving and restoring activity state.
+     See corresponding Java code com.android.sdk.app.SaveRestoreState.java. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+    <LinearLayout android:orientation="vertical" android:padding="4dip"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <TextView android:id="@+id/msg"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="0" android:textAppearance="?android:attr/textAppearanceMedium"
+            android:paddingBottom="8dip"
+            android:text="@string/text_undo_msg" />
+
+        <EditText android:id="@+id/text"
+            android:layout_width="match_parent" android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:freezesText="true">
+        </EditText>
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingTop="8dip">
+            <Button
+                android:id="@+id/undo"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/undo"
+                android:layout_gravity="bottom" />
+            <Button
+                android:id="@+id/redo"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/redo"
+                android:layout_gravity="bottom" />
+        </LinearLayout>
+
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/transition.xml b/samples/ApiDemos/res/layout/transition.xml
new file mode 100644
index 0000000..57b91be
--- /dev/null
+++ b/samples/ApiDemos/res/layout/transition.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+    <RadioGroup
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+        <RadioButton android:id="@+id/scene1"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:checked="true"
+                     android:onClick="selectScene"
+                     android:text="Scene 1" />
+
+        <RadioButton android:id="@+id/scene2"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="selectScene"
+                     android:text="Scene 2" />
+
+        <RadioButton android:id="@+id/scene3"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="selectScene"
+                     android:text="Scene 3" />
+
+        <RadioButton android:id="@+id/scene4"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="selectScene"
+                     android:text="Scene 4" />
+
+    </RadioGroup>
+
+    <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:id="@+id/sceneRoot">
+
+        <include layout="@layout/transition_scene1"/>
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/transition_scene1.xml b/samples/ApiDemos/res/layout/transition_scene1.xml
new file mode 100644
index 0000000..a98da60
--- /dev/null
+++ b/samples/ApiDemos/res/layout/transition_scene1.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:id="@+id/container">
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"
+            android:background="#f00"
+            android:id="@+id/view1"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentRight="true"
+            android:background="#0f0"
+            android:id="@+id/view2"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:background="#00f"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:id="@+id/view3"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:background="#0ff"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentRight="true"
+            android:id="@+id/view4"/>
+
+</RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/transition_scene2.xml b/samples/ApiDemos/res/layout/transition_scene2.xml
new file mode 100644
index 0000000..fda2276
--- /dev/null
+++ b/samples/ApiDemos/res/layout/transition_scene2.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/container">
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="100dip"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentRight="true"
+            android:background="#f00"
+            android:id="@+id/view1"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="100dip"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:background="#0f0"
+            android:id="@+id/view2"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="100dip"
+            android:background="#00f"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentRight="true"
+            android:id="@+id/view3"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="100dip"
+            android:background="#0ff"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"
+            android:id="@+id/view4"/>
+
+</RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/transition_scene3.xml b/samples/ApiDemos/res/layout/transition_scene3.xml
new file mode 100644
index 0000000..39c4da7
--- /dev/null
+++ b/samples/ApiDemos/res/layout/transition_scene3.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/container">
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"
+            android:background="#f00"
+            android:id="@+id/view1"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentRight="true"
+            android:background="#0f0"
+            android:id="@+id/view2"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:background="#00f"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:id="@+id/view3"/>
+
+    <View
+            android:layout_width="100dip"
+            android:layout_height="50dip"
+            android:background="#0ff"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentRight="true"
+            android:id="@+id/view4"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:orientation="vertical"
+        android:id="@+id/grayscaleContainer">
+
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#000"
+                android:id="@+id/gray1"/>
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#222"
+                android:id="@+id/gray2"/>
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#444"
+                android:id="@+id/gray3"/>
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#666"
+                android:id="@+id/gray4"/>
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#888"
+                android:id="@+id/gray5"/>
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#aaa"
+                android:id="@+id/gray6"/>
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#ccc"
+                android:id="@+id/gray7"/>
+        <View
+                android:layout_width="match_parent"
+                android:layout_height="10dip"
+                android:background="#fff"
+                android:id="@+id/gray8"/>
+
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/samples/ApiDemos/res/transition/changebounds.xml b/samples/ApiDemos/res/transition/changebounds.xml
new file mode 100644
index 0000000..a217003
--- /dev/null
+++ b/samples/ApiDemos/res/transition/changebounds.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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(ChangeBounds) -->
+<changeBounds/>
+<!-- END_INCLUDE(ChangeBounds) -->
diff --git a/samples/ApiDemos/res/transition/changebounds_fadein_together.xml b/samples/ApiDemos/res/transition/changebounds_fadein_together.xml
new file mode 100644
index 0000000..c0bb26f
--- /dev/null
+++ b/samples/ApiDemos/res/transition/changebounds_fadein_together.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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 xmlns:android="http://schemas.android.com/apk/res/android">
+    <changeBounds/>
+    <fade android:fadingMode="fade_in" >
+        <targets>
+            <target android:targetId="@id/grayscaleContainer" />
+        </targets>
+    </fade>
+</set>
diff --git a/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml b/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml
new file mode 100644
index 0000000..df36306
--- /dev/null
+++ b/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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(TransitionSet) -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:transitionOrdering="sequential">
+    <changeBounds/>
+    <fade android:fadingMode="fade_out" >
+        <targets>
+            <target android:targetId="@id/grayscaleContainer" />
+        </targets>
+    </fade>
+</set>
+<!-- END_INCLUDE(TransitionSet) -->
diff --git a/samples/ApiDemos/res/transition/transitions_mgr.xml b/samples/ApiDemos/res/transition/transitions_mgr.xml
new file mode 100644
index 0000000..bd11906
--- /dev/null
+++ b/samples/ApiDemos/res/transition/transitions_mgr.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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(TransitionManager) -->
+<transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
+    <transition android:fromScene="@layout/transition_scene1"
+                android:toScene="@layout/transition_scene2"
+                android:transition="@transition/changebounds"/>
+    <transition android:fromScene="@layout/transition_scene2"
+                android:toScene="@layout/transition_scene1"
+                android:transition="@transition/changebounds"/>
+    <transition android:toScene="@layout/transition_scene3"
+                android:transition="@transition/changebounds_fadein_together"/>
+    <transition android:fromScene="@layout/transition_scene3"
+                android:toScene="@layout/transition_scene1"
+                android:transition="@transition/changebounds_fadeout_sequential"/>
+    <transition android:fromScene="@layout/transition_scene3"
+                android:toScene="@layout/transition_scene2"
+                android:transition="@transition/changebounds_fadeout_sequential"/>
+</transitionManager>
+<!-- END_INCLUDE(TransitionManager) -->
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 9329cdd..d81f769 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -421,6 +421,12 @@
     <string name="styled_text">Plain, <b>bold</b>, <i>italic</i>, <b><i>bold-italic</i></b></string>
     <string name="styled_text_prog">Assigned programmatically:</string>
 
+    <string name="activity_text_undo">Content/Undo Manager/Text</string>
+    <string name="text_undo_msg">Demonstrates simple use of UndoManager with text editing
+            in a TextView.</string>
+    <string name="undo">Undo</string>
+    <string name="redo">Redo</string>
+
     <string name="activity_resources_layout_reference">Content/Resources/Layout Reference</string>
     <string name="resources_layout_reference_description">Shows how to write layout
         resource references, so that you can define multiple different configurations of
@@ -461,6 +467,8 @@
     <string name="activity_intents">App/Activity/Intents</string>
     <string name="intents">Example of launching various Intents.</string>
     <string name="get_music">Get Music</string>
+    <string name="get_image">Get Image</string>
+    <string name="get_stream">Get Stream</string>
 
     <!-- ============================== -->
     <!--  app/intents activity flags examples strings     -->
@@ -1419,10 +1427,6 @@
     <!--  Accessibility examples strings  -->
     <!-- ============================ -->
 
-    <string name="accessibility_node_provider">Accessibility/Accessibility Node Provider</string>
-    <string name="accessibility_node_provider_instructions">Enable TalkBack and Explore-by-touch from accessibility
-        settings. Then touch the colored squares.</string>
-
     <string name="accessibility_service">Accessibility/Accessibility Service</string>
     <string name="accessibility_service_label">ClockBack</string>
     <string name="accessibility_service_instructions">
diff --git a/samples/ApiDemos/src/com/example/android/apis/accessibility/AccessibilityNodeProviderActivity.java b/samples/ApiDemos/src/com/example/android/apis/accessibility/AccessibilityNodeProviderActivity.java
deleted file mode 100644
index 1ca036a..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/accessibility/AccessibilityNodeProviderActivity.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.apis.accessibility;
-
-import com.example.android.apis.R;
-
-import android.app.Activity;
-import android.app.Service;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeProvider;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * This sample demonstrates how a View can expose a virtual view sub-tree
- * rooted at it. A virtual sub-tree is composed of imaginary Views
- * that are reported as a part of the view hierarchy for accessibility
- * purposes. This enables custom views that draw complex content to report
- * them selves as a tree of virtual views, thus conveying their logical
- * structure.
- * <p>
- * For example, a View may draw a monthly calendar as a grid of days while
- * each such day may contains some events. From a perspective of the View
- * hierarchy the calendar is composed of a single View but an accessibility
- * service would benefit of traversing the logical structure of the calendar
- * by examining each day and each event on that day.
- * </p>
- */
-public class AccessibilityNodeProviderActivity extends Activity {
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.accessibility_node_provider);
-    }
-
-   /**
-    * This class presents a View that is composed of three virtual children
-    * each of which is drawn with a different color and represents a region
-    * of the View that has different semantics compared to other such regions.
-    * While the virtual view tree exposed by this class is one level deep
-    * for simplicity, there is no bound on the complexity of that virtual
-    * sub-tree.
-    */
-    public static class VirtualSubtreeRootView extends View {
-
-        /** Paint object for drawing the virtual sub-tree */
-        private final Paint mPaint = new Paint();
-
-        /** Temporary rectangle to minimize object creation. */
-        private final Rect mTempRect = new Rect();
-
-        /** Handle to the system accessibility service. */
-        private final AccessibilityManager mAccessibilityManager;
-
-        /** The virtual children of this View. */
-        private final List<VirtualView> mChildren = new ArrayList<VirtualView>();
-
-        /** The instance of the node provider for the virtual tree - lazily instantiated. */
-        private AccessibilityNodeProvider mAccessibilityNodeProvider;
-
-        /** The last hovered child used for event dispatching. */
-        private VirtualView mLastHoveredChild;
-
-        public VirtualSubtreeRootView(Context context, AttributeSet attrs) {
-            super(context, attrs);
-            mAccessibilityManager = (AccessibilityManager) context.getSystemService(
-                    Service.ACCESSIBILITY_SERVICE);
-            createVirtualChildren();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public AccessibilityNodeProvider getAccessibilityNodeProvider() {
-            // Instantiate the provide only when requested. Since the system
-            // will call this method multiple times it is a good practice to
-            // cache the provider instance.
-            if (mAccessibilityNodeProvider == null) {
-                mAccessibilityNodeProvider = new VirtualDescendantsProvider();
-            }
-            return mAccessibilityNodeProvider;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public boolean dispatchHoverEvent(MotionEvent event) {
-            // This implementation assumes that the virtual children
-            // cannot overlap and are always visible. Do NOT use this
-            // code as a reference of how to implement hover event
-            // dispatch. Instead, refer to ViewGroup#dispatchHoverEvent.
-            boolean handled = false;
-            List<VirtualView> children = mChildren;
-            final int childCount = children.size();
-            for (int i = 0; i < childCount; i++) {
-                VirtualView child = children.get(i);
-                Rect childBounds = child.mBounds;
-                final int childCoordsX = (int) event.getX() + getScrollX();
-                final int childCoordsY = (int) event.getY() + getScrollY();
-                if (!childBounds.contains(childCoordsX, childCoordsY)) {
-                    continue;
-                }
-                final int action = event.getAction();
-                switch (action) {
-                    case MotionEvent.ACTION_HOVER_ENTER: {
-                        mLastHoveredChild = child;
-                        handled |= onHoverVirtualView(child, event);
-                        event.setAction(action);
-                    } break;
-                    case MotionEvent.ACTION_HOVER_MOVE: {
-                        if (child == mLastHoveredChild) {
-                            handled |= onHoverVirtualView(child, event);
-                            event.setAction(action);
-                        } else {
-                            MotionEvent eventNoHistory = event.getHistorySize() > 0
-                                ? MotionEvent.obtainNoHistory(event) : event;
-                            eventNoHistory.setAction(MotionEvent.ACTION_HOVER_EXIT);
-                            onHoverVirtualView(mLastHoveredChild, eventNoHistory);
-                            eventNoHistory.setAction(MotionEvent.ACTION_HOVER_ENTER);
-                            onHoverVirtualView(child, eventNoHistory);
-                            mLastHoveredChild = child;
-                            eventNoHistory.setAction(MotionEvent.ACTION_HOVER_MOVE);
-                            handled |= onHoverVirtualView(child, eventNoHistory);
-                            if (eventNoHistory != event) {
-                                eventNoHistory.recycle();
-                            } else {
-                                event.setAction(action);
-                            }
-                        }
-                    } break;
-                    case MotionEvent.ACTION_HOVER_EXIT: {
-                        mLastHoveredChild = null;
-                        handled |= onHoverVirtualView(child, event);
-                        event.setAction(action);
-                    } break;
-                }
-            }
-            if (!handled) {
-                handled |= onHoverEvent(event);
-            }
-            return handled;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-            // The virtual children are ordered horizontally next to
-            // each other and take the entire space of this View.
-            int offsetX = 0;
-            List<VirtualView> children = mChildren;
-            final int childCount = children.size();
-            for (int i = 0; i < childCount; i++) {
-                VirtualView child = children.get(i);
-                Rect childBounds = child.mBounds;
-                childBounds.set(offsetX, 0, offsetX + childBounds.width(), childBounds.height());
-                offsetX += childBounds.width();
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            // The virtual children are ordered horizontally next to
-            // each other and take the entire space of this View.
-            int width = 0;
-            int height = 0;
-            List<VirtualView> children = mChildren;
-            final int childCount = children.size();
-            for (int i = 0; i < childCount; i++) {
-                VirtualView child = children.get(i);
-                width += child.mBounds.width();
-                height = Math.max(height, child.mBounds.height());
-            }
-            setMeasuredDimension(width, height);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        protected void onDraw(Canvas canvas) {
-            // Draw the virtual children with the reusable Paint object
-            // and with the bounds and color which are child specific.
-            Rect drawingRect = mTempRect;
-            List<VirtualView> children = mChildren;
-            final int childCount = children.size();
-            for (int i = 0; i < childCount; i++) {
-                VirtualView child = children.get(i);
-                drawingRect.set(child.mBounds);
-                mPaint.setColor(child.mColor);
-                mPaint.setAlpha(child.mAlpha);
-                canvas.drawRect(drawingRect, mPaint);
-            }
-        }
-
-        /**
-         * Creates the virtual children of this View.
-         */
-        private void createVirtualChildren() {
-            // The virtual portion of the tree is one level deep. Note
-            // that implementations can use any way of representing and
-            // drawing virtual view.
-            VirtualView firstChild = new VirtualView(0, new Rect(0, 0, 150, 150), Color.RED,
-                    "Virtual view 1");
-            mChildren.add(firstChild);
-            VirtualView secondChild = new VirtualView(1, new Rect(0, 0, 150, 150), Color.GREEN,
-                    "Virtual view 2");
-            mChildren.add(secondChild);
-            VirtualView thirdChild = new VirtualView(2, new Rect(0, 0, 150, 150), Color.BLUE,
-                    "Virtual view 3");
-            mChildren.add(thirdChild);
-        }
-
-        /**
-         * Set the selected state of a virtual view.
-         *
-         * @param virtualView The virtual view whose selected state to set.
-         * @param selected Whether the virtual view is selected.
-         */
-        private void setVirtualViewSelected(VirtualView virtualView, boolean selected) {
-            virtualView.mAlpha = selected ? VirtualView.ALPHA_SELECTED : VirtualView.ALPHA_NOT_SELECTED;
-        }
-
-        /**
-         * Handle a hover over a virtual view.
-         *
-         * @param virtualView The virtual view over which is hovered.
-         * @param event The event to dispatch.
-         * @return Whether the event was handled.
-         */
-        private boolean onHoverVirtualView(VirtualView virtualView, MotionEvent event) {
-            // The implementation of hover event dispatch can be implemented
-            // in any way that is found suitable. However, each virtual View
-            // should fire a corresponding accessibility event whose source
-            // is that virtual view. Accessibility services get the event source
-            // as the entry point of the APIs for querying the window content.
-            final int action = event.getAction();
-            switch (action) {
-                case MotionEvent.ACTION_HOVER_ENTER: {
-                    sendAccessibilityEventForVirtualView(virtualView,
-                            AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
-                } break;
-                case MotionEvent.ACTION_HOVER_EXIT: {
-                    sendAccessibilityEventForVirtualView(virtualView,
-                            AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
-                } break;
-            }
-            return true;
-        }
-
-        /**
-         * Sends a properly initialized accessibility event for a virtual view..
-         *
-         * @param virtualView The virtual view.
-         * @param eventType The type of the event to send.
-         */
-        private void sendAccessibilityEventForVirtualView(VirtualView virtualView, int eventType) {
-            // If touch exploration, i.e. the user gets feedback while touching
-            // the screen, is enabled we fire accessibility events.
-            if (mAccessibilityManager.isTouchExplorationEnabled()) {
-                AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
-                event.setPackageName(getContext().getPackageName());
-                event.setClassName(virtualView.getClass().getName());
-                event.setSource(VirtualSubtreeRootView.this, virtualView.mId);
-                event.getText().add(virtualView.mText);
-                getParent().requestSendAccessibilityEvent(VirtualSubtreeRootView.this, event);
-            }
-        }
-
-        /**
-         * Finds a virtual view given its id.
-         *
-         * @param id The virtual view id.
-         * @return The found virtual view.
-         */
-        private VirtualView findVirtualViewById(int id) {
-            List<VirtualView> children = mChildren;
-            final int childCount = children.size();
-            for (int i = 0; i < childCount; i++) {
-                VirtualView child = children.get(i);
-                if (child.mId == id) {
-                    return child;
-                }
-            }
-            return null;
-        }
-
-        /**
-         * Represents a virtual View.
-         */
-        private class VirtualView {
-            public static final int ALPHA_SELECTED = 255;
-            public static final int ALPHA_NOT_SELECTED = 127;
-
-            public final int mId;
-            public final int mColor;
-            public final Rect mBounds;
-            public final String mText;
-            public int mAlpha;
-
-            public VirtualView(int id, Rect bounds, int color, String text) {
-                mId = id;
-                mColor = color;
-                mBounds = bounds;
-                mText = text;
-                mAlpha = ALPHA_NOT_SELECTED;
-            }
-        }
-
-        /**
-         * This is the provider that exposes the virtual View tree to accessibility
-         * services. From the perspective of an accessibility service the
-         * {@link AccessibilityNodeInfo}s it receives while exploring the sub-tree
-         * rooted at this View will be the same as the ones it received while
-         * exploring a View containing a sub-tree composed of real Views.
-         */
-        private class VirtualDescendantsProvider extends AccessibilityNodeProvider {
-
-            /**
-             * {@inheritDoc}
-             */
-            @Override
-            public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
-                AccessibilityNodeInfo info = null;
-                if (virtualViewId == View.NO_ID) {
-                    // We are requested to create an AccessibilityNodeInfo describing
-                    // this View, i.e. the root of the virtual sub-tree. Note that the
-                    // host View has an AccessibilityNodeProvider which means that this
-                    // provider is responsible for creating the node info for that root.
-                    info = AccessibilityNodeInfo.obtain(VirtualSubtreeRootView.this);
-                    onInitializeAccessibilityNodeInfo(info);
-                    // Add the virtual children of the root View.
-                    List<VirtualView> children = mChildren;
-                    final int childCount = children.size();
-                    for (int i = 0; i < childCount; i++) {
-                        VirtualView child = children.get(i);
-                        info.addChild(VirtualSubtreeRootView.this, child.mId);
-                    }
-                } else {
-                    // Find the view that corresponds to the given id.
-                    VirtualView virtualView = findVirtualViewById(virtualViewId);
-                    if (virtualView == null) {
-                        return null;
-                    }
-                    // Obtain and initialize an AccessibilityNodeInfo with
-                    // information about the virtual view.
-                    info = AccessibilityNodeInfo.obtain();
-                    info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
-                    info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
-                    info.setPackageName(getContext().getPackageName());
-                    info.setClassName(virtualView.getClass().getName());
-                    info.setSource(VirtualSubtreeRootView.this, virtualViewId);
-                    info.setBoundsInParent(virtualView.mBounds);
-                    info.setParent(VirtualSubtreeRootView.this);
-                    info.setText(virtualView.mText);
-                }
-                return info;
-            }
-
-            /**
-             * {@inheritDoc}
-             */
-            @Override
-            public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String searched,
-                    int virtualViewId) {
-                if (TextUtils.isEmpty(searched)) {
-                    return Collections.emptyList();
-                }
-                String searchedLowerCase = searched.toLowerCase();
-                List<AccessibilityNodeInfo> result = null;
-                if (virtualViewId == View.NO_ID) {
-                    // If the search is from the root, i.e. this View, go over the virtual
-                    // children and look for ones that contain the searched string since
-                    // this View does not contain text itself.
-                    List<VirtualView> children = mChildren;
-                    final int childCount = children.size();
-                    for (int i = 0; i < childCount; i++) {
-                        VirtualView child = children.get(i);
-                        String textToLowerCase = child.mText.toLowerCase();
-                        if (textToLowerCase.contains(searchedLowerCase)) {
-                            if (result == null) {
-                                result = new ArrayList<AccessibilityNodeInfo>();
-                            }
-                            result.add(createAccessibilityNodeInfo(child.mId));
-                        }
-                    }
-                } else {
-                    // If the search is from a virtual view, find the view. Since the tree
-                    // is one level deep we add a node info for the child to the result if
-                    // the child contains the searched text.
-                    VirtualView virtualView = findVirtualViewById(virtualViewId);
-                    if (virtualView != null) {
-                        String textToLowerCase = virtualView.mText.toLowerCase();
-                        if (textToLowerCase.contains(searchedLowerCase)) {
-                            result = new ArrayList<AccessibilityNodeInfo>();
-                            result.add(createAccessibilityNodeInfo(virtualViewId));
-                        }
-                    }
-                }
-                if (result == null) {
-                    return Collections.emptyList();
-                }
-                return result;
-            }
-
-            /**
-             * {@inheritDoc}
-             */
-            @Override
-            public boolean performAction(int virtualViewId, int action, Bundle arguments) {
-                if (virtualViewId == View.NO_ID) {
-                    // Perform the action on the host View.
-                    switch (action) {
-                        case AccessibilityNodeInfo.ACTION_SELECT:
-                            if (!isSelected()) {
-                                setSelected(true);
-                                return isSelected();
-                            }
-                            break;
-                        case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION:
-                            if (isSelected()) {
-                                setSelected(false);
-                                return !isSelected();
-                            }
-                            break;
-                    }
-                } else {
-                    // Find the view that corresponds to the given id.
-                    VirtualView child = findVirtualViewById(virtualViewId);
-                    if (child == null) {
-                        return false;
-                    }
-                    // Perform the action on a virtual view.
-                    switch (action) {
-                        case AccessibilityNodeInfo.ACTION_SELECT:
-                            setVirtualViewSelected(child, true);
-                            invalidate();
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION:
-                            setVirtualViewSelected(child, false);
-                            invalidate();
-                            return true;
-                    }
-                }
-                return false;
-            }
-        }
-    }
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html b/samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html
index df54e96..1324f86 100644
--- a/samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html
@@ -21,12 +21,6 @@
     xml files, and adding additional information to AccessibilityEvents using
     AccessibilityRecords.
   </dd>
-  <dt><a href="AccessibilityNodeProviderActivity.html">Accessibility Node Provider</a></dt>
-  <dd>Demonstrates how to develop an accessibility node provider which manages a virtual
-    View tree reported to accessibility services. The virtual subtree is rooted at a View
-    that draws complex content and reports itself as a tree of virtual views, thus conveying
-    its logical structure.
-  </dd>
 </dl>
 
 <dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/Transitions.java b/samples/ApiDemos/src/com/example/android/apis/animation/Transitions.java
new file mode 100644
index 0000000..4878c5f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/Transitions.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
+import android.transition.TransitionManager;
+import com.example.android.apis.R;
+
+/**
+ * This application demonstrates some of the capabilities and uses of the
+ * {@link android.transition transitions} APIs. Scenes and a TransitionManager
+ * are loaded from resource files and transitions are run between those scenes
+ * as well as a dynamically-configured scene.
+ */
+public class Transitions extends Activity {
+
+    Scene mScene1, mScene2, mScene3;
+    ViewGroup mSceneRoot;
+    TransitionManager mTransitionManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.transition);
+
+        mSceneRoot = (ViewGroup) findViewById(R.id.sceneRoot);
+
+        TransitionInflater inflater = TransitionInflater.from(this);
+
+        // Note that this is not the only way to create a Scene object, but that
+        // loading them from layout resources cooperates with the
+        // TransitionManager that we are also loading from resources, and which
+        // uses the same layout resource files to determine the scenes to transition
+        // from/to.
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.transition_scene1, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.transition_scene2, this);
+        mScene3 = Scene.getSceneForLayout(mSceneRoot, R.layout.transition_scene3, this);
+        mTransitionManager = inflater.inflateTransitionManager(R.transition.transitions_mgr,
+                mSceneRoot);
+    }
+
+    public void selectScene(View view) {
+        switch (view.getId()) {
+            case R.id.scene1:
+                mTransitionManager.transitionTo(mScene1);
+                break;
+            case R.id.scene2:
+                mTransitionManager.transitionTo(mScene2);
+                break;
+            case R.id.scene3:
+                mTransitionManager.transitionTo(mScene3);
+                break;
+            case R.id.scene4:
+                // scene4 is not an actual 'Scene', but rather a dynamic change in the UI,
+                // transitioned to using beginDelayedTransition() to tell the TransitionManager
+                // to get ready to run a transition at the next frame
+                TransitionManager.beginDelayedTransition(mSceneRoot);
+                setNewSize(R.id.view1, 150, 25);
+                setNewSize(R.id.view2, 150, 25);
+                setNewSize(R.id.view3, 150, 25);
+                setNewSize(R.id.view4, 150, 25);
+                break;
+        }
+    }
+
+    private void setNewSize(int id, int width, int height) {
+        View view = findViewById(id);
+        ViewGroup.LayoutParams params = view.getLayoutParams();
+        params.width = width;
+        params.height = height;
+        view.setLayoutParams(params);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AppUpdateSspReceiver.java b/samples/ApiDemos/src/com/example/android/apis/app/AppUpdateSspReceiver.java
new file mode 100644
index 0000000..dfa265c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AppUpdateSspReceiver.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.Toast;
+
+/**
+ * Executed when a new version of the application is is installed.
+ */
+public class AppUpdateSspReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String msg = "Ssp update received: " + intent.getData();
+        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DoNothing.java b/samples/ApiDemos/src/com/example/android/apis/app/DoNothing.java
new file mode 100644
index 0000000..133a802
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DoNothing.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class DoNothing extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Intents.java b/samples/ApiDemos/src/com/example/android/apis/app/Intents.java
index 8f02b83..6207dd8 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/Intents.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/Intents.java
@@ -31,17 +31,23 @@
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.intents);
-
-        // Watch for button clicks.
-        Button button = (Button)findViewById(R.id.get_music);
-        button.setOnClickListener(mGetMusicListener);
     }
 
-    private OnClickListener mGetMusicListener = new OnClickListener() {
-        public void onClick(View v) {
-            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
-            intent.setType("audio/*");
-            startActivity(Intent.createChooser(intent, "Select music"));
-        }
-    };
+    public void onGetMusic(View view) {
+        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+        intent.setType("audio/*");
+        startActivity(Intent.createChooser(intent, "Select music"));
+    }
+
+    public void onGetImage(View view) {
+        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+        intent.setType("image/*");
+        startActivity(Intent.createChooser(intent, "Select image"));
+    }
+
+    public void onGetStream(View view) {
+        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+        intent.setType("*/*");
+        startActivity(Intent.createChooser(intent, "Select stream"));
+    }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/TextUndoActivity.java b/samples/ApiDemos/src/com/example/android/apis/content/TextUndoActivity.java
new file mode 100644
index 0000000..6b9dc8e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/TextUndoActivity.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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 android.app.Activity;
+//import android.content.UndoManager;
+import android.os.Parcelable;
+import android.view.View;
+import android.widget.Button;
+import com.example.android.apis.R;
+
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * Simple example of using an UndoManager for editing text in a TextView.
+ */
+public class TextUndoActivity extends Activity {
+    //UndoManager mUndoManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        /*
+        mUndoManager = new UndoManager();
+        if (savedInstanceState != null) {
+            Parcelable p = savedInstanceState.getParcelable("undo");
+            if (p != null) {
+                mUndoManager.restoreInstanceState(p);
+            }
+        }
+        */
+
+        setContentView(R.layout.text_undo);
+
+        /*
+        ((TextView)findViewById(R.id.text)).setUndoManager(mUndoManager, "text");
+        ((Button)findViewById(R.id.undo)).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mUndoManager.undo(null, 1);
+            }
+        });
+        ((Button)findViewById(R.id.redo)).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mUndoManager.redo(null, 1);
+            }
+        });
+        */
+     }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        //outState.putParcelable("undo", mUndoManager.saveInstanceState());
+    }
+}
diff --git a/samples/HelloActivity/src/com/example/android/helloactivity/HelloActivity.java b/samples/HelloActivity/src/com/example/android/helloactivity/HelloActivity.java
index f983d7a..f4babe7 100644
--- a/samples/HelloActivity/src/com/example/android/helloactivity/HelloActivity.java
+++ b/samples/HelloActivity/src/com/example/android/helloactivity/HelloActivity.java
@@ -37,17 +37,6 @@
         // in res/layout/hello_activity.xml
         View view = getLayoutInflater().inflate(R.layout.hello_activity, null);
         setContentView(view);
-
-        WindowManager.LayoutParams params = getWindow().getAttributes();
-        params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-        getWindow().setAttributes(params);
-        view.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
-            @Override public void onSystemUiVisibilityChange(int visibility) {
-                WindowManager.LayoutParams params = getWindow().getAttributes();
-                params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-                getWindow().setAttributes(params);
-            }
-        });
     }
 }
 
diff --git a/samples/Support4Demos/AndroidManifest.xml b/samples/Support4Demos/AndroidManifest.xml
index cc98540..ce6c29c 100644
--- a/samples/Support4Demos/AndroidManifest.xml
+++ b/samples/Support4Demos/AndroidManifest.xml
@@ -321,6 +321,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".widget.ExploreByTouchHelperActivity"
+                  android:label="@string/explore_by_touch_helper_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <provider android:authorities="com.example.supportv4.content.sharingsupportprovider"
                   android:name=".content.SharingSupportProvider" />
 
diff --git a/samples/Support4Demos/res/layout/explore_by_touch_helper.xml b/samples/Support4Demos/res/layout/explore_by_touch_helper.xml
new file mode 100644
index 0000000..0b367a4
--- /dev/null
+++ b/samples/Support4Demos/res/layout/explore_by_touch_helper.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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" >
+
+    <view
+        class="com.example.android.supportv4.widget.ExploreByTouchHelperActivity$CustomView"
+        android:id="@+id/custom_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/Support4Demos/res/values/strings.xml b/samples/Support4Demos/res/values/strings.xml
index 9949ee0..ce41aaf 100644
--- a/samples/Support4Demos/res/values/strings.xml
+++ b/samples/Support4Demos/res/values/strings.xml
@@ -167,6 +167,13 @@
 
     <string name="sliding_pane_layout_summary">This activity illustrates the use of sliding panes. The content pane may be slid to one side on narrow devices to reveal the left pane used to select content. Sliding panes can be used to fit a UI intended for wider screens in a smaller space. Tapping the Action Bar\'s Up button at the left side of the bar will navigate up in the hierarchy, represented by the left pane. If you rotate the device to landscape mode, on most devices you will see that both panes fit together side by side with no sliding necessary.</string>
 
+    <!-- ExploreByTouchHelper -->
+
+    <string name="explore_by_touch_helper_support">Widget/Explore by Touch helper</string>
+    <string name="sample_item_a">Sample item A</string>
+    <string name="sample_item_b">Sample item B</string>
+
     <!-- ContentLoadingProgressBar -->
     <string name="content_loading_progress_bar">Widget/Content Loading Progress Bar</string>
+
 </resources>
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/widget/ExploreByTouchHelperActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/widget/ExploreByTouchHelperActivity.java
new file mode 100644
index 0000000..946de01
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/widget/ExploreByTouchHelperActivity.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv4.widget;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
+import android.support.v4.widget.ExploreByTouchHelper;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import com.example.android.supportv4.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This example shows how to use the {@link ExploreByTouchHelper} class in the
+ * Android support library to add accessibility support to a custom view that
+ * represents multiple logical items.
+ * <p>
+ * The {@link ExploreByTouchHelper} class wraps
+ * {@link AccessibilityNodeProviderCompat} and simplifies exposing information
+ * about a custom view's logical structure to accessibility services.
+ * <p>
+ * The custom view in this example is responsible for:
+ * <ul>
+ * <li>Creating a helper class that extends {@link ExploreByTouchHelper}
+ * <li>Setting the helper as the accessibility delegate using
+ * {@link ViewCompat#setAccessibilityDelegate}
+ * <li>Dispatching hover events to the helper in {@link View#dispatchHoverEvent}
+ * </ul>
+ * <p>
+ * The helper class implementation in this example is responsible for:
+ * <ul>
+ * <li>Mapping hover event coordinates to logical items
+ * <li>Exposing information about logical items to accessibility services
+ * <li>Handling accessibility actions
+ * <ul>
+ */
+public class ExploreByTouchHelperActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.explore_by_touch_helper);
+
+        final CustomView customView = (CustomView) findViewById(R.id.custom_view);
+
+        // Adds an item at the top-left quarter of the custom view.
+        customView.addItem(getString(R.string.sample_item_a), 0, 0, 0.5f, 0.5f);
+
+        // Adds an item at the bottom-right quarter of the custom view.
+        customView.addItem(getString(R.string.sample_item_b), 0.5f, 0.5f, 1, 1);
+    }
+
+    /**
+     * Simple custom view that draws rectangular items to the screen. Each item
+     * has a checked state that may be toggled by tapping on the item.
+     */
+    public static class CustomView extends View {
+        private static final int NO_ITEM = -1;
+
+        private final Paint mPaint = new Paint();
+        private final Rect mTempBounds = new Rect();
+        private final List<CustomItem> mItems = new ArrayList<CustomItem>();
+        private CustomViewTouchHelper mTouchHelper;
+
+        public CustomView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+
+            // Set up accessibility helper class.
+            mTouchHelper = new CustomViewTouchHelper(this);
+            ViewCompat.setAccessibilityDelegate(this, mTouchHelper);
+        }
+
+        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+        @Override
+        public boolean dispatchHoverEvent(MotionEvent event) {
+            // Always attempt to dispatch hover events to accessibility first.
+            if (mTouchHelper.dispatchHoverEvent(event)) {
+                return true;
+            }
+
+            return super.dispatchHoverEvent(event);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    return true;
+                case MotionEvent.ACTION_UP:
+                    final int itemIndex = getItemIndexUnder(event.getX(), event.getY());
+                    if (itemIndex >= 0) {
+                        onItemClicked(itemIndex);
+                    }
+                    return true;
+            }
+
+            return super.onTouchEvent(event);
+        }
+
+        /**
+         * Adds an item to the custom view. The item is positioned relative to
+         * the custom view bounds and its descriptions is drawn at its center.
+         *
+         * @param description The item's description.
+         * @param top Top coordinate as a fraction of the parent height, range
+         *            is [0,1].
+         * @param left Left coordinate as a fraction of the parent width, range
+         *            is [0,1].
+         * @param bottom Bottom coordinate as a fraction of the parent height,
+         *            range is [0,1].
+         * @param right Right coordinate as a fraction of the parent width,
+         *            range is [0,1].
+         */
+        public void addItem(String description, float top, float left, float bottom, float right) {
+            final CustomItem item = new CustomItem();
+            item.bounds = new RectF(top, left, bottom, right);
+            item.description = description;
+            item.checked = false;
+            mItems.add(item);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+
+            final Paint paint = mPaint;
+            final Rect bounds = mTempBounds;
+            final int height = getHeight();
+            final int width = getWidth();
+
+            for (CustomItem item : mItems) {
+                paint.setColor(item.checked ? Color.RED : Color.BLUE);
+                paint.setStyle(Style.FILL);
+                scaleRectF(item.bounds, bounds, width, height);
+                canvas.drawRect(bounds, paint);
+                paint.setColor(Color.WHITE);
+                paint.setTextAlign(Align.CENTER);
+                canvas.drawText(item.description, bounds.centerX(), bounds.centerY(), paint);
+            }
+        }
+
+        protected boolean onItemClicked(int index) {
+            final CustomItem item = getItem(index);
+            if (item == null) {
+                return false;
+            }
+
+            item.checked = !item.checked;
+            invalidate();
+
+            // Since the item's checked state is exposed to accessibility
+            // services through its AccessibilityNodeInfo, we need to invalidate
+            // the item's virtual view. At some point in the future, the
+            // framework will obtain an updated version of the virtual view.
+            mTouchHelper.invalidateVirtualView(index);
+
+            // We also need to let the framework know what type of event
+            // happened. Accessibility services may use this event to provide
+            // appropriate feedback to the user.
+            mTouchHelper.sendEventForVirtualView(index, AccessibilityEvent.TYPE_VIEW_CLICKED);
+
+            return true;
+        }
+
+        protected int getItemIndexUnder(float x, float y) {
+            final float scaledX = (x / getWidth());
+            final float scaledY = (y / getHeight());
+            final int n = mItems.size();
+
+            for (int i = 0; i < n; i++) {
+                final CustomItem item = mItems.get(i);
+                if (item.bounds.contains(scaledX, scaledY)) {
+                    return i;
+                }
+            }
+
+            return NO_ITEM;
+        }
+
+        protected CustomItem getItem(int index) {
+            if ((index < 0) || (index >= mItems.size())) {
+                return null;
+            }
+
+            return mItems.get(index);
+        }
+
+        protected static void scaleRectF(RectF in, Rect out, int width, int height) {
+            out.top = (int) (in.top * height);
+            out.bottom = (int) (in.bottom * height);
+            out.left = (int) (in.left * width);
+            out.right = (int) (in.right * width);
+        }
+
+        private class CustomViewTouchHelper extends ExploreByTouchHelper {
+            private final Rect mTempRect = new Rect();
+
+            public CustomViewTouchHelper(View forView) {
+                super(forView);
+            }
+
+            @Override
+            protected int getVirtualViewAt(float x, float y) {
+                // We also perform hit detection in onTouchEvent(), and we can
+                // reuse that logic here. This will ensure consistency whether
+                // accessibility is on or off.
+                final int index = getItemIndexUnder(x, y);
+                if (index == NO_ITEM) {
+                    return ExploreByTouchHelper.INVALID_ID;
+                }
+
+                return index;
+            }
+
+            @Override
+            protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
+                // Since every item should be visible, and since we're mapping
+                // directly from item index to virtual view id, we can just add
+                // every available index in the item list.
+                final int n = mItems.size();
+                for (int i = 0; i < n; i++) {
+                    virtualViewIds.add(i);
+                }
+            }
+
+            @Override
+            protected void onPopulateEventForVirtualView(
+                    int virtualViewId, AccessibilityEvent event) {
+                final CustomItem item = getItem(virtualViewId);
+                if (item == null) {
+                    throw new IllegalArgumentException("Invalid virtual view id");
+                }
+
+                // The event must be populated with text, either using
+                // getText().add() or setContentDescription(). Since the item's
+                // description is displayed visually, we'll add it to the event
+                // text. If it was only used for accessibility, we would use
+                // setContentDescription().
+                event.getText().add(item.description);
+            }
+
+            @Override
+            protected void onPopulateNodeForVirtualView(
+                    int virtualViewId, AccessibilityNodeInfoCompat node) {
+                final CustomItem item = getItem(virtualViewId);
+                if (item == null) {
+                    throw new IllegalArgumentException("Invalid virtual view id");
+                }
+
+                // Node and event text and content descriptions are usually
+                // identical, so we'll use the exact same string as before.
+                node.setText(item.description);
+
+                // Reported bounds should be consistent with those used to draw
+                // the item in onDraw(). They should also be consistent with the
+                // hit detection performed in getVirtualViewAt() and
+                // onTouchEvent().
+                final Rect bounds = mTempRect;
+                final int height = getHeight();
+                final int width = getWidth();
+                scaleRectF(item.bounds, bounds, width, height);
+                node.setBoundsInParent(bounds);
+
+                // Since the user can tap an item, add the CLICK action. We'll
+                // need to handle this later in onPerformActionForVirtualView.
+                node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
+
+                // This item has a checked state.
+                node.setCheckable(true);
+                node.setChecked(item.checked);
+            }
+
+            @Override
+            protected boolean onPerformActionForVirtualView(
+                    int virtualViewId, int action, Bundle arguments) {
+                switch (action) {
+                    case AccessibilityNodeInfoCompat.ACTION_CLICK:
+                        // Click handling should be consistent with
+                        // onTouchEvent(). This ensures that the view works the
+                        // same whether accessibility is turned on or off.
+                        return onItemClicked(virtualViewId);
+                }
+
+                return false;
+            }
+
+        }
+
+        public static class CustomItem {
+            private String description;
+            private RectF bounds;
+            private boolean checked;
+        }
+    }
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
index 04d57a0..a534eee 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
@@ -33,6 +33,7 @@
 import android.media.RemoteControlClient;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -370,15 +371,18 @@
                     "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i])));
         }
 
-        // Scan local /sdcard/ directory for media files.
-        String sdcard = "/sdcard/";
-        File file = new File(sdcard);
-        File list[] = file.listFiles();
-        for (int i = 0; i < list.length; i++) {
-            String filename = list[i].getName();
-            if (filename.matches(".*\\.(m4v|mp4)")) {
-                mLibraryItems.add(new MediaItem(
-                        "[local] "+filename, Uri.parse("file:///sdcard/" + filename)));
+        // Scan local external storage directory for media files.
+        File externalDir = Environment.getExternalStorageDirectory();
+        if (externalDir != null) {
+            File list[] = externalDir.listFiles();
+            if (list != null) {
+                for (int i = 0; i < list.length; i++) {
+                    String filename = list[i].getName();
+                    if (filename.matches(".*\\.(m4v|mp4)")) {
+                        mLibraryItems.add(new MediaItem("[local] " + filename,
+                                Uri.fromFile(list[i])));
+                    }
+                }
             }
         }
 
diff --git a/samples/training/testingfun/app/AndroidManifest.xml b/samples/training/testingfun/app/AndroidManifest.xml
new file mode 100644
index 0000000..a71247a
--- /dev/null
+++ b/samples/training/testingfun/app/AndroidManifest.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT 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.testingfun"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="17" />
+    <application
+        android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/AppTheme"
+        android:allowBackup="false">
+
+        <activity
+            android:name=".lesson2.MyFirstTestActivity"
+            android:label="@string/my_first_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".lesson3.ClickFunActivity"
+            android:label="@string/click_fun">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".lesson4.LaunchActivity"
+            android:label="@string/launch_next">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".lesson4.NextActivity"
+            android:label="@string/next_activity" />
+        <activity
+            android:name=".lesson5.SenderActivity"
+            android:label="@string/sender_activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".lesson5.ReceiverActivity"
+            android:label="@string/receiver_activity" />
+    </application>
+</manifest>
diff --git a/samples/training/testingfun/app/build.gradle b/samples/training/testingfun/app/build.gradle
new file mode 100644
index 0000000..c68484f
--- /dev/null
+++ b/samples/training/testingfun/app/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'android'
+
+android {
+    compileSdkVersion 17
+    buildToolsVersion "17.0.0"
+
+    defaultConfig {
+        minSdkVersion 8
+    }
+
+    android {
+        sourceSets {
+            main {
+                manifest.srcFile 'AndroidManifest.xml'
+                java.srcDirs = ['src']
+                resources.srcDirs = ['src']
+                aild.srcDirs = ['src']
+                renderscript.srcDirs = ['src']
+                res.srcDirs = ['res']
+                assets.srcDirs = ['assets']
+            }
+
+            instrumentTest.setRoot('tests')
+            instrumentTest.java.srcDirs = ['tests/src']
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/training/testingfun/app/project.properties b/samples/training/testingfun/app/project.properties
new file mode 100644
index 0000000..a3ee5ab
--- /dev/null
+++ b/samples/training/testingfun/app/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-17
diff --git a/samples/training/testingfun/app/res/drawable-hdpi/ic_launcher.png b/samples/training/testingfun/app/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..136343e
--- /dev/null
+++ b/samples/training/testingfun/app/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/training/testingfun/app/res/drawable-mdpi/ic_launcher.png b/samples/training/testingfun/app/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6837266
--- /dev/null
+++ b/samples/training/testingfun/app/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/training/testingfun/app/res/drawable-xhdpi/ic_launcher.png b/samples/training/testingfun/app/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e88e975
--- /dev/null
+++ b/samples/training/testingfun/app/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/training/testingfun/app/res/drawable-xxhdpi/ic_launcher.png b/samples/training/testingfun/app/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..ac31a90
--- /dev/null
+++ b/samples/training/testingfun/app/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/training/testingfun/app/res/layout/activity_click_fun.xml b/samples/training/testingfun/app/res/layout/activity_click_fun.xml
new file mode 100644
index 0000000..c960c3b
--- /dev/null
+++ b/samples/training/testingfun/app/res/layout/activity_click_fun.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <Button
+        android:id="@+id/launch_next_activity_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/label_click_me" />
+
+    <TextView
+        android:id="@+id/info_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone" />
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/training/testingfun/app/res/layout/activity_launch_next.xml b/samples/training/testingfun/app/res/layout/activity_launch_next.xml
new file mode 100644
index 0000000..cfd0114
--- /dev/null
+++ b/samples/training/testingfun/app/res/layout/activity_launch_next.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT 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"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <Button
+        android:id="@+id/launch_next_activity_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/label_launch_next" />
+</merge>
\ No newline at end of file
diff --git a/samples/training/testingfun/app/res/layout/activity_my_first_test.xml b/samples/training/testingfun/app/res/layout/activity_my_first_test.xml
new file mode 100644
index 0000000..3499bc7
--- /dev/null
+++ b/samples/training/testingfun/app/res/layout/activity_my_first_test.xml
@@ -0,0 +1,27 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/my_first_test_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/my_first_test" />
+</LinearLayout>
+
diff --git a/samples/training/testingfun/app/res/layout/activity_next.xml b/samples/training/testingfun/app/res/layout/activity_next.xml
new file mode 100644
index 0000000..92f30f7
--- /dev/null
+++ b/samples/training/testingfun/app/res/layout/activity_next.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT 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"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/next_activity_info_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+</merge>
\ No newline at end of file
diff --git a/samples/training/testingfun/app/res/layout/activity_receiver.xml b/samples/training/testingfun/app/res/layout/activity_receiver.xml
new file mode 100644
index 0000000..e93d16b
--- /dev/null
+++ b/samples/training/testingfun/app/res/layout/activity_receiver.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT 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"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/received_message_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+</merge>
\ No newline at end of file
diff --git a/samples/training/testingfun/app/res/layout/activity_sender.xml b/samples/training/testingfun/app/res/layout/activity_sender.xml
new file mode 100644
index 0000000..e18f4c4
--- /dev/null
+++ b/samples/training/testingfun/app/res/layout/activity_sender.xml
@@ -0,0 +1,33 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <EditText
+        android:id="@+id/message_input_edit_text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="@string/message_input_hint_edit_text" />
+
+    <Button
+        android:id="@+id/send_message_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/label_send_message" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/training/testingfun/app/res/values-sw720dp-land/dimens.xml b/samples/training/testingfun/app/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..3201e93
--- /dev/null
+++ b/samples/training/testingfun/app/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,18 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+    <dimen name="activity_horizontal_margin">128dp</dimen>
+</resources>
diff --git a/samples/training/testingfun/app/res/values-v11/styles.xml b/samples/training/testingfun/app/res/values-v11/styles.xml
new file mode 100644
index 0000000..90ff160
--- /dev/null
+++ b/samples/training/testingfun/app/res/values-v11/styles.xml
@@ -0,0 +1,18 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+</resources>
diff --git a/samples/training/testingfun/app/res/values-v14/styles.xml b/samples/training/testingfun/app/res/values-v14/styles.xml
new file mode 100644
index 0000000..90ff160
--- /dev/null
+++ b/samples/training/testingfun/app/res/values-v14/styles.xml
@@ -0,0 +1,18 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+</resources>
diff --git a/samples/training/testingfun/app/res/values/dimens.xml b/samples/training/testingfun/app/res/values/dimens.xml
new file mode 100644
index 0000000..e96acda
--- /dev/null
+++ b/samples/training/testingfun/app/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/samples/training/testingfun/app/res/values/strings.xml b/samples/training/testingfun/app/res/values/strings.xml
new file mode 100644
index 0000000..1fc3bc0
--- /dev/null
+++ b/samples/training/testingfun/app/res/values/strings.xml
@@ -0,0 +1,34 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT 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">Android Testing Fun</string>
+
+    <string name="my_first_test">My First Test</string>
+
+    <string name="click_fun">Click Fun Test</string>
+    <string name="label_click_me">Click me</string>
+
+    <string name="launch_next">Launch Activity</string>
+    <string name="next_activity">Next Activity</string>
+
+    <string name="sender_activity">Sender Activity</string>
+    <string name="receiver_activity">Receiver Activity</string>
+
+    <string name="info_text">Button clicked!</string>
+    <string name="label_launch_next">Launch Next</string>
+    <string name="label_send_message">Send</string>
+    <string name="message_input_hint_edit_text">Enter a message</string>
+</resources>
diff --git a/samples/training/testingfun/app/res/values/styles.xml b/samples/training/testingfun/app/res/values/styles.xml
new file mode 100644
index 0000000..fa3d1bd
--- /dev/null
+++ b/samples/training/testingfun/app/res/values/styles.xml
@@ -0,0 +1,20 @@
+<!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+    <style name="AppBaseTheme" parent="android:Theme.Light" />
+
+    <style name="AppTheme" parent="AppBaseTheme" />
+</resources>
diff --git a/samples/training/testingfun/app/src/com/example/android/testingfun/lesson2/MyFirstTestActivity.java b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson2/MyFirstTestActivity.java
new file mode 100644
index 0000000..db977cf
--- /dev/null
+++ b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson2/MyFirstTestActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.lesson2;
+
+import com.example.android.testingfun.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Activity with a TextView that contains a String label.
+ */
+public class MyFirstTestActivity extends Activity {
+
+    /**
+     * Called when the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_my_first_test);
+    }
+}
diff --git a/samples/training/testingfun/app/src/com/example/android/testingfun/lesson3/ClickFunActivity.java b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson3/ClickFunActivity.java
new file mode 100644
index 0000000..09db694
--- /dev/null
+++ b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson3/ClickFunActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.lesson3;
+
+import com.example.android.testingfun.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Activity which shows a "click me" button. When the button is clicked, a TextView is shown below
+ * the button.
+ */
+public class ClickFunActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_click_fun);
+
+        final TextView infoTextView = (TextView) findViewById(R.id.info_text_view);
+        final Button clickMeButton = (Button) findViewById(R.id.launch_next_activity_button);
+        clickMeButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                infoTextView.setVisibility(View.VISIBLE);
+                infoTextView.setText(getString(R.string.info_text));
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/samples/training/testingfun/app/src/com/example/android/testingfun/lesson4/LaunchActivity.java b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson4/LaunchActivity.java
new file mode 100644
index 0000000..8f1fb9b
--- /dev/null
+++ b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson4/LaunchActivity.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.lesson4;
+
+import com.example.android.testingfun.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * Launches NextActivity and passes a payload in the Bundle.
+ */
+public class LaunchActivity extends Activity {
+
+    /**
+     * The payload that is passed as Intent data to NextActivity.
+     */
+    public final static String STRING_PAYLOAD = "Started from LaunchActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_launch_next);
+        Button launchNextButton = (Button) findViewById(R.id.launch_next_activity_button);
+        launchNextButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startActivity(NextActivity.makeIntent(LaunchActivity.this, STRING_PAYLOAD));
+                finish();
+            }
+        });
+    }
+}
diff --git a/samples/training/testingfun/app/src/com/example/android/testingfun/lesson4/NextActivity.java b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson4/NextActivity.java
new file mode 100644
index 0000000..68965c2
--- /dev/null
+++ b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson4/NextActivity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.lesson4;
+
+import com.example.android.testingfun.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * This activity is started from LaunchActivity. It reads the payload from the given bundle and
+ * displays it using a TextView.
+ */
+public class NextActivity extends Activity {
+
+    /**
+     * Extras key for the payload.
+     */
+    public final static String EXTRAS_PAYLOAD_KEY
+            = "com.example.android.testingfun.lesson4.EXTRAS_PAYLOAD_KEY";
+
+    /**
+     * Factory method to create a launch Intent for this activity.
+     *
+     * @param context the context that intent should be bound to
+     * @param payload the payload data that should be added for this intent
+     * @return a configured intent to launch this activity with a String payload.
+     */
+    public static Intent makeIntent(Context context, String payload) {
+        return new Intent(context, NextActivity.class).putExtra(EXTRAS_PAYLOAD_KEY, payload);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_next);
+
+        final String stringPayload = getIntent().getStringExtra(EXTRAS_PAYLOAD_KEY);
+
+        if (stringPayload != null) {
+            ((TextView) findViewById(R.id.next_activity_info_text_view)).setText(stringPayload);
+        }
+
+    }
+}
diff --git a/samples/training/testingfun/app/src/com/example/android/testingfun/lesson5/ReceiverActivity.java b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson5/ReceiverActivity.java
new file mode 100644
index 0000000..2bc401d
--- /dev/null
+++ b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson5/ReceiverActivity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.lesson5;
+
+import com.example.android.testingfun.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.widget.TextView;
+
+/**
+ * Receives a message from SenderActivity and displays the message.
+ */
+public class ReceiverActivity extends Activity {
+
+    /**
+     * The extra key that is used to identify the message in the Intents data bundle
+     */
+    private static final String EXTRA_SENDER_MESSAGE_TEXT
+            = "com.example.android.testingfun.lesson5.extra.sender.message.text";
+
+    /**
+     * Factory method to create an launch intent for this activity.
+     *
+     * @param context the context to this intent should be bound to
+     * @param message the message data that should be added to this intent
+     * @return a configured intent to launch this activity with a given message
+     */
+    public static Intent makeIntent(Context context, CharSequence message) {
+        return new Intent(context, ReceiverActivity.class)
+                .putExtra(EXTRA_SENDER_MESSAGE_TEXT, message);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_receiver);
+        final CharSequence senderMessage = getIntent()
+                .getCharSequenceExtra(EXTRA_SENDER_MESSAGE_TEXT);
+        final TextView receiverTextView = (TextView) findViewById(R.id.received_message_text_view);
+        if (!TextUtils.isEmpty(senderMessage)) {
+            receiverTextView.setText(senderMessage);
+        }
+    }
+}
diff --git a/samples/training/testingfun/app/src/com/example/android/testingfun/lesson5/SenderActivity.java b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson5/SenderActivity.java
new file mode 100644
index 0000000..495f1e6
--- /dev/null
+++ b/samples/training/testingfun/app/src/com/example/android/testingfun/lesson5/SenderActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.lesson5;
+
+import com.example.android.testingfun.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+/**
+ * Sends a user generated message to the ReceiverActivity
+ */
+public class SenderActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_sender);
+        final Button sendMessageButton = (Button) findViewById(R.id.send_message_button);
+        final EditText messageInputEditText = (EditText) findViewById(R.id.message_input_edit_text);
+        sendMessageButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (messageInputEditText != null) {
+                    final CharSequence message = messageInputEditText.getText();
+                    startActivity(ReceiverActivity.makeIntent(SenderActivity.this, message));
+                }
+            }
+        });
+    }
+}
diff --git a/samples/training/testingfun/app/tests/AndroidManifest.xml b/samples/training/testingfun/app/tests/AndroidManifest.xml
new file mode 100644
index 0000000..13ce6ab
--- /dev/null
+++ b/samples/training/testingfun/app/tests/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright (C) 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.testingfun.tests"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="17" />
+
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--
+    Specifies the instrumentation test runner used to run the tests.
+    -->
+    <instrumentation
+        android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.example.android.testingfun"
+        android:label="Tests for com.example.android.testingfun" />
+</manifest>
\ No newline at end of file
diff --git a/samples/training/testingfun/app/tests/project.properties b/samples/training/testingfun/app/tests/project.properties
new file mode 100644
index 0000000..a3ee5ab
--- /dev/null
+++ b/samples/training/testingfun/app/tests/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-17
diff --git a/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson2/MyFirstTestActivityTest.java b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson2/MyFirstTestActivityTest.java
new file mode 100644
index 0000000..ad18b55
--- /dev/null
+++ b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson2/MyFirstTestActivityTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.tests.lesson2;
+
+import com.example.android.testingfun.R;
+import com.example.android.testingfun.lesson2.MyFirstTestActivity;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.widget.TextView;
+
+/**
+ * Tests for MyFirstTestActivity.
+ */
+public class MyFirstTestActivityTest extends ActivityInstrumentationTestCase2<MyFirstTestActivity> {
+
+    private MyFirstTestActivity mFirstTestActivity;
+    private TextView mFirstTestText;
+
+    public MyFirstTestActivityTest() {
+        super(MyFirstTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Starts the activity under test using the default Intent with:
+        // action = {@link Intent#ACTION_MAIN}
+        // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+        // All other fields are null or empty.
+        mFirstTestActivity = getActivity();
+        mFirstTestText = (TextView) mFirstTestActivity.findViewById(R.id.my_first_test_text_view);
+    }
+
+    /**
+     * Test if your test fixture has been set up correctly. You should always implement a test that
+     * checks the correct setup of your test fixture. If this tests fails all other tests are
+     * likely to fail as well.
+     */
+    public void testPreconditions() {
+        //Try to add a message to add context to your assertions. These messages will be shown if
+        //a tests fails and make it easy to understand why a test failed
+        assertNotNull("mFirstTestActivity is null", mFirstTestActivity);
+        assertNotNull("mFirstTestText is null", mFirstTestText);
+    }
+
+    /**
+     * Tests the correctness of the initial text.
+     */
+    public void testMyFirstTestTextView_labelText() {
+        //It is good practice to read the string from your resources in order to not break
+        //multiple tests when a string changes.
+        final String expected = mFirstTestActivity.getString(R.string.my_first_test);
+        final String actual = mFirstTestText.getText().toString();
+        assertEquals("mFirstTestText contains wrong text", expected, actual);
+    }
+}
\ No newline at end of file
diff --git a/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson3/ClickFunActivityTest.java b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson3/ClickFunActivityTest.java
new file mode 100644
index 0000000..5d3d387
--- /dev/null
+++ b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson3/ClickFunActivityTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.tests.lesson3;
+
+
+import com.example.android.testingfun.R;
+import com.example.android.testingfun.lesson3.ClickFunActivity;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.TouchUtils;
+import android.test.ViewAsserts;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Tests for ClickFunActivity. Introduces touch mode, test size annotations and TouchUtils.
+ */
+public class ClickFunActivityTest extends ActivityInstrumentationTestCase2<ClickFunActivity> {
+    
+    private ClickFunActivity mClickFunActivity;
+    private Button mClickMeButton;
+    private TextView mInfoTextView;
+
+    public ClickFunActivityTest() {
+        super(ClickFunActivity.class);
+    }
+
+    /**
+     * Sets up the test fixture for this test case. This method is always called before every test
+     * run.
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        //Sets the initial touch mode for the Activity under test. This must be called before
+        //getActivity()
+        setActivityInitialTouchMode(true);
+
+        //Get a reference to the Activity under test, starting it if necessary.
+        mClickFunActivity = getActivity();
+
+        //Get references to all views
+        mClickMeButton = (Button) mClickFunActivity.findViewById(R.id.launch_next_activity_button);
+        mInfoTextView = (TextView) mClickFunActivity.findViewById(R.id.info_text_view);
+    }
+
+    /**
+     * Tests the preconditions of this test fixture.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        assertNotNull("mClickFunActivity is null", mClickFunActivity);
+        assertNotNull("mClickMeButton is null", mClickMeButton);
+        assertNotNull("mInfoTextView is null", mInfoTextView);
+    }
+
+    @MediumTest
+    public void testClickMeButton_layout() {
+        //Retrieve the top-level window decor view
+        final View decorView = mClickFunActivity.getWindow().getDecorView();
+
+        //Verify that the mClickMeButton is on screen
+        ViewAsserts.assertOnScreen(decorView, mClickMeButton);
+
+        //Verify width and heights
+        final ViewGroup.LayoutParams layoutParams = mClickMeButton.getLayoutParams();
+        assertNotNull(layoutParams);
+        assertEquals(layoutParams.width, WindowManager.LayoutParams.MATCH_PARENT);
+        assertEquals(layoutParams.height, WindowManager.LayoutParams.WRAP_CONTENT);
+    }
+
+    @MediumTest
+    public void testClickMeButton_labelText() {
+        //Verify that mClickMeButton uses the correct string resource
+        final String expectedNextButtonText = mClickFunActivity.getString(R.string.label_click_me);
+        final String actualNextButtonText = mClickMeButton.getText().toString();
+        assertEquals(expectedNextButtonText, actualNextButtonText);
+    }
+
+    @MediumTest
+    public void testInfoTextView_layout() {
+        //Retrieve the top-level window decor view
+        final View decorView = mClickFunActivity.getWindow().getDecorView();
+
+        //Verify that the mInfoTextView is on screen and is not visible
+        ViewAsserts.assertOnScreen(decorView, mInfoTextView);
+        assertTrue(View.GONE == mInfoTextView.getVisibility());
+    }
+
+    @MediumTest
+    public void testInfoTextViewText_isEmpty() {
+        //Verify that the mInfoTextView is initialized with the correct default value
+        assertEquals("", mInfoTextView.getText());
+    }
+
+    @MediumTest
+    public void testClickMeButton_clickButtonAndExpectInfoText() {
+        String expectedInfoText = mClickFunActivity.getString(R.string.info_text);
+        //Perform a click on mClickMeButton
+        TouchUtils.clickView(this, mClickMeButton);
+        //Verify the that mClickMeButton was clicked. mInfoTextView is visible and contains
+        //the correct text.
+        assertTrue(View.VISIBLE == mInfoTextView.getVisibility());
+        assertEquals(expectedInfoText, mInfoTextView.getText());
+    }
+}
diff --git a/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson4/LaunchActivityTest.java b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson4/LaunchActivityTest.java
new file mode 100644
index 0000000..7d472c3
--- /dev/null
+++ b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson4/LaunchActivityTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.tests.lesson4;
+
+import com.example.android.testingfun.R;
+import com.example.android.testingfun.lesson4.LaunchActivity;
+import com.example.android.testingfun.lesson4.NextActivity;
+
+import android.content.Intent;
+import android.test.ActivityUnitTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+
+/**
+ * Tests LaunchActivity in isolation from the system.
+ */
+public class LaunchActivityTest extends ActivityUnitTestCase<LaunchActivity> {
+
+    private Intent mLaunchIntent;
+
+    public LaunchActivityTest() {
+        super(LaunchActivity.class);
+    }
+
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        //Create an intent to launch target Activity
+        mLaunchIntent = new Intent(getInstrumentation().getTargetContext(),
+                LaunchActivity.class);
+    }
+
+    /**
+     * Tests the preconditions of this test fixture.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        //Start the activity under test in isolation, without values for savedInstanceState and
+        //lastNonConfigurationInstance
+        startActivity(mLaunchIntent, null, null);
+        final Button launchNextButton = (Button) getActivity().findViewById(R.id.launch_next_activity_button);
+
+        assertNotNull("mLaunchActivity is null", getActivity());
+        assertNotNull("mLaunchNextButton is null", launchNextButton);
+    }
+
+
+    @MediumTest
+    public void testLaunchNextActivityButton_labelText() {
+        startActivity(mLaunchIntent, null, null);
+        final Button launchNextButton = (Button) getActivity().findViewById(R.id.launch_next_activity_button);
+
+        final String expectedButtonText = getActivity().getString(R.string.label_launch_next);
+        assertEquals("Unexpected button label text", expectedButtonText,
+                launchNextButton.getText());
+    }
+
+    @MediumTest
+    public void testNextActivityWasLaunchedWithIntent() {
+        startActivity(mLaunchIntent, null, null);
+        final Button launchNextButton = (Button) getActivity().findViewById(R.id.launch_next_activity_button);
+        //Because this is an isolated ActivityUnitTestCase we have to directly click the
+        //button from code
+        launchNextButton.performClick();
+
+        // Get the intent for the next started activity
+        final Intent launchIntent = getStartedActivityIntent();
+        //Verify the intent was not null.
+        assertNotNull("Intent was null", launchIntent);
+        //Verify that LaunchActivity was finished after button click
+        assertTrue(isFinishCalled());
+
+
+        final String payload = launchIntent.getStringExtra(NextActivity.EXTRAS_PAYLOAD_KEY);
+        //Verify that payload data was added to the intent
+        assertEquals("Payload is empty", LaunchActivity.STRING_PAYLOAD
+                , payload);
+    }
+}
\ No newline at end of file
diff --git a/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson5/SenderActivityTest.java b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson5/SenderActivityTest.java
new file mode 100644
index 0000000..75bc302
--- /dev/null
+++ b/samples/training/testingfun/app/tests/src/com/example/android/testingfun/tests/lesson5/SenderActivityTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.testingfun.tests.lesson5;
+
+import com.example.android.testingfun.R;
+import com.example.android.testingfun.lesson5.ReceiverActivity;
+import com.example.android.testingfun.lesson5.SenderActivity;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/**
+ * Functional test across multiple Activities. Tests SenderActivity and ReceiverActivity. Introduces
+ * advanced Instrumentation testing practices as sending key events and interaction monitoring
+ * between Activities and the system.
+ */
+public class SenderActivityTest extends ActivityInstrumentationTestCase2<SenderActivity> {
+
+    private static final int TIMEOUT_IN_MS = 5000;
+    private static final String TEST_MESSAGE = "Hello Receiver";
+    private SenderActivity mSenderActivity;
+
+    public SenderActivityTest() {
+        super(SenderActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setActivityInitialTouchMode(true);
+        mSenderActivity = getActivity();
+    }
+
+    /**
+     * Tests the preconditions of this test fixture.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        assertNotNull("mSenderActivity is null", mSenderActivity);
+    }
+
+    @MediumTest
+    public void testSendMessageToReceiverActivity() {
+
+        //Because this functional test tests interaction across multiple components these views
+        //are part of the actual test method and not of the test fixture
+        final Button sendToReceiverButton = (Button) mSenderActivity
+                .findViewById(R.id.send_message_button);
+        final EditText senderMessageEditText = (EditText) mSenderActivity
+                .findViewById(R.id.message_input_edit_text);
+
+        //Create and add an ActivityMonitor to monitor interaction between the system and the
+        //ReceiverActivity
+        Instrumentation.ActivityMonitor receiverActivityMonitor = getInstrumentation()
+                .addMonitor(ReceiverActivity.class.getName(), null, false);
+
+        //Request focus on the EditText field. This must be done on the UiThread because
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                senderMessageEditText.requestFocus();
+            }
+        });
+        //Wait until all events from the MainHandler's queue are processed
+        getInstrumentation().waitForIdleSync();
+
+        //Send the text message
+        getInstrumentation().sendStringSync(TEST_MESSAGE);
+        getInstrumentation().waitForIdleSync();
+
+        //Click on the sendToReceiverButton to send the message to ReceiverActivity
+        TouchUtils.clickView(this, sendToReceiverButton);
+
+        //Wait until ReceiverActivity was launched and get a reference to it.
+        ReceiverActivity receiverActivity = (ReceiverActivity) receiverActivityMonitor
+                .waitForActivityWithTimeout(TIMEOUT_IN_MS);
+        //Verify that ReceiverActivity was started
+        assertNotNull("ReceiverActivity is null", receiverActivity);
+        assertEquals("Monitor for ReceiverActivity has not been called", 1,
+                receiverActivityMonitor.getHits());
+        assertEquals("Activity is of wrong type", ReceiverActivity.class,
+                receiverActivity.getClass());
+
+        //Read the message received by ReceiverActivity
+        final TextView receivedMessage = (TextView) receiverActivity
+                .findViewById(R.id.received_message_text_view);
+        //Verify that received message is correct
+        assertNotNull(receivedMessage);
+        assertEquals("Wrong received message", TEST_MESSAGE, receivedMessage.getText().toString());
+
+        //Unregister monitor for ReceiverActivity
+        getInstrumentation().removeMonitor(receiverActivityMonitor);
+    }
+}
\ No newline at end of file
diff --git a/samples/training/testingfun/build.gradle b/samples/training/testingfun/build.gradle
new file mode 100644
index 0000000..06b6030
--- /dev/null
+++ b/samples/training/testingfun/build.gradle
@@ -0,0 +1,8 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.4.2'
+    }
+}
diff --git a/samples/training/testingfun/gradle/wrapper/gradle-wrapper.jar b/samples/training/testingfun/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/samples/training/testingfun/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/samples/training/testingfun/gradle/wrapper/gradle-wrapper.properties b/samples/training/testingfun/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..5c22dec
--- /dev/null
+++ b/samples/training/testingfun/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip
diff --git a/samples/training/testingfun/gradlew b/samples/training/testingfun/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/samples/training/testingfun/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/samples/training/testingfun/gradlew.bat b/samples/training/testingfun/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/samples/training/testingfun/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windowz variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+if "%@eval[2+2]" == "4" goto 4NT_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+goto execute

+

+:4NT_args

+@rem Get arguments from the 4NT Shell from JP Software

+set CMD_LINE_ARGS=%$

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/samples/training/testingfun/settings.gradle b/samples/training/testingfun/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/samples/training/testingfun/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/scripts/compare-installed-size.py b/scripts/compare-installed-size.py
new file mode 100755
index 0000000..488723d
--- /dev/null
+++ b/scripts/compare-installed-size.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""summarize and compare the component sizes in installed-files.txt."""
+
+import sys
+
+bin_size1 = {}
+bin_size2 = {}
+bin_sizes = [bin_size1, bin_size2]
+
+file_sizes = {}
+
+def PrintUsage():
+  print "usage: " + sys.argv[0] + " filename [filename2]"
+  print ""
+  print "  Input file is installed-files.txt from the build output directory."
+  print "  When only one input file is given, it will generate module_0.csv."
+  print "  When two input files are given, in addition it will generate"
+  print "  module_1.csv and comparison.csv."
+  print ""
+  print "  The module_x.csv file shows the aggregated file size in each module"
+  print "  (eg bin, lib, app, ...)"
+  print "  The comparison.cvs file shows the individual file sizes side by side"
+  print "  from two different builds"
+  print ""
+  print "  These files can be uploaded to Google Doc for further processing."
+  sys.exit(1)
+
+def ParseFile(install_file, idx):
+  input_stream = open(install_file, 'r')
+  for line in input_stream:
+    # line = "25027208  /system/lib/libchromeview.so"
+    line = line.strip()
+
+    # size = "25027208", name = "/system/lib/libchromeview.so"
+    size, name = line.split()
+
+    # components = ["", "system", "lib", "libchromeview.so"]
+    components = name.split('/')
+
+    # module = "lib"
+    module = components[2]
+
+    # filename = libchromeview.so"
+    filename = components[-1]
+
+    # sum up the file sizes by module name
+    if module not in bin_sizes[idx]:
+      bin_sizes[idx][module] = int(size)
+    else:
+      bin_sizes[idx][module] += int(size)
+
+    # sometimes a file only exists on one build but not the other - use 0 as the
+    # default size.
+    if idx == 0:
+      file_sizes[name] = [module, size, 0]
+    else:
+      if name in file_sizes:
+        file_sizes[name][-1] = size
+      else:
+        file_sizes[name] = [module, 0, size]
+
+  input_stream.close()
+
+  # output the module csv file
+  output = open("module_%d.csv" % idx, 'w')
+  total = 0
+  for key in bin_sizes[idx]:
+    output.write("%s, %d\n" % (key, bin_sizes[idx][key]))
+  output.close()
+
+def main():
+  if len(sys.argv) < 2 or len(sys.argv) > 3:
+    PrintUsage()
+  # Parse the first installed-files.txt
+  ParseFile(sys.argv[1], 0)
+
+  # Parse the second installed-files.txt
+  if len(sys.argv) == 3:
+    ParseFile(sys.argv[2], 1)
+    # comparison.csv has the following columns:
+    # filename, module, size1, size2, size2-size1
+    # eg: /system/lib/libchromeview.so, lib, 25027208, 33278460, 8251252
+    output = open("comparison.csv", 'w')
+    for key in file_sizes:
+      output.write("%s, %s, %s, %s, %d\n" %
+                   (key, file_sizes[key][0], file_sizes[key][1],
+                    file_sizes[key][2],
+                    int(file_sizes[key][2]) - int(file_sizes[key][1])))
+    output.close()
+
+if __name__ == '__main__':
+  main()
+
+# vi: ts=2 sw=2
diff --git a/scripts/gdb/dalvik.gdb b/scripts/gdb/dalvik.gdb
new file mode 100644
index 0000000..cab0951
--- /dev/null
+++ b/scripts/gdb/dalvik.gdb
@@ -0,0 +1,51 @@
+#  dump dalvik backtrace
+define dbt
+    if $argc == 1
+        set $FP = $arg0
+    else
+        set $FP = $r5
+    end
+
+    set $frame = 0
+    set $savedPC = 0
+    while $FP
+        set $stackSave = $FP - sizeof(StackSaveArea)
+        set $savedPC = ((StackSaveArea *)$stackSave)->savedPc
+        set $method = ((StackSaveArea *)$stackSave)->method
+        printf "#%d\n", $frame
+        printf "    FP = %#x\n", $FP
+        printf "    stack save = %#x\n", $stackSave
+        printf "    Curr pc = %#x\n", ((StackSaveArea *) $stackSave)->xtra.currentPc
+        printf "    FP prev = %#x\n", ((StackSaveArea *) $stackSave)->prevFrame
+        if $method != 0
+            printf "    returnAddr: 0x%x\n", \
+                   ((StackSaveArea *)$stackSave)->returnAddr
+            printf "    class = %s\n", ((Method *) $method)->clazz->descriptor
+            printf "    method = %s (%#08x)\n", ((Method *) $method)->name, $method
+            printf "    signature = %s\n", ((Method *) $method)->shorty
+            printf "    bytecode offset = 0x%x\n", (short *) (((StackSaveArea *) $stackSave)->xtra.currentPc) - (short *) (((Method *) $method)->insns)
+            set $regSize = ((Method *) $method)->registersSize
+            set $insSize = ((Method *) $method)->insSize
+            set $index = 0
+            while $index < $regSize
+                printf "    v%d = %d", $index, ((int *)$FP)[$index]
+                if $regSize - $index <= $insSize
+                    printf " (in%d)\n", $insSize - $regSize + $index
+                else
+                    printf " (local%d)\n", $index
+                end
+                set $index = $index + 1
+            end
+        else
+            printf "    break frame\n"
+        end
+        set $FP = (int) ((StackSaveArea *)$stackSave)->prevFrame
+        set $frame = $frame + 1
+    end
+end
+
+document dbt
+    Unwind Dalvik stack frames. Argument 0 is the frame address of the top
+    frame. If omitted r5 will be used as the default (as the case in the
+    interpreter and JIT'ed code).
+end
diff --git a/scripts/stack b/scripts/stack
index 6750752..6bb8d0a 100755
--- a/scripts/stack
+++ b/scripts/stack
@@ -1,18 +1,25 @@
 #!/usr/bin/env python
 #
-# Copyright 2006 Google Inc. All Rights Reserved.
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 
 """stack symbolizes native crash dumps."""
 
 import getopt
-import getpass
-import glob
-import os
-import re
-import subprocess
 import sys
-import urllib
 
+import stack_core
 import symbol
 
 
@@ -22,17 +29,8 @@
   print
   print "  usage: " + sys.argv[0] + " [options] [FILE]"
   print
-  print "  --symbols-dir=path"
-  print "       the path to a symbols dir, such as =/tmp/out/target/product/dream/symbols"
-  print
-  print "  --symbols-zip=path"
-  print "       the path to a symbols zip file, such as =dream-symbols-12345.zip"
-  print
-  print "  --auto"
-  print "       attempt to:"
-  print "         1) automatically find the build number in the crash"
-  print "         2) if it's an official build, download the symbols "
-  print "            from the build server, and use them"
+  print "  --arch=arm|x86"
+  print "       the target architecture"
   print
   print "  FILE should contain a stack trace in it somewhere"
   print "       the tool will find that and re-print it with"
@@ -44,347 +42,23 @@
   sys.exit(1)
 
 
-class SSOCookie(object):
-  """Creates a cookie file so we can download files from the build server."""
-
-  def __init__(self, cookiename=".sso.cookie", keep=False):
-    self.sso_server = "login.corp.google.com"
-    self.name = cookiename
-    self.keeper = keep
-    if not os.path.exists(self.name):
-      user = os.environ["USER"]
-      print "\n%s, to access the symbols, please enter your LDAP " % user,
-      sys.stdout.flush()
-      password = getpass.getpass()
-      params = urllib.urlencode({"u": user, "pw": password})
-      url = "https://%s/login?ssoformat=CORP_SSO" % self.sso_server
-      # login to SSO
-      curlcmd = ["/usr/bin/curl",
-                 "--cookie", self.name,
-                 "--cookie-jar", self.name,
-                 "--silent",
-                 "--location",
-                 "--data", params,
-                 "--output", "/dev/null",
-                 url]
-      subprocess.check_call(curlcmd)
-      if os.path.exists(self.name):
-        os.chmod(self.name, 0600)
-      else:
-        print "Could not log in to SSO"
-        sys.exit(1)
-
-  def __del__(self):
-    """Clean up."""
-    if not self.keeper:
-      os.remove(self.name)
-
-
-class NoBuildIDException(Exception):
-  pass
-
-
-def FindBuildFingerprint(lines):
-  """Searches the given file (array of lines) for the build fingerprint."""
-  fingerprint_regex = re.compile("^.*Build fingerprint:\s'(?P<fingerprint>.*)'")
-  for line in lines:
-    fingerprint_search = fingerprint_regex.match(line.strip())
-    if fingerprint_search:
-      return fingerprint_search.group("fingerprint")
-
-  return None  # didn't find the fingerprint string, so return none
-
-
-class SymbolDownloadException(Exception):
-  pass
-
-
-DEFAULT_SYMROOT = "/tmp/symbols"
-
-
-def DownloadSymbols(fingerprint, cookie):
-  """Attempts to download the symbols from the build server.
-
-  If successful, extracts them, and returns the path.
-
-  Args:
-    fingerprint: build fingerprint from the input stack trace
-    cookie: SSOCookie
-
-  Returns:
-    tuple (None, None) if no fingerprint is provided. Otherwise
-    tuple (root directory, symbols directory).
-
-  Raises:
-    SymbolDownloadException: Problem downloading symbols for fingerprint
-  """
-  if fingerprint is None:
-    return (None, None)
-  symdir = "%s/%s" % (DEFAULT_SYMROOT, hash(fingerprint))
-  if not os.path.exists(symdir):
-    os.makedirs(symdir)
-  # build server figures out the branch based on the CL
-  params = {
-      "op": "GET-SYMBOLS-LINK",
-      "fingerprint": fingerprint,
-      }
-  print "url: http://android-build/buildbot-update?" + urllib.urlencode(params)
-  url = urllib.urlopen("http://android-build/buildbot-update?",
-                       urllib.urlencode(params)).readlines()[0]
-  if not url:
-    raise SymbolDownloadException("Build server down? Failed to find syms...")
-
-  regex_str = (r"(?P<base_url>http\:\/\/android-build\/builds\/.*\/[0-9]+)"
-               r"(?P<img>.*)")
-  url_regex = re.compile(regex_str)
-  url_match = url_regex.match(url)
-  if url_match is None:
-    raise SymbolDownloadException("Unexpected results from build server URL...")
-
-  base_url = url_match.group("base_url")
-  img = url_match.group("img")
-  symbolfile = img.replace("-img-", "-symbols-")
-  symurl = base_url + symbolfile
-  localsyms = symdir + symbolfile
-
-  if not os.path.exists(localsyms):
-    print "downloading %s ..." % symurl
-    curlcmd = ["/usr/bin/curl",
-               "--cookie", cookie.name,
-               "--silent",
-               "--location",
-               "--write-out", "%{http_code}",
-               "--output", localsyms,
-               symurl]
-    p = subprocess.Popen(curlcmd,
-                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                         close_fds=True)
-    code = p.stdout.read()
-    err = p.stderr.read()
-    if err:
-      raise SymbolDownloadException("stderr from curl download: %s" % err)
-    if code != "200":
-      raise SymbolDownloadException("Faied to download %s" % symurl)
-  else:
-    print "using existing cache for symbols"
-
-  return UnzipSymbols(localsyms, symdir)
-
-
-def UnzipSymbols(symbolfile, symdir=None):
-  """Unzips a file to DEFAULT_SYMROOT and returns the unzipped location.
-
-  Args:
-    symbolfile: The .zip file to unzip
-    symdir: Optional temporary directory to use for extraction
-
-  Returns:
-    A tuple containing (the directory into which the zip file was unzipped,
-    the path to the "symbols" directory in the unzipped file).  To clean
-    up, the caller can delete the first element of the tuple.
-
-  Raises:
-    SymbolDownloadException: When the unzip fails.
-  """
-  if not symdir:
-    symdir = "%s/%s" % (DEFAULT_SYMROOT, hash(symbolfile))
-  if not os.path.exists(symdir):
-    os.makedirs(symdir)
-
-  print "extracting %s..." % symbolfile
-  saveddir = os.getcwd()
-  os.chdir(symdir)
-  try:
-    unzipcode = subprocess.call(["unzip", "-qq", "-o", symbolfile])
-    if unzipcode > 0:
-      os.remove(symbolfile)
-      raise SymbolDownloadException("failed to extract symbol files (%s)."
-                                    % symbolfile)
-  finally:
-    os.chdir(saveddir)
-
-  return (symdir, glob.glob("%s/out/target/product/*/symbols" % symdir)[0])
-
-
-def PrintTraceLines(trace_lines):
-  """Print back trace."""
-  maxlen = max(map(lambda tl: len(tl[1]), trace_lines))
-  print
-  print "Stack Trace:"
-  print "  RELADDR   " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
-  for tl in trace_lines:
-    (addr, symbol_with_offset, location) = tl
-    print "  %8s  %s  %s" % (addr, symbol_with_offset.ljust(maxlen), location)
-  return
-
-
-def PrintValueLines(value_lines):
-  """Print stack data values."""
-  print
-  print "Stack Data:"
-  print "  ADDR      VALUE     FILE:LINE/FUNCTION"
-  for vl in value_lines:
-    (addr, value, symbol_with_offset, location) = vl
-    print "  " + addr + "  " + value + "  " + location
-    if location:
-      print "                      " + symbol_with_offset
-  return
-
-UNKNOWN = "<unknown>"
-HEAP = "[heap]"
-STACK = "[stack]"
-
-
-def ConvertTrace(lines):
-  """Convert strings containing native crash to a stack."""
-  process_info_line = re.compile("(pid: [0-9]+, tid: [0-9]+.*)")
-  signal_line = re.compile("(signal [0-9]+ \(.*\).*)")
-  register_line = re.compile("(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})")
-  thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-")
-  # Note taht both trace and value line matching allow for variable amounts of
-  # whitespace (e.g. \t). This is because the we want to allow for the stack
-  # tool to operate on AndroidFeedback provided system logs. AndroidFeedback
-  # strips out double spaces that are found in tombsone files and logcat output.
-  #
-  # Examples of matched trace lines include lines from tombstone files like:
-  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so
-  # Or lines from AndroidFeedback crash report system logs like:
-  #   03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so
-  # Please note the spacing differences.
-  trace_line = re.compile("(.*)\#([0-9]+)[ \t]+(..)[ \t]+([0-9a-f]{8})[ \t]+([^\r\n \t]*)( \((.*)\))?")  # pylint: disable-msg=C6310
-  # Examples of matched value lines include:
-  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so
-  #   03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so
-  # Again, note the spacing differences.
-  value_line = re.compile("(.*)([0-9a-f]{8})[ \t]+([0-9a-f]{8})[ \t]+([^\r\n \t]*)")
-  # Lines from 'code around' sections of the output will be matched before
-  # value lines because otheriwse the 'code around' sections will be confused as
-  # value lines.
-  #
-  # Examples include:
-  #   801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
-  #   03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
-  code_line = re.compile("(.*)[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[ \r\n]")  # pylint: disable-msg=C6310
-
-  trace_lines = []
-  value_lines = []
-
-  for ln in lines:
-    # AndroidFeedback adds zero width spaces into its crash reports. These
-    # should be removed or the regular expresssions will fail to match.
-    line = unicode(ln, errors='ignore')
-    header = process_info_line.search(line)
-    if header:
-      print header.group(1)
-      continue
-    header = signal_line.search(line)
-    if header:
-      print header.group(1)
-      continue
-    header = register_line.search(line)
-    if header:
-      print header.group(1)
-      continue
-    if trace_line.match(line):
-      match = trace_line.match(line)
-      (unused_0, unused_1, unused_2,
-       code_addr, area, symbol_present, symbol_name) = match.groups()
-
-      if area == UNKNOWN or area == HEAP or area == STACK:
-        trace_lines.append((code_addr, area, area))
-      else:
-        # If a calls b which further calls c and c is inlined to b, we want to
-        # display "a -> b -> c" in the stack trace instead of just "a -> c"
-        (source_symbol,
-         source_location,
-         object_symbol_with_offset) = symbol.SymbolInformation(area, code_addr)
-        if not source_symbol:
-          if symbol_present:
-            source_symbol = symbol.CallCppFilt(symbol_name)
-          else:
-            source_symbol = UNKNOWN
-        if not source_location:
-          source_location = area
-        if not object_symbol_with_offset:
-          object_symbol_with_offset = source_symbol
-        if not object_symbol_with_offset.startswith(source_symbol):
-          trace_lines.append(("v------>", source_symbol, source_location))
-          trace_lines.append((code_addr,
-                              object_symbol_with_offset,
-                              source_location))
-        else:
-          trace_lines.append((code_addr,
-                              object_symbol_with_offset,
-                              source_location))
-    if code_line.match(line):
-      # Code lines should be ignored. If this were exluded the 'code around'
-      # sections would trigger value_line matches.
-      continue;
-    if value_line.match(line):
-      match = value_line.match(line)
-      (unused_, addr, value, area) = match.groups()
-      if area == UNKNOWN or area == HEAP or area == STACK or not area:
-        value_lines.append((addr, value, area, ""))
-      else:
-        (source_symbol,
-         source_location,
-         object_symbol_with_offset) = symbol.SymbolInformation(area, value)
-        if not source_location:
-          source_location = ""
-        if not object_symbol_with_offset:
-          object_symbol_with_offset = UNKNOWN
-        value_lines.append((addr,
-                            value,
-                            object_symbol_with_offset,
-                            source_location))
-    header = thread_line.search(line)
-    if header:
-      if trace_lines:
-        PrintTraceLines(trace_lines)
-
-      if value_lines:
-        PrintValueLines(value_lines)
-      trace_lines = []
-      value_lines = []
-      print
-      print "-----------------------------------------------------\n"
-
-  if trace_lines:
-    PrintTraceLines(trace_lines)
-
-  if value_lines:
-    PrintValueLines(value_lines)
-
-
 def main():
   try:
     options, arguments = getopt.getopt(sys.argv[1:], "",
-                                       ["auto",
-                                        "symbols-dir=",
-                                        "symbols-zip=",
+                                       ["arch=",
                                         "help"])
   except getopt.GetoptError, unused_error:
     PrintUsage()
 
-  zip_arg = None
-  auto = False
-  fingerprint = None
   for option, value in options:
     if option == "--help":
       PrintUsage()
-    elif option == "--symbols-dir":
-      symbol.SYMBOLS_DIR = os.path.expanduser(value)
-    elif option == "--symbols-zip":
-      zip_arg = os.path.expanduser(value)
-    elif option == "--auto":
-      auto = True
+    elif option == "--arch":
+      symbol.ARCH = value
 
   if len(arguments) > 1:
     PrintUsage()
 
-  if auto:
-    cookie = SSOCookie(".symbols.cookie")
-
   if not arguments or arguments[0] == "-":
     print "Reading native crash info from stdin"
     f = sys.stdin
@@ -395,22 +69,8 @@
   lines = f.readlines()
   f.close()
 
-  rootdir = None
-  if auto:
-    fingerprint = FindBuildFingerprint(lines)
-    print "fingerprint:", fingerprint
-    rootdir, symbol.SYMBOLS_DIR = DownloadSymbols(fingerprint, cookie)
-  elif zip_arg:
-    rootdir, symbol.SYMBOLS_DIR = UnzipSymbols(zip_arg)
-
   print "Reading symbols from", symbol.SYMBOLS_DIR
-  ConvertTrace(lines)
-
-  if rootdir:
-    # be a good citizen and clean up...os.rmdir and os.removedirs() don't work
-    cmd = "rm -rf \"%s\"" % rootdir
-    print "\ncleaning up (%s)" % cmd
-    os.system(cmd)
+  stack_core.ConvertTrace(lines)
 
 if __name__ == "__main__":
   main()
diff --git a/scripts/stack_core.py b/scripts/stack_core.py
new file mode 100755
index 0000000..42285d4
--- /dev/null
+++ b/scripts/stack_core.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""stack symbolizes native crash dumps."""
+
+import re
+
+import symbol
+
+def PrintTraceLines(trace_lines):
+  """Print back trace."""
+  maxlen = max(map(lambda tl: len(tl[1]), trace_lines))
+  print
+  print "Stack Trace:"
+  print "  RELADDR   " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
+  for tl in trace_lines:
+    (addr, symbol_with_offset, location) = tl
+    print "  %8s  %s  %s" % (addr, symbol_with_offset.ljust(maxlen), location)
+  return
+
+
+def PrintValueLines(value_lines):
+  """Print stack data values."""
+  maxlen = max(map(lambda tl: len(tl[2]), value_lines))
+  print
+  print "Stack Data:"
+  print "  ADDR      VALUE     " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
+  for vl in value_lines:
+    (addr, value, symbol_with_offset, location) = vl
+    print "  %8s  %8s  %s  %s" % (addr, value, symbol_with_offset.ljust(maxlen), location)
+  return
+
+UNKNOWN = "<unknown>"
+HEAP = "[heap]"
+STACK = "[stack]"
+
+
+def PrintOutput(trace_lines, value_lines):
+  if trace_lines:
+    PrintTraceLines(trace_lines)
+  if value_lines:
+    PrintValueLines(value_lines)
+
+def PrintDivider():
+  print
+  print "-----------------------------------------------------\n"
+
+def ConvertTrace(lines):
+  """Convert strings containing native crash to a stack."""
+  process_info_line = re.compile("(pid: [0-9]+, tid: [0-9]+.*)")
+  signal_line = re.compile("(signal [0-9]+ \(.*\).*)")
+  register_line = re.compile("(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})")
+  thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-")
+  dalvik_jni_thread_line = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)")
+  dalvik_native_thread_line = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)")
+  # Note that both trace and value line matching allow for variable amounts of
+  # whitespace (e.g. \t). This is because the we want to allow for the stack
+  # tool to operate on AndroidFeedback provided system logs. AndroidFeedback
+  # strips out double spaces that are found in tombsone files and logcat output.
+  #
+  # Examples of matched trace lines include lines from tombstone files like:
+  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so
+  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so (symbol)
+  # Or lines from AndroidFeedback crash report system logs like:
+  #   03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so
+  # Please note the spacing differences.
+  trace_line = re.compile("(.*)\#([0-9]+)[ \t]+(..)[ \t]+([0-9a-f]{8})[ \t]+([^\r\n \t]*)( \((.*)\))?")  # pylint: disable-msg=C6310
+  # Examples of matched value lines include:
+  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so
+  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so (symbol)
+  #   03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so
+  # Again, note the spacing differences.
+  value_line = re.compile("(.*)([0-9a-f]{8})[ \t]+([0-9a-f]{8})[ \t]+([^\r\n \t]*)( \((.*)\))?")
+  # Lines from 'code around' sections of the output will be matched before
+  # value lines because otheriwse the 'code around' sections will be confused as
+  # value lines.
+  #
+  # Examples include:
+  #   801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
+  #   03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
+  code_line = re.compile("(.*)[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[ \r\n]")  # pylint: disable-msg=C6310
+
+  trace_lines = []
+  value_lines = []
+  last_frame = -1
+
+  for ln in lines:
+    # AndroidFeedback adds zero width spaces into its crash reports. These
+    # should be removed or the regular expresssions will fail to match.
+    line = unicode(ln, errors='ignore')
+    process_header = process_info_line.search(line)
+    signal_header = signal_line.search(line)
+    register_header = register_line.search(line)
+    thread_header = thread_line.search(line)
+    dalvik_jni_thread_header = dalvik_jni_thread_line.search(line)
+    dalvik_native_thread_header = dalvik_native_thread_line.search(line)
+    if process_header or signal_header or register_header or thread_header \
+        or dalvik_jni_thread_header or dalvik_native_thread_header:
+      if trace_lines or value_lines:
+        PrintOutput(trace_lines, value_lines)
+        PrintDivider()
+        trace_lines = []
+        value_lines = []
+        last_frame = -1
+      if process_header:
+        print process_header.group(1)
+      if signal_header:
+        print signal_header.group(1)
+      if register_header:
+        print register_header.group(1)
+      if thread_header:
+        print thread_header.group(1)
+      if dalvik_jni_thread_header:
+        print dalvik_jni_thread_header.group(1)
+      if dalvik_native_thread_header:
+        print dalvik_native_thread_header.group(1)
+      continue
+    if trace_line.match(line):
+      match = trace_line.match(line)
+      (unused_0, frame, unused_1,
+       code_addr, area, symbol_present, symbol_name) = match.groups()
+
+      if frame <= last_frame and (trace_lines or value_lines):
+        PrintOutput(trace_lines, value_lines)
+        PrintDivider()
+        trace_lines = []
+        value_lines = []
+      last_frame = frame
+
+      if area == UNKNOWN or area == HEAP or area == STACK:
+        trace_lines.append((code_addr, "", area))
+      else:
+        # If a calls b which further calls c and c is inlined to b, we want to
+        # display "a -> b -> c" in the stack trace instead of just "a -> c"
+        info = symbol.SymbolInformation(area, code_addr)
+        nest_count = len(info) - 1
+        for (source_symbol, source_location, object_symbol_with_offset) in info:
+          if not source_symbol:
+            if symbol_present:
+              source_symbol = symbol.CallCppFilt(symbol_name)
+            else:
+              source_symbol = UNKNOWN
+          if not source_location:
+            source_location = area
+          if nest_count > 0:
+            nest_count = nest_count - 1
+            trace_lines.append(("v------>", source_symbol, source_location))
+          else:
+            if not object_symbol_with_offset:
+              object_symbol_with_offset = source_symbol
+            trace_lines.append((code_addr,
+                                object_symbol_with_offset,
+                                source_location))
+    if code_line.match(line):
+      # Code lines should be ignored. If this were exluded the 'code around'
+      # sections would trigger value_line matches.
+      continue;
+    if value_line.match(line):
+      match = value_line.match(line)
+      (unused_, addr, value, area, symbol_present, symbol_name) = match.groups()
+      if area == UNKNOWN or area == HEAP or area == STACK or not area:
+        value_lines.append((addr, value, "", area))
+      else:
+        info = symbol.SymbolInformation(area, value)
+        (source_symbol, source_location, object_symbol_with_offset) = info.pop()
+        if not source_symbol:
+          if symbol_present:
+            source_symbol = symbol.CallCppFilt(symbol_name)
+          else:
+            source_symbol = UNKNOWN
+        if not source_location:
+          source_location = area
+        if not object_symbol_with_offset:
+          object_symbol_with_offset = source_symbol
+        value_lines.append((addr,
+                            value,
+                            object_symbol_with_offset,
+                            source_location))
+
+  PrintOutput(trace_lines, value_lines)
+
+
+# vi: ts=2 sw=2
diff --git a/scripts/symbol.py b/scripts/symbol.py
index b0e94d8..0f58df6 100755
--- a/scripts/symbol.py
+++ b/scripts/symbol.py
@@ -1,6 +1,18 @@
 #!/usr/bin/python
 #
-# Copyright 2006 Google Inc. All Rights Reserved.
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 
 """Module for looking up symbolic debugging information.
 
@@ -29,6 +41,10 @@
 
 SYMBOLS_DIR = FindSymbolsDir()
 
+ARCH = "arm"
+
+TOOLCHAIN_INFO = None
+
 def Uname():
   """'uname' for constructing prebuilt/<...> and out/host/<...> paths."""
   uname = os.uname()[0]
@@ -44,9 +60,9 @@
 def ToolPath(tool, toolchain_info=None):
   """Return a full qualified path to the specified tool"""
   if not toolchain_info:
-    toolchain_info = TOOLCHAIN_INFO
-  (label, target) = toolchain_info
-  return os.path.join(ANDROID_BUILD_TOP, "prebuilts", "gcc", Uname(), "arm", label, "bin",
+    toolchain_info = FindToolchain()
+  (label, platform, target) = toolchain_info
+  return os.path.join(ANDROID_BUILD_TOP, "prebuilts/gcc", Uname(), platform, label, "bin",
                      target + "-" + tool)
 
 def FindToolchain():
@@ -58,27 +74,32 @@
   Returns:
     A pair of strings containing toolchain label and target prefix.
   """
+  global TOOLCHAIN_INFO
+  if TOOLCHAIN_INFO is not None:
+    return TOOLCHAIN_INFO
 
   ## Known toolchains, newer ones in the front.
-  known_toolchains = [
-    ("arm-eabi-4.6", "arm-eabi"),
-    ("arm-linux-androideabi-4.4.x", "arm-linux-androideabi"),
-    ("arm-eabi-4.4.3", "arm-eabi"),
-    ("arm-eabi-4.4.0", "arm-eabi"),
-    ("arm-eabi-4.3.1", "arm-eabi"),
-    ("arm-eabi-4.2.1", "arm-eabi")
-  ]
+  if ARCH == "arm":
+    gcc_version = os.environ["TARGET_GCC_VERSION"]
+    known_toolchains = [
+      ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi"),
+    ]
+  elif ARCH =="x86":
+    known_toolchains = [
+      ("i686-android-linux-4.4.3", "x86", "i686-android-linux")
+    ]
+  else:
+    known_toolchains = []
 
   # Look for addr2line to check for valid toolchain path.
-  for (label, target) in known_toolchains:
-    toolchain_info = (label, target);
+  for (label, platform, target) in known_toolchains:
+    toolchain_info = (label, platform, target);
     if os.path.exists(ToolPath("addr2line", toolchain_info)):
+      TOOLCHAIN_INFO = toolchain_info
       return toolchain_info
 
   raise Exception("Could not find tool chain")
 
-TOOLCHAIN_INFO = FindToolchain()
-
 def SymbolInformation(lib, addr):
   """Look up symbol information about an address.
 
@@ -87,20 +108,19 @@
     addr: string hexidecimal address
 
   Returns:
-    For a given library and address, return tuple of: (source_symbol,
-    source_location, object_symbol_with_offset) the values may be None
-    if the information was unavailable.
+    A list of the form [(source_symbol, source_location,
+    object_symbol_with_offset)].
 
-    source_symbol may not be a prefix of object_symbol_with_offset if
-    the source function was inlined in the object code of another
-    function.
+    If the function has been inlined then the list may contain
+    more than one element with the symbols for the most deeply
+    nested inlined location appearing first.  The list is
+    always non-empty, even if no information is available.
 
-    usually you want to display the object_symbol_with_offset and
-    source_location, the source_symbol is only useful to show if the
-    address was from an inlined function.
+    Usually you want to display the source_location and
+    object_symbol_with_offset from the last element in the list.
   """
   info = SymbolInformationForSet(lib, set([addr]))
-  return (info and info.get(addr)) or (None, None, None)
+  return (info and info.get(addr)) or [(None, None, None)]
 
 
 def SymbolInformationForSet(lib, unique_addrs):
@@ -111,17 +131,17 @@
     unique_addrs: set of hexidecimal addresses
 
   Returns:
-    For a given library and set of addresses, returns a dictionary of the form
-    {addr: (source_symbol, source_location, object_symbol_with_offset)}. The
-    values may be None if the information was unavailable.
+    A dictionary of the form {addr: [(source_symbol, source_location,
+    object_symbol_with_offset)]} where each address has a list of
+    associated symbols and locations.  The list is always non-empty.
 
-    For a given address, source_symbol may not be a prefix of
-    object_symbol_with_offset if the source function was inlined in the
-    object code of another function.
+    If the function has been inlined then the list may contain
+    more than one element with the symbols for the most deeply
+    nested inlined location appearing first.  The list is
+    always non-empty, even if no information is available.
 
-    Usually you want to display the object_symbol_with_offset and
-    source_location; the source_symbol is only useful to show if the
-    address was from an inlined function.
+    Usually you want to display the source_location and
+    object_symbol_with_offset from the last element in the list.
   """
   if not lib:
     return None
@@ -136,14 +156,17 @@
 
   result = {}
   for addr in unique_addrs:
-    (source_symbol, source_location) = addr_to_line.get(addr, (None, None))
+    source_info = addr_to_line.get(addr)
+    if not source_info:
+      source_info = [(None, None)]
     if addr in addr_to_objdump:
       (object_symbol, object_offset) = addr_to_objdump.get(addr)
       object_symbol_with_offset = FormatSymbolWithOffset(object_symbol,
                                                          object_offset)
     else:
       object_symbol_with_offset = None
-    result[addr] = (source_symbol, source_location, object_symbol_with_offset)
+    result[addr] = [(source_symbol, source_location, object_symbol_with_offset)
+        for (source_symbol, source_location) in source_info]
 
   return result
 
@@ -156,8 +179,13 @@
     unique_addrs: set of string hexidecimal addresses look up.
 
   Returns:
-    A dictionary of the form {addr: (symbol, file:line)}. The values may
-    be (None, None) if the address could not be looked up.
+    A dictionary of the form {addr: [(symbol, file:line)]} where
+    each address has a list of associated symbols and locations
+    or an empty list if no symbol information was found.
+
+    If the function has been inlined then the list may contain
+    more than one element with the symbols for the most deeply
+    nested inlined location appearing first.
   """
   if not lib:
     return None
@@ -167,8 +195,9 @@
   if not os.path.exists(symbols):
     return None
 
-  (label, target) = TOOLCHAIN_INFO
-  cmd = [ToolPath("addr2line"), "--functions", "--demangle", "--exe=" + symbols]
+  (label, platform, target) = FindToolchain()
+  cmd = [ToolPath("addr2line"), "--functions", "--inlines",
+      "--demangle", "--exe=" + symbols]
   child = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
 
   result = {}
@@ -176,18 +205,45 @@
   for addr in addrs:
     child.stdin.write("0x%s\n" % addr)
     child.stdin.flush()
-    symbol = child.stdout.readline().strip()
-    if symbol == "??":
-      symbol = None
-    location = child.stdout.readline().strip()
-    if location == "??:0":
-      location = None
-    result[addr] = (symbol, location)
+    records = []
+    first = True
+    while True:
+      symbol = child.stdout.readline().strip()
+      if symbol == "??":
+        symbol = None
+      location = child.stdout.readline().strip()
+      if location == "??:0":
+        location = None
+      if symbol is None and location is None:
+        break
+      records.append((symbol, location))
+      if first:
+        # Write a blank line as a sentinel so we know when to stop
+        # reading inlines from the output.
+        # The blank line will cause addr2line to emit "??\n??:0\n".
+        child.stdin.write("\n")
+        first = False
+    result[addr] = records
   child.stdin.close()
   child.stdout.close()
   return result
 
 
+def StripPC(addr):
+  """Strips the Thumb bit a program counter address when appropriate.
+
+  Args:
+    addr: the program counter address
+
+  Returns:
+    The stripped program counter address.
+  """
+  global ARCH
+
+  if ARCH == "arm":
+    return addr & ~1
+  return addr
+
 def CallObjdumpForSet(lib, unique_addrs):
   """Use objdump to find out the names of the containing functions.
 
@@ -210,13 +266,13 @@
     return None
 
   addrs = sorted(unique_addrs)
-  start_addr_hex = addrs[0]
-  stop_addr_dec = str(int(addrs[-1], 16) + 8)
+  start_addr_dec = str(StripPC(int(addrs[0], 16)))
+  stop_addr_dec = str(StripPC(int(addrs[-1], 16)) + 8)
   cmd = [ToolPath("objdump"),
          "--section=.text",
          "--demangle",
          "--disassemble",
-         "--start-address=0x" + start_addr_hex,
+         "--start-address=" + start_addr_dec,
          "--stop-address=" + stop_addr_dec,
          symbols]
 
@@ -261,7 +317,7 @@
       addr = components.group(1)
       target_addr = addrs[addr_index]
       i_addr = int(addr, 16)
-      i_target = int(target_addr, 16)
+      i_target = StripPC(int(target_addr, 16))
       if i_addr == i_target:
         result[target_addr] = (current_symbol, i_target - current_symbol_addr)
         addr_index += 1
diff --git a/sdk/build_tools_source.prop_template b/sdk/build_tools_source.prop_template
new file mode 100644
index 0000000..5d62307
--- /dev/null
+++ b/sdk/build_tools_source.prop_template
@@ -0,0 +1,3 @@
+Pkg.UserSrc=false
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
+
diff --git a/sdk/build_tools_source.properties b/sdk/build_tools_source.properties
deleted file mode 100644
index 0025a2a..0000000
--- a/sdk/build_tools_source.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Pkg.UserSrc=false
-Pkg.Revision=18.1.0
-
diff --git a/sdk/images_armeabi-v7a_source.prop_template b/sdk/images_armeabi-v7a_source.prop_template
index 4f2daac..86fc2a0 100644
--- a/sdk/images_armeabi-v7a_source.prop_template
+++ b/sdk/images_armeabi-v7a_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=armeabi-v7a
diff --git a/sdk/plat_tools_source.prop_template b/sdk/plat_tools_source.prop_template
new file mode 100644
index 0000000..5d62307
--- /dev/null
+++ b/sdk/plat_tools_source.prop_template
@@ -0,0 +1,3 @@
+Pkg.UserSrc=false
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
+
diff --git a/sdk/plat_tools_source.properties b/sdk/plat_tools_source.properties
deleted file mode 100644
index 1ac7da0..0000000
--- a/sdk/plat_tools_source.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Pkg.UserSrc=false
-Pkg.Revision=18.0.1
-
diff --git a/sdk/platform_source.prop_template b/sdk/platform_source.prop_template
index 0f55383..be4c026 100644
--- a/sdk/platform_source.prop_template
+++ b/sdk/platform_source.prop_template
@@ -2,9 +2,9 @@
 Pkg.UserSrc=false
 Platform.Version=${PLATFORM_VERSION}
 Platform.CodeName=Jelly Bean
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
-Layoutlib.Api=10
+Layoutlib.Api=9
 Layoutlib.Revision=1
 Platform.MinToolsRev=21
diff --git a/sdk/support_source.properties b/sdk/support_source.prop_template
similarity index 82%
rename from sdk/support_source.properties
rename to sdk/support_source.prop_template
index 1617096..ba7e6fb 100644
--- a/sdk/support_source.properties
+++ b/sdk/support_source.prop_template
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
-Pkg.Revision=18
+Pkg.Revision=${PLATFORM_SDK_VERSION}
 Extra.Vendor=android
 Extra.VendorId=android
 Extra.VendorDisplay=Android
diff --git a/sdk/usbdriver_source.properties b/sdk/usbdriver_source.properties
index bff71f9..c33d032 100755
--- a/sdk/usbdriver_source.properties
+++ b/sdk/usbdriver_source.properties
@@ -1,4 +1,4 @@
-Pkg.Revision=7

+Pkg.Revision=8

 Archive.Os=WINDOWS

 Archive.Arch=ANY

 Extra.Path=usb_driver

diff --git a/testrunner/android_build.py b/testrunner/android_build.py
index a10d43b..cacd67e 100644
--- a/testrunner/android_build.py
+++ b/testrunner/android_build.py
@@ -48,6 +48,25 @@
   return root_path
 
 
+def GetHostOutDir():
+  """Returns the full pathname of out/host/arch of the Android development tree.
+
+  Assumes build environment has been properly configured by envsetup &
+  lunch/choosecombo.
+
+  Returns:
+    the absolute file path of the Android host output directory.
+  Raises:
+    AbortError: if Android host output directory could not be found.
+  """
+  host_out_path = os.getenv("ANDROID_HOST_OUT")
+  if host_out_path is None:
+    logger.Log("Error: ANDROID_HOST_OUT not defined. Please run "
+               "envsetup.sh and lunch/choosecombo")
+    raise errors.AbortError
+  return host_out_path
+
+
 def GetHostOsArch():
   """Identify the host os and arch.
 
@@ -72,10 +91,25 @@
   return (host_os, host_arch, "%s-%s" % (host_os, host_arch))
 
 
+def GetOutDir():
+  """Returns the full pathname of the "out" of the Android development tree.
+
+  Assumes build environment has been properly configured by envsetup &
+  lunch/choosecombo.
+
+  Returns:
+    the absolute file path of the Android build output directory.
+  """
+  root_path = os.getenv("OUT_DIR")
+  if root_path is None:
+    root_path = os.path.join(GetTop(), "out")
+  return root_path
+
+
 def GetHostBin():
   """Compute the full pathname to the host binary directory.
 
-  Typically $ANDROID_BUILD_TOP/out/host/linux-x86/bin.
+  Typically $ANDROID_HOST_OUT/bin.
 
   Assumes build environment has been properly configured by envsetup &
   lunch/choosecombo.
@@ -86,8 +120,7 @@
   Raises:
     AbortError: if Android host binary directory could not be found.
   """
-  (_, _, os_arch) = GetHostOsArch()
-  path = os.path.join(GetTop(), "out", "host", os_arch, "bin")
+  path = os.path.join(GetHostOutDir(), "bin")
   if not os.path.exists(path):
     logger.Log("Error: Host bin path could not be found %s" % path)
     raise errors.AbortError
@@ -139,7 +172,7 @@
 def GetHostLibraryPath():
   """Returns the full pathname to the host java library output directory.
 
-  Typically $ANDROID_BUILD_TOP/out/host/<host_os>/framework.
+  Typically $ANDROID_HOST_OUT/framework.
 
   Assumes build environment has been properly configured by envsetup &
   lunch/choosecombo.
@@ -150,8 +183,7 @@
   Raises:
     AbortError: if Android host java library directory could not be found.
   """
-  (_, _, os_arch) = GetHostOsArch()
-  path = os.path.join(GetTop(), "out", "host", os_arch, "framework")
+  path = os.path.join(GetHostOutDir(), "framework")
   if not os.path.exists(path):
     logger.Log("Error: Host library path could not be found %s" % path)
     raise errors.AbortError
diff --git a/testrunner/coverage/coverage.py b/testrunner/coverage/coverage.py
index 570527d..824f5c5 100755
--- a/testrunner/coverage/coverage.py
+++ b/testrunner/coverage/coverage.py
@@ -43,7 +43,7 @@
   _EMMA_JAR = os.path.join("external", "emma", "lib", "emma.jar")
   _TEST_COVERAGE_EXT = "ec"
   # root path of generated coverage report files, relative to Android build root
-  _COVERAGE_REPORT_PATH = os.path.join("out", "emma")
+  _COVERAGE_REPORT_PATH = "emma"
   _TARGET_DEF_FILE = "coverage_targets.xml"
   _CORE_TARGET_PATH = os.path.join("development", "testrunner",
                                    _TARGET_DEF_FILE)
@@ -53,12 +53,13 @@
                                      _TARGET_DEF_FILE)
 
   # path to root of target build intermediates
-  _TARGET_INTERMEDIATES_BASE_PATH = os.path.join("out", "target", "common",
+  _TARGET_INTERMEDIATES_BASE_PATH = os.path.join("target", "common",
                                                  "obj")
 
   def __init__(self, adb_interface):
     self._root_path = android_build.GetTop()
-    self._output_root_path = os.path.join(self._root_path,
+    self._out_path = android_build.GetOut()
+    self._output_root_path = os.path.join(self._out_path,
                                           self._COVERAGE_REPORT_PATH)
     self._emma_jar_path = os.path.join(self._root_path, self._EMMA_JAR)
     self._adb = adb_interface
@@ -78,7 +79,7 @@
       target: the CoverageTarget to use as basis for coverage calculation
       device_coverage_path: location of coverage file on device
       output_path: path to place output files in. If None will use
-        <android_root_path>/<_COVERAGE_REPORT_PATH>/<target>/<test[-qualifier]>
+        <android_out_path>/<_COVERAGE_REPORT_PATH>/<target>/<test[-qualifier]>
       test_qualifier: designates mode test was run with. e.g size=small.
         If not None, this will be used to customize output_path as shown above.
 
@@ -89,7 +90,7 @@
       report_name = test_suite_name
       if test_qualifier:
         report_name = report_name + "-" + test_qualifier
-      output_path = os.path.join(self._root_path,
+      output_path = os.path.join(self._out_path,
                                  self._COVERAGE_REPORT_PATH,
                                  target.GetName(),
                                  report_name)
@@ -153,7 +154,7 @@
 
   def _GetBuildIntermediatePath(self, target):
     return os.path.join(
-        self._root_path, self._TARGET_INTERMEDIATES_BASE_PATH, target.GetType(),
+        self._out_path, self._TARGET_INTERMEDIATES_BASE_PATH, target.GetType(),
         "%s_intermediates" % target.GetName())
 
   def _GatherSrcs(self, targets):
diff --git a/testrunner/coverage_targets.xml b/testrunner/coverage_targets.xml
index 99ea93b..4ac5979 100644
--- a/testrunner/coverage_targets.xml
+++ b/testrunner/coverage_targets.xml
@@ -92,8 +92,6 @@
         type="APPS" />
 
    <!-- content providers -->
-    <coverage_target name="ApplicationsProvider"
-        build_path="packages/providers/ApplicationsProvider" type="APPS" />
     <coverage_target name="CalendarProvider"
         build_path="packages/providers/CalendarProvider" type="APPS" />
     <coverage_target name="ContactsProvider"
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index f7a4759..a76d9c0 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -75,16 +75,18 @@
 
   _DALVIK_VERIFIER_OFF_PROP = "dalvik.vm.dexopt-flags = v=n"
 
-  # regular expression to match install: statements in make output
-  _RE_MAKE_INSTALL = re.compile(r'Install:\s(.+)')
+  # regular expression to match path to artifacts to install in make output
+  _RE_MAKE_INSTALL = re.compile(r'INSTALL-PATH:\s(.+)\s(.+)')
 
-  # regular expression to find remote device path from a file path relative
-  # to build root
-  _RE_MAKE_INSTALL_PATH = re.compile(r'out\/target\/product\/\w+\/(.+)$')
 
   def __init__(self):
     # disable logging of timestamp
     self._root_path = android_build.GetTop()
+    out_base_name = os.path.basename(android_build.GetOutDir())
+    # regular expression to find remote device path from a file path relative
+    # to build root
+    pattern = r'' + out_base_name + r'\/target\/product\/\w+\/(.+)$'
+    self._re_make_install_path = re.compile(pattern)
     logger.SetTimestampLogging(False)
     self._adb = None
     self._known_tests = None
@@ -270,12 +272,13 @@
 
       # 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" all_modules %s' % (
+      cmd = 'ONE_SHOT_MAKEFILE="%s" make -j%s -C "%s" GET-INSTALL-PATH all_modules %s' % (
           target_build_string, self._options.make_jobs, self._root_path,
           extra_args_string)
       logger.Log(cmd)
       if not self._options.preview:
         output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
+        logger.SilentLog(output)
         self._DoInstall(output)
 
   def _DoInstall(self, make_output):
@@ -289,7 +292,7 @@
     for line in make_output.split("\n"):
       m = self._RE_MAKE_INSTALL.match(line)
       if m:
-        install_path = m.group(1)
+        install_path = m.group(2)
         if install_path.endswith(".apk"):
           abs_install_path = os.path.join(self._root_path, install_path)
           logger.Log("adb install -r %s" % abs_install_path)
@@ -298,9 +301,12 @@
           self._PushInstallFileToDevice(install_path)
 
   def _PushInstallFileToDevice(self, install_path):
-    m = self._RE_MAKE_INSTALL_PATH.match(install_path)
+    m = self._re_make_install_path.match(install_path)
     if m:
       remote_path = m.group(1)
+      remote_dir = os.path.dirname(remote_path)
+      logger.Log("adb shell mkdir -p %s" % remote_dir)
+      self._adb.SendShellCommand("mkdir -p %s" % remote_dir)
       abs_install_path = os.path.join(self._root_path, install_path)
       logger.Log("adb push %s %s" % (abs_install_path, remote_path))
       self._adb.Push(abs_install_path, remote_path)
@@ -313,7 +319,8 @@
 
     # hack to build cts dependencies
     # TODO: remove this when cts dependencies are removed
-    if self._IsCtsTests(tests):
+    is_cts =  self._IsCtsTests(tests)
+    if is_cts:
       # 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')
@@ -335,8 +342,15 @@
         old_dir = os.getcwd()
         os.chdir(self._root_path)
         output = run_command.RunCommand(cmd, return_output=True)
+        logger.SilentLog(output)
         os.chdir(old_dir)
         self._DoInstall(output)
+        if is_cts:
+          # hack! hardcode install of CtsTestStubs
+          out = android_build.GetTestAppPath()
+          abs_install_path = os.path.join(out, "CtsTestStubs.apk")
+          logger.Log("adb install -r %s" % abs_install_path)
+          logger.Log(self._adb.Install(abs_install_path))
 
   def _AddBuildTarget(self, test_suite, target_tree, extra_args_set):
     if not test_suite.IsFullMake():
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 516dc7c..24e4dca 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -137,9 +137,13 @@
     description="Framework libutils unit tests." />
 
 <test-native name="libinput"
-    build_path="frameworks/base/services/input/tests"
+    build_path="frameworks/native/libs/input/tests"
     description="Framework libinput unit tests." />
 
+<test-native name="libinputservice"
+    build_path="frameworks/base/services/input/tests"
+    description="Framework libinputservice unit tests." />
+
 <test name="volley"
     build_path="frameworks/support/volley/tests"
     package="com.android.volley.tests"
@@ -187,6 +191,12 @@
     runner=".MediaFrameworkUnitTestRunner"
     coverage_target="framework" />
 
+<test name="mediaintegrationtest"
+    build_path="frameworks/base/media/tests/MediaFrameworkTest"
+    package="com.android.mediaframeworktest"
+    runner=".MediaFrameworkIntegrationTestRunner"
+    coverage_target="framework" />
+
 <test-native name="camera-client-native"
     build_path="frameworks/av/camera/tests/"
     description="Camera client native tests." />
@@ -336,7 +346,7 @@
 <test name="cts-net"
     build_path="cts/tests/tests/net"
     package="com.android.cts.net"
-    runner="android.test.InstrumentationTestRunner"
+    runner="android.test.InstrumentationCtsTestRunner"
     coverage_target="framework"
     suite="cts" />
 
@@ -403,12 +413,6 @@
     build_path="development/samples/ApiDemos"
     package="com.example.android.apis.tests" />
 
-<test name="applicationsprov"
-    build_path="packages/providers/ApplicationsProvider"
-    package="com.android.providers.applications.tests"
-    coverage_target="ApplicationsProvider"
-    continuous="true" />
-
 <test name="browser"
     build_path="packages/apps/Browser"
     package="com.android.browser.tests"
diff --git a/testrunner/test_defs/gtest.py b/testrunner/test_defs/gtest.py
index 094ceea..dc72f94 100644
--- a/testrunner/test_defs/gtest.py
+++ b/testrunner/test_defs/gtest.py
@@ -89,7 +89,8 @@
       logger.SilentLog('Creating gtest suite for file %s' % test_file)
       suite = GTestSuite()
       suite.SetBuildPath(self.GetBuildPath())
-      suite.SetTargetExecPath(os.path.join(target_root_path, test_file))
+      # expect tests in /data/nativetest/test_file/test_file
+      suite.SetTargetExecPath(os.path.join(target_root_path, test_file, test_file))
       test_suites.append(suite)
     return test_suites
 
diff --git a/testrunner/test_defs/native_test.py b/testrunner/test_defs/native_test.py
index dc26c73..caef877 100644
--- a/testrunner/test_defs/native_test.py
+++ b/testrunner/test_defs/native_test.py
@@ -154,7 +154,7 @@
 
     Args:
       binary: basename of the file to be run. It is expected to be under
-            out/host/<os>-<arch>/bin.
+            $ANDROID_HOST_OUT/bin.
       valgrind: If True the command will be run under valgrind.
 
     Returns:
diff --git a/tools/emulator/test-apps/ConnectivityTest/Android.mk b/tools/emulator/test-apps/ConnectivityTest/Android.mk
index 097d118..ca20d57 100644
--- a/tools/emulator/test-apps/ConnectivityTest/Android.mk
+++ b/tools/emulator/test-apps/ConnectivityTest/Android.mk
@@ -24,6 +24,8 @@
 
 LOCAL_SDK_VERSION := 4
 
+LOCAL_PROGUARD_ENABLED := disabled
+
 include $(BUILD_PACKAGE)
 
 # Use the following include to make our test apk.
diff --git a/tools/emulator/test-apps/GpsLocationTest/Android.mk b/tools/emulator/test-apps/GpsLocationTest/Android.mk
index 35c9443..5f90f3a 100644
--- a/tools/emulator/test-apps/GpsLocationTest/Android.mk
+++ b/tools/emulator/test-apps/GpsLocationTest/Android.mk
@@ -24,6 +24,8 @@
 
 LOCAL_SDK_VERSION := 4
 
+LOCAL_PROGUARD_ENABLED := disabled
+
 include $(BUILD_PACKAGE)
 
 # Use the following include to make our test apk.
diff --git a/tools/idegen/Android.mk b/tools/idegen/Android.mk
index d424ab6..8771160 100644
--- a/tools/idegen/Android.mk
+++ b/tools/idegen/Android.mk
@@ -2,8 +2,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := \
-        guavalib \
+LOCAL_STATIC_JAVA_LIBRARIES := guavalib
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
diff --git a/tools/idegen/index-gen.sh b/tools/idegen/index-gen.sh
index eadaa98..5b9e24b 100755
--- a/tools/idegen/index-gen.sh
+++ b/tools/idegen/index-gen.sh
@@ -14,12 +14,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Generates a module index file by searching through android source tree for make files.  The
-# intellij-gen.sh script automatically calls this script the first time or if you delete the
-# generated indexed file.  The only time you need to run this manually is if modules are added or
-# deleted.
+# Generates a module index file by searching through android source
+# tree for make files.  The intellij-gen.sh script automatically calls
+# this script the first time or if you delete the generated indexed
+# file.  The only time you need to run this manually is if modules are
+# added or deleted.
 #
-# To use:
+# To use, run the following command from either your repo root or
+# development/tools/idegen:
 #   index-gen.sh
 #
 # Only tested on linux.  Should work for macs but have not tried.
@@ -27,7 +29,15 @@
 set -e
 
 script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-root_dir=`readlink -f -n $script_dir/../../..`
+#root_dir=`readlink -f -n $script_dir/../../..`
+root_dir=$PWD
+if [ ! -e $root_dir/.repo ]; then
+  root_dir=$PWD/../../..
+  if [ ! -e $root_dir/.repo ]; then
+    echo "Repo root not found. Run this script from your repo root or the idegen directory."
+    exit 1
+  fi
+fi
 tmp_file=tmp.txt
 dest_file=module-index.txt
 
diff --git a/tools/idegen/intellij-gen.sh b/tools/idegen/intellij-gen.sh
index 7f00eba..d67c1f8 100755
--- a/tools/idegen/intellij-gen.sh
+++ b/tools/idegen/intellij-gen.sh
@@ -14,7 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# To use:
+# To use, run the following command from either your repo root or
+# development/tools/idegen:
 #   intellij-gen.sh <module name>
 #
 # where module name is the LOCAL_PACKAGE_NAME in Android.mk for the project.
@@ -22,27 +23,38 @@
 # For example, to generate a project for Contacts, use:
 #   intellij-gen.sh Contacts
 #
-# The project directory (.idea) will be put in the root directory of the module.  Sharable iml
-# files will be put into each respective module directory.
+# The project directory (.idea) will be put in the root directory of
+# the module.  Sharable iml files will be put into each respective
+# module directory.
 #
 # Only tested on linux.  Should work for macs but have not tried.
 #
 set -e
 
-script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-root_dir=`readlink -f -n $script_dir/../../..`
-index_file=$script_dir/module-index.txt
-idegenjar=$root_dir/out/host/common/obj/JAVA_LIBRARIES/idegen_intermediates/javalib.jar
-
 progname=`basename $0`
 if [ $# -ne 1 ]
 then
     echo "Usage: $progname <module_name>"
     exit 1
 fi
-
 module_name=$1
 
+script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+root_dir=$PWD
+if [ ! -e $root_dir/.repo ]; then
+  root_dir=$PWD/../../..
+  if [ ! -e $root_dir/.repo ]; then
+    echo "Repo root not found. Run this script from your repo root or the idegen directory."
+    exit 1
+  fi
+fi
+index_file=$root_dir/module-index.txt
+idegenjar=$script_dir/idegen.jar
+if [ ! -e $idegenjar ]; then
+  # See if the jar is in the build directory.
+  idegenjar=$root_dir/out/host/linux-x86/framework/idegen.jar
+fi
+
 if [ ! -e "$index_file" ]; then
   echo "Module index file missing; generating this is only done the first time."
   echo "If any dependencies change, you should generate a new index file by running index-gen.sh."
diff --git a/tools/idegen/src/com/android/idegen/Constants.java b/tools/idegen/src/com/android/idegen/Constants.java
deleted file mode 100644
index f541dd4..0000000
--- a/tools/idegen/src/com/android/idegen/Constants.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR 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.idegen;
-
-import java.nio.charset.Charset;
-
-/**
- * Constants
- */
-public class Constants {
-
-    public static final Charset CHARSET = Charset.forName("UTF-8");
-
-    public static final String REL_TEMPLATE_DIR = "development/tools/idegen/templates";
-    public static final String REL_MODULES_TEMPLATE = REL_TEMPLATE_DIR + "/idea/modules.xml";
-    public static final String REL_VCS_TEMPLATE = REL_TEMPLATE_DIR + "/idea/vcs.xml";
-    public static final String REL_IML_TEMPLATE = REL_TEMPLATE_DIR + "/module-template.iml";
-
-    public static final String REL_OUT_APP_DIR = "out/target/common/obj/APPS";
-
-    public static final String FRAMEWORK_MODULE = "framework";
-    public static final String[] AUTO_DEPENDENCIES = new String[]{
-            FRAMEWORK_MODULE, "libcore"
-    };
-    public static final String[] DIRS_WITH_AUTO_DEPENDENCIES = new String[] {
-      "packages", "vendor", "frameworks/ex", "frameworks/opt", "frameworks/support"
-    };
-
-    // Framework needs a special constant for it's intermediates because it does not follow
-    // normal conventions.
-    public static final String FRAMEWORK_INTERMEDIATES = "framework-res_intermediates";
-}
diff --git a/tools/idegen/src/com/android/idegen/DirectorySearch.java b/tools/idegen/src/com/android/idegen/DirectorySearch.java
index 1bbf99f..2ff23e3 100644
--- a/tools/idegen/src/com/android/idegen/DirectorySearch.java
+++ b/tools/idegen/src/com/android/idegen/DirectorySearch.java
@@ -21,8 +21,12 @@
 import com.google.common.collect.Sets;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FilenameFilter;
+import java.net.URISyntaxException;
 import java.util.HashSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -31,6 +35,8 @@
  */
 public class DirectorySearch {
 
+    private static final Logger logger = Logger.getLogger(DirectorySearch.class.getName());
+
     private static final HashSet<String> SOURCE_DIRS = Sets.newHashSet();
     static {
         SOURCE_DIRS.add("src");
@@ -40,6 +46,9 @@
     private static final Pattern EXCLUDE_PATTERN = Pattern.compile("values-..(-.*)*");
 
     private static File repoRoot = null;
+    public static final String REL_TEMPLATE_DIR = "templates";
+    public static final String REL_TEMPLATE_PATH_FROM_ROOT = "development/tools/idegen/"
+            + REL_TEMPLATE_DIR;
 
     /**
      * Find the repo root.  This is the root branch directory of a full repo checkout.
@@ -138,4 +147,38 @@
 
         return builder.build();
     }
+
+    private static File templateDirCurrent = null;
+    private static File templateDirRoot = null;
+
+    public static File findTemplateDir() throws FileNotFoundException {
+        // Cache optimization.
+        if (templateDirCurrent != null && templateDirCurrent.exists()) return templateDirCurrent;
+        if (templateDirRoot != null && templateDirRoot.exists()) return templateDirRoot;
+
+        File currentDir = null;
+        try {
+            currentDir = new File(IntellijProject.class.getProtectionDomain().getCodeSource()
+                    .getLocation().toURI().getPath()).getParentFile();
+        } catch (URISyntaxException e) {
+            logger.log(Level.SEVERE, "Could not get jar location.", e);
+            return null;
+        }
+
+        // First check relative to current run directory.
+        templateDirCurrent = new File(currentDir, REL_TEMPLATE_DIR);
+        if (templateDirCurrent.exists()) {
+            return templateDirCurrent;
+        } else {
+            // Then check relative to root directory.
+            templateDirRoot = new File(repoRoot, REL_TEMPLATE_PATH_FROM_ROOT);
+            if (templateDirRoot.exists()) {
+                return templateDirRoot;
+            }
+        }
+        throw new FileNotFoundException(
+                "Unable to find template dir. Tried the following locations:\n" +
+                templateDirCurrent.getAbsolutePath() + "\n" +
+                templateDirRoot.getAbsolutePath());
+    }
 }
diff --git a/tools/idegen/src/com/android/idegen/FrameworkModule.java b/tools/idegen/src/com/android/idegen/FrameworkModule.java
index bfcd1fa..8743925 100644
--- a/tools/idegen/src/com/android/idegen/FrameworkModule.java
+++ b/tools/idegen/src/com/android/idegen/FrameworkModule.java
@@ -25,15 +25,19 @@
  */
 public class FrameworkModule extends StandardModule {
 
+    // Framework needs a special constant for it's intermediates because it does not follow
+    // normal conventions.
+    private static final String FRAMEWORK_INTERMEDIATES = "framework-res_intermediates";
+
     public FrameworkModule(String moduleName, String makeFile) {
-        super(Constants.FRAMEWORK_MODULE, makeFile, true);
+        super(IntellijProject.FRAMEWORK_MODULE, makeFile, true);
     }
 
     @Override
     protected String buildIntermediates() {
         StringBuilder sb = new StringBuilder();
         File intermediates = new File(repoRoot,
-                Constants.REL_OUT_APP_DIR + File.separator +  Constants.FRAMEWORK_INTERMEDIATES);
+                REL_OUT_APP_DIR + File.separator +  FRAMEWORK_INTERMEDIATES);
         ImmutableList<File> intermediateSrcDirs = DirectorySearch.findSourceDirs(intermediates);
         sb.append("    <content url=\"file://").append(intermediates).append("\">\n");
         for (File src : intermediateSrcDirs) {
diff --git a/tools/idegen/src/com/android/idegen/IntellijProject.java b/tools/idegen/src/com/android/idegen/IntellijProject.java
index d5564d5..e49a12b 100644
--- a/tools/idegen/src/com/android/idegen/IntellijProject.java
+++ b/tools/idegen/src/com/android/idegen/IntellijProject.java
@@ -22,6 +22,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.util.Set;
 import java.util.logging.Logger;
@@ -31,9 +32,16 @@
  */
 public class IntellijProject {
 
+    public static final String FRAMEWORK_MODULE = "framework";
+    public static final Charset CHARSET = Charset.forName("UTF-8");
+
     private static final Logger logger = Logger.getLogger(IntellijProject.class.getName());
 
+    private static final String MODULES_TEMPLATE_FILE_NAME = "modules.xml";
+    private static final String VCS_TEMPLATE_FILE_NAME = "vcs.xml";
+
     ModuleCache cache = ModuleCache.getInstance();
+
     File indexFile;
     File repoRoot;
     File projectIdeaDir;
@@ -55,6 +63,11 @@
 
         // First pass, find all dependencies and cache them.
         Module module = cache.getAndCache(moduleName);
+        if (module == null) {
+            logger.info("Module '" + moduleName + "' not found." +
+                    " Module names are case senstive.");
+            return;
+        }
         projectIdeaDir = new File(module.getDir(), ".idea");
         projectIdeaDir.mkdir();
         copyTemplates();
@@ -104,19 +117,27 @@
 
     /**
      * Framework module needs special handling due to one off resource path:
-     *   frameworks/base/Android.mk
+     * frameworks/base/Android.mk
      */
     private void buildFrameWorkModule() throws IOException {
-        String makeFile = cache.getMakeFile(Constants.FRAMEWORK_MODULE);
-        logger.info("makefile: " + makeFile);
-        StandardModule frameworkModule = new FrameworkModule(Constants.FRAMEWORK_MODULE, makeFile);
-        frameworkModule.build();
-        cache.put(frameworkModule);
+        String makeFile = cache.getMakeFile(FRAMEWORK_MODULE);
+        if (makeFile == null) {
+            logger.warning("Unable to find framework module: " + FRAMEWORK_MODULE +
+                    ". Skipping.");
+        } else {
+            logger.info("makefile: " + makeFile);
+            StandardModule frameworkModule = new FrameworkModule(FRAMEWORK_MODULE,
+                    makeFile);
+            frameworkModule.build();
+            cache.put(frameworkModule);
+        }
     }
 
     private void createModulesFile(Module module) throws IOException {
-        String modulesContent = Files.toString(new File(repoRoot, Constants.REL_MODULES_TEMPLATE),
-                Constants.CHARSET);
+        String modulesContent = Files.toString(
+                new File(DirectorySearch.findTemplateDir(),
+                        "idea" + File.separator + MODULES_TEMPLATE_FILE_NAME),
+                CHARSET);
         StringBuilder sb = new StringBuilder();
         File moduleIml = module.getImlFile();
         sb.append("      <module fileurl=\"file://").append(moduleIml.getAbsolutePath())
@@ -131,12 +152,14 @@
 
         File out = new File(projectIdeaDir, "modules.xml");
         logger.info("Creating " + out.getAbsolutePath());
-        Files.write(modulesContent, out, Constants.CHARSET);
+        Files.write(modulesContent, out, CHARSET);
     }
 
     private void createVcsFile(Module module) throws IOException {
-        String vcsTemplate = Files.toString(new File(module.getRepoRoot(),
-                Constants.REL_VCS_TEMPLATE), Constants.CHARSET);
+        String vcsTemplate = Files.toString(
+                new File(DirectorySearch.findTemplateDir(),
+                        "idea" + File.separator + VCS_TEMPLATE_FILE_NAME),
+                CHARSET);
 
         StringBuilder sb = new StringBuilder();
         for (String name : module.getAllDependencies()) {
@@ -149,18 +172,17 @@
             }
         }
         vcsTemplate = vcsTemplate.replace("@VCS@", sb.toString());
-        Files.write(vcsTemplate, new File(projectIdeaDir, "vcs.xml"), Constants.CHARSET);
+        Files.write(vcsTemplate, new File(projectIdeaDir, "vcs.xml"), CHARSET);
     }
 
     private void createNameFile(String name) throws IOException {
-        File out =  new File(projectIdeaDir, ".name");
-        Files.write(name, out, Constants.CHARSET);
+        File out = new File(projectIdeaDir, ".name");
+        Files.write(name, out, CHARSET);
     }
 
     private void copyTemplates() throws IOException {
-        File templateDir = new File(repoRoot,
-                Constants.REL_TEMPLATE_DIR + File.separatorChar + "idea");
-        copyTemplates(templateDir, projectIdeaDir);
+        File templateDir = DirectorySearch.findTemplateDir();
+        copyTemplates(new File(templateDir, "idea"), projectIdeaDir);
     }
 
     private void copyTemplates(File fromDir, File toDir) throws IOException {
diff --git a/tools/idegen/src/com/android/idegen/Module.java b/tools/idegen/src/com/android/idegen/Module.java
index 7ba42a3..deb2281 100644
--- a/tools/idegen/src/com/android/idegen/Module.java
+++ b/tools/idegen/src/com/android/idegen/Module.java
@@ -34,6 +34,8 @@
 
     private static final Logger logger = Logger.getLogger(Module.class.getName());
 
+    private static final String IML_TEMPLATE_FILE_NAME = "module-template.iml";
+
     /**
      * All possible attributes for the make file.
      */
@@ -44,23 +46,35 @@
     }
 
     ModuleCache moduleCache = ModuleCache.getInstance();
+
     private File imlFile;
+
     private Set<String> allDependencies = Sets.newHashSet(); // direct + indirect
+
     private Set<File> allDependentImlFiles = Sets.newHashSet();
 
     protected abstract void build() throws IOException;
+
     protected abstract String getName();
+
     protected abstract File getDir();
+
     protected abstract boolean isAndroidModule();
+
     protected abstract List<File> getIntermediatesDirs();
+
     public abstract Set<String> getDirectDependencies();
+
     protected abstract ImmutableList<File> getSourceDirs();
+
     protected abstract ImmutableList<File> getExcludeDirs();
+
     public abstract File getRepoRoot();
 
     public void buildImlFile() throws IOException {
-        String imlTemplate = Files.toString(new File(getRepoRoot(), Constants.REL_IML_TEMPLATE),
-                Constants.CHARSET);
+        String imlTemplate = Files.toString(
+                new File(DirectorySearch.findTemplateDir(), IML_TEMPLATE_FILE_NAME),
+                IntellijProject.CHARSET);
 
         String facetXml = "";
         if (isAndroidModule()) {
@@ -100,7 +114,7 @@
 
         imlFile = new File(moduleDir, getName() + ".iml");
         logger.info("Creating " + imlFile.getAbsolutePath());
-        Files.write(imlTemplate, imlFile, Constants.CHARSET);
+        Files.write(imlTemplate, imlFile, IntellijProject.CHARSET);
     }
 
     protected String buildIntermediates() {
diff --git a/tools/idegen/src/com/android/idegen/StandardModule.java b/tools/idegen/src/com/android/idegen/StandardModule.java
index dffb95e..f7b24b0 100644
--- a/tools/idegen/src/com/android/idegen/StandardModule.java
+++ b/tools/idegen/src/com/android/idegen/StandardModule.java
@@ -17,6 +17,7 @@
 package com.android.idegen;
 
 import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
@@ -45,10 +46,18 @@
  */
 public class StandardModule extends Module {
 
+    static final String REL_OUT_APP_DIR = "out/target/common/obj/APPS";
+
     private static final Logger logger = Logger.getLogger(StandardModule.class.getName());
 
     private static final Pattern SRC_PATTERN = Pattern.compile(
             ".*\\(call all-java-files-under, (.*)\\)");
+    private static final String[] AUTO_DEPENDENCIES = new String[]{
+            IntellijProject.FRAMEWORK_MODULE, "libcore"
+    };
+    private static final String[] DIRS_WITH_AUTO_DEPENDENCIES = new String[]{
+            "packages", "vendor", "frameworks/ex", "frameworks/opt", "frameworks/support"
+    };
 
     String moduleName;
     File makeFile;
@@ -66,7 +75,8 @@
     }
 
     public StandardModule(String moduleName, String makeFile, boolean searchForSrc) {
-        this(moduleName, new File(makeFile), searchForSrc);
+        this(Preconditions.checkNotNull(moduleName), new File(Preconditions.checkNotNull(makeFile)),
+                searchForSrc);
     }
 
     public StandardModule(String moduleName, File makeFile, boolean searchForSrc) {
@@ -75,16 +85,16 @@
         this.moduleRoot = makeFile.getParentFile();
         this.repoRoot = DirectorySearch.findRepoRoot(makeFile);
         this.intermediatesDir = new File(repoRoot.getAbsolutePath() + File.separator +
-                Constants.REL_OUT_APP_DIR + File.separator + getName() + "_intermediates" +
+                REL_OUT_APP_DIR + File.separator + getName() + "_intermediates" +
                 File.separator + "src");
         this.searchForSrc = searchForSrc;
 
         // TODO: auto-detect when framework dependency is needed instead of using coded list.
-        for (String dir : Constants.DIRS_WITH_AUTO_DEPENDENCIES) {
+        for (String dir : DIRS_WITH_AUTO_DEPENDENCIES) {
             // length + 2 to account for slash
             boolean isDir = makeFile.getAbsolutePath().startsWith(repoRoot + "/" + dir);
             if (isDir) {
-                for (String dependency : Constants.AUTO_DEPENDENCIES) {
+                for (String dependency : AUTO_DEPENDENCIES) {
                     this.directDependencies.add(dependency);
                 }
             }
diff --git a/tutorials/ReverseDebug/Android.mk b/tutorials/ReverseDebug/Android.mk
new file mode 100644
index 0000000..586daf8
--- /dev/null
+++ b/tutorials/ReverseDebug/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ifneq ($(filter arm ,$(TARGET_ARCH)),)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= main.c.arm
+
+LOCAL_CFLAGS := -std=gnu99 -O0
+
+LOCAL_MODULE := reverse_debug
+
+include $(BUILD_EXECUTABLE)
+
+endif # arm in TARGET_ARCH
diff --git a/tutorials/ReverseDebug/README.txt b/tutorials/ReverseDebug/README.txt
new file mode 100644
index 0000000..2578a4d
--- /dev/null
+++ b/tutorials/ReverseDebug/README.txt
@@ -0,0 +1,137 @@
+This is a tutorial/unittest for gdb's reverse debugging feature. It is a new
+feature that allows users to take a snapshot of the machine state, continue
+until a later stage of the program, then return to the previously recorded
+state and execute again. An ideal usage case is to help track down the reason
+why a memory location is clobbered. 
+
+In the sample below, the "clobber" function trashes a neighboring variable "p"
+on the stack next to the "values" variable, and the program will crash at
+line 42 when "p" is being dereferenced.
+
+ 18 #include <stdio.h>
+ 19 #include <stdlib.h>
+ 20 
+ 21 #define ARRAY_LENGTH 10
+ 22 
+ 23 int flag;
+ 24 
+ 25 void clobber(int *array, int size) {
+ 26     /* Make sure it clobbers something. */
+ 27     array[-1] = 0x123;
+ 28     array[size] = 0x123;
+ 29 }
+ 30 
+ 31 int main(void) {
+ 32     int values[ARRAY_LENGTH];
+ 33     int *p = (int *) malloc(sizeof(int));
+ 34     *p = 10;
+ 35 
+ 36     while (!flag) {
+ 37         sleep(1);
+ 38     }
+ 39 
+ 40     /* Set a breakpint here: "b main.c:41" */
+ 41     clobber(values, ARRAY_LENGTH);
+ 42     printf("*p = %d\n", *p);
+ 43     free(p);
+ 44 
+ 45     return 0;
+ 46 }
+
+The test program can be built/installed on the device by doing:
+
+> mmm development/tutorials/ReverseDebug
+> adb sync
+> adb shell reverse_debug
+
+In another window the following command can be used to attach to the running
+program:
+
+> gdbclient reverse_debug :5039 reverse_debug
+[1] 12802
+Attached; pid = 1842
+Listening on port 5039
+GNU gdb (GDB) 7.6
+Copyright (C) 2013 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
+and "show warranty" for details.
+This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
+For bug reporting instructions, please see:
+<http://source.android.com/source/report-bugs.html>...
+Reading symbols from /usr/local/google/work/master/out/target/product/manta/symbols/system/bin/reverse_debug...done.
+Remote debugging from host 127.0.0.1
+nanosleep () at bionic/libc/arch-arm/syscalls/nanosleep.S:10
+10      mov     r7, ip
+
+====
+
+Now set a breakpoint on line 41 and set flag to 1 so that the program can
+ continue. 
+
+(gdb) b main.c:41
+Breakpoint 1 at 0xb6f174a8: file development/tutorials/ReverseDebug/main.c, line 41.
+(gdb) p flag=1
+$1 = 1
+(gdb) c
+Continuing.
+
+====
+
+Now try the new "record" command to take a snapshot of the machine state.
+
+Breakpoint 1, main () at development/tutorials/ReverseDebug/main.c:41
+41      clobber(values, ARRAY_LENGTH);
+(gdb) record
+(gdb) c
+Continuing.
+
+====
+
+Now the program crashes as expected as "p" has been clobbered. The
+"reverse-continue" command will bring the program back to line 41 and let you
+replay each instruction from there.
+
+Program received signal SIGSEGV, Segmentation fault.
+0xb6f174bc in main () at development/tutorials/ReverseDebug/main.c:42
+42      printf("*p = %d\n", *p);
+(gdb) reverse-continue
+Continuing.
+
+No more reverse-execution history.
+main () at development/tutorials/ReverseDebug/main.c:41
+41      clobber(values, ARRAY_LENGTH);
+
+
+====
+
+Now let's add a watch point at "&p" to hopefully catch the clobber on the spot:
+ 
+(gdb) watch *(&p)
+Hardware watchpoint 2: *(&p)
+(gdb) c
+Continuing.
+Hardware watchpoint 2: *(&p)
+
+====
+
+And here it is:
+
+Old value = (int *) 0xb728c020
+New value = (int *) 0x123
+0xb6f17440 in clobber (array=0xbebcaab0, size=10)
+    at development/tutorials/ReverseDebug/main.c:28
+28      array[size] = 0x123;
+
+
+===============================
+
+That said, reverse debugging on ARM is still in the infant stage. Currently
+(as of gdb 7.6) it only recognizes ARM instructions and will punt on all
+Thumb(2) instructions. To give it a try you will need to recompile your
+program in ARM mode. To do that you have to add the ".arm" suffix to the
+desired file in Android.mk:
+
+LOCAL_SRC_FILES:= main.c.arm
+
diff --git a/tutorials/ReverseDebug/main.c b/tutorials/ReverseDebug/main.c
new file mode 100644
index 0000000..5ae1890
--- /dev/null
+++ b/tutorials/ReverseDebug/main.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ARRAY_LENGTH 10
+
+int flag;
+
+void clobber(int *array, int size) {
+    /* Make sure it clobbers something. */
+    array[-1] = 0x123;
+    array[size] = 0x123;
+}
+
+int main(void) {
+    int values[ARRAY_LENGTH];
+    int *p = (int *) malloc(sizeof(int));
+    *p = 10;
+
+    while (!flag) {
+        sleep(1);
+    }
+
+    /* Set a breakpint here: "b main.c:41" */
+    clobber(values, ARRAY_LENGTH);
+    printf("*p = %d\n", *p);
+    free(p);
+
+    return 0;
+}