Merge "add tags to some docs. Training classes from top to bottom of "Connectivity and the Cloud"" into jb-mr1.1-docs
diff --git a/docs/downloads/training/BitmapFun.zip b/docs/downloads/training/BitmapFun.zip
index 61b537d..48bea78 100644
--- a/docs/downloads/training/BitmapFun.zip
+++ b/docs/downloads/training/BitmapFun.zip
Binary files differ
diff --git a/docs/downloads/training/InteractiveChart.zip b/docs/downloads/training/InteractiveChart.zip
new file mode 100644
index 0000000..95248ad
--- /dev/null
+++ b/docs/downloads/training/InteractiveChart.zip
Binary files differ
diff --git a/docs/html/google/play/licensing/adding-licensing.jd b/docs/html/google/play/licensing/adding-licensing.jd
index f991e14..3f2460f 100644
--- a/docs/html/google/play/licensing/adding-licensing.jd
+++ b/docs/html/google/play/licensing/adding-licensing.jd
@@ -598,15 +598,15 @@
 <p>First, open the class file of the application's main Activity and import
 {@code LicenseChecker} and {@code LicenseCheckerCallback} from the LVL package.</p>
 
-<pre>    import com.android.vending.licensing.LicenseChecker;
-    import com.android.vending.licensing.LicenseCheckerCallback;</pre>
+<pre>    import com.google.android.vending.licensing.LicenseChecker;
+    import com.google.android.vending.licensing.LicenseCheckerCallback;</pre>
 
 <p>If you are using the default {@code Policy} implementation provided with the LVL,
 ServerManagedPolicy, import it also, together with the AESObfuscator. If you are
 using a custom {@code Policy} or {@code Obfuscator}, import those instead. </p>
 
-<pre>    import com.android.vending.licensing.ServerManagedPolicy;
-    import com.android.vending.licensing.AESObfuscator;</pre>
+<pre>    import com.google.android.vending.licensing.ServerManagedPolicy;
+    import com.google.android.vending.licensing.AESObfuscator;</pre>
 
 <h3 id="lc-impl">Implement LicenseCheckerCallback as a private inner class</h3>
 
diff --git a/docs/html/guide/topics/manifest/intent-filter-element.jd b/docs/html/guide/topics/manifest/intent-filter-element.jd
index f90541c..68da981 100644
--- a/docs/html/guide/topics/manifest/intent-filter-element.jd
+++ b/docs/html/guide/topics/manifest/intent-filter-element.jd
@@ -119,7 +119,11 @@
 
 <p>
 The value must be an integer, such as "{@code 100}".  Higher numbers have a
-higher priority.
+higher priority. The default value is 0.
+The value must be greater than -1000 and less than 1000.</p>
+
+<p>Also see {@link android.content.IntentFilter#setPriority
+setPriority()}.
 </p></dd>
 
 </dl></dd>
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index f9e2785..3b3bb8f 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -26,14 +26,14 @@
 </div>
 </div>
 
-<div class="sidebox-wrapper"> 
+<div class="sidebox-wrapper">
 <div class="sidebox">
-    <img src="{@docRoot}assets/images/icon_play.png" style="float:left;margin:0;padding:0;"> 
-    <p style="color:#669999;padding-top:1em;">Google Play Filtering</p> 
+    <img src="{@docRoot}assets/images/icon_play.png" style="float:left;margin:0;padding:0;">
+    <p style="color:#669999;padding-top:1em;">Google Play Filtering</p>
     <p style="padding-top:1em;">Google Play uses the <code>&lt;uses-sdk&gt;</code>
-    attributes declared in your app manifest to filter your app from devices 
+    attributes declared in your app manifest to filter your app from devices
     that do not meet it's platform version requirements. Before setting these
-    attributes, make sure that you understand 
+    attributes, make sure that you understand
     <a href="{@docRoot}google/play/filters.html">Google Play filters</a>. </p>
   </div>
 </div>
@@ -41,7 +41,7 @@
 <dl class="xml">
 <dt>syntax:</dt>
 <dd><pre>
-&lt;uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>" 
+&lt;uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>"
           android:<a href="#target">targetSdkVersion</a>="<i>integer</i>"
           android:<a href="#max">maxSdkVersion</a>="<i>integer</i>" /&gt;</pre></dd>
 
@@ -55,14 +55,14 @@
 </p>
 
 <p>Despite its name, this element is used to specify the API Level, <em>not</em>
-the version number of the SDK (software development kit) or Android platform. 
+the version number of the SDK (software development kit) or Android platform.
 The API Level is always a single integer. You cannot derive the API Level from
 its associated Android version number (for example, it is not the same as the
 major version or the sum of the major and minor versions).</p>
 
 <p>Also read the document about
 <a href="{@docRoot}tools/publishing/versioning.html">Versioning Your Applications</a>.
-</p></dd> 
+</p></dd>
 
 <dt>attributes:</dt>
 
@@ -117,8 +117,8 @@
   </dd>
 
   <dt><a name="max"></a>{@code android:maxSdkVersion}</dt>
-  <dd>An integer designating the maximum API Level on which the application is 
-  designed to run. 
+  <dd>An integer designating the maximum API Level on which the application is
+  designed to run.
 
   <p>In Android 1.5, 1.6, 2.0, and 2.0.1, the system checks the value of this
   attribute when installing an application and when re-validating the application
@@ -165,7 +165,7 @@
 as a filter, however, when presenting users with applications available for
 download. </div>
   </dd>
-  
+
 
 </dl></dd>
 
@@ -217,7 +217,7 @@
 <p>The framework API that an Android platform delivers is specified using an
 integer identifier called "API Level". Each Android platform version supports
 exactly one API Level, although support is implicit for all earlier API Levels
-(down to API Level 1). The initial release of the Android platform provided 
+(down to API Level 1). The initial release of the Android platform provided
 API Level 1 and subsequent releases have incremented the API Level.</p>
 
 <p>The table below specifies the API Level supported by each version of the
@@ -227,8 +227,8 @@
 
 <table>
   <tr><th>Platform Version</th><th>API Level</th><th>VERSION_CODE</th><th>Notes</th></tr>
- 
-    <tr><td><a href="{@docRoot}about/versions/android-4.2.html">Android 4.2</a></td>
+
+    <tr><td><a href="{@docRoot}about/versions/android-4.2.html">Android 4.2, 4.2.2</a></td>
     <td><a href="{@docRoot}sdk/api_diff/17/changes.html" title="Diff Report">17</a></td>
     <td>{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}</td>
     <td><a href="{@docRoot}about/versions/jelly-bean.html">Platform
@@ -250,70 +250,70 @@
     <td><a href="{@docRoot}sdk/api_diff/14/changes.html" title="Diff Report">14</a></td>
     <td>{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}</td>
     </tr>
-  
+
     <tr><td><a href="{@docRoot}about/versions/android-3.2.html">Android 3.2</a></td>
     <td><a href="{@docRoot}sdk/api_diff/13/changes.html" title="Diff Report">13</a></td>
     <td>{@link android.os.Build.VERSION_CODES#HONEYCOMB_MR2}</td>
     <td><!-- <a href="{@docRoot}about/versions/android-3.2-highlights.html">Platform
 Highlights</a>--></td></tr>
-  
+
   <tr><td><a href="{@docRoot}about/versions/android-3.1.html">Android 3.1.x</a></td>
     <td><a href="{@docRoot}sdk/api_diff/12/changes.html" title="Diff Report">12</a></td>
     <td>{@link android.os.Build.VERSION_CODES#HONEYCOMB_MR1}</td>
     <td><a href="{@docRoot}about/versions/android-3.1-highlights.html">Platform Highlights</a></td></tr>
-    
+
   <tr><td><a href="{@docRoot}about/versions/android-3.0.html">Android 3.0.x</td>
     <td><a href="{@docRoot}sdk/api_diff/11/changes.html" title="Diff Report">11</a></td>
     <td>{@link android.os.Build.VERSION_CODES#HONEYCOMB}</td>
     <td><a href="{@docRoot}about/versions/android-3.0-highlights.html">Platform Highlights</a></td></tr>
-    
+
   <tr><td><a href="{@docRoot}about/versions/android-2.3.3.html">Android 2.3.4<br>Android 2.3.3</td>
     <td><a href="{@docRoot}sdk/api_diff/10/changes.html" title="Diff Report">10</a></td>
     <td>{@link android.os.Build.VERSION_CODES#GINGERBREAD_MR1}</td>
     <td rowspan="2"><a href="{@docRoot}about/versions/android-2.3-highlights.html">Platform
 Highlights</a></td></tr>
-  
+
   <tr><td><a href="{@docRoot}about/versions/android-2.3.html">Android 2.3.2<br>Android 2.3.1<br>Android
 2.3</td>
     <td><a href="{@docRoot}sdk/api_diff/9/changes.html" title="Diff Report">9</a></td>
     <td>{@link android.os.Build.VERSION_CODES#GINGERBREAD}</td>
     </tr>
-  
+
   <tr><td><a href="{@docRoot}about/versions/android-2.2.html">Android 2.2.x</td>
     <td ><a href="{@docRoot}sdk/api_diff/8/changes.html" title="Diff Report">8</a></td>
     <td>{@link android.os.Build.VERSION_CODES#FROYO}</td>
     <td><a href="{@docRoot}about/versions/android-2.2-highlights.html">Platform Highlights</a></td></tr>
-  
+
   <tr><td><a href="{@docRoot}about/versions/android-2.1.html">Android 2.1.x</td>
     <td><a href="{@docRoot}sdk/api_diff/7/changes.html" title="Diff Report">7</a></td>
     <td>{@link android.os.Build.VERSION_CODES#ECLAIR_MR1}</td>
     <td rowspan="3" ><a href="{@docRoot}about/versions/android-2.0-highlights.html">Platform
 Highlights</a></td></tr>
-    
+
   <tr><td><a href="{@docRoot}about/versions/android-2.0.1.html">Android 2.0.1</td>
     <td><a href="{@docRoot}sdk/api_diff/6/changes.html" title="Diff Report">6</a></td>
     <td>{@link android.os.Build.VERSION_CODES#ECLAIR_0_1}</td>
     </tr>
-    
+
   <tr><td><a href="{@docRoot}about/versions/android-2.0.html">Android 2.0</td>
     <td><a href="{@docRoot}sdk/api_diff/5/changes.html" title="Diff Report">5</a></td>
     <td>{@link android.os.Build.VERSION_CODES#ECLAIR}</td>
     </tr>
-    
+
   <tr><td><a href="{@docRoot}about/versions/android-1.6.html">Android 1.6</td>
     <td><a href="{@docRoot}sdk/api_diff/4/changes.html" title="Diff Report">4</a></td>
     <td>{@link android.os.Build.VERSION_CODES#DONUT}</td>
     <td><a href="{@docRoot}about/versions/android-1.6-highlights.html">Platform Highlights</a></td></tr>
-    
+
   <tr><td><a href="{@docRoot}about/versions/android-1.5.html">Android 1.5</td>
     <td><a href="{@docRoot}sdk/api_diff/3/changes.html" title="Diff Report">3</a></td>
     <td>{@link android.os.Build.VERSION_CODES#CUPCAKE}</td>
     <td><a href="{@docRoot}about/versions/android-1.5-highlights.html">Platform Highlights</a></td></tr>
-    
+
   <tr><td><a href="{@docRoot}about/versions/android-1.1.html">Android 1.1</td>
     <td>2</td>
     <td>{@link android.os.Build.VERSION_CODES#BASE_1_1}</td><td></td></tr>
-    
+
   <tr><td>Android 1.0</td>
     <td>1</td>
     <td>{@link android.os.Build.VERSION_CODES#BASE}</td>
@@ -324,10 +324,10 @@
 <h2 id="uses">Uses of API Level in Android</h2>
 
 <p>The API Level identifier serves a key role in ensuring the best possible
-experience for users and application developers: 
+experience for users and application developers:
 
 <ul>
-<li>It lets the Android platform describe the maximum framework API revision 
+<li>It lets the Android platform describe the maximum framework API revision
 that it supports</li>
 <li>It lets applications describe the framework API revision that they
 require</li>
@@ -349,7 +349,7 @@
 <li><code>android:targetSdkVersion</code> &mdash; Specifies the API Level
 on which the application is designed to run. In some cases, this allows the
 application to use manifest elements or behaviors defined in the target
-API Level, rather than being restricted to using only those defined 
+API Level, rather than being restricted to using only those defined
 for the minimum API Level.</li>
 <li><code>android:maxSdkVersion</code> &mdash; Specifies the maximum API Level
 on which the application is able to run. <strong>Important:</strong> Please read the <a
@@ -375,7 +375,7 @@
 must be less than or equal to the system's API Level integer. If not declared,
 the system assumes that the application requires API Level 1. </li>
 <li>If a <code>android:maxSdkVersion</code> attribute is declared, its value
-must be equal to or greater than the system's API Level integer. 
+must be equal to or greater than the system's API Level integer.
 If not declared, the system assumes that the application
 has no maximum API Level. Please read the <a
 href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code>&lt;uses-sdk&gt;</code></a>
@@ -470,7 +470,7 @@
 <p>When you are developing your application, you will need to choose
 the platform version against which you will compile the application. In
 general, you should compile your application against the lowest possible
-version of the platform that your application can support. 
+version of the platform that your application can support.
 
 <p>You can determine the lowest possible platform version by compiling the
 application against successively lower build targets. After you determine the
@@ -513,7 +513,7 @@
 located in the &lt;sdk&gt;/tools directory. You can launch the SDK updater by
 executing <code>android sdk</code>. You can
 also simply double-click the android.bat (Windows) or android (OS X/Linux) file.
-In ADT, you can also access the updater by selecting 
+In ADT, you can also access the updater by selecting
 <strong>Window</strong>&nbsp;>&nbsp;<strong>Android SDK
 Manager</strong>.</p>
 
@@ -552,9 +552,9 @@
 <h2 id="filtering">Filtering the Reference Documentation by API Level</h2>
 
 <p>Reference documentation pages on the Android Developers site offer a "Filter
-by API Level" control in the top-right area of each page. You can use the 
-control to show documentation only for parts of the API that are actually 
-accessible to your application, based on the API Level that it specifies in 
+by API Level" control in the top-right area of each page. You can use the
+control to show documentation only for parts of the API that are actually
+accessible to your application, based on the API Level that it specifies in
 the <code>android:minSdkVersion</code> attribute of its manifest file. </p>
 
 <p>To use filtering, select the checkbox to enable filtering, just below the
@@ -574,10 +574,10 @@
 </p>
 
 <p>Also note that the reference documentation for individual API elements
-specifies the API Level at which each element was introduced. The API Level 
-for packages and classes is specified as "Since &lt;api level&gt;" at the 
-top-right corner of the content area on each documentation page. The API Level 
-for class members is specified in their detailed description headers, 
+specifies the API Level at which each element was introduced. The API Level
+for packages and classes is specified as "Since &lt;api level&gt;" at the
+top-right corner of the content area on each documentation page. The API Level
+for class members is specified in their detailed description headers,
 at the right margin. </p>
 
 
diff --git a/docs/html/guide/topics/resources/animation-resource.jd b/docs/html/guide/topics/resources/animation-resource.jd
index 3af52aa..ef64f07 100644
--- a/docs/html/guide/topics/resources/animation-resource.jd
+++ b/docs/html/guide/topics/resources/animation-resource.jd
@@ -217,7 +217,7 @@
     </dd>
 
 <dt id="val-animator-element"><code>&lt;animator&gt;</code></dt>
-    <dd>Animates a over a specified amount of time.
+    <dd>Performs an animation over a specified amount of time.
     Represents a {@link android.animation.ValueAnimator}.
 
       <p class="caps">attributes:</p>
diff --git a/docs/html/index.jd b/docs/html/index.jd
index f2df7be..ec0469c 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -19,12 +19,11 @@
                     <div class="content-right col-5">
                     <h1>Google I/O 2013</h1>
                     <p>Android will be at Google I/O on May 15-17, 2013, with sessions covering a variety of topics
-                    such as design, performance, and how to extend your app with the latest Android features.
-                    Registration opens on March 13, 2013 at 7:00 AM PDT (GMT-7).</p>
+                    such as design, performance, and how to extend your app with the latest Android features.</p>
                     <p>For more information about event details and planned sessions,
                     stay tuned to <a
                     href="http://google.com/+GoogleDevelopers">+Google Developers</a>.</p>
-                    <p><a href="https://developers.google.com/events/io/register" class="button">Register here</a></p>
+                    <p><a href="https://developers.google.com/events/io/" class="button">Learn more</a></p>
                     </div>
                 </li>
                 <li class="item carousel-home">
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 6307c69..315c977 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -4,25 +4,25 @@
 page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
 
 
-sdk.linux32_bundle_download=adt-bundle-linux-x86.zip
-sdk.linux32_bundle_bytes=418614971
-sdk.linux32_bundle_checksum=24506708af221a887326c2a9ca9625dc
+sdk.linux32_bundle_download=adt-bundle-linux-x86-20130219.zip
+sdk.linux32_bundle_bytes=418664018
+sdk.linux32_bundle_checksum=e56ebb5c8eb84eb3227cf7c255373f4b
 
-sdk.linux64_bundle_download=adt-bundle-linux-x86_64.zip
-sdk.linux64_bundle_bytes=418889835
-sdk.linux64_bundle_checksum=464c1fbe92ea293d6b2292c27af5066a
+sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130219.zip
+sdk.linux64_bundle_bytes=418939098
+sdk.linux64_bundle_checksum=90cb420934170787938d0477c1a83a7f
 
-sdk.mac64_bundle_download=adt-bundle-mac-x86_64.zip
-sdk.mac64_bundle_bytes=390649300
-sdk.mac64_bundle_checksum=f557bc61a4bff466633037839771bffb
+sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130219.zip
+sdk.mac64_bundle_bytes=390697025
+sdk.mac64_bundle_checksum=b768c28f380c1846479664c4790e9c53
 
-sdk.win32_bundle_download=adt-bundle-windows-x86.zip
-sdk.win32_bundle_bytes=425429957
-sdk.win32_bundle_checksum=cca97f12904774385a57d542e70a490f
+sdk.win32_bundle_download=adt-bundle-windows-x86-20130219.zip
+sdk.win32_bundle_bytes=425487608
+sdk.win32_bundle_checksum=4a40039f28048e6d7b2440adf55b8321
 
-sdk.win64_bundle_download=adt-bundle-windows-x86_64.zip
-sdk.win64_bundle_bytes=425553759
-sdk.win64_bundle_checksum=c51679f4517e1c3ddefa1e662bbf17f6
+sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130219.zip
+sdk.win64_bundle_bytes=425611626
+sdk.win64_bundle_checksum=891f79816b4d19042faab26d670f4f77
 
 
 
diff --git a/docs/html/tools/extras/support-library.jd b/docs/html/tools/extras/support-library.jd
index 08ac172..6475e3c 100644
--- a/docs/html/tools/extras/support-library.jd
+++ b/docs/html/tools/extras/support-library.jd
@@ -46,10 +46,33 @@
 <p>The sections below provide notes about successive releases of
 the Support Package, as denoted by revision number.</p>
 
-
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" alt=""
+/>Support Package, revision 12</a> <em>(February 2013)</em>
+  </p>
+  <div class="toggle-content-toggleme">
+    <dl>
+      <dt>Changes for v4 support library:</dt>
+      <dd>
+        <ul>
+          <li>Improved interaction behavior for {@link android.support.v4.view.ViewPager}.</li>
+          <li>Fixed a bug that could cause {@link android.support.v4.view.ViewPager} to select the
+            wrong page.</li>
+          <li>Fixed use of {@link android.support.v4.view.ViewPager#removeView removeView()} method
+            during layout for {@link android.support.v4.view.ViewPager}.</li>
+          <li>Fixed issue with {@link android.support.v4.widget.SearchViewCompat} where using the
+            back button to dismiss does not clear the search text. This fix only applies to
+            host API levels 14 and higher.</li>
+        </ul>
+      </dd>
+    </dl>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt=""
 />Support Package, revision 11</a> <em>(November 2012)</em>
   </p>
   <div class="toggle-content-toggleme">
@@ -119,7 +142,7 @@
       <dt>Changes for v4 support library:</dt>
       <dd>
         <ul>
-          <li>Added support for notification features introduced in Android 4.1 (API Level 16) with
+          <li>Added support for notification features introduced in Android 4.1 (API level 16) with
           additions to {@link android.support.v4.app.NotificationCompat}.</li>
         </ul>
       </dd>
@@ -210,7 +233,7 @@
           <li>Fixed intent flags for {@link android.app.PendingIntent} objects generated
             by {@link android.support.v4.app.TaskStackBuilder}.</li>
           <li>Removed unused attributes from the gridlayout library projects to make sure
-            the library can be built with API Level 7 and higher.</li>
+            the library can be built with API level 7 and higher.</li>
           <li>Added {@code .classpath} and {@code .project} files for the gridlayout
             library project.</li>
         </ul>
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index c1bc185..31cec0e 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -44,11 +44,28 @@
 SDK tools to revision 20 or later and restart the Android SDK Manager. If you do not,
 the Android 4.2 system components will not be available for download.</p>
 
-
 <div class="toggle-content opened">
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png"
+class="toggle-content-img" alt="" />Revision 2</a> <em>(February 2013)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <p>Maintenance update. The system version is 4.2.2.</p>
+    <dl>
+      <dt>Dependencies:</dt>
+      <dd>SDK Tools r21 or higher is required.</dd>
+    </dl>
+
+  </div>
+</div>
+
+<div class="toggle-content closed">
+
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png"
 class="toggle-content-img" alt="" />Revision 1</a> <em>(November 2012)</em>
   </p>
 
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index 4adb7b2..a3f53bbe 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -69,7 +69,7 @@
       <li>Java 1.6 or higher is required for ADT 21.1.0.</li>
       <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 21.1.0.</li>
       <li>ADT 21.1.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
-      Tools r21.1.0</a>. If you haven't already installed SDK Tools r21.1.0 into your SDK, use the
+      Tools r21.1</a>. If you haven't already installed SDK Tools r21.1 into your SDK, use the
       Android SDK Manager to do so.</li>
     </ul>
   </dd>
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index a5b7eee..7d121844 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -28,7 +28,7 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
-      alt=""/>SDK Tools, Revision 21.1.0</a> <em>(February 2013)</em>
+      alt=""/>SDK Tools, Revision 21.1</a> <em>(February 2013)</em>
   </p>
 
   <div class="toggle-content-toggleme">
@@ -38,7 +38,7 @@
     <dd>
       <ul>
         <li>Android SDK Platform-tools revision 16 or later.</li>
-        <li>If you are developing in Eclipse with ADT, note that the SDK Tools r21.1.0 is
+        <li>If you are developing in Eclipse with ADT, note that the SDK Tools r21.1 is
           designed for use with ADT 21.1.0 and later. If you haven't already, update your
         <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 21.1.0.</li>
         <li>If you are developing outside Eclipse, you must have
diff --git a/docs/html/training/displaying-bitmaps/cache-bitmap.jd b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
index 417ec5b..b1608c3 100644
--- a/docs/html/training/displaying-bitmaps/cache-bitmap.jd
+++ b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
@@ -3,10 +3,6 @@
 parent.link=index.html
 
 trainingnavtop=true
-next.title=Displaying Bitmaps in Your UI
-next.link=display-bitmap.html
-previous.title=Processing Bitmaps Off the UI Thread
-previous.link=process-bitmap.html
 
 @jd:body
 
diff --git a/docs/html/training/displaying-bitmaps/display-bitmap.jd b/docs/html/training/displaying-bitmaps/display-bitmap.jd
index 4572c42..ed1836c 100644
--- a/docs/html/training/displaying-bitmaps/display-bitmap.jd
+++ b/docs/html/training/displaying-bitmaps/display-bitmap.jd
@@ -3,8 +3,6 @@
 parent.link=index.html
 
 trainingnavtop=true
-previous.title=Caching Bitmaps
-previous.link=cache-bitmap.html
 
 @jd:body
 
diff --git a/docs/html/training/displaying-bitmaps/index.jd b/docs/html/training/displaying-bitmaps/index.jd
index 378d977..857edee 100644
--- a/docs/html/training/displaying-bitmaps/index.jd
+++ b/docs/html/training/displaying-bitmaps/index.jd
@@ -25,7 +25,7 @@
 </div>
 </div>
 
-<p>This class covers some common techniques for processing and loading {@link
+<p>Learn how to use common techniques to process and load {@link
 android.graphics.Bitmap} objects in a way that keeps your user interface (UI) components responsive
 and avoids exceeding your application memory limit. If you're not careful, bitmaps can quickly
 consume your available memory budget leading to an application crash due to the dreaded
@@ -69,6 +69,9 @@
     <dd>This lesson walks you through using a memory and disk bitmap cache to improve the
     responsiveness and fluidity of your UI when loading multiple bitmaps.</dd>
 
+  <dt><b><a href="manage-memory.html">Managing Bitmap Memory</a></b></dt>
+    <dd>This lesson explains how to manage bitmap memory to maximize your app's performance.</dd>
+
   <dt><b><a href="display-bitmap.html">Displaying Bitmaps in Your UI</a></b></dt>
     <dd>This lesson brings everything together, showing you how to load multiple bitmaps into
     components like {@link android.support.v4.view.ViewPager} and {@link android.widget.GridView}
diff --git a/docs/html/training/displaying-bitmaps/load-bitmap.jd b/docs/html/training/displaying-bitmaps/load-bitmap.jd
index 283f272..633ffd2 100644
--- a/docs/html/training/displaying-bitmaps/load-bitmap.jd
+++ b/docs/html/training/displaying-bitmaps/load-bitmap.jd
@@ -3,8 +3,6 @@
 parent.link=index.html
 
 trainingnavtop=true
-next.title=Processing Bitmaps Off the UI Thread
-next.link=process-bitmap.html
 
 @jd:body
 
@@ -167,4 +165,4 @@
 <p>You can follow a similar process to decode bitmaps from other sources, by substituting the
 appropriate {@link
 android.graphics.BitmapFactory#decodeByteArray(byte[],int,int,android.graphics.BitmapFactory.Options)
-BitmapFactory.decode*} method as needed.</p>
\ No newline at end of file
+BitmapFactory.decode*} method as needed.</p>
diff --git a/docs/html/training/displaying-bitmaps/manage-memory.jd b/docs/html/training/displaying-bitmaps/manage-memory.jd
new file mode 100644
index 0000000..60ac2e6
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/manage-memory.jd
@@ -0,0 +1,297 @@
+page.title=Managing Bitmap Memory
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#recycle">Manage Memory on Android 2.3.3 and Lower</a></li>
+  <li><a href="#inBitmap">Manage Memory on Android 3.0 and Higher</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html">Memory Analysis for Android Applications</a> blog post</li>
+  <li><a href="http://www.google.com/events/io/2011/sessions/memory-management-for-android-apps.html">Memory management for Android Apps</a> Google I/O presentation</li>
+  <li><a href="{@docRoot}design/patterns/swipe-views.html">Android Design: Swipe Views</a></li>
+  <li><a href="{@docRoot}design/building-blocks/grid-lists.html">Android Design: Grid Lists</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+  <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>In addition to the steps described in <a href="cache-bitmap.html">Caching Bitmaps</a>,
+there are  specific things you can do to facilitate garbage collection
+and bitmap reuse. The recommended strategy depends on which version(s)
+of Android you are targeting. The {@code BitmapFun} sample app included with
+this class shows you how to design your app to work efficiently across
+different versions of Android.</p>
+
+<p>To set the stage for this lesson, here is how Android's management of
+bitmap memory has evolved:</p>
+<ul> 
+  <li>
+On Android Android 2.2 (API level 8) and lower, when garbage 
+collection occurs, your app's threads get stopped. This causes a lag that
+can degrade performance. 
+<strong>Android 2.3 adds concurrent garbage collection, which means that
+the memory is reclaimed soon after a bitmap is no longer referenced.</strong>
+</li>
+
+  <li>On Android 2.3.3 (API level 10) and lower, the backing pixel data for a
+bitmap is stored in native memory. It is separate from the bitmap itself,
+which is stored in the Dalvik heap. The pixel data in native memory is
+not released in a predictable manner, potentially causing an application
+to briefly exceed its memory limits and crash.
+<strong>As of Android 3.0 (API Level 11), the pixel data is stored on the
+Dalvik heap along with the associated bitmap.</strong></li>
+
+</ul>
+
+<p>The following sections describe how to optimize bitmap memory
+management for different Android versions.</p>
+
+<h2 id="recycle">Manage Memory on Android 2.3.3 and Lower</h2>
+
+<p>On Android 2.3.3 (API level 10) and lower, using 
+{@link android.graphics.Bitmap#recycle recycle()}
+is recommended. If you're displaying large amounts of bitmap data in your app,
+you're likely to run into
+{@link java.lang.OutOfMemoryError} errors. The
+{@link android.graphics.Bitmap#recycle recycle()} method allows an app
+to reclaim memory as soon as possible.</p>
+
+<p class="note"><strong>Caution:</strong> You should use
+{@link android.graphics.Bitmap#recycle recycle()} only when you are sure that the
+bitmap is no longer being used. If you call {@link android.graphics.Bitmap#recycle recycle()}
+and later attempt to draw the bitmap, you will get the error:
+{@code &quot;Canvas: trying to use a recycled bitmap&quot;}.</p>
+
+<p>The following code snippet gives an example of calling
+{@link android.graphics.Bitmap#recycle recycle()}. It uses reference counting
+(in the variables {@code mDisplayRefCount} and {@code mCacheRefCount}) to track 
+whether a bitmap is currently being displayed or in the cache. The
+code recycles the bitmap when these conditions are met:</p>
+
+<ul>
+<li>The reference count for both {@code mDisplayRefCount} and 
+{@code mCacheRefCount} is 0.</li>
+<li>The bitmap is not {@code null}, and it hasn't been recycled yet.</li>
+</ul>
+
+<pre>private int mCacheRefCount = 0;
+private int mDisplayRefCount = 0;
+...
+// Notify the drawable that the displayed state has changed.
+// Keep a count to determine when the drawable is no longer displayed.
+public void setIsDisplayed(boolean isDisplayed) {
+    synchronized (this) {
+        if (isDisplayed) {
+            mDisplayRefCount++;
+            mHasBeenDisplayed = true;
+        } else {
+            mDisplayRefCount--;
+        }
+    }
+    // Check to see if recycle() can be called.
+    checkState();
+}
+
+// Notify the drawable that the cache state has changed.
+// Keep a count to determine when the drawable is no longer being cached.
+public void setIsCached(boolean isCached) {
+    synchronized (this) {
+        if (isCached) {
+            mCacheRefCount++;
+        } else {
+            mCacheRefCount--;
+        }
+    }
+    // Check to see if recycle() can be called.
+    checkState();
+}
+
+private synchronized void checkState() {
+    // If the drawable cache and display ref counts = 0, and this drawable
+    // has been displayed, then recycle.
+    if (mCacheRefCount <= 0 && mDisplayRefCount <= 0 && mHasBeenDisplayed
+            && hasValidBitmap()) {
+        getBitmap().recycle();
+    }
+}
+
+private synchronized boolean hasValidBitmap() {
+    Bitmap bitmap = getBitmap();
+    return bitmap != null && !bitmap.isRecycled();
+}</pre>
+
+<h2 id="inBitmap">Manage Memory on Android 3.0 and Higher</h2>
+
+<p>Android 3.0 (API Level 11) introduces the
+{@link android.graphics.BitmapFactory.Options#inBitmap BitmapFactory.Options.inBitmap}
+field. If this option is set, decode methods that take the 
+{@link android.graphics.BitmapFactory.Options Options} object
+will attempt to reuse an existing bitmap when loading content. This means
+that the bitmap's memory is reused, resulting in improved performance, and
+removing both memory allocation and de-allocation. There are some caveats in using
+{@link android.graphics.BitmapFactory.Options#inBitmap}:</p>
+<ul>
+  <li>The reused bitmap must be of the same size as the source content (to make
+sure that the same amount of memory is used), and in JPEG or PNG format
+(whether as a resource or as a stream).</li>
+
+
+<li>The {@link android.graphics.Bitmap.Config configuration} of the reused bitmap
+overrides the setting of
+{@link android.graphics.BitmapFactory.Options#inPreferredConfig}, if set. </li>
+
+  <li>You should always use the returned bitmap of the decode method,
+because you can't assume that reusing the bitmap worked (for example, if there is
+a size mismatch).</li>
+
+<h3>Save a bitmap for later use</h3>
+
+<p>The following snippet demonstrates how an existing bitmap is stored for possible
+later use in the sample app. When an app is running on Android 3.0 or higher and 
+a bitmap is evicted from the {@link android.util.LruCache},
+a soft reference to the bitmap is placed
+in a {@link java.util.HashSet}, for possible reuse later with
+{@link android.graphics.BitmapFactory.Options#inBitmap}:
+
+<pre>HashSet&lt;SoftReference&lt;Bitmap&gt;&gt; mReusableBitmaps;
+private LruCache&lt;String, BitmapDrawable&gt; mMemoryCache;
+
+// If you're running on Honeycomb or newer, create
+// a HashSet of references to reusable bitmaps.
+if (Utils.hasHoneycomb()) {
+    mReusableBitmaps = new HashSet&lt;SoftReference&lt;Bitmap&gt;&gt;();
+}
+
+mMemoryCache = new LruCache&lt;String, BitmapDrawable&gt;(mCacheParams.memCacheSize) {
+
+    // Notify the removed entry that is no longer being cached.
+    &#64;Override
+    protected void entryRemoved(boolean evicted, String key,
+            BitmapDrawable oldValue, BitmapDrawable newValue) {
+        if (RecyclingBitmapDrawable.class.isInstance(oldValue)) {
+            // The removed entry is a recycling drawable, so notify it
+            // that it has been removed from the memory cache.
+            ((RecyclingBitmapDrawable) oldValue).setIsCached(false);
+        } else {
+            // The removed entry is a standard BitmapDrawable.
+            if (Utils.hasHoneycomb()) {
+                // We're running on Honeycomb or later, so add the bitmap
+                // to a SoftReference set for possible use with inBitmap later.
+                mReusableBitmaps.add
+                        (new SoftReference&lt;Bitmap&gt;(oldValue.getBitmap()));
+            }
+        }
+    }
+....
+}</pre>
+
+
+<h3>Use an existing bitmap</h3>
+<p>In the running app, decoder methods check to see if there is an existing
+bitmap they can use. For example:</p>
+
+<pre>public static Bitmap decodeSampledBitmapFromFile(String filename,
+        int reqWidth, int reqHeight, ImageCache cache) {
+
+    final BitmapFactory.Options options = new BitmapFactory.Options();
+    ...
+    BitmapFactory.decodeFile(filename, options);
+    ...
+
+    // If we're running on Honeycomb or newer, try to use inBitmap.
+    if (Utils.hasHoneycomb()) {
+        addInBitmapOptions(options, cache);
+    }
+    ...
+    return BitmapFactory.decodeFile(filename, options);
+}</pre
+
+<p>The next snippet shows the {@code addInBitmapOptions()} method that is called in the
+above snippet. It looks for an existing bitmap to set as the value for
+{@link android.graphics.BitmapFactory.Options#inBitmap}. Note that this
+method only sets a value for {@link android.graphics.BitmapFactory.Options#inBitmap}
+if it finds a suitable match (your code should never assume that a match will be found):</p>
+
+<pre>private static void addInBitmapOptions(BitmapFactory.Options options,
+        ImageCache cache) {
+    // inBitmap only works with mutable bitmaps, so force the decoder to
+    // return mutable bitmaps.
+    options.inMutable = true;
+
+    if (cache != null) {
+        // Try to find a bitmap to use for inBitmap.
+        Bitmap inBitmap = cache.getBitmapFromReusableSet(options);
+
+        if (inBitmap != null) {
+            // If a suitable bitmap has been found, set it as the value of
+            // inBitmap.
+            options.inBitmap = inBitmap;
+        }
+    }
+}
+
+// This method iterates through the reusable bitmaps, looking for one 
+// to use for inBitmap:
+protected Bitmap getBitmapFromReusableSet(BitmapFactory.Options options) {
+        Bitmap bitmap = null;
+
+    if (mReusableBitmaps != null && !mReusableBitmaps.isEmpty()) {
+        final Iterator&lt;SoftReference&lt;Bitmap&gt;&gt; iterator
+                = mReusableBitmaps.iterator();
+        Bitmap item;
+
+        while (iterator.hasNext()) {
+            item = iterator.next().get();
+
+            if (null != item && item.isMutable()) {
+                // Check to see it the item can be used for inBitmap.
+                if (canUseForInBitmap(item, options)) {
+                    bitmap = item;
+
+                    // Remove from reusable set so it can't be used again.
+                    iterator.remove();
+                    break;
+                }
+            } else {
+                // Remove from the set if the reference has been cleared.
+                iterator.remove();
+            }
+        }
+    }
+    return bitmap;
+}</pre>
+
+<p>Finally, this method determines whether a candidate bitmap
+satisfies the size criteria to be used for
+{@link android.graphics.BitmapFactory.Options#inBitmap}:</p>
+
+<pre>private static boolean canUseForInBitmap(
+        Bitmap candidate, BitmapFactory.Options targetOptions) {
+    int width = targetOptions.outWidth / targetOptions.inSampleSize;
+    int height = targetOptions.outHeight / targetOptions.inSampleSize;
+
+    // Returns true if "candidate" can be used for inBitmap re-use with
+    // "targetOptions".
+    return candidate.getWidth() == width && candidate.getHeight() == height;
+}</pre>
+
+</body>
+</html>
diff --git a/docs/html/training/displaying-bitmaps/process-bitmap.jd b/docs/html/training/displaying-bitmaps/process-bitmap.jd
index d4fcff3..272b8bc 100644
--- a/docs/html/training/displaying-bitmaps/process-bitmap.jd
+++ b/docs/html/training/displaying-bitmaps/process-bitmap.jd
@@ -3,10 +3,6 @@
 parent.link=index.html
 
 trainingnavtop=true
-next.title=Caching Bitmaps
-next.link=cache-bitmap.html
-previous.title=Loading Large Bitmaps Efficiently
-previous.link=load-bitmap.html
 
 @jd:body
 
diff --git a/docs/html/training/gestures/detector.jd b/docs/html/training/gestures/detector.jd
index 06d0e98..65ddb1b 100644
--- a/docs/html/training/gestures/detector.jd
+++ b/docs/html/training/gestures/detector.jd
@@ -25,12 +25,18 @@
    <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
     </li>
     <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
-    <li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
     <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
     <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
     <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/InteractiveChart.zip"
+class="button">Download the sample</a>
+ <p class="filename">InteractiveChart.zip</p>
+</div>
 
 </div>
 </div>
diff --git a/docs/html/training/gestures/index.jd b/docs/html/training/gestures/index.jd
index 0191450..16ca7b0 100644
--- a/docs/html/training/gestures/index.jd
+++ b/docs/html/training/gestures/index.jd
@@ -20,12 +20,18 @@
     <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
     </li>
     <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
-    <li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
     <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
     <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
     <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/InteractiveChart.zip"
+class="button">Download the sample</a>
+ <p class="filename">InteractiveChart.zip</p>
+</div>
 
 </div>
 </div>
diff --git a/docs/html/training/gestures/movement.jd b/docs/html/training/gestures/movement.jd
index f2c49d7..fdc1ea4 100644
--- a/docs/html/training/gestures/movement.jd
+++ b/docs/html/training/gestures/movement.jd
@@ -24,12 +24,18 @@
     <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
     </li>
     <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
-    <li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
     <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
     <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
     <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/InteractiveChart.zip"
+class="button">Download the sample</a>
+ <p class="filename">InteractiveChart.zip</p>
+</div>
 
 </div>
 </div>
diff --git a/docs/html/training/gestures/multi.jd b/docs/html/training/gestures/multi.jd
index d4c5b1d..6a0df11 100644
--- a/docs/html/training/gestures/multi.jd
+++ b/docs/html/training/gestures/multi.jd
@@ -25,12 +25,18 @@
    <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
     </li>
     <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
-    <li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
     <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
     <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
     <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/InteractiveChart.zip"
+class="button">Download the sample</a>
+ <p class="filename">InteractiveChart.zip</p>
+</div>
 
 </div>
 </div>
diff --git a/docs/html/training/gestures/scale.jd b/docs/html/training/gestures/scale.jd
index 17e4085..f2e4eb8 100644
--- a/docs/html/training/gestures/scale.jd
+++ b/docs/html/training/gestures/scale.jd
@@ -15,6 +15,7 @@
 <h2>This lesson teaches you to</h2>
 <ol>
   <li><a href="#drag">Drag an Object</a></li>
+  <li><a href="#pan">Drag to Pan</a></li>
   <li><a href="#scale">Use Touch to Perform Scaling</a></li>
 </ol>
 
@@ -25,20 +26,25 @@
     <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
     </li>
     <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
-    <li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
     <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
     <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
     <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/InteractiveChart.zip"
+class="button">Download the sample</a>
+ <p class="filename">InteractiveChart.zip</p>
+</div>
 
 </div>
 </div>
+
 <p>This lesson describes how to use touch gestures to drag and scale on-screen
 objects, using {@link android.view.View#onTouchEvent onTouchEvent()} to intercept
-touch events. Here is the original <a
-href="http://code.google.com/p/android-touchexample/">source code</a>
-for the examples used in this lesson.
+touch events. 
 </p>
 
 <h2 id="drag">Drag an Object</h2>
@@ -128,17 +134,15 @@
         final float x = MotionEventCompat.getX(ev, pointerIndex);
         final float y = MotionEventCompat.getY(ev, pointerIndex);
             
-        // Only move if the ScaleGestureDetector isn't processing a gesture.
-        if (!mScaleDetector.isInProgress()) {
-            // Calculate the distance moved
-            final float dx = x - mLastTouchX;
-            final float dy = y - mLastTouchY;
+        // Calculate the distance moved
+        final float dx = x - mLastTouchX;
+        final float dy = y - mLastTouchY;
 
-            mPosX += dx;
-            mPosY += dy;
+        mPosX += dx;
+        mPosY += dy;
 
-            invalidate();
-        }
+        invalidate();
+
         // Remember this touch position for the next move event
         mLastTouchX = x;
         mLastTouchY = y;
@@ -175,6 +179,88 @@
     return true;
 }</pre>
 
+<h2 id="pan">Drag to Pan</h2>
+
+<p>The previous section showed an example of dragging an object around the screen. Another 
+common scenario is <em>panning</em>, which is when a user's dragging motion causes scrolling 
+in both the x and y axes. The above snippet directly intercepted the {@link android.view.MotionEvent} 
+actions to implement dragging. The snippet in this section takes advantage of the platform's 
+built-in support for common gestures. It overrides 
+{@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()} in 
+{@link android.view.GestureDetector.SimpleOnGestureListener}.</p>
+
+<p>To provide a little more context, {@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()} 
+is called when a user is dragging his finger to pan the content. 
+{@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()} is only called when 
+a finger is down; as soon as the finger is lifted from the screen, the gesture either ends, 
+or a fling gesture is started (if the finger was moving with some speed just before it was lifted). 
+For more discussion of scrolling vs. flinging, see <a href="scroll.html">Animating a Scroll Gesture</a>.</p>
+
+<p>Here is the snippet for {@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()}:
+
+
+<pre>// The current viewport. This rectangle represents the currently visible 
+// chart domain and range. 
+private RectF mCurrentViewport = 
+        new RectF(AXIS_X_MIN, AXIS_Y_MIN, AXIS_X_MAX, AXIS_Y_MAX);
+
+// The current destination rectangle (in pixel coordinates) into which the 
+// chart data should be drawn.
+private Rect mContentRect;
+
+private final GestureDetector.SimpleOnGestureListener mGestureListener
+            = new GestureDetector.SimpleOnGestureListener() {
+...
+
+&#64;Override
+public boolean onScroll(MotionEvent e1, MotionEvent e2, 
+            float distanceX, float distanceY) {
+    // Scrolling uses math based on the viewport (as opposed to math using pixels).
+    
+    // Pixel offset is the offset in screen pixels, while viewport offset is the
+    // offset within the current viewport. 
+    float viewportOffsetX = distanceX * mCurrentViewport.width() 
+            / mContentRect.width();
+    float viewportOffsetY = -distanceY * mCurrentViewport.height() 
+            / mContentRect.height();
+    ...
+    // Updates the viewport, refreshes the display. 
+    setViewportBottomLeft(
+            mCurrentViewport.left + viewportOffsetX,
+            mCurrentViewport.bottom + viewportOffsetY);
+    ...
+    return true;
+}</pre>
+
+<p>The implementation of {@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()} 
+scrolls the viewport in response to the touch gesture:</p>
+
+<pre>
+/**
+ * Sets the current viewport (defined by mCurrentViewport) to the given
+ * X and Y positions. Note that the Y value represents the topmost pixel position, 
+ * and thus the bottom of the mCurrentViewport rectangle.
+ */
+private void setViewportBottomLeft(float x, float y) {
+    /*
+     * Constrains within the scroll range. The scroll range is simply the viewport 
+     * extremes (AXIS_X_MAX, etc.) minus the viewport size. For example, if the 
+     * extremes were 0 and 10, and the viewport size was 2, the scroll range would 
+     * be 0 to 8.
+     */
+
+    float curWidth = mCurrentViewport.width();
+    float curHeight = mCurrentViewport.height();
+    x = Math.max(AXIS_X_MIN, Math.min(x, AXIS_X_MAX - curWidth));
+    y = Math.max(AXIS_Y_MIN + curHeight, Math.min(y, AXIS_Y_MAX));
+
+    mCurrentViewport.set(x, y - curHeight, x + curWidth, y);
+
+    // Invalidates the View to update the display.
+    ViewCompat.postInvalidateOnAnimation(this);
+}
+</pre>
+
 <h2 id="scale">Use Touch to Perform Scaling</h2>
 
 <p>As discussed in <a href="detector.html">Detecting Common Gestures</a>,
@@ -191,10 +277,10 @@
 {@link android.view.ScaleGestureDetector.SimpleOnScaleGestureListener} 
 as a helper class that you can extend if you don’t care about all of the reported events.</p>
 
-<p>Here is a snippet that gives you the basic idea of how to perform scaling.
-Here is the original <a
-href="http://code.google.com/p/android-touchexample/">source code</a>
-for the examples.</p>
+
+<h3>Basic scaling example</h3>
+
+<p>Here is a snippet that illustrates the basic ingredients involved in scaling.</p>
 
 <pre>private ScaleGestureDetector mScaleDetector;
 private float mScaleFactor = 1.f;
@@ -238,3 +324,88 @@
         return true;
     }
 }</pre>
+
+
+
+
+<h3>More complex scaling example</h3>
+<p>Here is a more complex example from the {@code InteractiveChart} sample provided with this class. 
+The {@code InteractiveChart} sample supports both scrolling (panning) and scaling with multiple fingers,
+using the {@link android.view.ScaleGestureDetector} "span" 
+({@link android.view.ScaleGestureDetector#getCurrentSpanX getCurrentSpanX/Y}) and 
+"focus" ({@link android.view.ScaleGestureDetector#getFocusX getFocusX/Y}) features:</p>
+
+<pre>&#64;Override
+private RectF mCurrentViewport = 
+        new RectF(AXIS_X_MIN, AXIS_Y_MIN, AXIS_X_MAX, AXIS_Y_MAX);
+private Rect mContentRect;
+private ScaleGestureDetector mScaleGestureDetector;
+...
+public boolean onTouchEvent(MotionEvent event) {
+    boolean retVal = mScaleGestureDetector.onTouchEvent(event);
+    retVal = mGestureDetector.onTouchEvent(event) || retVal;
+    return retVal || super.onTouchEvent(event);
+}
+
+/**
+ * The scale listener, used for handling multi-finger scale gestures.
+ */
+private final ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener
+        = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
+    /**
+     * This is the active focal point in terms of the viewport. Could be a local
+     * variable but kept here to minimize per-frame allocations.
+     */
+    private PointF viewportFocus = new PointF();
+    private float lastSpanX;
+    private float lastSpanY;
+
+    // Detects that new pointers are going down.
+    &#64;Override
+    public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
+        lastSpanX = ScaleGestureDetectorCompat.
+                getCurrentSpanX(scaleGestureDetector);
+        lastSpanY = ScaleGestureDetectorCompat.
+                getCurrentSpanY(scaleGestureDetector);
+        return true;
+    }
+
+    &#64;Override
+    public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
+
+        float spanX = ScaleGestureDetectorCompat.
+                getCurrentSpanX(scaleGestureDetector);
+        float spanY = ScaleGestureDetectorCompat.
+                getCurrentSpanY(scaleGestureDetector);
+
+        float newWidth = lastSpanX / spanX * mCurrentViewport.width();
+        float newHeight = lastSpanY / spanY * mCurrentViewport.height();
+
+        float focusX = scaleGestureDetector.getFocusX();
+        float focusY = scaleGestureDetector.getFocusY();
+        // Makes sure that the chart point is within the chart region.
+        // See the sample for the implementation of hitTest().
+        hitTest(scaleGestureDetector.getFocusX(),
+                scaleGestureDetector.getFocusY(),
+                viewportFocus);
+
+        mCurrentViewport.set(
+                viewportFocus.x
+                        - newWidth * (focusX - mContentRect.left)
+                        / mContentRect.width(),
+                viewportFocus.y
+                        - newHeight * (mContentRect.bottom - focusY)
+                        / mContentRect.height(),
+                0,
+                0);
+        mCurrentViewport.right = mCurrentViewport.left + newWidth;
+        mCurrentViewport.bottom = mCurrentViewport.top + newHeight;     
+        ...
+        // Invalidates the View to update the display.
+        ViewCompat.postInvalidateOnAnimation(InteractiveLineGraphView.this);
+
+        lastSpanX = spanX;
+        lastSpanY = spanY;
+        return true;
+    }
+};</pre>
diff --git a/docs/html/training/gestures/scroll.jd b/docs/html/training/gestures/scroll.jd
index 8576948..bd1537a 100644
--- a/docs/html/training/gestures/scroll.jd
+++ b/docs/html/training/gestures/scroll.jd
@@ -14,6 +14,7 @@
 <!-- table of contents -->
 <h2>This lesson teaches you to</h2>
 <ol>
+  <li><a href="#term">Understand Scrolling Terminology</a></li>
   <li><a href="#scroll">Implement Touch-Based Scrolling</a></li>
 </ol>
 
@@ -24,12 +25,18 @@
     <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
     </li>
     <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
-    <li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
     <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
     <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
     <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/InteractiveChart.zip"
+class="button">Download the sample</a>
+ <p class="filename">InteractiveChart.zip</p>
+</div>
 
 </div>
 </div>
@@ -45,7 +52,26 @@
 
 <p>You can use scrollers ({@link android.widget.Scroller} or {@link
 android.widget.OverScroller}) to collect the data you need to produce a
-scrolling animation in response to a touch event.</p>
+scrolling animation in response to a touch event. They are similar, but
+{@link android.widget.OverScroller}
+includes methods for indicating to users that they've reached the content edges 
+after a pan or fling gesture. The {@code InteractiveChart} sample 
+uses the the {@link android.widget.EdgeEffect} class 
+(actually the {@link android.support.v4.widget.EdgeEffectCompat} class)
+to display a "glow" effect when users reach the content edges.</p>
+
+<p class="note"><strong>Note:</strong> We recommend that you
+use {@link android.widget.OverScroller} rather than {@link
+android.widget.Scroller} for scrolling animations.
+{@link android.widget.OverScroller} provides the best backward
+compatibility with older devices.
+<br />
+Also note that you generally only need to use scrollers
+when implementing scrolling yourself. {@link android.widget.ScrollView} and
+{@link android.widget.HorizontalScrollView} do all of this for you if you nest your 
+layout within them.
+</p>
+
 
 <p>A scroller is used  to animate scrolling over time, using platform-standard
 scrolling physics (friction, velocity, etc.). The scroller itself doesn't
@@ -54,101 +80,280 @@
 responsibility to get and apply new coordinates at a rate that will make the
 scrolling animation look smooth.</p>
 
-<p class="note"><strong>Note:</strong> You generally only need to use scrollers
-when implementing scrolling yourself. {@link android.widget.ScrollView} and
-{@link android.widget.HorizontalScrollView} do all this for you do all of this for you if you nest your layout within them.</p>
-
-<h2 id = "scroll">Implement Touch-Based Scrolling</h2>
 
 
-<p>This snippet illustrates the basics of using a scroller. It uses a 
-{@link android.view.GestureDetector}, and overrides the  
-{@link android.view.GestureDetector.SimpleOnGestureListener} methods 
-{@link android.view.GestureDetector.OnGestureListener#onDown onDown()} and 
-{@link android.view.GestureDetector.OnGestureListener#onFling onFling()}. It also 
-overrides {@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()} 
-to return {@code false} since you don't need to animate a scroll.</p>
+<h2 id="term">Understand Scrolling Terminology</h2>
 
+<p>"Scrolling" is a word that can take on different meanings in Android, depending on the context.</p>
 
-<p>It's common to use scrollers in conjunction with a fling gesture, but they
+<p><strong>Scrolling</strong> is the general process of moving the viewport (that is, the 'window' 
+of content you're looking at). When scrolling is in both the x and y axes, it's called 
+<em>panning</em>. The sample application provided with this class, {@code InteractiveChart}, illustrates 
+two different types of scrolling, dragging and flinging:</p>
+<ul>
+    <li><strong>Dragging</strong> is the type of scrolling that occurs when a user drags her 
+finger across the touch screen. Simple dragging is often implemented by overriding 
+{@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()} in 
+{@link android.view.GestureDetector.OnGestureListener}. For more discussion of dragging, see 
+<a href="dragging.jd">Dragging and Scaling</a>.</li>
+
+    <li><strong>Flinging</strong> is the type of scrolling that occurs when a user 
+drags and lifts her finger quickly. After the user lifts her finger, you generally 
+want to keep scrolling (moving the viewport), but decelerate until the viewport stops moving. 
+Flinging can be implemented by overriding 
+{@link android.view.GestureDetector.OnGestureListener#onFling onFling()} 
+in {@link android.view.GestureDetector.OnGestureListener}, and by using 
+a scroller object. This is the use 
+case that is the topic of this lesson.</li>
+</ul>
+
+<p>It's common to use scroller objects 
+in conjunction with a fling gesture, but they
 can be used in pretty much any context where you want the UI to display
-scrolling in response to a touch event. For example, you could override {@link
-android.view.View#onTouchEvent onTouchEvent()} to process touch events directly,
-and produce a scrolling effect in response to those touch events.</p>
+scrolling in response to a touch event. For example, you could override  
+{@link android.view.View#onTouchEvent onTouchEvent()} to process touch 
+events directly, and produce a scrolling effect or a "snapping to page" animation 
+in response to those touch events.</p>
 
-<pre>
-private OverScroller mScroller = new OverScroller(context);
 
-private GestureDetector.SimpleOnGestureListener mGestureListener
+<h2 id="#scroll">Implement Touch-Based Scrolling</h2> 
+
+<p>This section describes how to use a scroller.
+The snippet shown below comes from the {@code InteractiveChart} sample 
+provided with this class.
+It uses a 
+{@link android.view.GestureDetector}, and overrides the  
+{@link android.view.GestureDetector.SimpleOnGestureListener} method 
+{@link android.view.GestureDetector.OnGestureListener#onFling onFling()}.
+It uses {@link android.widget.OverScroller} to track the fling gesture.
+If the user reaches the content edges 
+after the fling gesture, the app displays a "glow" effect.
+</p>
+
+<p class="note"><strong>Note:</strong> The {@code InteractiveChart} sample app displays a 
+chart that you can zoom, pan, scroll, and so on. In the following snippet, 
+{@code mContentRect} represents the rectangle coordinates within the view that the chart 
+will be drawn into. At any given time, a subset of the total chart domain and range are drawn 
+into this rectangular area. 
+{@code mCurrentViewport} represents the portion of the chart that is currently 
+visible in the screen. Because pixel offsets are generally treated as integers, 
+{@code mContentRect} is of the type {@link android.graphics.Rect}. Because the 
+graph domain and range are decimal/float values, {@code mCurrentViewport} is of 
+the type {@link android.graphics.RectF}.</p>
+
+<p>The first part of the snippet shows the implementation of 
+{@link android.view.GestureDetector.OnGestureListener#onFling onFling()}:</p>
+
+<pre>// The current viewport. This rectangle represents the currently visible 
+// chart domain and range. The viewport is the part of the app that the
+// user manipulates via touch gestures.
+private RectF mCurrentViewport = 
+        new RectF(AXIS_X_MIN, AXIS_Y_MIN, AXIS_X_MAX, AXIS_Y_MAX);
+
+// The current destination rectangle (in pixel coordinates) into which the 
+// chart data should be drawn.
+private Rect mContentRect;
+
+private OverScroller mScroller;
+private RectF mScrollerStartViewport;
+...
+private final GestureDetector.SimpleOnGestureListener mGestureListener
         = new GestureDetector.SimpleOnGestureListener() {
     &#64;Override
     public boolean onDown(MotionEvent e) {
-        // Abort any active scroll animations and invalidate.
+        // Initiates the decay phase of any active edge effects.
+        releaseEdgeEffects();
+        mScrollerStartViewport.set(mCurrentViewport);
+        // Aborts any active scroll animations and invalidates.
         mScroller.forceFinished(true);
-        // There is also a compatibility version: 
-        // ViewCompat.postInvalidateOnAnimation
-        postInvalidateOnAnimation();
+        ViewCompat.postInvalidateOnAnimation(InteractiveLineGraphView.this);
         return true;
     }
-
-    &#64;Override
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, 
-            float distanceX, float distanceY) {
-        // You don't use a scroller in onScroll because you don't need to animate
-        // a scroll. The scroll occurs instantly in response to touch feedback.
-        return false;
-    }
-
+    ...
     &#64;Override
     public boolean onFling(MotionEvent e1, MotionEvent e2, 
             float velocityX, float velocityY) {
-        // Before flinging, abort the current animation.
-        mScroller.forceFinished(true);
-        // Begin the scroll animation
-        mScroller.fling(
-                // Current scroll position
-                startX,
-                startY,
-                // Velocities, negated for natural touch response
-                (int) -velocityX,
-                (int) -velocityY,
-                // Minimum and maximum scroll positions. The minimum scroll 
-                // position is generally zero and the maximum scroll position 
-                // is generally the content size less the screen size. So if the 
-                // content width is 1000 pixels and the screen width is 200  
-                // pixels, the maximum scroll offset should be 800 pixels.
-                minX, maxX,
-                minY, maxY,
-                // The maximum overscroll bounds. This is useful when using
-                // the EdgeEffect class to draw overscroll "glow" overlays.
-                mContentRect.width() / 2,
-                mContentRect.height() / 2);
-        // Invalidate to trigger computeScroll()
-        postInvalidateOnAnimation();
+        fling((int) -velocityX, (int) -velocityY);
         return true;
     }
 };
 
+private void fling(int velocityX, int velocityY) {
+    // Initiates the decay phase of any active edge effects.
+    releaseEdgeEffects();
+    // Flings use math in pixels (as opposed to math based on the viewport).
+    Point surfaceSize = computeScrollSurfaceSize();
+    mScrollerStartViewport.set(mCurrentViewport);
+    int startX = (int) (surfaceSize.x * (mScrollerStartViewport.left - 
+            AXIS_X_MIN) / (
+            AXIS_X_MAX - AXIS_X_MIN));
+    int startY = (int) (surfaceSize.y * (AXIS_Y_MAX - 
+            mScrollerStartViewport.bottom) / (
+            AXIS_Y_MAX - AXIS_Y_MIN));
+    // Before flinging, aborts the current animation.
+    mScroller.forceFinished(true);
+    // Begins the animation
+    mScroller.fling(
+            // Current scroll position
+            startX,
+            startY,
+            velocityX,
+            velocityY,
+            /*
+             * Minimum and maximum scroll positions. The minimum scroll 
+             * position is generally zero and the maximum scroll position 
+             * is generally the content size less the screen size. So if the 
+             * content width is 1000 pixels and the screen width is 200  
+             * pixels, the maximum scroll offset should be 800 pixels.
+             */
+            0, surfaceSize.x - mContentRect.width(),
+            0, surfaceSize.y - mContentRect.height(),
+            // The edges of the content. This comes into play when using
+            // the EdgeEffect class to draw "glow" overlays.
+            mContentRect.width() / 2,
+            mContentRect.height() / 2);
+    // Invalidates to trigger computeScroll()
+    ViewCompat.postInvalidateOnAnimation(this);
+}</pre>
+
+<p>When {@link android.view.GestureDetector.OnGestureListener#onFling onFling()} calls 
+{@link android.support.v4.view.ViewCompat#postInvalidateOnAnimation postInvalidateOnAnimation()}, 
+it triggers 
+{@link android.view.View#computeScroll computeScroll()} to update the values for x and y. 
+This is typically be done when a view child is animating a scroll using a scroller object, as in this example. </p>
+
+<p>Most views pass the scroller object's x and y position directly to 
+{@link android.view.View#scrollTo scrollTo()}. 
+The following implementation of {@link android.view.View#computeScroll computeScroll()} 
+takes a different approach&mdash;it calls 
+{@link android.widget.OverScroller#computeScrollOffset computeScrollOffset()} to get the current 
+location of x and y. When the criteria for displaying an overscroll "glow" edge effect are met 
+(the display is zoomed in, x or y is out of bounds, and the app isn't already showing an overscroll), 
+the code sets up the overscroll glow effect and calls 
+{@link android.support.v4.view.ViewCompat#postInvalidateOnAnimation postInvalidateOnAnimation()} 
+to trigger an invalidate on the view:</p>
+
+<pre>// Edge effect / overscroll tracking objects.
+private EdgeEffectCompat mEdgeEffectTop;
+private EdgeEffectCompat mEdgeEffectBottom;
+private EdgeEffectCompat mEdgeEffectLeft;
+private EdgeEffectCompat mEdgeEffectRight;
+
+private boolean mEdgeEffectTopActive;
+private boolean mEdgeEffectBottomActive;
+private boolean mEdgeEffectLeftActive;
+private boolean mEdgeEffectRightActive;
+
 &#64;Override
 public void computeScroll() {
     super.computeScroll();
 
-    // Compute the current scroll offsets. If this returns true, then the 
-    // scroll has not yet finished.
+    boolean needsInvalidate = false;
+
+    // The scroller isn't finished, meaning a fling or programmatic pan 
+    // operation is currently active.
     if (mScroller.computeScrollOffset()) {
+        Point surfaceSize = computeScrollSurfaceSize();
         int currX = mScroller.getCurrX();
         int currY = mScroller.getCurrY();
 
-        // Actually render the scrolled viewport, or actually scroll the 
-        // view using View.scrollTo.
+        boolean canScrollX = (mCurrentViewport.left > AXIS_X_MIN
+                || mCurrentViewport.right < AXIS_X_MAX);
+        boolean canScrollY = (mCurrentViewport.top > AXIS_Y_MIN
+                || mCurrentViewport.bottom < AXIS_Y_MAX);
 
-        // If currX or currY are outside the bounds, render the overscroll 
-        // glow using EdgeEffect.
+        /*          
+         * If you are zoomed in and currX or currY is
+         * outside of bounds and you're not already
+         * showing overscroll, then render the overscroll
+         * glow edge effect.
+         */
+        if (canScrollX
+                && currX < 0
+                && mEdgeEffectLeft.isFinished()
+                && !mEdgeEffectLeftActive) {
+            mEdgeEffectLeft.onAbsorb((int) 
+                    OverScrollerCompat.getCurrVelocity(mScroller));
+            mEdgeEffectLeftActive = true;
+            needsInvalidate = true;
+        } else if (canScrollX
+                && currX > (surfaceSize.x - mContentRect.width())
+                && mEdgeEffectRight.isFinished()
+                && !mEdgeEffectRightActive) {
+            mEdgeEffectRight.onAbsorb((int) 
+                    OverScrollerCompat.getCurrVelocity(mScroller));
+            mEdgeEffectRightActive = true;
+            needsInvalidate = true;
+        }
 
-    } else {
-        // The scroll has finished.
-    }
+        if (canScrollY
+                && currY < 0
+                && mEdgeEffectTop.isFinished()
+                && !mEdgeEffectTopActive) {
+            mEdgeEffectTop.onAbsorb((int) 
+                    OverScrollerCompat.getCurrVelocity(mScroller));
+            mEdgeEffectTopActive = true;
+            needsInvalidate = true;
+        } else if (canScrollY
+                && currY > (surfaceSize.y - mContentRect.height())
+                && mEdgeEffectBottom.isFinished()
+                && !mEdgeEffectBottomActive) {
+            mEdgeEffectBottom.onAbsorb((int) 
+                    OverScrollerCompat.getCurrVelocity(mScroller));
+            mEdgeEffectBottomActive = true;
+            needsInvalidate = true;
+        }
+        ...
+    }</pre>
+
+<p>Here is the section of the code that performs the actual zoom:</p>
+
+<pre>// Custom object that is functionally similar to Scroller
+Zoomer mZoomer;
+private PointF mZoomFocalPoint = new PointF();
+...
+
+// If a zoom is in progress (either programmatically or via double
+// touch), performs the zoom.
+if (mZoomer.computeZoom()) {
+    float newWidth = (1f - mZoomer.getCurrZoom()) * 
+            mScrollerStartViewport.width();
+    float newHeight = (1f - mZoomer.getCurrZoom()) * 
+            mScrollerStartViewport.height();
+    float pointWithinViewportX = (mZoomFocalPoint.x - 
+            mScrollerStartViewport.left)
+            / mScrollerStartViewport.width();
+    float pointWithinViewportY = (mZoomFocalPoint.y - 
+            mScrollerStartViewport.top)
+            / mScrollerStartViewport.height();
+    mCurrentViewport.set(
+            mZoomFocalPoint.x - newWidth * pointWithinViewportX,
+            mZoomFocalPoint.y - newHeight * pointWithinViewportY,
+            mZoomFocalPoint.x + newWidth * (1 - pointWithinViewportX),
+            mZoomFocalPoint.y + newHeight * (1 - pointWithinViewportY));
+    constrainViewport();
+    needsInvalidate = true;
+}
+if (needsInvalidate) {
+    ViewCompat.postInvalidateOnAnimation(this);
+}
+</pre>
+
+<p>This is the {@code computeScrollSurfaceSize()} method that's called in the above snippet. It 
+computes the current scrollable surface size, in pixels. For example, if the entire chart area is visible, 
+this is simply the current size of {@code mContentRect}. If the chart is zoomed in 200% in both directions, 
+the returned size will be twice as large horizontally and vertically.</p>
+
+<pre>private Point computeScrollSurfaceSize() {
+    return new Point(
+            (int) (mContentRect.width() * (AXIS_X_MAX - AXIS_X_MIN)
+                    / mCurrentViewport.width()),
+            (int) (mContentRect.height() * (AXIS_Y_MAX - AXIS_Y_MIN)
+                    / mCurrentViewport.height()));
 }</pre>
 
-<p>For another example of scroller usage, see the <a href="http://github.com/android/platform_frameworks_support/blob/master/v4/java/android/support/v4/view/ViewPager.java">source code</a> for the 
-{@link android.support.v4.view.ViewPager} class.</p>
+<p>For another example of scroller usage, see the 
+<a href="http://github.com/android/platform_frameworks_support/blob/master/v4/java/android/support/v4/view/ViewPager.java">source code</a> for the 
+{@link android.support.v4.view.ViewPager} class. It scrolls in response to flings, 
+and uses scrolling to implement the "snapping to page" animation.</p>
+
diff --git a/docs/html/training/gestures/viewgroup.jd b/docs/html/training/gestures/viewgroup.jd
index 257a5d8..5b32300 100644
--- a/docs/html/training/gestures/viewgroup.jd
+++ b/docs/html/training/gestures/viewgroup.jd
@@ -26,12 +26,19 @@
     <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide
     </li>
     <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li>
-    <li><a href="http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html">Making Sense of Multitouch</a> blog post</li>
     <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li>
     <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li>
     <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/InteractiveChart.zip"
+class="button">Download the sample</a>
+ <p class="filename">InteractiveChart.zip</p>
+</div>
+
 
 </div>
 </div>
diff --git a/docs/html/training/id-auth/authenticate.jd b/docs/html/training/id-auth/authenticate.jd
index c316af7..3084bea 100644
--- a/docs/html/training/id-auth/authenticate.jd
+++ b/docs/html/training/id-auth/authenticate.jd
@@ -114,7 +114,7 @@
     new Handler(new OnError()));    // Callback called if an error occurs
 </pre>
 
-<p>In this example, <code>OnTokenAcquired</code> is a class that extends
+<p>In this example, <code>OnTokenAcquired</code> is a class that implements
 {@link android.accounts.AccountManagerCallback}. {@link android.accounts.AccountManager} calls
 {@link android.accounts.AccountManagerCallback#run run()} on <code>OnTokenAcquired</code> with an
 {@link android.accounts.AccountManagerFuture} that contains a {@link android.os.Bundle}. If
diff --git a/docs/html/training/implementing-navigation/lateral.jd b/docs/html/training/implementing-navigation/lateral.jd
index b59bab2..9a31d7a 100644
--- a/docs/html/training/implementing-navigation/lateral.jd
+++ b/docs/html/training/implementing-navigation/lateral.jd
@@ -131,6 +131,9 @@
     ViewPager mViewPager;
 
     public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_collection_demo);
+
         // ViewPager and its adapters use support library
         // fragments, so use getSupportFragmentManager.
         mDemoCollectionPagerAdapter =
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 79980be..985fc44 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -287,6 +287,10 @@
             Caching Bitmaps
           </a>
           </li>
+          <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/manage-memory.html">
+            Managing Bitmap Memory
+          </a>
+          </li>
           <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/display-bitmap.html">
             Displaying Bitmaps in Your UI
           </a></li>