Merge "docs: note to install linux packages" into lmp-docs
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 5230128..3604891 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -276,7 +276,7 @@
 
     private static native byte[] nativeMarshall(long nativePtr);
     private static native void nativeUnmarshall(
-            long nativePtr, byte[] data, int offest, int length);
+            long nativePtr, byte[] data, int offset, int length);
     private static native void nativeAppendFrom(
             long thisNativePtr, long otherNativePtr, int offset, int length);
     private static native boolean nativeHasFileDescriptors(long nativePtr);
@@ -432,8 +432,8 @@
     /**
      * Set the bytes in data to be the raw bytes of this Parcel.
      */
-    public final void unmarshall(byte[] data, int offest, int length) {
-        nativeUnmarshall(mNativePtr, data, offest, length);
+    public final void unmarshall(byte[] data, int offset, int length) {
+        nativeUnmarshall(mNativePtr, data, offset, length);
     }
 
     public final void appendFrom(Parcel parcel, int offset, int length) {
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 5265f20..4e03108 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -57,7 +57,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 5, 2015.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 2, 2015.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
@@ -88,7 +88,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 5, 2015.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 2, 2015.
 
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
@@ -108,7 +108,7 @@
 
 
 <img alt="" style="float:right"
-src="//chart.googleapis.com/chart?chl=GL%202.0%7CGL%203.0&chf=bg%2Cs%2C00000000&chd=t%3A69.9%2C30.1&chco=c4df9b%2C6fad0c&cht=p&chs=400x250" />
+src="//chart.googleapis.com/chart?chl=GL%202.0%7CGL%203.0&chf=bg%2Cs%2C00000000&chd=t%3A68.9%2C31.1&chco=c4df9b%2C6fad0c&cht=p&chs=400x250" />
 
 
 <p>To declare which version of OpenGL ES your application requires, you should use the {@code
@@ -127,17 +127,17 @@
 </tr>
 <tr>
 <td>2.0</td>
-<td>69.9%</td>
+<td>68.9%</td>
 </tr>
 <tr>
 <td>3.0</td>
-<td>30.1%</td>
+<td>31.1%</td>
 </tr>
 </table>
 
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 5, 2015</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 2, 2015</em></p>
 
 
 
@@ -155,7 +155,7 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chco=c4df9b%2C6fad0c&chd=t%3A0.4%2C7.8%2C6.7%2C46.0%2C39.1&chf=bg%2Cs%2C00000000&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat",
+    "chart": "//chart.googleapis.com/chart?chf=bg%2Cs%2C00000000&chd=t%3A0.4%2C7.4%2C6.4%2C44.5%2C39.7%2C1.6&chco=c4df9b%2C6fad0c&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat%7CLollipop&chs=500x250&cht=p",
     "data": [
       {
         "api": 8,
@@ -165,32 +165,37 @@
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "7.8"
+        "perc": "7.4"
       },
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "6.7"
+        "perc": "6.4"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "19.2"
+        "perc": "18.4"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "20.3"
+        "perc": "19.8"
       },
       {
         "api": 18,
         "name": "Jelly Bean",
-        "perc": "6.5"
+        "perc": "6.3"
       },
       {
         "api": 19,
         "name": "KitKat",
-        "perc": "39.1"
+        "perc": "39.7"
+      },
+      {
+        "api": 21,
+        "name": "Lollipop",
+        "perc": "1.6"
       }
     ]
   }
@@ -203,29 +208,29 @@
     "data": {
       "Large": {
         "hdpi": "0.6",
-        "ldpi": "0.6",
-        "mdpi": "5.4",
-        "tvdpi": "2.3",
+        "ldpi": "0.5",
+        "mdpi": "5.1",
+        "tvdpi": "2.2",
         "xhdpi": "0.6"
       },
       "Normal": {
-        "hdpi": "37.5",
-        "mdpi": "8.8",
+        "hdpi": "38.3",
+        "mdpi": "8.7",
         "tvdpi": "0.1",
-        "xhdpi": "18.4",
-        "xxhdpi": "16.3"
+        "xhdpi": "18.8",
+        "xxhdpi": "15.9"
       },
       "Small": {
         "ldpi": "4.8"
       },
       "Xlarge": {
         "hdpi": "0.3",
-        "mdpi": "3.7",
+        "mdpi": "3.5",
         "xhdpi": "0.6"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b%2C6fad0c&chd=t%3A5.4%2C17.9%2C2.4%2C38.4%2C19.6%2C16.3&chf=bg%2Cs%2C00000000&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi",
-    "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b%2C6fad0c&chd=t%3A4.6%2C9.5%2C81.1%2C4.8&chf=bg%2Cs%2C00000000&chl=Xlarge%7CLarge%7CNormal%7CSmall"
+    "densitychart": "//chart.googleapis.com/chart?chf=bg%2Cs%2C00000000&chd=t%3A5.3%2C17.3%2C2.3%2C39.2%2C20.0%2C15.9&chco=c4df9b%2C6fad0c&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chs=400x250&cht=p",
+    "layoutchart": "//chart.googleapis.com/chart?chf=bg%2Cs%2C00000000&chd=t%3A4.4%2C9.0%2C81.8%2C4.8&chco=c4df9b%2C6fad0c&chl=Xlarge%7CLarge%7CNormal%7CSmall&chs=400x250&cht=p"
   }
 ];
 
@@ -305,7 +310,7 @@
   },
   {
     "api":21,
-    "link":"<a href='/about/versions/android-5.0.html'>4.4</a>",
+    "link":"<a href='/about/versions/android-5.0.html'>5.0</a>",
     "codename":"Lollipop"
   }
 ];
diff --git a/docs/html/about/versions/android-5.0-changes.jd b/docs/html/about/versions/android-5.0-changes.jd
index 3de5c3c..f51af40 100644
--- a/docs/html/about/versions/android-5.0-changes.jd
+++ b/docs/html/about/versions/android-5.0-changes.jd
@@ -24,13 +24,6 @@
   <li><a href="#managed_profiles">Support for Managed Profiles</a></li>
 </ol>
 
-<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
-<div>
-    <h3>Video</h3>
-    <p>Notifications</p>
-</div>
-</a>
-
 <h2>API Differences</h2>
 <ol>
 <li><a href="{@docRoot}sdk/api_diff/21/changes.html">API level 20 to 21 &raquo;</a> </li>
@@ -48,6 +41,20 @@
 </div>
 </div>
 
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=um1S2u022HA">
+<div>
+    <h3>Video</h3>
+    <p>Dev Byte: What's New in Android 5.0</p>
+</div>
+</a>
+
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+    <h3>Video</h3>
+    <p>Dev Byte: Notifications</p>
+</div>
+</a>
+
 <p>API Level: {@sdkPlatformApiLevel}</p>
 <p>Along with new features and capabilities, Android 5.0 includes a variety of
 system changes and API behavior changes. This document highlights
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index d212b06..1a92753 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -516,23 +516,41 @@
         <em>finished_asset</em>.png
     drawable-xxhdpi/...
         <em>finished_asset</em>.png
+
+    mipmap-ldpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-mdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-hdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-xhdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-xxhdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-xxxhdpi/...
+        <em>finished_launcher_asset</em>.png
 </pre>
 
 <p>For more information about how to save resources in the application project,
 see <a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.
 </p>
 
+<p> For more information about using the mipmap folders, see
+<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.</p>
 
 <h3 id="xxxhdpi-launcher">Provide an xxx-high-density launcher icon</h3>
 
-<p>Some devices scale-up the launcher icon by as much as 25%. For example, if your highest density 
+<p>Some devices scale-up the launcher icon by as much as 25%. For example, if your highest density
 launcher icon image is already extra-extra-high density, the scaling process will make it appear
-less crisp. So you should provide a higher density launcher icon in the <code>drawable-xxxhdpi
+less crisp. So you should provide a higher density launcher icon in the <code>mipmap-xxxhdpi
 </code> directory, which the system uses instead of scaling up a smaller version of the icon.</p>
 
-<p class="note"><strong>Note:</strong> the <code>drawable-xxxhdpi</code> qualifier is necessary only
-to provide a launcher icon that can appear larger than usual on an xxhdpi device. You do not need to
-provide xxxhdpi assets for all your app's images.</p>
+<p class="note"><strong>Note:</strong> The <code>mipmap-xxxhdpi</code> qualifier is necessary
+only to provide a launcher icon that can appear larger than usual on an xxhdpi device. It is best
+practice to place all your launcher icons in the <code>res/mipmap-[density]/</code> folders. This
+enables your app to display launcher icons that have a higher density than the device, without
+scaling up a lower density version of the icon. You do not need to provide xxxhdpi assets for all
+your app's images.</p>
 
 <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a> for
 more information.</p>
diff --git a/docs/html/design/wear/watchfaces.jd b/docs/html/design/wear/watchfaces.jd
index 99dc3dd..2a00802 100644
--- a/docs/html/design/wear/watchfaces.jd
+++ b/docs/html/design/wear/watchfaces.jd
@@ -101,7 +101,7 @@
 <!-- H2: plan for all display modes -->
 <div style="float:right;margin-top:35px;margin-left:20px">
   <img src="{@docRoot}design/media/wear/Render_Interactive.png"
-       width="200" height="195" alt="" style="margin-right:5px"/><br/>
+       width="200" height="195" alt="" style="margin-right:5px;margin-top:20px"/><br/>
   <img src="{@docRoot}design/media/wear/Render_Ambient.png"
      width="200" height="195" alt="" style="margin-right:5px"/>
 </div>
@@ -118,11 +118,12 @@
 
 <h3>Ambient mode</h3>
 <p>Ambient mode helps the device conserve power. Your design should make clear to the user that
-the screen is in ambient mode by using only grayscale colors. Do not use a lot of white in ambient
-mode, since this distracting and hurts battery life on some screens. In this mode, the screen
-is only updated once every minute. Only show hours and minutes in ambient mode; do not show
-seconds. Your watch face is notified when the device switches to ambient mode, and you should
-thoughtfully design for it.</p>
+the screen is in ambient mode. The background color scheme is <em>strictly limited</em> to black,
+white, and grays. Your watch face may use some color elements on screens that support it
+provided it is unambiguous that the device is in ambient mode. You can use color elements for up
+to 5 percent of total pixels. In this mode, the screen is only updated once every minute. Only
+show hours and minutes in ambient mode; do not show seconds. Your watch face is notified when
+the device switches to ambient mode, and you should thoughtfully design for it.</p>
 
 
 
@@ -131,23 +132,29 @@
 
 <p>Android Wear devices feature a variety of screen technologies, each with their own advantages
 and considerations. One important consideration when designing the ambient mode display for your
-watch face is how it affects battery life and screen burn-in on some screens.</p>
-
-<p>You can configure your watch face to display different ambient designs depending on the kind
+watch face is how it affects battery life and screen burn-in on some screens.
+You can configure your watch face to display different ambient designs depending on the kind
 of screen available on the device. Consider the best design for your watch faces on all
 screens.</p>
 
 <div class="layout-content-row" style="margin-top:20px">
 <div class="layout-content-col span-9">
-  <h3>Low bit</h3>
-  <p>Pixels on some screens (including OLED and transflective LED) in ambient mode are either
-  "on" or "off", also known as "low-bit". When designing for low-bit ambient mode, use only black
-  and white, avoid grayscale colors, and disable antialiasing in your paint styles. Make sure to
-  test your design on devices with low-bit ambient mode.</p>
+  <h3>Reduced color space</h3>
+  <p>Some displays use a reduced color space in ambient mode to save power.</p>
+  <p>One reduced color space power saving method is to use a "low-bit" mode. In low-bit mode,
+  the available colors are limited to black, white, blue, red, magenta, green, cyan, and yellow.
+  When designing for low-bit ambient mode, use a black or a white background. For OLED screens,
+  you must use a black background. Non-background pixels must be less than 10 percent of total
+  pixels. You can use low-bit color for up to 5 percent of pixels on screens that support it.
+  You should also disable antialiasing in your paint styles for this mode. Make sure to test
+  your design on devices with low-bit ambient mode.</p>
+  <p>Other displays save power in ambient mode by not producing any color. When designing for
+  displays which do not use color in ambient mode, the background may be either black or
+  white.</p>
 </div>
 <div class="layout-content-col span-4">
   <img src="{@docRoot}design/media/wear/Render_LowBit.png" width="200"
-       height="" alt="" style="margin-top:-30px;margin-left:13px">
+       height="" alt="" style="margin-top:45px;margin-left:13px">
 </div>
 </div>
 
@@ -164,7 +171,7 @@
 </div>
 <div class="layout-content-col span-4">
   <img src="{@docRoot}design/media/wear/Render_1Bit.png" width="200"
-       height="" alt="" style="margin-top:-30px;margin-left:13px">
+       height="" alt="" style="margin-top:-10px;margin-left:13px">
 </div>
 </div>
 
diff --git a/docs/html/distribute/tools/promote/device-art-resources/wear/thumb.png b/docs/html/distribute/tools/promote/device-art-resources/wear/thumb.png
new file mode 100644
index 0000000..adfe16f
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/wear/thumb.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/wear_round/port_back.png b/docs/html/distribute/tools/promote/device-art-resources/wear_round/port_back.png
new file mode 100644
index 0000000..0b3d04a
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/wear_round/port_back.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/wear_square/port_back.png b/docs/html/distribute/tools/promote/device-art-resources/wear_square/port_back.png
new file mode 100644
index 0000000..aa44795
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/wear_square/port_back.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art.jd b/docs/html/distribute/tools/promote/device-art.jd
index 3902b30..f583eb9 100644
--- a/docs/html/distribute/tools/promote/device-art.jd
+++ b/docs/html/distribute/tools/promote/device-art.jd
@@ -1,13 +1,13 @@
 page.title=Device Art Generator
 page.image=/images/device-art-ex-crop.jpg
-page.metaDescription=Drag and drop screenshots of your app into real device artwork, for better looking promotional images and improved visual context.
+page.metaDescription=Drag and drop screenshots of your app into device artwork, for better looking promotional images and improved visual context.
 meta.tags="disttools, promoting, deviceart, marketing"
 page.tags="device, deviceart, nexus, assets"
 Xnonavpage=true
 
 @jd:body
 
-<p>The device art generator enables you to quickly wrap app screenshots in real device artwork. This provides better visual context for your app screenshots on your website or in other promotional materials</p>
+<p>The device art generator enables you to quickly wrap app screenshots in device artwork. This provides better visual context for your app screenshots on your website or in other promotional materials</p>
 
 <p class="note"><strong>Note</strong>: Do <em>not</em> use graphics created here in your 1024x500
 feature image or screenshots for your Google Play app listing.</p>
@@ -41,6 +41,12 @@
       <label for="output-glare">Screen Glare</label><br><br>
       <a class="button" id="rotate-button">Rotate</a>
     </p>
+    <p id="wear-customizations">
+      <input type="radio" id="output-square" name="output-wear" checked="checked" class="form-field-checkbutton">
+      <label for="output-square">Square</label><br>
+      <input type="radio" id="output-round" name="output-wear" class="form-field-checkbutton">
+      <label for="output-round">Round</label><br><br>
+    </p>
   </div>
   <div class="layout-content-col span-10">
     <!-- position:relative fixes an issue where dragging an image out of a inline-block container
@@ -52,7 +58,7 @@
 </div>
 
 <div class="unsupported-browser" style="display: none">
-  <p class="warning"><strong>Error:</strong> This page requires 
+  <p class="warning"><strong>Error:</strong> This page requires
     <span id="unsupported-browser-reason">certain features</span>, which your web browser
     doesn't support. To continue, navigate to this page on a supported web browser, such as
     <strong>Google Chrome</strong>.</p>
@@ -165,6 +171,10 @@
   // Global constants
   var MSG_INVALID_INPUT_IMAGE = 'Invalid screenshot provided. Screenshots must be PNG files '
       + 'matching the target device\'s screen aspect ratio in either portrait or landscape.';
+  var MSG_INVALID_WEAR_IMAGE = 'Invalid screenshot provided. Screenshots must be PNG files '
+      + 'matching the target device\'s screen aspect ratio.'
+      + ' Capture screenshots from a Wear emulator or device with '
+      + '<a href="http://developer.android.com/tools/debugging/debugging-studio.html#screenCap">Android Studio</a>.';
   var MSG_NO_INPUT_IMAGE = 'Drag a screenshot (in PNG format) from your desktop onto a '
       + 'target device above.'
   var MSG_GENERATING_IMAGE = 'Generating device art&hellip;';
@@ -270,6 +280,47 @@
       portSize: [768,1280],
       archived: true
     },
+    {
+      id: 'wear',
+      title: 'Android Wear',
+      url: 'http://www.android.com/wear/',
+      physicalSize: 1.8,
+      physicalHeight: 1.8,
+      density: 'HDPI',
+      landRes: ['back'],
+      landOffset: [225,206],
+      portRes: ['back'],
+      portOffset: [200,214],
+      portSize: [320,320],
+    },
+    {
+      id: 'wear_square',
+      title: 'Android Wear Square',
+      url: 'http://www.android.com/wear/',
+      physicalSize: 1.8,
+      physicalHeight: 1.8,
+      density: 'HDPI',
+      landRes: ['back'],
+      landOffset: [225,206],
+      portRes: ['back'],
+      portOffset: [200,214],
+      portSize: [320,320],
+      hidden: true
+    },
+    {
+      id: 'wear_round',
+      title: 'Android Wear Round',
+      url: 'http://www.android.com/wear/',
+      physicalSize: 1.8,
+      physicalHeight: 1.8,
+      density: 'HDPI',
+      landRes: ['back'],
+      landOffset: [161,167],
+      portRes: ['back'],
+      portOffset: [128,134],
+      portSize: [320,320],
+      hidden: true
+    },
   ];
 
   DEVICES = DEVICES.sort(function(x, y) { return x.physicalSize - y.physicalSize; });
@@ -343,15 +394,21 @@
     $('#output').html(MSG_NO_INPUT_IMAGE);
 
     $('#frame-customizations').hide();
+    $('#wear-customizations').hide();
 
     $('#output-shadow, #output-glare').click(function() {
       createFrame();
     });
 
+    $('input[name="output-wear"]').change(function() {
+      createFrame();
+    });
+
     // Build device list.
     $.each(DEVICES, function() {
       var resolution = this.actualResolution || this.portSize;
       var scaleFactorText = '';
+      var deviceList = '.device-list.primary';
       if (resolution[0] != this.portSize[0]) {
         scaleFactorText = '<br>' + (100 * (this.portSize[0] / resolution[0])).toFixed(0) +
             '% size output';
@@ -359,6 +416,12 @@
         scaleFactorText = '<br>&nbsp;';
       }
 
+      if (this.archived) {
+        deviceList = '.device-list.archived';
+      } else if (this.hidden) {
+        deviceList = '.device-list.hidden';
+      }
+
       $('<li>')
           .append($('<div>')
               .addClass('thumb-container')
@@ -374,7 +437,7 @@
                   '<br>' +  this.physicalSize + '" @ ' + this.density +
                   '<br>' + (resolution[0] + 'x' + resolution[1]) + scaleFactorText))
           .data('deviceId', this.id)
-          .appendTo(this.archived ? '.device-list.archive' : '.device-list.primary');
+          .appendTo(deviceList)
     });
 
     // Set up "older devices" expando.
@@ -406,7 +469,11 @@
           evt.preventDefault();
           loadImageFromFileList(evt.dataTransfer.files, function(data) {
             if (data == null) {
-              $('#output').html(MSG_INVALID_INPUT_IMAGE);
+              if (g_currentDevice.id == 'wear') {
+                $('#output').html(MSG_INVALID_WEAR_IMAGE);
+              }else {
+                $('#output').html(MSG_INVALID_INPUT_IMAGE);
+              }
               return;
             }
             loadImageFromUri(data.uri, function(img) {
@@ -450,6 +517,14 @@
   function createFrame() {
     var port;
 
+    if (g_currentDevice.id == 'wear' || g_currentDevice.id == 'wear_square' || g_currentDevice.id == 'wear_round') {
+      if ($('#output-square').is(':checked')) {
+        g_currentDevice = getDeviceById('wear_square');
+      } else {
+        g_currentDevice = getDeviceById('wear_round');
+      }
+    }
+
     var aspect1 = g_currentImage.naturalWidth / g_currentImage.naturalHeight;
     var aspect2 = g_currentDevice.portSize[0] / g_currentDevice.portSize[1];
 
@@ -458,11 +533,18 @@
     } else if (aspect1 == 1 / aspect2) {
       port = false;
     } else {
-      alert('The screenshot must have an aspect ratio of ' +
+      if (g_currentDevice.id == 'wear_square' || g_currentDevice.id == 'wear_round') {
+        alert('The screenshot must have an aspect ratio of ' +
+          aspect2.toFixed(3) +
+          ' (ideally ' + g_currentDevice.portSize[0] + 'x' + g_currentDevice.portSize[1] + ').');
+        $('#output').html(MSG_INVALID_WEAR_IMAGE);
+      }else {
+        alert('The screenshot must have an aspect ratio of ' +
           aspect2.toFixed(3) + ' or ' + (1 / aspect2).toFixed(3) +
           ' (ideally ' + g_currentDevice.portSize[0] + 'x' + g_currentDevice.portSize[1] +
           ' or ' + g_currentDevice.portSize[1] + 'x' + g_currentDevice.portSize[0] + ').');
-      $('#output').html(MSG_INVALID_INPUT_IMAGE);
+        $('#output').html(MSG_INVALID_INPUT_IMAGE);
+      }
       return;
     }
 
@@ -497,9 +579,37 @@
         ctx.drawImage(resourceImages['shadow'], 0, 0);
       }
       ctx.drawImage(resourceImages['back'], 0, 0);
-      ctx.fillStyle = '#000';
-      ctx.fillRect(offset[0], offset[1], size[0], size[1]);
-      ctx.drawImage(g_currentImage, offset[0], offset[1], size[0], size[1]);
+
+      if (g_currentDevice.id == 'wear_round') {
+        var scratchCanvas = document.createElement('canvas');
+        scratchCanvas.width = width;
+        scratchCanvas.height = height;
+        var scratchCtx = scratchCanvas.getContext('2d');
+
+
+        //drawing code
+        scratchCtx.clearRect(offset[0], offset[1], scratchCanvas.width, scratchCanvas.height);
+
+        scratchCtx.globalCompositeOperation = 'source-over'; //default
+
+        scratchCtx.drawImage(g_currentImage, offset[0], offset[1], size[0], size[1]);
+
+        scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity
+        scratchCtx.globalCompositeOperation = 'destination-in';
+        scratchCtx.beginPath();
+        scratchCtx.arc(288, 294, size[0] / 2, 0, 2 * Math.PI, false);
+        scratchCtx.closePath();
+        scratchCtx.fill();
+
+        // After tinkering with the offset, the 1 in the x-position drew the image
+        // perfectly
+        ctx.drawImage(scratchCanvas, 1, 0);
+      } else {
+        ctx.fillStyle = '#000';
+        ctx.fillRect(offset[0], offset[1], size[0], size[1]);
+        ctx.drawImage(g_currentImage, offset[0], offset[1], size[0], size[1]);
+      }
+
       if (resourceImages['fore'] && $('#output-glare').is(':checked')) {
         ctx.drawImage(resourceImages['fore'], 0, 0);
       }
@@ -546,7 +656,13 @@
               .attr('data-downloadurl', ['image/png', filename, imageUrl].join(':')))
           .appendTo($('#output').empty());
 
-      $('#frame-customizations').show();
+      if (g_currentDevice.id == 'wear' || g_currentDevice.id == 'wear_round' || g_currentDevice.id == 'wear_square') {
+        $('#wear-customizations').show();
+        $('#frame-customizations').hide();
+      } else {
+        $('#frame-customizations').show();
+        $('#wear-customizations').hide();
+      }
     }
   }
 
diff --git a/docs/html/google/gcm/adv.jd b/docs/html/google/gcm/adv.jd
deleted file mode 100644
index 95497e3..0000000
--- a/docs/html/google/gcm/adv.jd
+++ /dev/null
@@ -1,410 +0,0 @@
-page.title=GCM Advanced Topics
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>Quickview</h2>
-
-<ul>
-<li>Learn more about GCM advanced features.</li>
-</ul>
-
-
-<h2>In this document</h2>
-
-<ol>
-<li><a href="#lifetime">Lifetime of a Message</a></li>
-<li><a href="#throttling">Throttling</a></li>
-<li><a href="#reg-state">Keeping the Registration State in Sync</a>
-  <ol>
-    <li><a href="#canonical">Canonical IDs</a></li>
-  </ol>
-</li>
-<li><a href="#retry">Automatic Retry Using Exponential Back-Off</a></li>
-<li><a href="#unreg">Unregistration</a>
-  <ol>
-    <li><a href="#unreg-why">Why you should rarely unregister</a></li>
-    <li><a href="#unreg-how">How unregistration works</a></li>
-  </ol>
-</li>
-<li><a href="#collapsible">Send-to-Sync vs. Messages with Payload</a>
-  <ol>
-    <li><a href="#s2s">Send-to-sync messages</a></li>
-    <li><a href="#payload">Messages with payload</a></li>
-<li><a href="#which">Which should I use?</a></li>
-    </ol>
-</li>
-<li><a href="#ttl">Setting an Expiration Date for a Message</a> </li>
-<li><a href="#throttling"></a><a href="#multi-senders">Receiving Messages from
-Multiple Senders</a></li>
-</ol>
-
-</div>
-</div>
-<p>This document covers advanced topics for GCM.</p>
-
-
-
-
-<h2 id="msg-lifetime">Lifetime of a Message</h2>
-<p>When a 3rd-party server posts a message to GCM and receives a message ID back,
-it does not mean that the message was already delivered to the device. Rather, it
-means that it was accepted for delivery. What happens to the message after it is
-accepted depends on many factors.</p>
-
-<p>In the best-case scenario, if the device is connected to GCM, the screen is on,
-and there are no throttling restrictions (see <a href="#throttling">Throttling</a>),
-the message will be delivered right away.</p>
-
-<p>If the device is connected but idle, the message will still be
-delivered right away unless the <code>delay_while_idle</code> flag is set to true.
-Otherwise, it will be stored in the GCM servers until the device is awake. And
-that's where the <code>collapse_key</code> flag plays a role: if there is already
-a message with the same collapse key (and registration ID) stored and waiting for
-delivery, the old message will be discarded and the new message will take its place
-(that is, the old message will be collapsed by the new one). However, if the collapse
-key is not set, both the new and old messages are stored for future delivery.
-Collapsible messages are also called <a href="#s2s">send-to-sync messages</a>.</p>
-
-<p class="note"><strong>Note:</strong> There is a limit on how many messages can
-be stored without collapsing. That limit is currently 100. If the limit is reached,
-all stored messages are discarded. Then when the device is back online, it receives
-a special message indicating that the limit was reached. The application can then
-handle the situation properly, typically by requesting a full sync.
-<br><br>
-Likewise, there is a limit on how many <code>collapse_key</code>s you can have for
-a particular device. GCM allows a maximum of 4 different collapse keys to be used
-by the GCM server per device
-any given time. In other words, the GCM server can simultaneously store 4 different
-send-to-sync messages, each with a different collapse key. If you exceed this number
-GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.
-See <a href="#s2s">Send-to-sync messages</a> for more information.
-</p>
-
-<p>If the device is not connected to GCM, the message will be stored until a
-connection is established (again respecting the collapse key rules). When a connection
-is established, GCM will deliver all pending messages to the device, regardless of
-the <code>delay_while_idle</code> flag. If the device never gets connected again
-(for instance, if it was factory reset), the message will eventually time out and
-be discarded from GCM storage. The default timeout is 4 weeks, unless the
-<code>time_to_live</code> flag is set.</p>
-
-<p>Finally, when GCM attempts to deliver a message to the device and the
-application was uninstalled, GCM will discard that message right away and
-invalidate the registration ID. Future attempts to send a message to that device
-will get a <code>NotRegistered</code> error. See <a href="#unreg">
-How Unregistration Works</a> for more information.</p>
-<p>Although is not possible to track the status of each individual message, the
-Google Cloud Console stats are broken down by messages sent to device, messages
-collapsed, and messages waiting for delivery.</p>
-
-<h2 id="throttling">Throttling</h2>
-<p>To prevent abuse (such as sending a flood of messages to a device) and
-to optimize for the overall network efficiency and battery life of
-devices, GCM implements throttling of messages using a token bucket
-scheme. Messages are throttled on a per application and per <a href="#collapsible">collapse
-key</a> basis (including non-collapsible messages). Each application
-collapse key is granted some initial tokens, and new tokens are granted
-periodically therefter. Each token is valid for a single message sent to
-the device. If an application collapse key exhausts its supply of
-available tokens, new messages are buffered in a pending queue until
-new tokens become available at the time of the periodic grant. Thus
-throttling in between periodic grant intervals may add to the latency
-of message delivery for an application collapse key that sends a large
-number of messages within a short period of time. Messages in the pending
-queue of an application collapse key may be delivered before the time
-of the next periodic grant, if they are piggybacked with messages
-belonging to a non-throttled category by GCM for network and battery
-efficiency reasons.</p>
-
-<h2 id="reg-state">Keeping the Registration State in Sync</h2>
-<p>Whenever the application registers as described in
-<a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a>,
-it should save the registration ID for future use, pass it to the
-3rd-party server to complete the registration, and keep track of
-whether the server completed the registration. If the server fails
-to complete the registration, it should try again or unregister from GCM.</p>
-
-<p>There are also two other scenarios that require special care:</p>
-<ul>
-  <li>Application update</li>
-  <li>Backup and restore
-  </li>
-</ul>
-<p>When an application is updated, it should invalidate its existing registration
-ID, as it is not guaranteed to work with the new version.  Because there is no
-lifecycle method called when the application is updated, the best way to achieve
-this validation is by storing the current application version when a registration
-ID is stored. Then when the application is started, compare the stored value with
-the current application version. If they do not match, invalidate the stored data
-and start the registration process again.</p>
-
-<p>Similarly, you should not save the registration ID when an application is
-backed up. This is because the registration ID could become invalid by the time
-the application is restored, which would put the application in an invalid state
-(that is, the application thinks it is registered, but the server and GCM do not
-store that registration ID anymore&mdash;thus the application will not get more
-messages).</p>
-<h3 id="canonical">Canonical IDs</h3>
-<p>On the server side, as long as the application is behaving well, everything
-should work normally. However, if a bug in the application triggers multiple
-registrations for the same device, it can be hard to reconcile state and you might
-end up with duplicate messages.</p>
-<p>GCM provides a facility called &quot;canonical registration IDs&quot; to easily
-recover from these situations. A canonical registration ID is defined to be the ID
-of the last registration requested by your application. This is the ID that the
-server should use when sending messages to the device.</p>
-<p>If later on you try to send a message using a different registration ID, GCM
-will process the request as usual, but it will include the canonical registration
-ID in the <code>registration_id</code> field of the response. Make sure to replace
-the registration ID stored in your server with this canonical ID, as eventually
-the ID you're using will stop working.</p>
-
-<h2 id="retry">Automatic Retry Using Exponential Back-Off</h2>
-
-<p>When registration or unregistration fails, the app should retry the failed operation.</p>
-<p>In the simplest case, if your application attempts to register and GCM is not a
-fundamental part of the application, the application could simply ignore the error
-and try to register again the next time it starts. Otherwise, it should retry the
-previous operation using exponential back-off. In exponential back-off, each time
-there is a failure, it should wait twice the previous amount of time before trying
-again. If the register (or unregister) operation was synchronous, it could be retried
-in a simple loop. However, since it is asynchronous, the best approach is to schedule
-a {@link android.app.PendingIntent} to retry the operation.
-
-<h2 id="unreg">Unregistration</h2>
-
-<p>This section explains when you should unregister in GCM and what happens
-when you do.</p>
-
-<h3 id="unreg-why">Why you should rarely unregister</h3>
-
-<p>A registration ID (regID) represents a particular Android application running
-on a particular device. You should only need to unregister in rare cases, such as
-if you want an app to stop receiving messages, or if you suspect that the regID has
-been compromised. In general, though, once an app has a regID, you shouldn't need
-to change it.</p>
-
-<p>In particular, you should never unregister your app as a mechanism for
-logout or for switching between users, for the following reasons:</p>
-
-<ul>
-  <li>A regID maps an app to a device. It isn't associated with a particular
-  logged in user. If you unregister and then re-register, GCM may return the same
-  ID or a different ID&mdash;there's no guarantee either way.</li>
-
-  <li>Unregistration may take up to 5 minutes to propagate.</li>
-  <li>After unregistration, re-registration may again take up to 5 minutes to
-propagate. During this time messages may be rejected due to the state of being
-unregistered, and after all this, messages may still go to the wrong user.</li>
-</ul>
-
-
-<p>The solution is to manage your own mapping between users, the regID, and
-individual messages:</p>
-
-<ul>
-  <li>Your app server should maintain a mapping between the current user
-and the regID. This should include information about which user is supposed to
-receive a particular message.</li>
-  <li>The app running on the device should check to ensure that messages it
-receives match the logged in user.</li>
-</ul>
-
-
-<h3 id="unreg-how">How unregistration works</h3>
-
-<p>An application can be automatically unregistered after it is uninstalled from
-the device. However, this process does not happens right away, as Android does not
-provide an uninstall callback. What happens in this scenario is as follows:</p>
-<ol>
-  <li>The end user uninstalls the application.</li>
-  <li>The 3rd-party server sends a message to GCM server.</li>
-  <li>The GCM server sends the message to the device.</li>
-  <li>The GCM client receives the message and queries Package Manager about
-whether there are broadcast receivers configured to receive it, which returns
-<code>false</code>.
-</li>
-  <li>The GCM client informs the GCM server that the application was uninstalled.</li>
-  <li>The GCM server marks the registration ID for deletion.</li>
-  <li>The 3rd-party server sends a message to  GCM.</li>
-  <li>The GCM returns a <code>NotRegistered</code> error message to the 3rd-party server.</li>
-  <li>The 3rd-party deletes the registration ID.
-  </li>
-</ol>
-
-<p class ="note"><strong>Note:</strong> The GCM client is the Google Cloud
-Messaging framework present on the device.</p>
-
-<p>Note that it might take a while for the registration ID be completely removed
-from GCM. Thus it is possible that messages sent during step 7 above gets a valid
-message ID as response, even though the message will not be delivered to the device.
-Eventually, the registration ID will be removed and the server will get a
-<code>NotRegistered</code> error, without any further action being required from
-the 3rd-party server (this scenario happens frequently while an application is
-being developed and tested).</p>
-
-<h2 id="collapsible">Send-to-Sync  vs. Messages with Payload</h2>
-
-<p>Every message sent in GCM has the following characteristics:</p>
-<ul>
-  <li>It has a payload limit of 4096 bytes.</li>
-  <li>By default, it is stored by GCM for 4 weeks.</li>
-</ul>
-
-<p>But despite these similarities, messages can behave very differently depending
-on their particular settings. One major distinction between messages is whether
-they are collapsed (where each new message replaces the preceding message) or not
-collapsed (where each individual message is delivered). Every message sent in GCM
-is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with
-payload&quot; (non-collapsible message). These concepts are described in more
-detail in the following sections.</p>
-
-<h3 id="s2s">Send-to-sync messages</h3>
-
-<p>A send-to-sync (collapsible) message is often a &quot;tickle&quot; that tells
-a mobile application to sync data from the server. For example, suppose you have
-an email application. When a user receives new email on the server, the server
-pings the mobile application with a &quot;New mail&quot; message. This tells the
-application to sync to the server to pick up the new email. The server might send
-this message multiple times as new mail continues to accumulate, before the application
-has had a chance to sync. But if the user has received 25 new emails, there's no
-need to preserve every &quot;New mail&quot; message. One is sufficient. Another
-example would be a sports application that updates users with the latest score.
-Only the most recent message is relevant, so it makes sense to have each new
-message replace the preceding message. </p>
-
-<p>The email and sports applications are cases where you would probably use the
-GCM <code>collapse_key</code> parameter. A <em>collapse key</em> is an arbitrary
-string that is used to collapse a group of like messages when the device is offline,
-so that only the most recent message gets sent to the client. For example,
-&quot;New mail,&quot; &quot;Updates available,&quot; and so on</p>
-<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server
-at any given time. In other words, the GCM server can simultaneously store 4
-different send-to-sync messages per device, each with a different collapse key.
-For example, Device A can have A1, A2, A3, and A4. Device B can have B1, B2, B3,
-and B4, and so on. If you exceed this number GCM will only keep 4 collapse keys, with no
-guarantees about which ones they will be.</p>
-
-<h3 id="payload">Messages with payload</h3>
-
-<p>Unlike a send-to-sync message, every &quot;message with payload&quot;
-(non-collapsible message) is delivered. The payload the message contains can be
-up to 4kb. For example, here is a JSON-formatted message in an IM application in
-which spectators are discussing a sporting event:</p>
-
-<pre class="prettyprint pretty-json">{
-  "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
-  "data" : {
-    "Nick" : "Mario",
-    "Text" : "great match!",
-    "Room" : "PortugalVSDenmark",
-  },
-}</pre>
-
-<p>A &quot;message with payload&quot; is not simply a &quot;ping&quot; to the
-mobile application to contact the server to fetch data. In the aforementioned IM
-application, for example, you would want to deliver every message, because every
-message has different content. To specify a non-collapsible message, you simply
-omit the <code>collapse_key</code> parameter. Thus GCM will send each message
-individually. Note that the order of delivery is not guaranteed.</p>
-
-<p>GCM will store up to 100 non-collapsible messages. After that, all messages
-are discarded from GCM, and a new message is created that tells the client how
-far behind it is. The message is delivered through a regular
-<code>com.google.android.c2dm.intent.RECEIVE</code> intent with the
-extra <code>message_type</code>, for which the value is always the string
-&quot;deleted_messages&quot;.</p>
-
-<p>The application should respond by syncing with the server to recover the
-discarded messages. </p>
-
-<h3 id="which">Which should I use?</h3>
-  <p>If your application does not need to use non-collapsible messages, collapsible
-messages are a better choice from a performance standpoint, because they put less
-of a burden on the device battery. However, if you use collapsible messages, remember that
-<strong>GCM only allows a maximum of 4 different collapse keys to be used by the GCM server
-per device at any given time</strong>. You must not exceed this number, or it could cause
-unpredictable consequences.</p>
-
-<h2 dir="ltr" id="ttl">Setting an Expiration Date for a Message</h2>
-<p>The Time to Live (TTL) feature lets  the sender  specify the maximum lifespan
-of a message using the <code>time_to_live</code> parameter in the send request.
-The value of this parameter must be a duration from 0 to 2,419,200 seconds, and
-it corresponds to the maximum period of time for which GCM will store and try to
-deliver the message. Requests that don't contain this field default to the maximum
-period of 4 weeks.</p>
-<p>Here are some possible uses for this feature:</p>
-<ul>
-  <li>Video chat incoming calls</li>
-  <li>Expiring invitation events</li>
-  <li>Calendar events</li>
-</ul>
-<h3 id="bg">Background </h3>
-<p>GCM will usually deliver messages immediately after they are sent. However,
-this might not always be possible. For example, the device could be turned off,
-offline, or otherwise unavailable. In other cases, the sender itself might request
-that messages not be delivered until the device becomes active by using the
-<code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages
-to prevent an application from consuming excessive resources and negatively
-impacting battery life.</p>
-
-<p>When this happens, GCM will store the message and deliver it as soon as it's
-feasible. While this is fine in most cases, there are some applications for which
-a late message might as well never be delivered. For example, if the message is
-an incoming call or video chat notification, it will only be meaningful for a
-small period of time before the call is terminated. Or if the message is an
-invitation to an event, it will be useless if received after the event has ended.</p>
-
-<p>Another advantage of specifying the expiration date for a message is that GCM
-will never throttle messages with a <code>time_to_live</code> value of 0 seconds.
-In other words, GCM will guarantee best effort for messages that must be delivered
-&quot;now or never.&quot; Keep in mind that a <code>time_to_live</code> value of
-0 means messages that can't be delivered immediately will be discarded. However,
-because such messages are never stored, this provides the best latency for
-sending notifications.</p>
-
-<p>Here is an example of a JSON-formatted request that includes TTL:</p>
-<pre class="prettyprint pretty-json">
-{
-  "collapse_key" : "demo",
-  "delay_while_idle" : true,
-  "registration_ids" : ["xyz"],
-  "data" : {
-    "key1" : "value1",
-    "key2" : "value2",
-  },
-  "time_to_live" : 3
-},
-</pre>
-
-
-<h2 id="multi-senders">Receiving Messages from Multiple Senders</h2>
-
-<p>GCM allows multiple parties to send messages to the same application. For
-example, suppose your application is an articles aggregator with multiple
-contributors, and you want each of them to be able to send a message when they
-publish a new article. This message might contain a URL so that the application
-can download the article. Instead of having to centralize all sending activity in
-one location, GCM gives you the ability to let each of these contributors send
-its own messages.</p>
-
-<p>To make this possible, all you need to do is have each sender generate its own
-project number. Then include those IDs in the sender field, separated by commas,
-when requesting a registration. Finally, share the registration ID with your
-partners, and they'll be able to send messages to your application using their
-own authentication keys.</p>
-<p>This code snippet illustrates this feature. Senders are passed as an intent
-extra in a comma-separated list:</p>
-
-<pre class="prettyprint pretty-java">Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION);
-intent.setPackage(GSF_PACKAGE);
-intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
-        PendingIntent.getBroadcast(context, 0, new Intent(), 0));
-String senderIds = &quot;968350041068,652183961211&quot;;
-intent.putExtra(GCMConstants.EXTRA_SENDER, senderIds);
-ontext.startService(intent);
- </pre>
-
-<p>Note that there is limit of 100 multiple senders.</p>
diff --git a/docs/html/google/gcm/c2dm.jd b/docs/html/google/gcm/c2dm.jd
index 5c4a86e..fc95c2b 100644
--- a/docs/html/google/gcm/c2dm.jd
+++ b/docs/html/google/gcm/c2dm.jd
@@ -79,7 +79,7 @@
 
 <h3 id="interop">Relationship between C2DM and GCM</h3>
 
-<p>C2DM and GCM are not interoperable. For example, you cannot post notifications from GCM to C2DM registration IDs, nor can you use C2DM registration IDs as GCM registration IDs. From your server-side application, you must keep keep track of whether a registration ID is from C2DM or GCM and use the proper endpoint. </p>
+<p>C2DM and GCM are not interoperable. For example, you cannot post notifications from GCM to C2DM registration IDs, nor can you use C2DM registration IDs as GCM registration IDs. From your server-side application, you must keep track of whether a registration ID is from C2DM or GCM and use the proper endpoint. </p>
 
 <p>As you transition from C2DM to GCM, your server needs to be aware of whether a given registration ID
 contains an old C2DM sender or a new GCM project number. This is the approach we recommend: have the new app version (the one that uses GCM) send a bit along with the registration ID. This bit tells your server that this registration ID is for GCM. If you don't get the extra bit, you mark the registration ID as C2DM. Once no more valid registration IDs are marked as C2DM, you can complete the migration.</p>
@@ -87,13 +87,11 @@
 <h2 id="migrating">Migrating Your Apps</h2>
 <p>This section describes how to move existing C2DM apps to GCM.</p>
 <h3 id="client">Client changes</h3>
-<p>Migration is simple! The only change required in the application is replacing the email account passed in the sender parameter of the registration intent with the project number generated when signing up for the new service. For example:</p>
-<pre class="prettyprint pretty-java">Intent registrationIntent = new Intent(&quot;com.google.android.c2dm.intent.REGISTER&quot;);
-// sets the app name in the intent
-registrationIntent.putExtra(&quot;app&quot;, PendingIntent.getBroadcast(this, 0, new Intent(), 0));
-registrationIntent.putExtra(&quot;sender&quot;, senderID);
-startService(registrationIntent);</pre>
+<p>Migration is simple! Just re-register the client app for your target GCM-enabled platform. For
+  example, see <a href="{@docRoot}google/gcm/client.html#sample-register">Register for GCM</a></p>
+
 <p>After receiving a response from GCM, the registration ID obtained must be sent to the application server. When doing this, the application should indicate that it is sending a GCM registration ID so that the server can distinguish it from existing C2DM registrations.</p>
+
 <h3 id="server">Server changes</h3>
 <p>When the application server receives a GCM registration ID, it should store it and mark it as such.</p>
 <p>Sending messages to GCM devices requires a few changes:</p>
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
index 6332b8d..143b057 100644
--- a/docs/html/google/gcm/ccs.jd
+++ b/docs/html/google/gcm/ccs.jd
@@ -36,6 +36,7 @@
 <h2>See Also</h2>
 
 <ol class="toc">
+<li><a href="server-ref.html">Server Reference</a></li>
 <li><a href="{@docRoot}google/gcm/http.html">HTTP</a></li>
 <li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li>
 <li><a href="{@docRoot}google/gcm/server.html">Implementing GCM Server</a></li>
@@ -73,8 +74,8 @@
 APIs. For examples, see
 <a href="#implement">Implementing an XMPP-based App Server</a>.</p>
 
-<p class="note"><strong>Note:</strong> See
-<a href="server.html#params">Implementing GCM Server</a> for a list of all the message
+<p class="note"><strong>Note:</strong> See the
+<a href="server-ref.html">Server Reference</a> for a list of all the message
 parameters and which connection server(s) supports them.</p>
 
 <h2 id="connecting">Establishing a Connection</h2>
@@ -176,8 +177,8 @@
 <a href="#flow">Flow Control</a> for details.
 </p>
 
-<p class="note"><strong>Note:</strong> See
-<a href="server.html#params">Implementing GCM Server</a> for a list of all the message
+<p class="note"><strong>Note:</strong> See the
+<a href="server-ref.html">Server Reference</a> for a list of all the message
 parameters and which connection server(s) supports them.</p>
 
 <h3 id="request">Request format</h3>
@@ -278,56 +279,11 @@
 &lt;/message&gt;
 </pre>
 
-<p>The following table lists NACK error codes. Unless otherwise
+<p>See the <a href="server-ref.html#table11">Server Reference</a> for a complete list of the
+NACK error codes. Unless otherwise
 indicated, a NACKed message should not be retried. Unexpected NACK error codes
 should be treated the same as {@code INTERNAL_SERVER_ERROR}.</p>
 
-<p class="table-caption" id="table1">
-  <strong>Table 1.</strong> NACK error codes.</p>
-
-<table border="1">
-<tr>
-<th>Error Code</th>
-<th>Description</th>
-</tr>
-<tr>
-<td>{@code BAD_ACK}</td>
-<td>The ACK message is improperly formed.</td>
-</tr>
-<tr>
-<td>{@code BAD_REGISTRATION}</td>
-<td>The device has a registration ID, but it's invalid or expired.</td>
-</tr>
-<tr>
-<td>{@code CONNECTION_DRAINING}</td>
-<td>The message couldn't be processed because the connection is draining. The
-message should be immediately retried over another connection.</td>
-</tr>
-<tr>
-<td>{@code DEVICE_UNREGISTERED}</td>
-<td>The device is not registered.</td>
-</tr>
-<tr>
-<td>{@code INTERNAL_SERVER_ERROR}</td>
-<td>The server encountered an error while trying to process the request.</td>
-</tr>
-<tr>
-<td>{@code INVALID_JSON}</td>
-<td>The JSON message payload is not valid.</td>
-</tr>
-<td>{@code DEVICE_MESSAGE_RATE_EXCEEDED}</td>
-<td>The rate of messages to a particular device is too high. You should reduce
-the number of messages sent to this device and should not immediately retry
-sending to this device. This error code is replacing {@code QUOTA_EXCEEDED}.</td>
-</tr>
-<tr>
-  <td>{@code SERVICE_UNAVAILABLE}</td>
-  <td>CCS is not currently able to process the message. The
-    message should be retried over the same connection using exponential backoff
-    with an initial delay of 1 second.</td>
-</tr>
-</table>
-
 <h4 id="stanza">Stanza error</h4>
 
 <p>You can also get a stanza error in certain cases.
diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd
index d44ee3c..9cb3f84 100644
--- a/docs/html/google/gcm/client.jd
+++ b/docs/html/google/gcm/client.jd
@@ -1,4 +1,4 @@
-page.title=Implementing GCM Client
+page.title=Implementing GCM Client on Android
 page.tags=cloud,push,messaging
 @jd:body
 
@@ -15,8 +15,8 @@
   <ol class="toc">
     <li><a href="#sample-play">Check for Google Play Services APK</a></li>
     <li><a href="#sample-register">Register for GCM</a></li>
-    <li><a href="#sample-send">Send a message</a></li>
-    <li><a href="#sample-receive">Receive a message</a></li>
+    <li><a href="#sample-receive">Receive a downstream message</a></li>
+    <li><a href="#sample-send">Send an upstream message</a></li>
   </ol>
   <li><a href="#run">Running the Sample</a></li>
   <li><a href="#stats">Viewing Statistics</a></li>
@@ -34,14 +34,26 @@
 </div>
 </div>
 
-<p>A Google Cloud Messaging (GCM) client is a GCM-enabled app that runs on an
+<p>A Google Cloud Messaging (GCM) Android client is a GCM-enabled app that runs on an
 Android device. To write your client code, we recommend that you use the
 <a href="{@docRoot}reference/com/google/android/gms/gcm/package-summary.html">
-GCM APIs</a>.
-The client helper library that was offered in previous versions of GCM still works,
-but it has been superseded by the more efficient
-<a href="{@docRoot}reference/com/google/android/gms/gcm/package-summary.html">
-GCM APIs</a>.</p>
+{@code GoogleCloudMessaging}</a> API.</p>
+
+<p>Here are the requirements for running a GCM Android client:</p>
+
+<ul>
+  <li>At a bare minimum, GCM requires devices running Android 2.2 or higher that also have the
+Google Play Store application installed, or an emulator running Android 2.2
+with Google APIs. Note that you are not limited to deploying your
+Android applications through Google Play Store.</li>
+  <li>However, if you want to continue to use new GCM features that are distributed
+through Google Play Services, the device must be running Android 2.3 or higher, or
+you can use an emulator running Android 2.3 with Google APIs.</li>
+<li>On Android devices, GCM uses an existing connection for Google services. For
+pre-3.0 devices, this requires users to set up their Google accounts on their mobile
+devices. A Google account is not a requirement on devices running Android 4.0.4 or higher.</li>
+
+</ul>
 
 <p>A full GCM implementation requires both a client implementation and a server
 implementation. For more
@@ -58,7 +70,7 @@
 
 <p>To write your client application, use the
 <a href="{@docRoot}reference/com/google/android/gms/gcm/package-summary.html">
-GCM APIs</a>.
+{@code GoogleCloudMessaging}</a> API.
 To use this API, you must set up your project to use the Google Play services SDK,
 as described in <a href="/google/play-services/setup.html">Setup Google Play
 Services SDK</a>.</p>
@@ -88,9 +100,6 @@
 the Android application can register and receive messages.</li>
   <li>The <code>android.permission.INTERNET</code> permission so the Android
 application can send the registration ID to the 3rd party server.</li>
-  <li>The <code>android.permission.GET_ACCOUNTS</code> permission as GCM requires
-a Google account (necessary only if if the device is running a version lower than
-Android 4.0.4)</li>
   <li>The <code>android.permission.WAKE_LOCK</code> permission so the application
 can keep the processor from sleeping when a message is received. Optional&mdash;use
 only if the app wants to keep the device from sleeping.</li>
@@ -101,7 +110,7 @@
    <li>A receiver for <code>com.google.android.c2dm.intent.RECEIVE</code>, with
 the category set
 as <code>applicationPackage</code>. The receiver should require the
-<code>com.google.android.c2dm.SEND</code> permission, so that only the GCM
+<code>com.google.android.c2dm.permission.SEND</code> permission, so that only the GCM
 Framework can send a message to it. If your app uses an {@link android.app.IntentService}
 (not required, but a common pattern), this receiver should be an instance of
 {@link android.support.v4.content.WakefulBroadcastReceiver}.
@@ -324,8 +333,8 @@
         return "";
     }
     // Check if app was updated; if so, it must clear the registration ID
-    // since the existing regID is not guaranteed to work with the new
-    // app version.
+    // since the existing registration ID is not guaranteed to work with
+    // the new app version.
     int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
     int currentVersion = getAppVersion(context);
     if (registeredVersion != currentVersion) {
@@ -340,14 +349,14 @@
  */
 private SharedPreferences getGCMPreferences(Context context) {
     // This sample app persists the registration ID in shared preferences, but
-    // how you store the regID in your app is up to you.
+    // how you store the registration ID in your app is up to you.
     return getSharedPreferences(DemoActivity.class.getSimpleName(),
             Context.MODE_PRIVATE);
 }</pre>
 
 <p>If the registration ID doesn't exist or the app was updated,
 {@code getRegistrationId()} returns an empty string
-to indicate that the app needs to get a new regID. {@code getRegistrationId()} calls
+to indicate that the app needs to get a new registration ID. {@code getRegistrationId()} calls
 the following method to check the app version:</p>
 
 <pre>/**
@@ -400,7 +409,7 @@
                 // will send upstream messages to a server that echo back the
                 // message using the 'from' address in the message.
 
-                // Persist the regID - no need to register again.
+                // Persist the registration ID - no need to register again.
                 storeRegistrationId(context, regid);
             } catch (IOException ex) {
                 msg = "Error :" + ex.getMessage();
@@ -433,7 +442,8 @@
 
 <p>After registering, the app calls {@code storeRegistrationId()} to store the
 registration ID in shared preferences for future use. This is just one way of
-persisting a regID. You might choose to use a different approach in your app:</p>
+persisting a registration ID. You might choose to use a different approach in
+your app:</p>
 
 <pre>/**
  * Stores the registration ID and app versionCode in the application's
@@ -455,64 +465,22 @@
 <h4 id="reg-errors">Handle registration errors</h4>
 
 <p>As stated above, an Android app must register with GCM servers and get a registration ID
-(regID) before it can receive messages. A given regID is not guaranteed to last indefinitely,
-so the first thing your app should always do is check to make sure it has a valid regID
-(as shown in the code snippets above).</p>
+before it can receive messages. A given registration ID is not guaranteed to last indefinitely,
+so the first thing your app should always do is check to make sure it has a valid
+registration ID (as shown in the code snippets above).</p>
 
-<p>In addition to confirming that it has a valid regID, your app should be prepared to handle
+<p>In addition to confirming that it has a valid registration ID, your app should be prepared to handle
 the registration error {@code TOO_MANY_REGISTRATIONS}. This error indicates that the device
 has too many apps registered with GCM. The error only occurs in cases where there are
 extreme numbers of apps, so it should not affect the average user. The remedy is to prompt
-the user to delete some of the other GCM-enabled apps from the device to make
+the user to delete some of the other client apps from the device to make
 room for the new one.</p>
 
-
-<h3 id="sample-send">Send a message</h3>
-<p>When the user clicks the app's <strong>Send</strong> button, the app sends an
-upstream message using the
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
-{@code GoogleCloudMessaging}</a> API. In order to receive the upstream message,
-your server should be connected to CCS. You can use one of the demo servers in
-<a href="ccs.html#implement">Implementing an XMPP-based App Server</a> to run the sample and connect
-to CCS.</p>
-
-<pre>public void onClick(final View view) {
-    if (view == findViewById(R.id.send)) {
-        new AsyncTask<Void, Void, String>() {
-            &#64;Override
-            protected String doInBackground(Void... params) {
-                String msg = "";
-                try {
-                    Bundle data = new Bundle();
-                        data.putString("my_message", "Hello World");
-                        data.putString("my_action",
-                                "com.google.android.gcm.demo.app.ECHO_NOW");
-                        String id = Integer.toString(msgId.incrementAndGet());
-                        gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
-                        msg = "Sent message";
-                } catch (IOException ex) {
-                    msg = "Error :" + ex.getMessage();
-                }
-                return msg;
-            }
-
-            &#64;Override
-            protected void onPostExecute(String msg) {
-                mDisplay.append(msg + "\n");
-            }
-        }.execute(null, null, null);
-    } else if (view == findViewById(R.id.clear)) {
-        mDisplay.setText("");
-    }
-}</pre>
-
-<h3 id="sample-receive">Receive a message</h3>
+<h3 id="sample-receive">Receive a downstream message</h3>
 
 <p>As described above in <a href="#manifest">Step 2</a>, the app includes a
 {@link android.support.v4.content.WakefulBroadcastReceiver} for the <code>com.google.android.c2dm.intent.RECEIVE</code>
-intent. A broadcast receiver is the mechanism GCM uses to deliver messages. When {@code onClick()}
-calls {@code gcm.send()}, it triggers the broadcast receiver's {@code onReceive()}
-method, which has the responsibility of making sure that the GCM message gets handled.</p>
+intent. A broadcast receiver is the mechanism GCM uses to deliver messages. </p>
 <p>A {@link android.support.v4.content.WakefulBroadcastReceiver} is a special type of
 broadcast receiver that takes care of
 creating and managing a
@@ -646,6 +614,46 @@
     }
 }</pre>
 
+
+<h3 id="sample-send">Send an upstream message</h3>
+<p>When the user clicks the app's <strong>Send</strong> button, the app sends an
+upstream message using the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> API. In order to receive the upstream message,
+your server should be connected to CCS. You can use one of the demo servers in
+<a href="ccs.html#implement">Implementing an XMPP-based App Server</a> to run the sample and connect
+to CCS.</p>
+
+<pre>public void onClick(final View view) {
+    if (view == findViewById(R.id.send)) {
+        new AsyncTask<Void, Void, String>() {
+            &#64;Override
+            protected String doInBackground(Void... params) {
+                String msg = "";
+                try {
+                    Bundle data = new Bundle();
+                        data.putString("my_message", "Hello World");
+                        data.putString("my_action",
+                                "com.google.android.gcm.demo.app.ECHO_NOW");
+                        String id = Integer.toString(msgId.incrementAndGet());
+                        gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
+                        msg = "Sent message";
+                } catch (IOException ex) {
+                    msg = "Error :" + ex.getMessage();
+                }
+                return msg;
+            }
+
+            &#64;Override
+            protected void onPostExecute(String msg) {
+                mDisplay.append(msg + "\n");
+            }
+        }.execute(null, null, null);
+    } else if (view == findViewById(R.id.clear)) {
+        mDisplay.setText("");
+    }
+}</pre>
+
 <h2 id="run">Running the Sample</h2>
 
 <p>To run the sample:</p>
diff --git a/docs/html/google/gcm/gcm.jd b/docs/html/google/gcm/gcm.jd
index 3d6594d..4e345b3 100644
--- a/docs/html/google/gcm/gcm.jd
+++ b/docs/html/google/gcm/gcm.jd
@@ -9,58 +9,24 @@
 <ol class="toc">
   <li><a href="#key">Key Concepts</a></li>
   <li><a href="#arch">Architectural Overview</a></li>
-  <li><a href="#lifecycle">Lifecycle Flow</a>
-    <ol class="toc">
-      <li><a href="#register">Enable GCM</a></li>
-      <li><a href="#push-process">Send a message</a></li>
-      <li><a href="#receiving">Receive a message</a></li>
-    </ol>
-  </li>
+  <li><a href="#lifecycle">Lifecycle Flow</a></li>
+  <li><a href="#reg">Register to enable GCM</a></li>
 </ol>
 
 </div>
 </div>
 
-<p>Google Cloud Messaging (GCM) for Android is a free service that helps
-developers  send data from servers to their Android applications on  Android
-devices, and upstream messages from the user's device back to the cloud.
-This could be a lightweight message telling the Android application
+<p>Google Cloud Messaging (GCM) is a free service that enables developers
+to send downstream messages (from servers to GCM-enabled client apps), and
+upstream messages (from the GCM-enabled client apps to servers).
+This could be a lightweight message telling the client app
 that there is new data to be fetched from the server (for instance, a "new email"
-notification informing the application that it is out of sync with the back end),
+notification informing the app that it is out of sync with the back end),
 or it could be a message containing up to 4kb of payload
 data (so apps like instant messaging can consume the message directly). The GCM
-service handles all aspects  of queueing of messages and delivery to the target
-Android application running  on the target device.</p>
-  
-<p class="note"> To jump right into using GCM with your Android
-  applications, see <a href="gs.html">Getting Started</a>.</p>
+service handles all aspects of queueing of messages and delivery to and from
+the target client app.</p>
 
-<p>Here are the primary characteristics of Google Cloud 
-Messaging (GCM):</p>
-
-<ul>
-  <li>It allows 3rd-party application servers to send messages to
-their Android applications.</li>
-  <li>Using the <a href="ccs.html">GCM Cloud Connection Server</a>, you can receive
-upstream messages from the user's device.</li>
-  <li>An Android application on an Android device doesn't need to be running to receive
-messages. The system will wake up the Android application via Intent broadcast
-when the  message arrives, as long as the application is set up with the proper
-broadcast receiver and permissions.</li>
-  <li>It does not provide any  built-in user interface or other handling for
-message data. GCM  simply passes raw message data received straight to the
-Android application,  which has full control of how to handle it. For example, the
-application might post a notification, display a custom user interface, or 
-silently sync data.</li>
-  <li>It requires devices running Android 2.2 or higher that also have the
-Google Play Store application installed, or or an emulator running Android 2.2
-with Google APIs. However, you are not limited to deploying your
-Android applications through Google Play Store.</li>
-  <li>It uses an existing connection for Google services. For pre-3.0 devices,
-this requires users to
-set up their Google account on their mobile devices. A Google account is not a
-requirement on devices running Android 4.0.4 or higher.</li>
-</ul>
 
 <h2 id="key">Key Concepts</h2>
 
@@ -70,7 +36,7 @@
   <li><strong>Components</strong> &mdash; The entities that play a primary role in
 GCM.</li>
   <li><strong>Credentials</strong> &mdash; The IDs and tokens that are used in
-different stages of GCM to ensure that all parties have been authenticated, and
+GCM to ensure that all parties have been authenticated, and
 that the message is going to the correct place.</li>
 </ul>
 
@@ -81,24 +47,20 @@
   <tr>
     <th colspan="2">Components</th>
   </tr>
-  <tr>
-    <td width="165"><strong>Client App</strong></td>
-    <td width="1176">The GCM-enabled Android application that is running on a
-    device. This must be a 2.2 Android device that has Google Play Store installed, and it must
-have at least one logged in Google account if the device is running a version
-lower than Android 4.0.4. Alternatively, for testing you can use an emulator
-running Android 2.2 with Google APIs.</td>
-  </tr>
-  <tr>
-    <td><strong>3rd-party Application Server</strong></td>
-    <td>An application server that you write as part of implementing
-GCM. The 3rd-party application server sends data to an
-Android application on the device via the GCM connection server.</td>
-  </tr>
-  <tr>
+<tr>
     <td><strong>GCM Connection Servers</strong></td>
-    <td>The Google-provided servers involved in taking messages from the 3rd-party
-application server and sending them to the device. </td>
+    <td>The Google-provided servers involved in sending messages between the
+3rd-party app server and the client app.</td>
+  </tr>
+  <tr>
+    <td><strong>Client App</strong></td>
+    <td>A GCM-enabled client app that communicates with a 3rd-party app server.</td>
+  </tr>
+  <tr>
+    <td><strong>3rd-party App Server</strong></td>
+    <td>An app server that you write as part of implementing
+GCM. The 3rd-party app server sends data to a client app via
+the GCM connection server.</td>
   </tr>
   <tr>
     <th colspan="2">Credentials</th>
@@ -108,42 +70,28 @@
     <td>A project number you acquire from the API console, as described in
 <a href="gs.html#create-proj">Getting Started</a>. The sender
 ID is used in the <a href="#register">registration process</a> to identify a
-3rd-party application server that is permitted to send messages to the device.</td>
-  </tr>
-  <tr>
-    <td><strong>Application ID</strong></td>
-    <td>The Android application that is registering to receive messages. The Android application
-is identified by the package name from the <a href="client.html#manifest">manifest</a>.
-This  ensures that the messages are targeted to the correct Android application.</td>
-  </tr>
-  <tr>
-    <td><strong>Registration ID</strong></td>
-    <td>An ID issued by the GCM servers to the Android application that allows
-it to receive messages. Once the Android application has the registration ID, it sends
-it to the 3rd-party application server, which uses it to identify each device 
-that has registered to receive messages for a given Android application. In other words,
-a registration ID is tied to a particular Android application running on a particular
-device. Note that registration IDs must be kept secret.
-<br/>
-<br/>
-<strong>Note:</strong> If you use 
-<a href="https://developer.android.com/google/backup/index.html">backup and restore</a>,
-you should explicitly avoid backing up registration IDs. When you back up
-a device, apps back up shared prefs indiscriminately. If you don't explicitly
-exclude the GCM registration ID, it could get reused on a new device,
-which would cause delivery errors.
-</td>
-  </tr>
-  <tr>
-    <td><strong>Google User Account</strong></td>
-    <td>For GCM to work, the mobile device must include at least one Google
-account if the device is running a version lower than Android 4.0.4.</td>
+3rd-party app server that is permitted to send messages to the client app.</td>
   </tr>
   <tr>
     <td id="apikey"><strong>Sender Auth Token</strong></td>
-    <td>An API key that is saved on the 3rd-party application
-server that gives the application server authorized access to Google services.
-The API key is included in the header of POST requests  that send messages.</td>
+    <td>An API key that is saved on the 3rd-party app
+server that gives the app server authorized access to Google services.
+The API key is included in the header of POST requests.
+</td>
+  </tr>
+  <tr>
+    <td><strong>Application ID</strong></td>
+    <td>The client app that is registering to receive messages. How this is implemented
+is platform-dependent. For example, an Android app
+is identified by the package name from the <a href="client.html#manifest">manifest</a>.
+This  ensures that the messages are targeted to the correct Android app.</td>
+  </tr>
+  <tr>
+    <td><strong>Registration ID</strong></td>
+    <td>An ID issued by the GCM servers to the client app that allows
+it to receive messages. Note that registration IDs must be kept secret.
+
+</td>
   </tr>
 
 </table>
@@ -152,7 +100,8 @@
 
 <p>A GCM implementation includes a Google-provided
 connection server, a 3rd-party app server that interacts with the connection
-server, and a GCM-enabled client app running on an Android device:</p>
+server, and a GCM-enabled client app. For example, this diagram shows GCM
+communicating with a client app on an Android device:</p>
 
 <img src="{@docRoot}images/gcm/GCM-arch.png">
 
@@ -163,84 +112,196 @@
 <p>This is how these components interact:</p>
 <ul>
   <li>Google-provided <strong>GCM Connection Servers</strong> take messages from
-a 3rd-party application server and send these messages to a
-GCM-enabled Android application (the &quot;client app&quot;) running on a device.
+a 3rd-party app server and send these messages to a
+GCM-enabled client app (the &quot;client app&quot;).
 Currently Google provides connection servers for <a href="http.html">HTTP</a>
 and <a href="ccs.html">XMPP</a>.</li>
-  <li>The <strong>3rd-Party Application Server</strong> is a component that you
+  <li>The <strong>3rd-Party App Server</strong> is a component that you
 implement to work with your chosen GCM connection server(s). App servers send
 messages to a GCM connection server; the connection server enqueues and stores the
-message, and then sends it to the device when the device is online.
+message, and then sends it to the client app.
 For more information, see <a href="server.html">Implementing GCM Server</a>.</li>
-  <li>The <strong>Client App</strong> is a GCM-enabled Android application running
-on a device. To receive GCM messages, this app must register with GCM and get a
+  <li>The <strong>Client App</strong> is a GCM-enabled client app.
+To receive GCM messages, this app must register with GCM and get a
 registration ID. If you are using the <a href="ccs.html">XMPP</a> (CCS) connection
-server, the client app can send "upstream" messages back to the connection server.
+server, the client app can send "upstream" messages back to the 3rd-party app server.
 For more information on how to implement the client app, see
-<a href="client.html">Implementing GCM Client</a>.</li>
+the documentation for your platform.</li>
 </ul>
 
 <h2 id="lifecycle">Lifecycle Flow</h2>
 
 <ul>
-  <li><a href="#register">Enable GCM</a>. An Android application running on a
-mobile device registers to receive messages.</li>
+  <li><strong>Register to enable GCM</strong>. A client app registers to receive messages.
+For more discussion, see <a href="#register">Register to enable GCM</a>.</li>
+  <li><strong>Send and receive downstream messages</strong>.
+  <ul>
+     <li>Send a message. A 3rd-party app server sends messages to the client app:
+       <ol>
+         <li>The 3rd-party app server <a href="server.html#send-msg">sends a message</a>
+to GCM connection servers.</li>
+         <li>The GCM connection server enqueues and stores the message if the device is offline.</li>
+         <li>When the device is online, the GCM connection server sends the message to the device. </li>
+         <li>On the device, the client app receives the message according to the platform-specific implementation.
+See your platform-specific documentation for details.</li>
+       </ol>
+    </li>
+  <li>Receive a message. A client app
+receives a message from a GCM server. See your platform-specific documentation for details
+on how a client app in that environment processes the messages it receives.</li>
+  </ul>
+</li>
 
-  <li><a href="#push-process">Send a message</a>. A 3rd-party application
-server sends messages to the device.</li>
-  <li><a href="#receiving">Receive a message</a>. An Android application
-receives a message from a GCM server.</li>
+  <li><strong>Send and receive upstream messages</strong>. This feature is only available if
+you're using the <a href="ccs.html">XMPP Cloud Connection Server</a> (CCS).
+<ul>
+     <li>Send a message. A client app sends messages to the 3rd-party app server:
+      <ol>
+        <li>On the device, the client app sends messages to XMPP (CCS).See your platform-specific
+          documentation for details on how a client app can send a message to XMPP (CCS).</li>
+        <li>XMPP (CCS) enqueues and stores the message if the server is disconnected.</li>
+        <li>When the 3rd-party app server is re-connected, XMPP (CCS) sends the message to the 3rd-party app server.</li>
+      </ol>
+    </li>
+  <li>Receive a message. A 3rd-party app server receives a message from XMPP (CCS) and then does the following:
+      <ol>
+        <li>Parses the message header to verify client app sender information.
+        <li>Sends "ack" to GCM XMPP connection server to acknowledge receiving the message.
+        <li>Optionally parses the message payload, as defined by the client app.
+      </ol>
+</li>
 </ul>
 
-<p>These processes are described in more detail below.</p>
+</li>
 
-<h3 id="register">Enable GCM</h3>
 
-<p>The first time the Android application needs to use the messaging service, it
-calls the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
-{@code GoogleCloudMessaging}</a> method {@code register()}, as discussed in
-<a href="client.html">Implementing GCM Client</a>.
-The {@code register()} method returns a registration ID. The Android
-application should store this ID for later use (for instance,
-to check in <code>onCreate()</code> if it is already registered).
+</ul>
+
+<h2 id="reg">Register to enable GCM</h2>
+
+<p>Regardless of the platform you're developing on, the first step
+a client app must do is register with GCM. This section covers some of the general
+best practices for registration and unregistration. See your platform-specific docs for
+details on writing a GCM-enabled client app on that platform.</p>
+
+<h3 id="reg-state">Keeping the Registration State in Sync</h3>
+<p>Whenever the app registers as described in
+<a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a>,
+it should save the registration ID for future use, pass it to the
+3rd-party server to complete the registration, and keep track of
+whether the server completed the registration. If the server fails
+to complete the registration, the client app should retry passing the
+registration ID to 3rd-party app server to complete the registration.
+If this continues to fail, the client app should unregister from GCM.</p>
+
+<p>There are also two other scenarios that require special care:</p>
+<ul>
+  <li>Client app update</li>
+  <li>Backup and restore
+  </li>
+</ul>
+<p><bold>Client app update:</bold> When a client app is updated, it should invalidate its existing registration
+ID, as it is not guaranteed to work with the new version.  The recommended way to achieve
+this validation is by storing the current app version when a registration
+ID is stored. Then when the app starts, compare the stored value with
+the current app version. If they do not match, invalidate the stored data
+and start the registration process again.</p>
+
+<p><bold>Backup and restore: </bold> You should not save the registration ID when an app is
+backed up. This is because the registration ID could become invalid by the time
+the app is restored, which would put the app in an invalid state
+(that is, the app thinks it is registered, but the server and GCM do not
+store that registration ID anymore&mdash;thus the app will not get more
+messages). The best practice is to initiate the registration process as if the app has been
+installed for the first time.</p>
+
+<h4 id="canonical">Canonical IDs</h4>
+<p>If a bug in the app triggers multiple
+registrations for the same device, it can be hard to reconcile state and you might
+end up with duplicate messages.</p>
+<p>GCM provides a facility called &quot;canonical registration IDs&quot; to easily
+recover from these situations. A canonical registration ID is defined to be the ID
+of the last registration requested by your app. This is the ID that the
+server should use when sending messages to the device.</p>
+<p>If later on you try to send a message using a different registration ID, GCM
+will process the request as usual, but it will include the canonical registration
+ID in the <code>registration_id</code> field of the response. Make sure to replace
+the registration ID stored in your server with this canonical ID, as eventually
+the ID you're using will stop working.</p>
+
+<h3 id="retry">Automatic Retry Using Exponential Back-Off</h3>
+
+<p>When registration or unregistration fails, the app should retry the failed operation.</p>
+<p>In the simplest case, if your app attempts to register and GCM is not a
+fundamental part of the app, the app could simply ignore the error
+and try to register again the next time it starts. Otherwise, it should retry the
+previous operation using exponential back-off. In exponential back-off, each time
+there is a failure, it should wait twice the previous amount of time before trying
+again.
 </p>
 
-<h3 id="push-process">Send a message</h3>
+<h3 id="unreg">Unregistration</h3>
 
-<p>Here is the sequence of events that occurs when the application server sends a 
-message:</p>
+<p>This section explains when you should unregister in GCM and what happens
+when you do.</p>
 
+<h4 id="unreg-why">Why you should rarely unregister</h4>
+
+<p>You should only need to unregister in rare cases, such as
+if you want an app to stop receiving messages, or if you suspect that the registration ID has
+been compromised. In general, once an app has a registration ID, you shouldn't need
+to change it.</p>
+
+<p>In particular, you should never unregister your app as a mechanism for
+logout or for switching between users, for the following reasons:</p>
+
+<ul>
+  <li>A registration ID isn't associated with a particular
+  logged in user. If you unregister and then re-register, GCM may return the same
+  ID or a different ID&mdash;there's no guarantee either way.</li>
+
+  <li>Unregistration may take up to 5 minutes to propagate.</li>
+  <li>After unregistration, re-registration may again take up to 5 minutes to
+propagate. During this time messages may be rejected due to the state of being
+unregistered, and after all this, messages may still go to the wrong user.</li>
+</ul>
+
+
+<p>To make sure that messages go to the intended user:</p>
+
+<ul>
+  <li>Your app server can maintain a mapping between the current user
+and the registration ID.</li>
+  <li>The app can then check to ensure that messages it
+receives match the logged in user.</li>
+</ul>
+
+
+<h4 id="unreg-how">How unregistration works</h4>
+
+<p>An app can be automatically unregistered after it is uninstalled.
+However, this process does not happen right away. What happens in
+this scenario is as follows:</p>
 <ol>
-  <li>The application server sends a  message to  GCM servers.</li>
-  <li>Google enqueues and stores the message in case the device is
-offline.</li>
-  <li>When the device is online, Google sends the message to the device. </li>
-  <li>On the device, the system  broadcasts the  message to the specified
-Android application via Intent broadcast with proper permissions, so that only the
-targeted Android application gets the message. This wakes the Android application up. The
-Android application does not need to be running beforehand to receive the message.</li>
-  <li>The Android application processes the message. If the Android application is doing
-non-trivial processing, you may want to grab a
-{@link android.os.PowerManager.WakeLock} and do any processing in a service.</li>
+  <li>The end user uninstalls the client app.</li>
+  <li>The 3rd-party app server sends a message to GCM server.</li>
+  <li>The GCM server sends the message to the GCM client on the device.</li>
+  <li>The GCM client on the device receives the message and detects that the client app has been
+   uninstalled; the detection details depend on the platform on which the client app is running.
+</li>
+  <li>The GCM client on the device informs the GCM server that the client app was uninstalled.</li>
+  <li>The GCM server marks the registration ID for deletion.</li>
+  <li>The 3rd-party app server sends a message to  GCM.</li>
+  <li>The GCM returns a <code>NotRegistered</code> error message to the 3rd-party app server.</li>
+  <li>The 3rd-party app server deletes the registration ID.
+  </li>
 </ol>
 
-<p> An Android application can  unregister GCM if it no longer wants to receive 
-messages.</p>
-
-<h3 id="receiving">Receive a message</h3>
-
-<p>This is the sequence of events that occurs when an Android application
-installed on a mobile device receives a message:</p>
-
-<ol>
-  <li>The system receives the incoming message and extracts the raw key/value
-pairs from the message payload, if any.</li>
-  <li>The system passes the key/value pairs to the targeted Android application
-in a <code>com.google.android.c2dm.intent.RECEIVE</code> Intent as a set of
-extras.</li>
-  <li>The Android application extracts the raw data
-from the <code>com.google.android.c2dm.intent.RECEIVE</code><code> </code>Intent
-by key and processes the data.</li>
-</ol>
-
+<p>Note that it might take a while for the registration ID be completely removed
+from GCM. Thus it is possible that messages sent during step 7 above gets a valid
+message ID as response, even though the message will not be delivered to the client app.
+Eventually, the registration ID will be removed and the server will get a
+<code>NotRegistered</code> error, without any further action being required from
+the 3rd-party server (this scenario happens frequently while an app is
+being developed and tested).</p>
 
diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd
index a889624..2331292 100644
--- a/docs/html/google/gcm/gs.jd
+++ b/docs/html/google/gcm/gs.jd
@@ -1,4 +1,4 @@
-page.title=Getting Started
+page.title=Getting Started on Android
 page.tags=cloud,push,messaging
 @jd:body
 
@@ -46,7 +46,7 @@
 
   <li>Copy down your project number. You will use it later on as the
   <a href="{@docRoot}google/gcm/gcm.html#senderid">GCM sender ID</a>.</li>
-  
+
 </ol>
 <h2 id="gcm-service">Enabling the GCM Service</h2>
 <p>To enable the GCM service:</p>
@@ -71,7 +71,7 @@
 
 <li>In the refreshed page, copy the
 <a href="{@docRoot}google/gcm/gcm.html#apikey">API key</a>.
-You will need the API key later on to perform authentication in your application server.</li>
+You will need the API key later on to perform authentication in your app server.</li>
 
 <p class="note"><strong>Note:</strong> If you need to rotate the key, click
 <strong>Regenerate key</strong>. A new key  will be created. If you think the key has been
@@ -84,16 +84,11 @@
 implementing GCM. Here is an overview of the basic steps:</p>
 
 <ol>
-  <li>Decide which Google-provided GCM connection server you want to use&mdash;
-  <a href="http.html">HTTP</a> or <a href="ccs.html">XMPP</a> (CCS). GCM connection servers
-take messages from a 3rd-party application
-server (written by you) and send them to a GCM-enabled Android application (the
-"client app," also written by you) running on a device. </li>
-  <li>Implement an application server (the "3rd-party application server") to interact
+  <li>Implement an app server (the "3rd-party app server") to interact
 with your chosen GCM connection server. The app server sends data to a
-GCM-enabled Android client application via the GCM connection server. For more
+GCM-enabled Android client app via the GCM connection server. For more
 information about implementing the server side, see <a href="server.html">
 Implementing GCM Server</a>.</li>
-<li>Write your client app. This is the GCM-enabled Android application that runs
+<li>Write your client app. This is the GCM-enabled Android app that runs
 on a device. See <a href="client.html">Implementing GCM Client</a> for more information.</li>
 </ol>
diff --git a/docs/html/google/gcm/http.jd b/docs/html/google/gcm/http.jd
index 773acd1..5022e09 100644
--- a/docs/html/google/gcm/http.jd
+++ b/docs/html/google/gcm/http.jd
@@ -23,6 +23,7 @@
 <h2>See Also</h2>
 
 <ol class="toc">
+<li><a href="server-ref.html">Server Reference</a></li>
 <li><a href="gs.html">Getting Started</a></li>
 <li><a href="client.html">Implementing GCM Client</a></li>
 <li><a href="ccs.html">Cloud Connection Server</a></li>
@@ -42,26 +43,30 @@
 applies to <a href="http://developer.chrome.com/apps/cloudMessaging">
 GCM with Chrome apps</a> as well as Android.</p>
 
-<p>See
-<a href="server.html#params">Implementing GCM Server</a> for a list of all the message
+<p>See the
+<a href="server-ref.html">Server Reference</a> for a list of all the message
 parameters and which connection server(s) supports them.</p>
 
 
 <h2 id="auth">Authentication</h2>
 
-<p>To send a  message, the application server issues a POST request to
-<code>https://android.googleapis.com/gcm/send</code>.</p>
+<p>To send a  message, the application server issues a POST request. For example:</p>
+<pre>https://android.googleapis.com/gcm/send</pre>
 <p>A  message request is made of 2 parts: HTTP header and HTTP body.</p>
 
 <p>The HTTP header must contain the following headers:</p>
 <ul>
   <li><code>Authorization</code>: key=YOUR_API_KEY</li>
-  <li><code>Content-Type</code>: <code>application/json</code> for JSON; <code>application/x-www-form-urlencoded;charset=UTF-8</code> for plain text.
+  <li><code>Content-Type</code>: <code>application/json</code> for JSON;
+<code>application/x-www-form-urlencoded;charset=UTF-8</code> for plain text.
+If <code>Content-Type</code> is omitted, the format
+is assumed to be plain text.
   </li>
 </ul>
 
 <p>For example:
 </p>
+
 <pre>Content-Type:application/json
 Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
 
@@ -71,26 +76,30 @@
     ...
   },
 }</pre>
-<p class="note">
-  <p><strong>Note:</strong> If <code>Content-Type</code> is omitted, the format
-is assumed to be plain text.</p>
-</p>
+
 
 <p>The HTTP body content depends on whether you're using JSON or plain text.
 See
-<a href="server.html#params">Implementing GCM Server</a> for a list of all the
+<a href="server-ref.html#params">the Server Reference</a> for a list of all the
 parameters your JSON or plain text message can contain.</p>
 
 
   <h2 id="request">Request Format</h2>
+
+<p>This section shows you how to format a request for both JSON and plain text. See
+the <a href="server-ref.html#table1">Server Reference</a> for a complete
+list of the fields you can include in a request.</p>
+
   <p>Here is the smallest possible request (a message without any parameters and
 just one recipient) using JSON:</p>
+
   <pre class="prettyprint pretty-json">{ &quot;registration_ids&quot;: [ &quot;42&quot; ] }</pre>
 
   <p>And here the same example using plain text:</p>
   <pre class="prettyprint">registration_id=42</pre>
 
   <p> Here is a message with a payload and 6 recipients:</p>
+
   <pre class="prettyprint pretty-HTML">{ "data": {
     "score": "5x1",
     "time": "15:10"
@@ -112,10 +121,25 @@
   <pre class="prettyprint">collapse_key=score_update&amp;time_to_live=108&amp;delay_while_idle=1&amp;data.score=4x8&amp;data.time=15:16.2342&amp;registration_id=42
   </pre>
 
+<p>Here is a message that includes a notification key and payload:</p>
+
+<pre>
+{
+  "data": {
+    "message": "ciao"
+  },
+  "notification_key":"aUniqueKey"
+}
+</pre>
+
+<p>For more information about notifications and how to use them, see
+<a href="{@docRoot}google/gcm/notifications.html">User Notifications</a>.</p>
+
+
 <p class="note"><strong>Note:</strong> If your organization has a firewall
 that restricts the traffic to or
 from the Internet, you need to configure it to allow connectivity with GCM in order for
-your Android devices to receive messages.
+your GCM client apps to receive messages.
 The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but
 it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs, so you should allow
 your firewall to accept outgoing connections to all IP addresses
@@ -127,54 +151,12 @@
 
 <p>There are two possible outcomes when trying to send a message:</p>
 <ul>
-  <li>The message is processed successfully.</li>
-  <li>The GCM server rejects the request.</li>
+  <li>The message is processed successfully. The HTTP response has a 200 status, and
+the body contains more information about the status of the message (including possible errors).</li>
+  <li>The GCM server rejects the request. The HTTP response contains a
+non-200 status code (such as 400, 401 or 5xx).</li>
 </ul>
 
-<p>When the message is processed successfully, the HTTP response has a 200 status
-and the body contains more information about the status of the message
-(including possible errors). When the request is rejected,
-the HTTP response contains a non-200 status code (such as 400, 401, or 503).</p>
-
-<p>The following table summarizes the statuses that the HTTP response header might
-contain. Click the troubleshoot link for advice on how to deal with each type of
-error.</p>
-<table border=1>
-  <tr>
-    <th>Response</th>
-    <th>Description</th>
-  </tr>
-  <tr>
-    <td>200</td>
-    <td>Message was processed successfully. The response body will contain more
-details about the message status, but its format will depend whether the request
-was JSON or plain text. See <a href="#success">Interpreting a success response</a>
-for more details.</td>
-  </tr>
-  <tr>
-    <td>400</td>
-    <td><span id="internal-source-marker_0.2">Only applies for JSON requests.
-Indicates that the request could not be parsed as JSON, or it contained invalid
-fields (for instance, passing a string where a number was expected). The exact
-failure reason is described in the response and the problem should be addressed
-before the request can be retried.</td>
-  </tr>
-  <tr>
-    <td>401</td>
-    <td>There was an error authenticating the sender account.
-<a href="#auth_error">Troubleshoot</a></td>
-  </tr>
-  <tr>
-    <td>5xx</td>
-    <td>Errors in the 500-599 range (such as 500 or 503) indicate that there was
-an internal error in the GCM server while trying to process the request, or that
-the server is temporarily unavailable (for example, because of timeouts). Sender
-must retry later, honoring any <code>Retry-After</code> header included in the
-response. Application servers must implement exponential back-off.
-<a href="#internal_error">Troubleshoot</a></td>
-  </tr>
-</table>
-
 <h3 id="success">Interpreting a success response</h3>
 <p>When a JSON request is successful (HTTP status code 200), the response body
 contains a JSON object with the following fields:</p>
@@ -241,8 +223,8 @@
 request.</li>
       <li>If it is <code>NotRegistered</code>, you should remove the registration
 ID from your server database because the application was uninstalled from the
-device or it does not have a broadcast receiver configured to receive
-<code>com.google.android.c2dm.intent.RECEIVE</code> intents.</li>
+device, or the client app isn't configured to receive
+messages.</li>
       <li>Otherwise, there is something wrong in the registration ID passed in
 the request; it is probably a non-recoverable error that will also require removing
 the registration from the server database. See <a href="#error_codes">Interpreting
@@ -291,8 +273,7 @@
 
 <dt id="invalid_reg"><strong>Invalid Registration ID</strong></dt>
 <dd>Check the formatting of the registration ID that you pass to the server. Make
-sure it matches the registration ID the phone receives in the
-<code>com.google.android.c2dm.intent.REGISTRATION</code> intent and that you're
+sure it matches the registration ID the client app receives and that you're
 not truncating it or adding additional characters.
 <br/>Happens when error code is <code>InvalidRegistration</code>.</dd>
 
@@ -306,17 +287,13 @@
 <dt id="unreg_device"><strong>Unregistered Device</strong></dt>
 <dd>An existing registration ID may cease to be valid in a number of scenarios, including:
 <ul>
-  <li>If the application manually unregisters by issuing a
-<span class="prettyprint pretty-java">
-<code>com.google.android.c2dm.intent.UNREGISTER</code></span><code>
-</code>intent.</li>
+  <li>If the application manually unregisters.</li>
   <li>If the application is automatically unregistered, which can happen
 (but is not guaranteed) if the user uninstalls the application.</li>
   <li>If the registration ID expires. Google might decide to refresh registration
 IDs. </li>
-  <li>If the application is updated but the new version does not have a broadcast
-receiver configured to receive <code>com.google.android.c2dm.intent.RECEIVE</code>
-intents.</li>
+  <li>If the application is updated but the new version is not configured to receive
+messages.</li>
 </ul>
 For all these cases, you should remove this registration ID from the 3rd-party
 server and stop using it to send
@@ -331,8 +308,7 @@
 
 <dt id="invalid_datakey"><strong>Invalid Data Key</strong></dt>
 <dd>The payload data contains a key (such as <code>from</code> or any value
-prefixed by <code>google.</code>) that is used internally by GCM in the
-<code>com.google.android.c2dm.intent.RECEIVE</code> Intent and cannot be used.
+prefixed by <code>google.</code>) that is used internally by GCM and therefore cannot be used.
 Note that some words (such as <code>collapse_key</code>) are also used by GCM
 but are allowed in the payload, in which case the payload value will be
 overridden by the GCM value.
@@ -354,9 +330,9 @@
 <li>Request originated from a server not whitelisted in the Server Key IPs.</li>
 
 </ul>
-Check that the token you're sending inside the <code>Authorization</code> header
-is the correct API key associated with your project. You can check the validity
-of your API key by running the following command:<br/>
+When there is an Authentication Error, you can check the validity of your API key by running You can check the validity
+of your API key by running the following command (this example shows what you
+would do on Android; see the documentation for your platform):<br/>
 
 <pre># api_key=YOUR_API_KEY
 
@@ -405,8 +381,7 @@
 <dd>
 The server encountered an error while trying to process the request. You
 could retry the same request (obeying the requirements listed in the <a href="#timeout">Timeout</a>
-section), but if the error persists, please report the problem in the
-<a href="https://groups.google.com/forum/?fromgroups#!forum/android-gcm">android-gcm group</a>.
+section), but if the error persists, please report the problem to Google.
 <br />
 Happens when the HTTP status code is 500, or when the <code>error</code> field of a JSON
 object in the results array is <code>InternalServerError</code>.
@@ -488,7 +463,7 @@
 
 <p>This section gives examples of implementing an app server that works with the
 GCM HTTP connection server. Note that a full GCM implementation requires a
-client-side implementation, in addition to the server.</a>
+client-side implementation, in addition to the server. This example is based on Android.</a>
 
 
 <p>Requirements</p>
@@ -508,7 +483,7 @@
 </ul>
 <p>For the Android application:</p>
 <ul>
-  <li>Emulator (or device) running Android 2.2 with Google APIs.</li>
+  <li>Emulator (or device) running Android 2.2 (ideally, 2.3 or above) with Google APIs.</li>
   <li>The Google API project number of the account registered to use GCM.</li>
 </ul>
 
diff --git a/docs/html/google/gcm/notifications.jd b/docs/html/google/gcm/notifications.jd
index 147b69c..333d4b6 100644
--- a/docs/html/google/gcm/notifications.jd
+++ b/docs/html/google/gcm/notifications.jd
@@ -306,9 +306,3 @@
 <p>In the case of failure, the response has HTTP code 503 and no JSON. When a message
 fails to be delivered to one or more of the regIDs associated with a {@code notification_key},
 the 3rd-party server should retry.</p>
-
-
-
-
-
-
diff --git a/docs/html/google/gcm/server-ref.jd b/docs/html/google/gcm/server-ref.jd
new file mode 100644
index 0000000..a94e727
--- /dev/null
+++ b/docs/html/google/gcm/server-ref.jd
@@ -0,0 +1,763 @@
+page.title=Server Reference
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ol class="toc">
+  <li><a href="#downstream">Downstream Messages</a></li>
+<ol class="toc">
+      <li><a href="#send-downstream">Sending a downstream message</a></li>
+      <li><a href="#interpret-downstream">Interpreting a downstream message response</a></li>
+    </ol>
+  <li><a href="#upstream">Upstream Messages (XMPP)</a>
+    <ol class="toc">
+      <li><a href="#interpret-upstream">Interpreting an upstream XMPP message</a></li>
+      <li><a href="#upstream-response">Sending an upstream XMPP message response</a></li>
+    </ol>
+  </li>
+<li><a href="#ccs">Cloud Connection Server Messages (XMPP)</a></li>
+<li><a href="#error-codes">Downstream message error response codes (HTTP and XMPP)</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>This document provides a reference for the syntax used to pass
+messages back and forth in GCM. These messages fall into
+the following broad categories:</p>
+
+<ul>
+   <li><a href="#downstream">Downstream messages</a></li>
+   <li><a href="#upstream">Upstream messages</a></li>
+   <li><a href="#ccs">Cloud Connection Server messages (XMPP)</a></li>
+   <li><a href="#error-codes">Downstream message error response codes (HTTP and XMPP)</a></li>
+</ul>
+
+<p>The following sections describe the basic requirements for
+sending messages.</p>
+
+<h2 id="downstream">Downstream Messages</h2>
+<p>This is the message that a 3rd-party app server sends to a client app.
+</p>
+<p>A downstream message includes the following components:</p>
+<ul>
+  <li>Target: specifies the recipient of the message.</li>
+  <li>Options: specifies attributes of the message.</li>
+  <li>Payload: specifies additional content to be included in the message. Optional.</li>
+</ul>
+
+<p>The syntax for each of these components is described in the tables below. </p>
+
+<h3 id="send-downstream">Sending a downstream message</h3>
+
+<p>This section gives the syntax for sending a downstream messages. For JSON,
+these messages can be either HTTP or XMPP. For plain text, these messages can only be HTTP.</p>
+
+<h4>Downstream HTTP or XMPP messages (JSON)</h4>
+
+<p>The following table lists the targets, options, and payload for HTTP or XMPP JSON messages.</p>
+<p class="table-caption" id="table1">
+  <strong>Table 1.</strong> Targets, options, and payload for downstream HTTP or XMPP message (JSON).</p>
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Protocol</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+<tr>
+    <td colspan="4"><strong>Targets</strong></td>
+  </tr>
+  <tr>
+    <td><code>to</code></td>
+    <td>XMPP</td>
+    <td>Required, string</td>
+    <td><p>This parameter specifies the recipient of a message. </p>
+      <p>The value must be a registration ID or notification key.</p>
+    <p>This parameter is used in XMPP in place of {@code registration_ids} or   {@code notification_key} in HTTP.</p></td>
+  </tr>
+  <tr>
+    <td><code>registration_ids</code></td>
+    <td>HTTP</td>
+    <td>Required if {@code notification_key} not present, string array</td>
+    <td><p>This parameter specifies the list of devices (registration IDs)
+receiving the message. It must contain at least 1 and at most 1000 registration IDs.</p>
+      <p>Multicast messages (sending to more than 1 registration IDs) are allowed using HTTP JSON format only.</p>
+    <p>This parameter or {@code notification_key} is used in HTTP in place of {@code to} in XMPP.</p></td>
+  </tr>
+  <tr>
+    <td><code>notification_key</code></td>
+    <td>HTTP</td>
+    <td>Required if {@code registration_ids} not present, string</td>
+    <td><p>This parameter specifies the mapping of a single user to
+multiple registration IDs associated with that user.</p>
+      <p>This allows a 3rd-party app server to send a single message to multiple app instances
+(typically on multiple devices) owned by a single user.</p>
+      <p>A 3rd-party app server can use {@code notification_key} as the target for a
+message instead of an individual registration ID (or array of registration IDs).
+The maximum number of members allowed for a {@code notification_key} is 20.</p>
+      <p>This parameter or {@code registration_ids} is used in HTTP in place of {@code to} in XMPP.</p>
+    <p>See <a href="notifications.html">User Notifications</a> for details.</p></td>
+  </tr>
+<tr>
+    <td colspan="4"><strong>Options</strong></td>
+  </tr>
+  <tr>
+    <td><code>message_id</code></td>
+    <td>XMPP</td>
+    <td>Required, string</td>
+    <td><p>This parameter uniquely identifies a message in an XMPP connection.</p></td>
+  </tr>
+  <tr>
+    <td><code>collapse_key</code></td>
+    <td>HTTP, XMPP</td>
+    <td>Optional, string</td>
+    <td><p>This parameters identifies a group of messages (e.g., with
+{@code collapse_key: "Updates Available"}) that can be collapsed, so that only the
+last message gets sent when delivery can be resumed. This is intended to avoid sending too
+many of the same messages when the device comes back online or becomes active (see {@code delay_while_idle}).</p>
+      <p>Note that there is no guarantee of the order in which messages get sent.</p>
+      <p>Messages with collapse key are also called
+<a href="{@docRoot}google/gcm/server.html#s2s">send-to-sync messages</a> messages.
+</p>
+    <p>Note: A maximum of 4 different collapse keys is allowed at any given time. This means a
+GCM connection server can simultaneously store 4 different send-to-sync messages per client app. If you
+exceed this number, there is no guarantee which 4 collapse keys the GCM connection server will keep. </p></td>
+  </tr>
+  <tr>
+    <td><code>delay_while_idle</code></td>
+    <td>HTTP, XMPP</td>
+    <td>Optional, JSON boolean</td>
+    <td>When this parameter is set to {@code true}, it indicates that the message should not be
+sent until the device becomes active.</p>
+    <p>The default value is {@code false}.</p></td>
+  </tr>
+  <tr>
+    <td><code>time_to_live</code></td>
+    <td>HTTP, XMPP</td>
+    <td>Optional, JSON number</td>
+    <td><p>This parameter specifies how long (in seconds) the message should be kept in GCM storage
+if the device is offline. The maximum time to live supported is 4 weeks.</p>
+    <p>The default value is 4 weeks. </p></td>
+  </tr>
+  <tr>
+    <td><code>delivery_receipt_
+<br>requested</code></td>
+    <td>XMPP</td>
+    <td>Optional, JSON boolean</td>
+    <td><p>This parameter lets 3rd-party app server request confirmation of message delivery.</p>
+      <p>When this parameter is set to {@code true}, CCS sends a delivery receipt
+when the device confirms that it received the message.</p>
+    <p>The default value is {@code false}.</p></td>
+  </tr>
+  <tr>
+    <td><code>restricted_package_
+<br>name</code></td>
+    <td>HTTP</td>
+    <td>Optional, string</td>
+    <td>This parameter specifies the package name of the application where the
+registration IDs must match in order to receive the message.</td>
+  </tr>
+  <tr>
+    <td><code>dry_run</code></td>
+    <td>HTTP</td>
+    <td>Optional, JSON boolean</td>
+    <td><p>This parameter, when set to {@code true}, allows developers to test a
+request without actually sending a message.</p>
+    <p>The default value is {@code false}.</p></td>
+  </tr>
+<tr>
+    <td colspan="4"><strong>Payload</strong></td>
+  </tr>
+  <tr>
+    <td><code>data</code></td>
+    <td>HTTP, XMPP</td>
+    <td>Optional, JSON object</td>
+    <td><p>This parameter specifies the key-value pairs of the message's payload. There is
+no limit on the number of key-value pairs, but there is a total message size limit of 4kb.</p>
+      <p>For instance, in Android, <code>data:{"score":"3x1"}</code> would result in an intent extra
+named {@code score} with the string value {@code 3x1}.</p>
+      <p>The key should not be a reserved word ({@code from} or any word starting with
+{@code google}). It is also not recommended to use words defined in this table
+(such as {@code collapse_key}) because that could yield unpredictable outcomes. </p>
+    <p>Values in string types are recommended. You have to convert values in objects
+or other non-string data types (e.g., integers or booleans) to string.</p></td>
+  </tr>
+</table>
+
+<h3>Downstream HTTP messages (Plain Text)</h3>
+
+<p>The following table lists the syntax for targets, options, and payload in plain
+text downstream HTTP messages.</p>
+
+<p class="table-caption" id="table2">
+  <strong>Table 2.</strong> Targets, options, and payload for downstream plain text HTTP messages.</p>
+
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+<tr>
+    <td colspan="3"><strong>Targets</strong></td>
+  </tr>
+  <tr>
+    <td><code>registration _id</code></td>
+    <td>Required, string</td>
+    <td><p>This parameter specifies the client apps (registration ID) receiving the message.</p>
+    <p>Multicast messaging (sending to more than one registration ID) is allowed using HTTP JSON format only.</p></td>
+  </tr>
+<tr>
+    <td colspan="3"><strong>Options</strong></td>
+  </tr>
+  <tr>
+    <td><code>collapse_key</code></td>
+    <td>Optional, string</td>
+    <td>See <a href="#table1">table 1</a> for details.</td>
+  </tr>
+  <tr>
+    <td><code>delay_while_idle</code></td>
+    <td>Optional, boolean or number</td>
+    <td>See <a href="#table1">table 1</a> for details.</td>
+  </tr>
+  <tr>
+    <td><code>time_to_live</code></td>
+    <td>Optional, number</td>
+    <td>See <a href="#table1">table 1</a> for details.</td>
+  </tr>
+  <tr>
+    <td><code>restricted_package_name</code></td>
+    <td>Optional, string</td>
+    <td>See <a href="#table1">table 1</a> for details.</td>
+  </tr>
+  <tr>
+    <td><code>dry_run </code></td>
+    <td>Optional, boolean</td>
+    <td>See <a href="#table1">table 1</a> for details.</td>
+  </tr>
+<tr>
+    <td colspan="3"><strong>Payload</strong></td>
+  </tr>
+  <tr>
+    <td><code>data.&lt;key&gt;</code></td>
+    <td>Optional, string</td>
+    <td><p>This parameter specifies the key-value pairs of the message's payload.
+There is no limit on the number of key-value parameters,
+but there is a total message size limit of 4kb.</p>
+      <p>For instance, in Android, <code>data:{"score":"3x1"}</code> would result in an intent extra
+named {@code score} with the string value {@code 3x1}.</p>
+    <p>The key should not be a reserved word ({@code from} or any word starting with
+{@code google}). It is also not recommended to use words defined in this table
+(such as {@code collapse_key}) because that could yield unpredictable outcomes.</p></td>
+  </tr>
+</table>
+
+<h3 id="interpret-downstream">Interpreting a Downstream Message Response</h3>
+
+<p>This section describes the syntax of a response to a downstream message. A client
+app or the GCM Connection Server sends the response to 3rd-party app server upon processing
+the message request. </p>
+
+<h4>Interpreting a downstream HTTP message response </h4>
+<p>The 3rd-party app server should look at both the message response header and the body
+to interpret the message response sent from the GCM Connection Server. The following table
+describes the possible responses.</p>
+<p>
+
+<p class="table-caption" id="table3">
+  <strong>Table 3.</strong> Downstream HTTP message response header.</p>
+<table border=1>
+  <tr>
+    <th>Response</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>200</td>
+    <td>Message was processed successfully. The response body will contain more
+details about the message status, but its format will depend whether the request
+was JSON or plain text. See <a href="#table4">table 4</a>
+for more details.</td>
+  </tr>
+  <tr>
+    <td>400</td>
+    <td>Only applies for JSON requests.
+Indicates that the request could not be parsed as JSON, or it contained invalid
+fields (for instance, passing a string where a number was expected). The exact
+failure reason is described in the response and the problem should be addressed
+before the request can be retried.</td>
+  </tr>
+  <tr>
+    <td>401</td>
+    <td>There was an error authenticating the sender account.
+<a href="server.html#auth_error">Troubleshoot</a></td>
+  </tr>
+  <tr>
+    <td>5xx</td>
+    <td>Errors in the 500-599 range (such as 500 or 503) indicate that there was
+an internal error in the GCM server while trying to process the request, or that
+the server is temporarily unavailable (for example, because of timeouts). Sender
+must retry later, honoring any <code>Retry-After</code> header included in the
+response. Application servers must implement exponential back-off.
+<a href="server.html#internal_error">Troubleshoot</a></td>
+  </tr>
+</table>
+
+<p>The following table lists the fields in a downstream message response body
+(JSON).</p>
+
+
+<p class="table-caption" id="table4">
+  <strong>Table 4.</strong> Downstream HTTP message response body (JSON).</p>
+<table>
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><code>multicast_id</code></td>
+    <td>Required, number</td>
+    <td>Unique ID (number) identifying the multicast message.</td>
+  </tr>
+  <tr>
+    <td><code>success</code></td>
+    <td>Required, number</td>
+    <td>Number of messages that were processed without an error.</td>
+  </tr>
+  <tr>
+    <td><code>failure</code></td>
+    <td>Required, number</td>
+    <td>Number of messages that could not be processed.</td>
+  </tr>
+  <tr>
+    <td><code>canonical_ids</code></td>
+    <td>Required, number</td>
+    <td>Number of results that contain a canonical registration ID. See the
+<a href="{@docRoot}google/gcm/gcm.html#canonical">Overview</a> for more discussion of this topic.</td>
+  </tr>
+  <tr>
+    <td><code>results</code></td>
+    <td>Optional, array object</td>
+    <td>Array of objects representing the status of the messages processed. The
+objects are listed in the same order as the request (i.e., for each registration
+ID in the request, its result is listed in the same index in the response).<br>
+      <ul>
+        <li><code>message_id</code>: String specifying a unique ID for each successfully processed
+          message.</li>
+        <li><code>registration_id</code>: Optional string specifying the canonical registration ID
+          for the client app that the message was processed and sent to. Sender should use this
+          value as the Registration ID for future requests. Otherwise, the messages might
+          be rejected.
+        </li>
+        <li><code>error</code>: String specifying the error that occurred when processing the
+          message for the recipient. The possible values can be found in <a href="#table11">table 11
+        </a>.</li>
+    </ul></td>
+  </tr>
+</table>
+
+
+<p class="table-caption" id="table5">
+  <strong>Table 5.</strong> Success response for downstream HTTP message response body (Plain Text).</p>
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><code>id</code></td>
+    <td>Required, string</td>
+    <td>This parameter specifies the unique message ID that GCM server processed successfully.</td>
+  </tr>
+  <tr>
+    <td><code>registration_id</code></td>
+    <td>Optional, string</td>
+    <td>This parameter specifies the canonical registration ID for the client app that the message was
+processed and sent to. Sender should replace the registration ID with this value on future requests,
+otherwise, the messages might be rejected.</td>
+  </tr>
+</table>
+
+<p class="table-caption" id="table6">
+  <strong>Table 6.</strong> Error response for downstream HTTP message response body (Plain Text).</p>
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>{@code Error}</td>
+    <td>Required, string</td>
+    <td>This parameter specifies the error value while processing the message for the recipient.
+See <a href="#table11">table 11</a> for details. </td>
+  </tr>
+</table>
+
+<h4>Interpreting a downstream XMPP message response</h4>
+
+<p>The following table lists the fields that appear in a downstream XMPP message response.</p>
+
+<p class="table-caption" id="table7">
+  <strong>Table 7.</strong> Downstream message XMPP message response body.</p>
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><code>from</code></td>
+    <td>Required, string</td>
+    <td><p>This parameter specifies who sent this response.</p>
+    <p>The value is the registration ID of the client app.</p></td>
+  </tr>
+  <tr>
+    <td><code>message_id</code></td>
+    <td>Required, string</td>
+    <td>This parameter uniquely identifies a message in an XMPP connection.
+The value is a string that uniquely identifies the associated message.</td>
+  </tr>
+  <tr>
+    <td><code>message_type</code></td>
+    <td>Required, string</td>
+    <td><p>This parameter specifies an 'ack' or 'nack' message from XMPP (CCS)
+to the 3rd-party app server.</p>
+    <p>If the value is set to {@code nack}, the 3rd-party app server should look at
+{@code error} and {@code error_description} to get failure information. </p></td>
+  </tr>
+  <tr>
+    <td><code>error</code></td>
+    <td>Optional, string</td>
+    <td>This parameter specifies an error related to the downstream message. It is set when the
+{@code message_type} is {@code nack}. See <a href="#table11">table 6</a> for details.</td>
+  </tr>
+  <tr>
+    <td><code>error_description</code></td>
+    <td>Optional, string</td>
+    <td>This parameter provides descriptive information for the error. It is set
+when the {@code message_type} is {@code nack}.</td>
+  </tr>
+</table>
+<h2 id="upstream">Upstream Messages (XMPP)</h2>
+
+<p>An upstream message is a message the client app sends to the 3rd-party app server.
+Currently only CCS (XMPP) supports upstream messaging.</p>
+
+<h3 id="interpret-upstream">Interpreting an upstream XMPP message </h3>
+<p>The following table describes the fields that appear in an upstream XMPP message.
+
+<p class="table-caption" id="table8">
+  <strong>Table 8.</strong> Upstream XMPP messages.</p>
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><code>from</code></td>
+    <td>Required, string</td>
+    <td><p>This parameter specifies who sent the message.</p>
+    <p>The value is the registration ID of the client app.</p></td>
+  </tr>
+  <tr>
+    <td><code>category</code></td>
+    <td>Required, string</td>
+    <td>This parameter specifies the application package name of the client app that sent the message. </td>
+  </tr>
+  <tr>
+    <td><code>message_id</code></td>
+    <td>Required, string</td>
+    <td>This parameter specifies the unique ID of the message. </td>
+  </tr>
+  <tr>
+    <td><code>data</code></td>
+    <td>Optional, string</td>
+    <td>This parameter specifies the key-value pairs of the message's payload.</td>
+  </tr>
+</table>
+
+<h3 id="upstream-response">Sending an upstream XMPP message response</h3>
+
+<p>The following table describes the response that 3rd-party app server is expected to send to
+<a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a> in response to an
+upstream message it (the app server) received.</p>
+
+<p class="table-caption" id="table9">
+  <strong>Table 9.</strong> Upstream XMPP message response.</p>
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><code>to</code></td>
+    <td>Required, string</td>
+    <td><p>This parameter specifies the recipient of a response message. </p>
+    <p>The value must be a registration ID of the client app that sent the upstream message.</p></td>
+  </tr>
+  <tr>
+    <td><code>message_id</code></td>
+    <td>Required, string</td>
+    <td>This parameter specifies which message the response is intended for. The value must be
+the {@code message_id} value from the corresponding upstream message.</td>
+  </tr>
+  <tr>
+    <td><code>message_type</code></td>
+    <td>Required, string</td>
+    <td>This parameter specifies an {@code ack} message from a 3rd-party app server to CCS.</td>
+  </tr>
+</table>
+<h2 id="ccs">Cloud Connection Server Messages (XMPP) </h2>
+<p>This is a message sent from XMPP (CCS) to a 3rd-party app server. Here are the primary types
+of messages that XMPP (CCS) sends to the 3rd-party app server:</p>
+<ul>
+  <li><strong>Delivery Receipt:</strong> If the 3rd-party app server included {@code delivery_receipt_requested}
+in the downstream message, XMPP (CCS) sends a delivery receipt when it receives confirmation
+that the device received the message.</li>
+  <li><strong>Control:</strong> These CCS-generated messages indicate that
+action is required from the 3rd-party app server.</li>
+</ul>
+
+<p>The following table describes the fields included in the messages CCS
+sends to a 3rd-party app server.</p>
+
+<p class="table-caption" id="table10">
+  <strong>Table 10.</strong> GCM Cloud Connection Server messages (XMPP).</p>
+<table border="1">
+  <tr>
+    <th>Parameter</th>
+    <th>Usage</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td colspan="3"><strong>Common Field</strong></td>
+  </tr>
+  <tr>
+    <td><code>message_type</code></td>
+    <td>Required, string</td>
+    <td><p>This parameter specifies the type of the CCS message: either delivery receipt or control.</p>
+      <p>When it is set to {@code receipt}, the message includes {@code from}, {@code message_id},
+        {@code category} and {@code data} fields to provide additional information.</p>
+    <p>When it is set to {@code control}, the message includes {@code control_type} to indicate the
+type of control message.</p></td>
+  </tr>
+  <tr>
+    <td colspan="3"><strong>Delivery receipt-specific</strong></td>
+  </tr>
+  <tr>
+    <td><code>from</code></td>
+    <td>Required, string</td>
+    <td>This parameter is set to {@code gcm.googleapis.com}, indicating that the
+message is sent from CCS.</td>
+  </tr>
+  <tr>
+    <td><code>message_id</code></td>
+    <td>Required, string</td>
+    <td>This parameter specifies the original message ID that the receipt is intended for,
+prefixed with {@code dr2:} to indicate that the message is a delivery receipt. A 3rd-party app
+server must send an {@code ack} message with this message ID to acknowledge that it
+received this delivery receipt. See <a href="#table9">table 9</a> for the 'ack' message format.</td>
+  </tr>
+  <tr>
+    <td><code>category</code></td>
+    <td>Optional, string</td>
+    <td>This parameter specifies the application package name of the client app that
+receives the message that this delivery receipt is reporting. This is available when
+{@code message_type} is {@code receipt}.</td>
+  </tr>
+  <tr>
+    <td><code>data</code></td>
+    <td>Optional, string</td>
+    <td>This parameter specifies the key-value pairs for the delivery receipt message. This is available
+when the {@code message_type} is {@code receipt}.
+      <ul>
+        <li>{@code message_status}: This parameter specifies the status of the receipt message.
+It is set to {@code MESSAGE_SENT_TO_DEVICE} to indicate the device has confirmed its receipt of
+the original message.</li>
+      <li>{@code original_message_id}: This parameter specifies the ID of the original message
+that the 3rd-party app server sent to the client app.</li>
+     <li>{@code device_registration_id}: This parameter specifies the registration ID of the
+client app to which the original message was sent.</li>
+    </ul>
+</td>
+  </tr>
+  <tr>
+    <td colspan="3"><strong>Control-specific</strong></td>
+  </tr>
+  <tr>
+    <td><code>control_type</code></td>
+    <td>Optional, string</td>
+    <td><p>This parameter specifies the type of control message sent from CCS.</p>
+    <p>Currently, only {@code CONNECTION_DRAINING} is supported. XMPP (CCS) sends this control message
+before it closes a connection to perform load balancing. As the connection drains, no more messages
+are allowed to be sent to the connection, but existing messages in the pipeline will
+continue to be processed.</p></td>
+  </tr>
+</table>
+
+<h2 id="error-codes">Downstream message error response codes (HTTP and XMPP)</h2>
+
+<p>The following table lists the error response codes for downstream messages (HTTP and XMPP).</p>
+
+<p class="table-caption" id="table11">
+  <strong>Table 11.</strong> Downstream message error response codes.</p>
+<table border="1">
+  <tr>
+    <th>Error</th>
+    <th>HTTP Code</th>
+    <th>XMPP Code</th>
+    <th>Recommended Action</th>
+  </tr>
+  <tr>
+    <td>Missing Registration ID</td>
+    <td>200 + error:MissingRegistration</td>
+    <td><code>INVALID_JSON</code></td>
+    <td>Check that the request contains a registration ID (either in the
+{@code registration_id} in a plain text message, or in the {@code registration_ids} in JSON).</td>
+  </tr>
+  <tr>
+    <td>Invalid Registration ID</td>
+    <td>200 + error:InvalidRegistration</td>
+    <td><code>BAD_REGISTRATION</code></td>
+    <td>Check the format of the registration ID you pass to the server. Make sure it
+matches the registration ID the client app receives from registering with GCM. Do not
+truncate or add additional characters.</td>
+  </tr>
+  <tr>
+    <td>Unregistered Device</td>
+    <td>200 + error:NotRegistered</td>
+    <td><code>DEVICE_UNREGISTERED</code></td>
+    <td>An existing registration ID may cease to be valid in a number of scenarios, including:<br>
+     <ul>
+      <li>If the client app unregisters with GCM.</li>
+      <li>If the client app is automatically unregistered, which can happen if the user uninstalls the application.</li>
+      <li>If the registration ID expires (for example, Google might decide to refresh registration IDs).</li>
+      <li>If the client app is updated but the new version is not configured to receive messages.</li>
+</ul>
+ For all these cases, remove this registration ID from the 3rd-party app
+server and stop using it to send messages.</td>
+  </tr>
+  <tr>
+    <td>Invalid Package Name</td>
+    <td>200 + error:InvalidPackageName</td>
+    <td></td>
+    <td>Make sure the message was addressed to a registration ID whose package name
+matches the value passed in the request.</td>
+  </tr>
+  <tr>
+    <td>Authentication Error</td>
+    <td>401</td>
+    <td>&nbsp;</td>
+    <td>The sender account used to send a message couldn't be authenticated. Possible causes are:<br>
+<ul>
+      <li>Authorization header missing or with invalid syntax in HTTP request.</li>
+      <li>Invalid project number sent as key.</li>
+      <li>Key valid but with GCM service disabled.</li>
+      <li>Request originated from a server not whitelisted in the Server Key IPs.</li>
+</ul>
+    Check that the token you're sending inside the Authentication header is
+the correct API key associated with your project. See
+<a href="{@docRoot}google/gcm/http.html">GCM HTTP Connection Server</a> for details.</td>
+  </tr>
+  <tr>
+    <td>Mismatched Sender</td>
+    <td>200 + error:MismatchSenderId</td>
+    <td><code>BAD_REGISTRATION</code></td>
+    <td>A registration ID is tied to a certain group of senders. When a client app registers
+for GCM, it must specify which senders are allowed to send messages. You should use one
+of those sender IDs when sending messages to the client app. If you switch to a different
+sender, the existing registration IDs won't work.</td>
+  </tr>
+  <tr>
+    <td>Invalid JSON</td>
+    <td>400</td>
+    <td><code>INVALID_JSON</code></td>
+    <td>Check that the JSON message is properly formatted and contains valid fields
+(for instance, making sure the right data type is passed in).</td>
+  </tr>
+  <tr>
+    <td>Message Too Big</td>
+    <td>200 + error:MessageTooBig</td>
+    <td><code>INVALID_JSON</code></td>
+    <td>Check that the total size of the payload data included in a message does
+not exceed 4096 bytes. This includes both the the keys and the values.</td>
+  </tr>
+  <tr>
+    <td>Invalid Data Key</td>
+    <td>200 + error:
+<br />
+InvalidDataKey</td>
+    <td><code>INVALID_JSON</code></td>
+    <td>Check that the payload data does not contain a key (such as {@code from} or any value
+prefixed by {@code google}) that is used internally by GCM. Note that some words (such as {@code collapse_key})
+are also used by GCM but are allowed in the payload, in which case the payload value
+will be overridden by the GCM value.</td>
+  </tr>
+  <tr>
+    <td>Invalid Time to Live</td>
+    <td>200 + error:InvalidTtl</td>
+    <td><code>INVALID_JSON</code></td>
+    <td>Check that the value used in {@code time_to_live} is an integer representing a
+duration in seconds between 0 and 2,419,200 (4 weeks).</td>
+  </tr>
+  <tr>
+    <td>Bad ACK message</td>
+    <td>N/A</td>
+    <td><code>BAD_ACK</code></td>
+    <td>Check that the 'ack' message is properly formatted before retrying. See
+<a href="#table9">table 9</a> for details.</td>
+  </tr>
+  <tr>
+    <td>Timeout</td>
+    <td>5xx or 200 + error:Unavailable</td>
+    <td><code>SERVICE_UNAVAILABLE</code></td>
+    <td><p>The server couldn't process the request in time. Retry the same request, but you must:<br>
+<ul>
+      <li>For HTTP: Honor the {@code Retry-After} header if it is included in the response from the
+GCM Connection Server.</li>
+      <li>Implement exponential back-off in your retry mechanism. (e.g. if you waited one second
+before the first retry, wait at least two second before the next one, then 4 seconds and so on).
+If you're sending multiple messages, delay each one independently by an additional random amount
+to avoid issuing a new request for all messages at the same time.</li>
+    <li>For CCS: The initial retry delay should be set to 1 second.</li>
+</ul>
+    <p>Senders that cause problems risk being blacklisted.</p></td>
+  </tr>
+  <tr>
+    <td>Internal Server Error</td>
+    <td>500 or 200 + error:InternalServerError</td>
+    <td><code>INTERNAL_SERVER_
+<br />
+ERROR</code></td>
+    <td>The server encountered an error while trying to process the request. You could retry
+the same request following the requirements listed in "Timeout" (see row above). If the error persists, please
+report the problem in the {@code android-gcm group}.</td>
+  </tr>
+  <tr>
+    <td>Device Message Rate Exceeded</td>
+    <td>200 + error:
+<br />DeviceMessageRate
+<br />
+Exceeded</td>
+    <td><code>DEVICE_MESSAGE_RATE<br />
+_EXCEEDED</code></td>
+    <td>The rate of messages to a particular device is too high. Reduce the
+number of messages sent to this device and do not immediately retry sending to this device.</td>
+  </tr>
+  <tr>
+    <td>Connection Draining</td>
+    <td>N/A</td>
+    <td><code>CONNECTION_DRAINING</code></td>
+    <td>The message couldn't be processed because the connection is draining. This happens because
+periodically, XMPP (CCS) needs to close down a connection to perform load balancing. Retry the message over
+another XMPP connection.</td>
+  </tr>
+</table>
diff --git a/docs/html/google/gcm/server.jd b/docs/html/google/gcm/server.jd
index 20e2b2e..004fd0e 100644
--- a/docs/html/google/gcm/server.jd
+++ b/docs/html/google/gcm/server.jd
@@ -7,9 +7,9 @@
 <h2>In this document</h2>
 
 <ol class="toc">
-  <li><a href="#choose">Choosing a GCM Connection Server</a></li>
   <li><a href="#role">Role of the 3rd-party Application Server</a></li>
-    <li><a href="#send-msg">Sending Messages</a>
+  <li><a href="#choose">Choosing a GCM Connection Server</a></li>
+  <li><a href="#send-msg">Sending Messages</a>
     <ol class="toc">
 
       <li><a href="#target">Target</a></li>
@@ -17,7 +17,18 @@
       <li><a href="#params">Message parameters</a>
     </ol>
     </li>
-  <li><a href="#receive">Receiving Messages</a> </li>
+  <li><a href="#adv">Messaging Concepts and Best Practices</a>
+
+   <ol class="toc">
+
+      <li><a href="#collapsible">Send-to-Sync vs. Messages with Payload</a></li>
+      <li><a href="#ttl">Setting an Expiration Date for a Message</a></li>
+      <li><a href="#multi-senders">Receiving Messages from Multiple Senders</a>
+      <li><a href="#lifetime">Lifetime of a Message</a>
+      <li><a href="#throttling">Throttling</a>
+    </ol>
+
+</li>
   </li>
 
 </ol>
@@ -25,6 +36,7 @@
 <h2>See Also</h2>
 
 <ol class="toc">
+<li><a href="server-ref.html">Server Reference</a></li>
 <li><a href="gs.html">Getting Started</a></li>
 <li><a href="client.html">Implementing GCM Client</a></li>
 <li><a href="ccs.html">Cloud Connection Server (XMPP)</a></li>
@@ -37,79 +49,28 @@
 </div>
 
 
-<p>The server side of Google Cloud Messaging (GCM) consists of 2 components:</p>
+<p>The server side of Google Cloud Messaging (GCM) consists of two components:</p>
 <ul>
 <li>Google-provided <strong>GCM Connection Servers</strong>
-take messages from a 3rd-party application server and send them to a GCM-enabled
-Android application (the &quot;client app&quot;) running on a device. For example,
+take messages from a <a href="{@docRoot}google/gcm/server.html#role">3rd-party app server</a>
+and send them to a GCM-enabled
+application (the &quot;client app&quot;) running on a device. For example,
 Google provides connection servers for <a href="{@docRoot}google/gcm/http.html">
-HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">CCS</a> (XMPP).</li>
+HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a> (XMPP).</li>
 <li>A <strong>3rd-party application server</strong> that you must implement. This application
-server sends data to a GCM-enabled Android application via the chosen GCM connection server.</li>
+server sends data to a GCM-enabled client app via the chosen GCM connection server.</li>
 </ul>
 </p>
 
-<p>Here are the basic steps you follow to implement your 3rd-party app server:</p>
-
-<ul>
-      <li>Decide which GCM connection server(s) you want to use. Note that if you want to use
-      upstream messaging from your client applications, you must use CCS. For a more detailed
-      discussion of this, see <a href="#choose">
-      Choosing a GCM Connection Server</a>.</li>
-      <li>Decide how you want to implement your app server. For example:
-        <ul>
-          <li>If you decide to use the HTTP connection server, you can use the
-GCM server helper library and demo app to help in implementing your app server.</li>
-          <li>If you decide to use the XMPP connection server, you can use
-the provided Python or Java <a href="http://www.igniterealtime.org/projects/smack/">
-Smack</a> demo apps as a starting point.</li>
-        <li>Note that Google AppEngine does not support connections to CCS.</li>
-        </ul>
-      </li>
-    </ul>
-  </li>
-</ul>
-
 <p>A full GCM implementation requires both a client implementation and a server
 implementation. For more
 information about implementing the client side, see <a href="client.html">
 Implementing GCM Client</a>.</p>
 
-<h2 id="choose">Choosing a GCM Connection Server</h2>
-
-<p>Currently GCM provides two connection servers: <a href="{@docRoot}google/gcm/http.html">
-HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">CCS</a> (XMPP). You can use them
-separately or in tandem. CCS messaging differs from GCM HTTP messaging in the following ways:</p>
-<ul>
-  <li>Upstream/Downstream messages
-    <ul>
-      <li>GCM HTTP: Downstream only: cloud-to-device. </li>
-      <li>CCS: Upstream and downstream (device-to-cloud, cloud-to-device). </li>
-    </ul>
-  </li>
-  <li>Asynchronous messaging
-    <ul>
-      <li>GCM HTTP: 3rd-party app servers send messages as HTTP POST requests and
-wait for a response. This mechanism is synchronous and causes the sender to block
-before sending another message.</li>
-      <li>CCS: 3rd-party app servers connect to Google infrastructure using a
-persistent XMPP connection and send/receive messages to/from all their devices
-at full line speed. CCS sends acknowledgment or failure notifications (in the
-form of special ACK and NACK JSON-encoded XMPP messages) asynchronously.</li>
-    </ul>
-  </li>
-
-  <li>JSON
-    <ul>
-      <li>GCM HTTP: JSON messages sent as HTTP POST.</li>
-      <li>CCS: JSON messages encapsulated in XMPP messages.</li>
-    </ul>
-  </li>
-</ul>
 
 <h2 id="role">Role of the 3rd-party Application Server</h2>
 
-<p>Before you can write client Android applications that use the GCM feature, you must
+<p>Before you can write client apps that use the GCM feature, you must
 have an  application server that meets the following criteria:</p>
 
 <ul>
@@ -117,308 +78,363 @@
   <li>Able to  fire off properly formatted requests to the GCM server.</li>
   <li>Able to handle requests and resend them as needed, using
 <a href="http://en.wikipedia.org/wiki/Exponential_backoff">exponential back-off.</a></li>
-  <li>Able to store the API key and client registration IDs. The
-API key is included in the header of POST requests that send
-messages.</li>
+  <li>Able to store the API key and client registration IDs. In HTTP, the API key is
+included in the header of POST requests that send messages. In XMPP, the API key is
+used in the SASL PLAIN authentication request as a password to authenticate the connection.</li>
  <li>Able to generate message IDs to uniquely identify each message it sends. Message IDs
 should be unique per sender ID.</li>
 </ul>
 
+<p>Here are the basic steps you follow to implement your 3rd-party app server:</p>
+
+<ul>
+      <li>Decide which GCM connection server(s) you want to use. Note that if you want to use
+      upstream messaging from your client applications, you must use XMPP (CCS). For a more detailed
+      discussion of this, see <a href="#choose">
+      Choosing a GCM Connection Server</a>.</li>
+      <li>Decide how you want to implement your app server. We provide helper libraries and code
+samples to assist you with your 3rd-party app server implementation. For example:
+        <ul>
+          <li>If you decide to use the HTTP connection server, you can use the
+GCM server helper library and demo app to help in implementing your app server.</li>
+          <li>If you decide to use the XMPP connection server, you can use
+the provided Python or Java <a href="http://www.igniterealtime.org/projects/smack/">
+Smack</a> demo apps as a starting point.</li>
+        <li>Note that Google AppEngine does not support connections to XMPP (CCS).</li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+
+<h2 id="choose">Choosing a GCM Connection Server</h2>
+
+<p>Currently GCM provides two connection servers: <a href="{@docRoot}google/gcm/http.html">
+HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a>. You can use them
+separately or in tandem. XMPP (CCS) messaging differs from HTTP messaging in the following ways:</p>
+<ul>
+  <li>Upstream/Downstream messages
+    <ul>
+      <li>HTTP: Downstream only, cloud-to-device up to 4KB of data. </li>
+      <li>XMPP (CCS): Upstream and downstream (device-to-cloud, cloud-to-device),
+        up to 4 KB of data. </li>
+    </ul>
+  </li>
+  <li>Messaging (synchronous or asynchronous)
+    <ul>
+      <li>HTTP: Synchronous. 3rd-party app servers send messages as HTTP POST requests and
+wait for a response. This mechanism is synchronous and blocks the sender from sending
+another message until the response is received.</li>
+      <li>XMPP (CCS): Asynchronous. 3rd-party app servers send/receive messages to/from all their
+devices at full line speed over persistent XMPP connections.
+XMPP (CCS) sends acknowledgment or failure notifications (in the
+form of special ACK and NACK JSON-encoded XMPP messages) asynchronously.</li>
+    </ul>
+  </li>
+
+  <li>JSON
+    <ul>
+      <li>HTTP: JSON messages sent as HTTP POST.</li>
+      <li>XMPP (CCS): JSON messages encapsulated in XMPP messages.</li>
+    </ul>
+  </li>
+  <li>Plain Text
+    <ul>
+      <li>HTTP: Plain Text messages sent as HTTP POST.</li>
+      <li>XMPP (CCS): Not supported.</li>
+    </ul>
+  </li>
+  <li>Multicast downstream send to multiple registration IDs.
+    <ul>
+      <li>HTTP: Supported in JSON message format.</li>
+      <li>XMPP (CCS): Not supported.</li>
+    </ul>
+  </li>
+</ul>
+
+
 <h2 id="send-msg">Sending Messages</h2>
 
+<p>This section gives an overview of sending messages. For details of message syntax,
+see <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a>.</p>
+
+<h3>Overview</h3>
+
 <p>Here is the general sequence of events that occurs when a 3rd-party application
-server sends a message:</p>
+server sends a message (the details vary depending on the platform):</p>
 <ol>
-  <li>The application server sends a message to GCM servers.</li>
-  <li>Google enqueues and stores the message in case the device is offline.</li>
-  <li>When the device is online, Google sends the message to the device.</li>
-  <li>On the device, the system broadcasts the message to the specified Android
-application via Intent broadcast with proper permissions, so that only the targeted
-Android application gets the message. This wakes the Android application up.
-The Android application does not need to be running beforehand to receive the message.</li>
-  <li>The Android application processes the message. </li>
+  <li>The 3rd-party app server sends a message to GCM servers.</li>
+  <li>The GCM connection server enqueues and stores the message if the device is offline.</li>
+  <li>When the device is online, GCM connection server sends the message to the device.</li>
+  <li>The client app processes the message. </li>
 </ol>
 
-<p>The following sections describe the basic requirements for
-sending messages.</p>
+<h3>Implement send request</h3>
 
-<h3 id="target">Target</h3>
+<p>The following sections describe the basic components involved in
+sending a request. See the <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a>
+for details.</p>
+
+<h4 id="target">Target</h4>
 <p>Required. When your app server sends a message in GCM, it must specify a target.</p>
-<p>For HTTP you must specify the target as one of:</p>
+<p>For HTTP you must specify the target as one of the following:</p>
 <ul>
 <li><code>registration_ids</code>: For sending to 1 or more devices (up to 1000).
 When you send a message to multiple registration IDs, that is called a multicast message.</li>
 <li><code>notification_key</code>: For sending to multiple devices owned by a single user.</li>
 </ul>
-<p>For CCS (XMPP):</p>
+<p>For CCS (XMPP) you must specify the target as:</p>
 <ul>
-<li>You must specify the target as the &quot;to&quot; field, where the &quot;to&quot;
+<li>{@code to}: This
 field may contain a single registration ID or a notification key.
-CCS does not support multicast messaging.</li>
+XMPP (CCS) does not support multicast messaging.</li>
 </ul>
-<h3 id="payload">Payload</h3>
-<p>Optional. If you are including a payload in the message, you use the <code>data</code>
-parameter to include the payload. This applies for both HTTP and CCS.</p>
 
-<h3 id="params">Message parameters</h3>
+<h4 id="options">Options</h4>
 
-<p>The following table lists the parameters that a 3rd-party app server might
-include in the JSON messages it sends to a connection server. See the "Where Supported"
-column for information about which connection servers support that particular
-parameter.</p>
+<p>There are various options the 3rd-party app server can set when sending a downstream
+message to a client app. See the <a href="{@docRoot}google/gcm/server-ref.html#table1">
+Server Reference</a> for details. Here are a few examples of possible options:</p>
 
-<p class="table-caption" id="table1">
-  <strong>Table 1.</strong> Message Parameters JSON (CCS and HTTP).</p>
-
-<table>
-  <tr>
-    <th>Parameter</th>
-    <th>Description</th>
-<th>Where Supported</th>
-</tr>
-  <td><code>to</code></td>
-<td>In CCS, this parameter is used in place of <code>registration_ids</code> to
-specify the recipient of a message. Its value must be a registration ID.
-The value is a string. Required.</td>
-<td>CCS</td>
-</tr>
-<tr>
-<td><code>message_id</code></td>
-<td>In CCS, this parameter uniquely identifies a message in an XMPP connection.
-The value is a string that uniquely identifies the associated message. Required.</td>
-<td>CCS</td>
-</tr>
-<tr>
-<td><code>message_type</code></td>
-<td>In CCS, this parameter indicates a special status message, typically sent by the system.
-However, your app server also uses this parameter to send an 'ack' or 'nack'
-message back to the CCS connection server. For more discussion of this topic, see
-<a href="ccs.html">Cloud Connection Server</a>. The value is a string. Optional.</td>
-<td>CCS</td>
-<tr>
-  <td><code>registration_ids</code></td>
-  <td>This parameter specifies a string array containing the list of devices
-(registration IDs) receiving the
-message. It must contain at least 1 and at most 1000 registration IDs. To send a
-multicast message, you must use JSON. For sending a single message to a single
-device, you could use a JSON object with just 1 registration id, or plain text
-(see below). A request must include a recipient&mdash;this can be either a
-registration ID, an array of registration IDs, or a {@code notification_key}.
-Required.</td>
-<td>HTTP</td>
-</tr>
- <tr>
-    <td><code>notification_key</code></td>
-    <td>This parameter specifies a string that maps a single user to multiple
-registration IDs associated
-with that user. This allows a 3rd-party server to send a single message to
-multiple app instances (typically on multiple devices) owned by a single user.
-A 3rd-party server can use {@code notification_key} as the target for a message
-instead of an individual registration ID (or array of registration IDs). The maximum
-number of members allowed for a {@code notification_key} is 20. For more discussion
-of this topic, see <a href="notifications.html">User Notifications</a>. Optional.
-</td>
-<td style="width:100px">HTTP. This feature is supported in CCS, but you use it by
-specifying a notification key in the &quot;to&quot; field.</td>
-</tr>
-  <tr>
-    <td><code>collapse_key</code></td>
-    <td>This parameter specifies an arbitrary string (such as
-&quot;Updates Available&quot;) that is used
-to collapse a group of like messages
-when the device is offline, so that only the last message gets sent to the
-client. This is intended to avoid sending too many messages to the phone when it
-comes back online. Note that since there is no guarantee of the order in which
-messages get sent, the &quot;last&quot; message may not actually be the last
-message sent by the application server. Messages with collapse keys are also called
-<a href="#s2s">send-to-sync messages</a>.
-<br>
-<strong>Note:</strong> GCM allows a maximum of 4 different collapse keys to be
-used by the GCM server
-at any given time. In other words, the GCM server can simultaneously store 4
-different send-to-sync messages per device, each with a different collapse key.
-If you exceed
-this number GCM will only keep 4 collapse keys, with no guarantees about which
-ones they will be. See <a href="adv.html#collapsible">Advanced Topics</a> for more
-discussion of this topic. Optional.</td>
-<td>CCS, HTTP</td>
-</tr>
-  <tr>
-    <td><code>data</code></td>
-    <td>This parameter specifies a JSON object whose fields represents the
-key-value pairs of the message's
-payload data. If present, the payload data will be
-included in the Intent as application data, with the key being the extra's name.
-For instance, <code>"data":{"score":"3x1"}</code> would result in an intent extra
-named <code>score</code> whose value is the string <code>3x1</code>.
-There is no limit on the number of key/value pairs, though there is a limit on
-the total size of the message (4kb). The values could be any JSON object, but we
-recommend using strings, since the values will be converted to strings in the GCM
-server anyway. If you want to include objects or other non-string data types
-(such as integers or booleans), you have to do the conversion to string yourself.
-Also note that the key cannot be a reserved word (<code>from</code> or any word
-starting with <code>google.</code>). Using words defined in this table as field
-names (such as <code>collapse_key</code>) could yield unpredictable outcomes and
-is not recommended. Optional.</td>
-<td>CCS, HTTP</td>
-</tr>
-  <tr>
-    <td><code>delay_while_idle</code></td>
-    <td>This parameter indicates that the message should not be sent immediately
-if the device is idle. The server will wait for the device to become active, and
-then only the last message for each <code>collapse_key</code> value will be
-sent. The default value is <code>false</code>, and must be a JSON boolean. Optional.</td>
-<td>CCS, HTTP</td>
-</tr>
-  <tr>
-    <td><code>time_to_live</code></td>
-    <td>This parameter specifies how long (in seconds) the message should be kept on GCM
-storage if the device is offline. Optional (default time-to-live is 4 weeks, and must be set as
-a JSON number).</td>
-<td>CCS, HTTP</td>
-</tr>
-<tr>
-  <td><code>restricted_package_name</code></td>
-  <td>This parameter specifies a string containing the package
-name of your application. When set, messages
-are only sent to registration IDs that match the package name. Optional.
-  </td>
-<td>HTTP</td>
-</tr>
-<tr>
-  <td><code>dry_run</code></td>
-  <td>This parameter allows developers to test a request without actually
-sending a message. Optional. The default value is <code>false</code>, and must
-be a JSON boolean.
-  </td>
-<td>HTTP</td>
-</tr>
-<tr>
-  <td><code>delivery_receipt_requested</code></td>
-  <td>This parameter lets you request confirmation of message delivery. When
-this parameter is set to <code>true</code>, CCS sends a
-delivery receipt when a device confirms that it received a message sent by CCS.
-The default value is <code>false</code>, and must be a JSON boolean. Optional.<br />
-This parameter relates to <a href="{@docRoot}google/gcm/ccs.html#receipts"}>
-delivery receipts</a>.
-</td>
-  <td>CCS</td>
-</tr>
-<tr>
-  <td><code>message_status</code></td>
-  <td>This parameter specifies the status of the receipt message.
-The parameter appears inside the
-<code>&quot;data&quot;</code> field of a
-delivery receipt message. Currently the only possible value
-is <code>MESSAGE_SENT_TO_DEVICE</code>, which indicates that a device acknowledges
-receiving  a message sent by CCS.<br />
-This parameter relates to <a href="{@docRoot}google/gcm/ccs.html#receipts"}>
-delivery receipts</a>.</td>
-  <td>CCS</td>
-</tr>
-<tr>
-  <td><code>original_message_id</code></td>
-  <td>The value of this parameter is the ID of the original message that the server sent to
-the device. This parameter appears inside the <code>&quot;data&quot;</code> field of a
-delivery receipt message. <br />
-This parameter relates to <a href="{@docRoot}google/gcm/ccs.html#receipts"}>
-delivery receipts</a>.</td>
-  <td>CCS</td>
-</tr>
-<tr>
-  <td><code>device_registration_id</code></td>
-  <td>For the purpose of tracking the delivery receipt, this parameter lists
-the registration ID of the device to which a given message was sent. This parameter
-appears inside the <code>&quot;data&quot;</code> field of a
-delivery receipt message. <br />
-This parameter relates to <a href="{@docRoot}google/gcm/ccs.html#receipts"}>
-delivery receipts</a>.</td>
-  <td>CCS</td>
-</tr>
-
-</table>
-
+<ul>
+  <li>{@code collapse_key}: whether a message should be "send-to-sync" or a "message with
+payload".</li>
+  <li>{@code time_to_live}: setting an expiration date for a message.</li>
+  <li>{@code dry_run}: Test your server.
 <p>If you want to test your request (either JSON or plain text) without delivering
-the message to the devices, you can set an optional HTTP or JSON parameter called
+the message to the devices, you can set an optional HTTP parameter called
 <code>dry_run</code> with the value <code>true</code>. The result will be almost
 identical to running the request without this parameter, except that the message
 will not be delivered to the devices. Consequently, the response will contain fake
 IDs for the message and multicast parameters.</p>
+</li>
+</ul>
 
-<p>If you are using plain text instead of JSON, the message parameters must be set as
-HTTP parameters sent in the body, and their syntax is slightly different, as
-described in the following table:
+<h4 id="payload">Payload</h4>
+<p>Optional. If you are including a payload in the message, you use the <code>data</code>
+parameter to include the payload. This applies for both HTTP and XMPP.</p>
 
-<p class="table-caption" id="table2">
-  <strong>Table 2.</strong> Message Parameters Plain Text (HTTP only).</p>
-<table>
-  <tr>
-    <th>Parameter</th>
-    <th>Description</th>
-  </tr>
-  <tr>
-    <td><code>registration_id</code></td>
-    <td>This parameter specifies the registration ID of the single device
-receiving the message.
-Required.</td>
-  </tr>
-  <tr>
-    <td><code>collapse_key</code></td>
-    <td>Same as JSON (see previous table). Optional.</td>
-  </tr>
-  <tr>
-    <td><code>data.&lt;key&gt;</code></td>
+<p>See the <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a> for details on sending
+and receiving messages.</p>
 
-    <td>This parameter specifies payload data, expressed as parameters
-prefixed with <code>data.</code> and
-suffixed as the key. For instance, a parameter of <code>data.score=3x1</code> would
-result in an intent extra named <code>score</code> whose value is the string
-<code>3x1</code>. There is no limit on the number of key/value parameters, though
-there is a limit on the total size of the  message. Also note that the key cannot
-be a reserved word (<code>from</code> or any word starting with
-<code>google.</code>). Using words defined in this table as field
-names (such as <code>collapse_key</code>) could yield unpredictable outcomes and
-is not recommended. Optional.</td>
+<h2 id="adv">Messaging Concepts and Best Practices</h2>
 
-  </tr>
-  <tr>
-    <td><code>delay_while_idle</code></td>
-    <td>This parameter specifies whether messages should be delivered when the device
-is asleep. A value of <code>1</code> or <code>true</code> indicates
-<code>true</code>, and anything else indicates <code>false</code>. Optional. The default
-value is <code>false</code>.</td>
-  </tr>
-  <tr>
-    <td><code>time_to_live</code></td>
-    <td>Same as JSON (see previous table). Optional.</td>
-  </tr>
-<tr>
-  <td><code>restricted_package_name</code></td>
-  <td>Same as JSON (see previous table). Optional.
-  </td>
-</tr>
-<tr>
-  <td><code>dry_run</code></td>
-  <td>Same as JSON (see previous table). Optional.
-  </td>
-</tr>
-</table>
+<p>This section has a discussion of general messaging topics.</p>
 
-<h2 id="receive">Receiving Messages</h2>
+<h3 id="collapsible">Send-to-Sync  vs. Messages with Payload</h3>
 
-<p>This is the sequence of events that occurs when an Android application
-installed on a mobile device receives a message:</p>
+<p>Every message sent in GCM has the following characteristics:</p>
+<ul>
+  <li>It has a payload limit of 4096 bytes.</li>
+  <li>By default, it is stored by GCM for 4 weeks.</li>
+</ul>
 
-<ol>
-  <li>The system receives the incoming message and extracts the raw key/value
-pairs from the message payload, if any.</li>
-  <li>The system passes the key/value pairs to the targeted Android application
-in a <code>com.google.android.c2dm.intent.RECEIVE</code> Intent as a set of
-extras.</li>
-  <li>The Android application extracts the raw data
-from the <code>com.google.android.c2dm.intent.RECEIVE</code><code> </code>Intent
-by key and processes the data.</li>
-</ol>
+<p>But despite these similarities, messages can behave very differently depending
+on their particular settings. One major distinction between messages is whether
+they are collapsed (where each new message replaces the preceding message) or not
+collapsed (where each individual message is delivered). Every message sent in GCM
+is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with
+payload&quot; (non-collapsible message).</p>
 
-<p>See the documentation for each connection server for more detail on how it
-handles responses.</p>
+<h4 id="s2s">Send-to-sync messages</h4>
+
+<p>A send-to-sync (collapsible) message is often a &quot;tickle&quot; that tells
+a mobile application to sync data from the server. For example, suppose you have
+an email application. When a user receives new email on the server, the server
+pings the mobile application with a &quot;New mail&quot; message. This tells the
+application to sync to the server to pick up the new email. The server might send
+this message multiple times as new mail continues to accumulate, before the application
+has had a chance to sync. But if the user has received 25 new emails, there's no
+need to preserve every &quot;New mail&quot; message. One is sufficient. Another
+example would be a sports application that updates users with the latest score.
+Only the most recent message is relevant. </p>
+
+<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server
+at any given time. In other words, the GCM server can simultaneously store 4
+different send-to-sync messages per device, each with a different collapse key.
+For example, Device A can have A1, A2, A3, and A4. Device B can have B1, B2, B3,
+and B4, and so on. If you exceed this number GCM will only keep 4 collapse keys, with no
+guarantees about which ones they will be.</p>
+
+<h3 id="payload">Messages with payload</h3>
+
+<p>Unlike a send-to-sync message, every &quot;message with payload&quot;
+(non-collapsible message) is delivered. The payload the message contains can be
+up to 4kb. For example, here is a JSON-formatted message in an IM application in
+which spectators are discussing a sporting event:</p>
+
+<pre class="prettyprint pretty-json">{
+  "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
+  "data" : {
+    "Nick" : "Mario",
+    "Text" : "great match!",
+    "Room" : "PortugalVSDenmark",
+  },
+}</pre>
+
+<p>A &quot;message with payload&quot; is not simply a &quot;ping&quot; to the
+mobile application to contact the server to fetch data. In the aforementioned IM
+application, for example, you would want to deliver every message, because every
+message has different content. To specify a non-collapsible message, you simply
+omit the <code>collapse_key</code> parameter. Thus GCM will send each message
+individually. Note that the order of delivery is not guaranteed.</p>
+
+<p>GCM will store up to 100 non-collapsible messages. After that, all messages
+are discarded from GCM, and a new message is created that tells the client how
+far behind it is.</p>
+
+<p>The application should respond by syncing with the server to recover the
+discarded messages. </p>
+
+<h4 id="which">Which should I use?</h4>
+  <p>If your application does not need to use non-collapsible messages, collapsible
+messages are a better choice from a performance standpoint. However, if you use
+collapsible messages, remember that <strong>GCM only allows a maximum of 4 different collapse
+keys to be used by the GCM server per registration ID at any given time</strong>. You must
+not exceed this number, or it could cause unpredictable consequences.</p>
+
+<h3 id="ttl">Setting an Expiration Date for a Message</h3>
+<p>You can use the <code>time_to_live</code> parameter in the send request
+to specify the maximum lifespan of a message.
+The value of this parameter must be a duration from 0 to 2,419,200 seconds, and
+it corresponds to the maximum period of time for which GCM will store and try to
+deliver the message. Requests that don't contain this field default to the maximum
+period of 4 weeks.</p>
+<p>Here are some possible uses for this feature:</p>
+<ul>
+  <li>Video chat incoming calls</li>
+  <li>Expiring invitation events</li>
+  <li>Calendar events</li>
+</ul>
+<h4 id="bg">Background </h4>
+<p>GCM usually delivers messages immediately after they are sent. However,
+this might not always be possible. For example, if the platform is Android,
+the device could be turned off, offline, or otherwise unavailable.
+Or the sender itself might request
+that messages not be delivered until the device becomes active by using the
+<code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages
+to prevent an application from consuming excessive resources and negatively
+impacting battery life.</p>
+
+<p>When this happens, GCM will store the message and deliver it as soon as it's
+feasible. While this is fine in most cases, there are some applications for which
+a late message might as well never be delivered. For example, if the message is
+an incoming call or video chat notification, it will only be meaningful for a
+small period of time before the call is terminated. Or if the message is an
+invitation to an event, it will be useless if received after the event has ended.</p>
+
+<p>Another advantage of specifying the expiration date for a message is that GCM
+will never throttle messages with a <code>time_to_live</code> value of 0 seconds.
+In other words, GCM will guarantee best effort for messages that must be delivered
+&quot;now or never.&quot; Keep in mind that a <code>time_to_live</code> value of
+0 means messages that can't be delivered immediately will be discarded. However,
+because such messages are never stored, this provides the best latency for
+sending notifications.</p>
+
+<p>Here is an example of a JSON-formatted request that includes TTL:</p>
+<pre class="prettyprint pretty-json">
+{
+  "collapse_key" : "demo",
+  "delay_while_idle" : true,
+  "registration_ids" : ["xyz"],
+  "data" : {
+    "key1" : "value1",
+    "key2" : "value2",
+  },
+  "time_to_live" : 3
+},
+</pre>
+
+
+<h3 id="multi-senders">Receiving Messages from Multiple Senders</h3>
+
+<p>GCM allows multiple parties to send messages to the same application. For
+example, suppose your application is an articles aggregator with multiple
+contributors, and you want each of them to be able to send a message when they
+publish a new article. This message might contain a URL so that the application
+can download the article. Instead of having to centralize all sending activity in
+one location, GCM gives you the ability to let each of these contributors send
+its own messages.</p>
+
+<p>To make this possible, all you need to do is have each sender generate its own
+project number. Then include those IDs in the sender field, separated by commas,
+when requesting a registration. Finally, share the registration ID with your
+partners, and they'll be able to send messages to your application using their
+own authentication keys.</p>
+
+<p>Note that there is limit of 100 multiple senders.</p>
+
+<h3 id="lifetime">Lifetime of a Message</h3>
+
+<p>When a 3rd-party server posts a message to GCM and receives a message ID back,
+it does not mean that the message was already delivered to the device. Rather, it
+means that it was accepted for delivery. What happens to the message after it is
+accepted depends on many factors.</p>
+
+<p>In the best-case scenario, if the device is connected to GCM, the screen is on,
+and there are no throttling restrictions (see <a href="#throttling">Throttling</a>),
+the message will be delivered right away.</p>
+
+<p>If the device is connected but idle, the message will still be
+delivered right away unless the <code>delay_while_idle</code> flag is set to true.
+Otherwise, it will be stored in the GCM servers until the device is awake. And
+that's where the <code>collapse_key</code> flag plays a role: if there is already
+a message with the same collapse key (and registration ID) stored and waiting for
+delivery, the old message will be discarded and the new message will take its place
+(that is, the old message will be collapsed by the new one). However, if the collapse
+key is not set, both the new and old messages are stored for future delivery.
+Collapsible messages are also called <a href="#s2s">send-to-sync messages</a>.</p>
+
+<p class="note"><strong>Note:</strong> There is a limit on how many messages can
+be stored without collapsing. That limit is currently 100. If the limit is reached,
+all stored messages are discarded. Then when the device is back online, it receives
+a special message indicating that the limit was reached. The application can then
+handle the situation properly, typically by requesting a full sync.
+<br><br>
+Likewise, there is a limit on how many <code>collapse_key</code>s you can have for
+a particular device. GCM allows a maximum of 4 different collapse keys to be used
+by the GCM server per device
+any given time. In other words, the GCM server can simultaneously store 4 different
+send-to-sync messages, each with a different collapse key. If you exceed this number
+GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.
+See <a href="#s2s">Send-to-sync messages</a> for more information.
+</p>
+
+<p>If the device is not connected to GCM, the message will be stored until a
+connection is established (again respecting the collapse key rules). When a connection
+is established, GCM will deliver all pending messages to the device, regardless of
+the <code>delay_while_idle</code> flag. If the device never gets connected again
+(for instance, if it was factory reset), the message will eventually time out and
+be discarded from GCM storage. The default timeout is 4 weeks, unless the
+<code>time_to_live</code> flag is set.</p>
+
+<p>Finally, when GCM attempts to deliver a message to the device and the
+application was uninstalled, GCM will discard that message right away and
+invalidate the registration ID. Future attempts to send a message to that device
+will get a <code>NotRegistered</code> error. See <a href="#unreg">
+How Unregistration Works</a> for more information.</p>
+<p>Although is not possible to track the status of each individual message, the
+Google Cloud Console stats are broken down by messages sent to device, messages
+collapsed, and messages waiting for delivery.</p>
+
+<h3 id="throttling">Throttling</h3>
+<p>To prevent abuse (such as sending a flood of messages to a device) and
+to optimize for the overall network efficiency and battery life of
+devices, GCM implements throttling of messages using a token bucket
+scheme. Messages are throttled on a per application and per <a href="#collapsible">collapse
+key</a> basis (including non-collapsible messages). Each application
+collapse key is granted some initial tokens, and new tokens are granted
+periodically therefter. Each token is valid for a single message sent to
+the device. If an application collapse key exhausts its supply of
+available tokens, new messages are buffered in a pending queue until
+new tokens become available at the time of the periodic grant. Thus
+throttling in between periodic grant intervals may add to the latency
+of message delivery for an application collapse key that sends a large
+number of messages within a short period of time. Messages in the pending
+queue of an application collapse key may be delivered before the time
+of the next periodic grant, if they are piggybacked with messages
+belonging to a non-throttled category by GCM for network and battery
+efficiency reasons.</p>
+
+
diff --git a/docs/html/google/google_toc.cs b/docs/html/google/google_toc.cs
index 0c48a0a..4e8e638 100644
--- a/docs/html/google/google_toc.cs
+++ b/docs/html/google/google_toc.cs
@@ -169,22 +169,15 @@
               <span class="en">HTTP</span></a></li>
               </ul>
         </li>
+        <li><a href="<?cs var:toroot?>google/gcm/server-ref.html">
+            <span class="en">Server Reference</span></a>
+        </li>
         <li><a href="<?cs var:toroot?>google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="<?cs var:toroot?>google/gcm/adv.html">
-            <span class="en">Advanced Topics</span></a>
-        </li>
         <li><a href="<?cs var:toroot?>google/gcm/c2dm.html">
             <span class="en">Migration</span></a>
         </li>
-        <li id="gcm-tree-list" class="nav-section">
-          <div class="nav-section-header">
-            <a href="<?cs var:toroot ?>reference/gcm-packages.html">
-              <span class="en">Reference</span>
-            </a>
-          <div>
-        </li>
       </ul>
   </li>
 
diff --git a/docs/html/google/play-services/ads.jd b/docs/html/google/play-services/ads.jd
index e4f0b2c..2f915f3 100644
--- a/docs/html/google/play-services/ads.jd
+++ b/docs/html/google/play-services/ads.jd
@@ -98,10 +98,8 @@
     serve banner and interstitial ads using the Google Mobile Ads APIs.</p>
 
     <h4>3. Read the documentation</h4>
-    <p>Read the <a class="external-link" href="https://www.google.com/adsense/localized-terms">AdSense
-    Terms of Service</a> and the <a class="external-link"
-    href="https://support.google.com/admob/topic/1307235?hl=en&ref_topic=1307209">AdMob
-    publisher guidelines and policies</a>.</p>
+    <p>Your use of the Google Mobile Ads SDK is governed by the terms between you and Google that
+    govern your use of the Google product (AdSense/AdMob, AdX or DFP) with which you use the SDK.</p>
     <p>For quick access while developing your Android apps, the <a
     href="{@docRoot}reference/gms-packages.html">Google Mobile Ads API reference</a> is available here on
     developer.android.com.</p>
diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd
index 052cf75..e3cacf9 100644
--- a/docs/html/google/play/billing/billing_integrate.jd
+++ b/docs/html/google/play/billing/billing_integrate.jd
@@ -232,7 +232,7 @@
    1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
    Integer.valueOf(0));
 </pre>
-<p>Google Plays sends a response to your {@link android.app.PendingIntent} to the {@link android.app.Activity#onActivityResult onActivityResult} method of your application. The {@link android.app.Activity#onActivityResult onActivityResult} method will have a result code of {@code Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To see the types of order information that is returned in the response {@link android.content.Intent}, see <a href="{@docRoot}google/play/billing/billing_reference.html#getBuyIntent">In-app Billing Reference</a>.</p> 
+<p>Google Play sends a response to your {@link android.app.PendingIntent} to the {@link android.app.Activity#onActivityResult onActivityResult} method of your application. The {@link android.app.Activity#onActivityResult onActivityResult} method will have a result code of {@code Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To see the types of order information that is returned in the response {@link android.content.Intent}, see <a href="{@docRoot}google/play/billing/billing_reference.html#getBuyIntent">In-app Billing Reference</a>.</p> 
 
 <p>The purchase data for the order is a String in JSON format that is mapped to the {@code INAPP_PURCHASE_DATA} key in the response {@link android.content.Intent}, for example:
 <pre>
@@ -243,11 +243,19 @@
    "purchaseTime":1345678900000,
    "purchaseState":0,
    "developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
-   "purchaseToken":"rojeslcdyyiapnqcynkjyyjh"
+   "purchaseToken":<em>"opaque-token-up-to-1000-characters"</em>
  }'
 </pre>
 </p>
 
+<p class="note"><strong>Note:</strong> Google Play generates a token for the
+purchase. This token is an opaque character sequence that may be up to 1,000
+characters long. Pass this entire token to other methods, such as when you
+consume the purchase, as described in
+<a href="{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consume
+a Purchase</a>. Do not abbreviate or truncate this token; you must save and
+return the entire token.</p>
+
 <p>Continuing from the previous example, you get the response code, purchase data, and signature from the response {@link android.content.Intent}.</p>
 <pre>
 &#64;Override
diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd
index 902c2c6..da9178d 100644
--- a/docs/html/google/play/billing/billing_reference.jd
+++ b/docs/html/google/play/billing/billing_reference.jd
@@ -202,7 +202,12 @@
   </tr>
   <tr>
     <td>{@code purchaseToken}</td>
-    <td>A token that uniquely identifies a purchase for a given item and user pair. </td>
+    <td>A token that uniquely identifies a purchase for a given item and user
+    pair. This token may be up to 1,000 characters long.
+    Pass this entire token to other methods, such as when you consume the
+    purchase (as described in
+<a href="{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consume
+    a Purchase</a>). Do not abbreviate or truncate this token.</td>
   </tr>
 </table>
 </p>
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 7ebda53..7c963dd 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -1,5 +1,5 @@
 page.title=Supporting Multiple Screens
-page.metaDescription=Nanaging UIs for the best display on multiple screen sizes.
+page.metaDescription=Managing UIs for the best display on multiple screen sizes.
 meta.tags="multiple screens"
 
 @jd:body
@@ -348,13 +348,13 @@
 <code>hdpi</code> (high), <code>xhdpi</code> extra-high), <code>xxhdpi</code>
 (extra-extra-high), and <code>xxxhdpi</code> (extra-extra-extra-high). For example, bitmaps
 for high-density screens should go in {@code drawable-hdpi/}.</p>
-    <p class="note" id="xxxhdpi-note"><strong>Note:</strong>  the <code>drawable-xxxhdpi</code>
+    <p class="note" id="xxxhdpi-note"><strong>Note:</strong>  The <code>mipmap-xxxhdpi</code>
 qualifier is necessary only to provide a launcher icon that can appear larger than usual on an
 xxhdpi device. You do not need to provide xxxhdpi assets for all your app's images.</p>
     <p>Some devices scale-up the launcher icon by as much as 25%. For example, if your highest
 density launcher icon image is already extra-extra-high-density, the scaling process will make it
 appear less crisp. So you should provide a higher density launcher icon in the
-<code>drawable-xxxhdpi</code> directory, which the system uses instead of scaling up a smaller
+<code>mipmap-xxxhdpi</code> directory, which the system uses instead of scaling up a smaller
 version of the icon.</p>
     <p>See <a href="{@docRoot}design/style/iconography.html#xxxhdpi-launcher">Provide an
 xxx-high-density launcher icon</a> for more information. You should not use the
@@ -362,6 +362,16 @@
   </li>
 </ul>
 
+<p class="note"><strong>Note:</strong> Place all your launcher icons in the
+<code>res/mipmap-[density]/</code> folders, rather than the <code>res/drawable-[density]/</code>
+folders. The Android system retains the resources in these density-specific folders, such as
+mipmap-xxxhdpi, regardless of the screen resolution of the device where your app is installed. This
+behavior allows launcher apps to pick the best resolution icon for your app to display on the home
+screen. For more information about using the mipmap folders, see
+<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.
+</p>
+
+
 <p>The size and density configuration qualifiers correspond to the generalized sizes and densities
 described in <a href="#range">Range of screens supported</a>, above.</p>
 
@@ -538,9 +548,9 @@
 sizes and densities, see <a href="#range">Range of Screens Supported</a>, earlier in this
 document.</p>
 
-<p>For example, the following is a list of resource directories in an application that
-provides different layout designs for different screen sizes and different bitmap drawables
-for medium, high, and extra-high-density screens.</p>
+<p>For example, the following application resource directories provide different layout designs
+for different screen sizes and different drawables. Use the <code>mipmap/</code> folders for
+launcher icons.</p>
 
 <pre class="classic">
 res/layout/my_layout.xml              // layout for normal screen size ("default")
@@ -548,10 +558,16 @@
 res/layout-xlarge/my_layout.xml       // layout for extra-large screen size
 res/layout-xlarge-land/my_layout.xml  // layout for extra-large in landscape orientation
 
-res/drawable-mdpi/my_icon.png         // bitmap for medium-density
-res/drawable-hdpi/my_icon.png         // bitmap for high-density
-res/drawable-xhdpi/my_icon.png        // bitmap for extra-high-density
-res/drawable-xxhdpi/my_icon.png       // bitmap for extra-extra-high-density
+res/drawable-mdpi/graphic.png         // bitmap for medium-density
+res/drawable-hdpi/graphic.png         // bitmap for high-density
+res/drawable-xhdpi/graphic.png        // bitmap for extra-high-density
+res/drawable-xxhdpi/graphic.png       // bitmap for extra-extra-high-density
+
+res/mipmap-mdpi/my_icon.png         // launcher icon for medium-density
+res/mipmap-hdpi/my_icon.png         // launcher icon for high-density
+res/mipmap-xhdpi/my_icon.png        // launcher icon for extra-high-density
+res/mipmap-xxhdpi/my_icon.png       // launcher icon for extra-extra-high-density
+res/mipmap-xxxhdpi/my_icon.png      // launcher icon for extra-extra-extra-high-density
 </pre>
 
 <p>For more information about how to use alternative resources and a complete list of
@@ -560,7 +576,7 @@
 Providing Alternative Resources</a>.</p>
 
 <p>Be aware that, when the Android system picks which resources to use at runtime, it uses
-certain logic to determing the "best matching" resources. That is, the qualifiers you use don't
+certain logic to determine the "best matching" resources. That is, the qualifiers you use don't
 have to exactly match the current screen configuration in all cases in order for the system to
 use them. Specifically, when selecting resources based on the size qualifiers, the system will
 use resources designed for a screen smaller than the current screen if there are no resources
@@ -703,10 +719,10 @@
 smallest width your layout supports once it's complete.</p>
 
 <p class="note"><strong>Note:</strong> Remember that all the figures used with these new size APIs
-are density-indpendent pixel (dp) values and your layout dimensions should also always be defined
+are density-independent pixel (dp) values and your layout dimensions should also always be defined
 using dp units, because what you care about is the amount of screen space available after the system
 accounts for screen density (as opposed to using raw pixel resolution). For more information about
-density-indpendent pixels, read <a href="#terms">Terms and concepts</a>, earlier in this
+density-independent pixels, read <a href="#terms">Terms and concepts</a>, earlier in this
 document.</p>
 
 
@@ -728,7 +744,7 @@
 a part of your application's window space, although your layout does not declare it, so it reduces
 the space available for your layout and you must account for it in your design.</p>
 
-<p class="table-caption"><strong>Table 2.</strong> New configuration qualifers for screen size
+<p class="table-caption"><strong>Table 2.</strong> New configuration qualifiers for screen size
 (introduced in Android 3.2).</p>
 <table>
   <tr><th>Screen configuration</th><th>Qualifier values</th><th>Description</th></tr>
@@ -745,7 +761,7 @@
 use this qualifier to ensure that, regardless of the screen's current orientation, your
 application's has at least {@code &lt;N&gt;} dps of width available for its UI.</p>
         <p>For example, if your layout requires that its smallest dimension of screen area be at
-least 600 dp at all times, then you can use this qualifer to create the layout resources, {@code
+least 600 dp at all times, then you can use this qualifier to create the layout resources, {@code
 res/layout-sw600dp/}. The system will use these resources only when the smallest dimension of
 available screen is at least 600dp, regardless of whether the 600dp side is the user-perceived
 height or width. The smallestWidth is a fixed screen size characteristic of the device; <strong>the
@@ -851,7 +867,7 @@
 res/layout-sw720dp/main_activity.xml   # For 10” tablets (720dp wide and bigger)
 </pre>
 
-<p>Notice that the previous two sets of example resources use the "smallest width" qualifer, {@code
+<p>Notice that the previous two sets of example resources use the "smallest width" qualifier, {@code
 sw&lt;N&gt;dp}, which specifies the smallest of the screen's two sides, regardless of the
 device's current orientation. Thus, using {@code sw&lt;N&gt;dp} is a simple way to specify the
 overall screen size available for your layout by ignoring the screen's orientation.</p>
@@ -1392,4 +1408,4 @@
 
 <p>For more information about creating AVDs from the command line, see <a
 href="{@docRoot}tools/devices/managing-avds-cmdline.html">Managing AVDs from the
-Command Line</a>.</p>
\ No newline at end of file
+Command Line</a>.</p>
diff --git a/docs/html/guide/topics/data/backup.jd b/docs/html/guide/topics/data/backup.jd
index f09ff9e..5710a47 100644
--- a/docs/html/guide/topics/data/backup.jd
+++ b/docs/html/guide/topics/data/backup.jd
@@ -643,7 +643,8 @@
     // Allocate a helper and add it to the backup agent
     &#64;Override
     public void onCreate() {
-        SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
+        SharedPreferencesBackupHelper helper =
+                new SharedPreferencesBackupHelper(this, PREFS);
         addHelper(PREFS_BACKUP_KEY, helper);
     }
 }
@@ -688,8 +689,10 @@
     static final String FILES_BACKUP_KEY = "myfiles";
 
     // Allocate a helper and add it to the backup agent
-    void onCreate() {
-        FileBackupHelper helper = new FileBackupHelper(this, TOP_SCORES, PLAYER_STATS);
+    &#64;Override
+    public void onCreate() {
+        FileBackupHelper helper = new FileBackupHelper(this,
+                TOP_SCORES, PLAYER_STATS);
         addHelper(FILES_BACKUP_KEY, helper);
     }
 }
diff --git a/docs/html/guide/topics/media/exoplayer.jd b/docs/html/guide/topics/media/exoplayer.jd
index 17b4669..1e8601f 100644
--- a/docs/html/guide/topics/media/exoplayer.jd
+++ b/docs/html/guide/topics/media/exoplayer.jd
@@ -72,10 +72,8 @@
 <ul>
     <li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/library">
       ExoPlayer Library</a> &mdash; This part of the project contains the core library classes.</li>
-    <li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/demo/src/main/java/com/google/android/exoplayer/demo/simple">
-      Simple Demo</a> &mdash; This part of the app demonstrates a basic use of ExoPlayer.</li>
-    <li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/demo/src/main/java/com/google/android/exoplayer/demo/full">
-      Full Demo</a> &mdash; This part of the app demonstrates more advanced features,
+    <li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/demo">
+      Demo App</a> &mdash; This part of the project demonstrates usage of ExoPlayer,
       including the ability to select between multiple audio tracks, a background audio mode,
       event logging and DRM protected playback. </li>
 </ul>
@@ -137,9 +135,10 @@
 player.release(); // Don’t forget to release when done!
 </pre>
 
-<p>For a complete example, see the {@code SimplePlayerActivity} in the ExoPlayer demo app, which
-  correctly manages an ExoPlayer instance with respect to both the {@link android.app.Activity} and
-  {@link android.view.Surface} lifecycles.</p>
+<p>For a complete example, see {@code PlayerActivity} and {@code DemoPlayer} in the ExoPlayer demo
+  app. Between them these classes correctly manage an ExoPlayer instance with respect to both the
+  {@link android.app.Activity} and {@link android.view.Surface} lifecycles.
+</p>
 
 
 <h2 id="samplesource">SampleSource</h2>
@@ -187,7 +186,7 @@
 </pre>
 
 <p>The ExoPlayer demo app provides a complete implementation of this code in
-  {@code DefaultRendererBuilder}. The {@code SimplePlaybackActivity} class uses it to play one
+  {@code DefaultRendererBuilder}. The {@code PlayerActivity} class uses it to play one
   of the videos available in the demo app. Note that in the example, video and audio
   are muxed, meaning they are streamed together from a single URI. The {@code FrameworkSampleSource}
   instance provides video samples to the {@code videoRenderer} object and audio samples to the
@@ -211,9 +210,9 @@
   which loads chunks of media data from which individual samples can be extracted. Each {@code
   ChunkSampleSource} requires a {@code ChunkSource} object to be injected through its constructor,
   which is responsible for providing media chunks from which to load and read samples. The {@code
-  DashMp4ChunkSource} and {@code SmoothStreamingChunkSource} classes provide DASH and SmoothStreaming
-  playback using the FMP4 container format. The {@code DashWebMChunkSource} class uses the WebM
-  container format to provide DASH playback.</p>
+  DashChunkSource} class provides DASH playback using the FMP4 and WebM container formats. The
+  {@code SmoothStreamingChunkSource} class provides SmoothStreaming playback using the FMP4
+  container format.</p>
 
 <p>All of the standard {@code ChunkSource} implementations require a {@code FormatEvaluator} and
   a {@code DataSource} to be injected through their constructors. The {@code FormatEvaluator}
@@ -242,7 +241,7 @@
 // Build the video renderer.
 DataSource videoDataSource = new HttpDataSource(userAgent,
         HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
-ChunkSource videoChunkSource = new DashMp4ChunkSource(videoDataSource,
+ChunkSource videoChunkSource = new DashChunkSource(videoDataSource,
         new AdaptiveEvaluator(bandwidthMeter), videoRepresentations);
 ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource,
         loadControl, VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
@@ -253,7 +252,7 @@
 // Build the audio renderer.
 DataSource audioDataSource = new HttpDataSource(userAgent,
         HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
-ChunkSource audioChunkSource = new DashMp4ChunkSource(audioDataSource,
+ChunkSource audioChunkSource = new DashChunkSource(audioDataSource,
         new FormatEvaluator.FixedEvaluator(), audioRepresentation);
 SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource,
         loadControl, AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
@@ -273,9 +272,8 @@
 </p>
 
 <p>The ExoPlayer demo app provides complete implementation of this code in
-  {@code DashVodRendererBuilder}. The {@code SimplePlaybackActivity} class uses this builder to
-  construct renderers for playing DASH sample videos in the demo app. It asynchronously fetches a
-  specified MPD file in order to construct the required {@code Representation} objects. For an
+  {@code DashRendererBuilder}. The {@code PlayerActivity} class uses this builder to
+  construct renderers for playing DASH sample videos in the demo app. For an
   equivalent SmoothStreaming example, see the {@code SmoothStreamingRendererBuilder} class in the
   demo app.</p>
 
@@ -313,7 +311,7 @@
 }
 </pre>
 
-<p>This approach is used to filter {@code Representations} in the {@code DashVodRendererBuilder}
+<p>This approach is used to filter {@code Representations} in the {@code DashRendererBuilder}
   class of the ExoPlayer demo app, and similarly to filter track indices in {@code
   SmoothStreamingRendererBuilder}.</p>
 
@@ -372,24 +370,26 @@
 <p>In addition to high level listeners, many of the individual components provided by the
   ExoPlayer library allow their own event listeners. For example, {@code
   MediaCodecVideoTrackRenderer} has constructors that take a {@code
-  MediaCodecVideoTrackRenderer.EventListener}. In the ExoPlayer demo app, {@code SimplePlayerActivity}
-  acts as a listener so that it can adjust the dimensions of the target surface to have the correct
-  height and width ratio for the video being played:</p>
+  MediaCodecVideoTrackRenderer.EventListener}. In the ExoPlayer demo app, {@code DemoPlayer}
+  acts as the listener to multiple individual components, forwarding events to {@code PlayerActivity}.
+  This approach allows {@code PlayerActivity} to adjust the dimensions of the target surface
+  to have the correct height and width ratio for the video being played:</p>
 
 <pre>
 &#64;Override
-public void onVideoSizeChanged(int width, int height) {
-  surfaceView.setVideoWidthHeightRatio(height == 0 ? 1 : (float) width / height);
+public void onVideoSizeChanged(int width, int height, float pixelWidthAspectRatio) {
+  surfaceView.setVideoWidthHeightRatio(
+          height == 0 ? 1 : (width * pixelWidthAspectRatio) / height);
 }
 </pre>
 
-<p>The {@code RendererBuilder} classes in the ExoPlayer demo app inject the activity as the
-  listener, for example in the {@code DashVodRendererBuilder} class:</p>
+<p>The {@code RendererBuilder} classes in the ExoPlayer demo app inject the {@code DemoPlayer} as
+  the listener to each component, for example in the {@code DashRendererBuilder} class:</p>
 
 <pre>
 MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(
-        videoSampleSource, null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT,
-        0, <strong>mainHandler, playerActivity</strong>, 50);
+        sampleSource, null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
+        null, <strong>player.getMainHandler(), player</strong>, 50);
 </pre>
 
 <p>Note that you must pass a {@link android.os.Handler} object to the renderer, which determines
@@ -441,9 +441,7 @@
 
 <p>You must use a blocking message because the contract of {@link
   android.view.SurfaceHolder.Callback#surfaceDestroyed surfaceDestroyed()} requires that the
-  app does not attempt to access the surface after the method returns. The {@code
-  SimplePlayerActivity} class in the demo app demonstrates how the surface should be set and
-  cleared.</p>
+  app does not attempt to access the surface after the method returns.</p>
 
 
 <h2 id="customizing">Customizing ExoPlayer</h2>
diff --git a/docs/html/guide/topics/resources/available-resources.jd b/docs/html/guide/topics/resources/available-resources.jd
index 19babee..db1bf8d 100644
--- a/docs/html/guide/topics/resources/available-resources.jd
+++ b/docs/html/guide/topics/resources/available-resources.jd
@@ -29,6 +29,7 @@
   <dt><a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a></dt>
     <dd>Define various graphics with bitmaps or XML.<br/>
 Saved in {@code res/drawable/} and accessed from the {@code R.drawable} class.</dd>
+
   <dt><a href="{@docRoot}guide/topics/resources/layout-resource.html">Layout Resource</a></dt>
     <dd>Define the layout for your application UI.<br/>
 Saved in {@code res/layout/} and accessed from the {@code R.layout} class.</dd>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 6d9527f..98e7c96 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -60,18 +60,24 @@
         MyActivity.java  </span>
     res/
         drawable/  <span style="color:black">
-            icon.png  </span>
+            graphic.png  </span>
         layout/  <span style="color:black">
             main.xml
             info.xml</span>
+        mipmap/  <span style="color:black">
+            icon.png </span>
         values/  <span style="color:black">
             strings.xml  </span>
 </pre>
 
 <p>As you can see in this example, the {@code res/} directory contains all the resources (in
-subdirectories): an image resource, two layout resources, and a string resource file. The resource
+subdirectories): an image resource, two layout resources, {@code mipmap/} directories for launcher
+icons, and a string resource file. The resource
 directory names are important and are described in table 1.</p>
 
+<p class="note"><strong>Note:</strong> For more information about using the mipmap folders, see
+<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.</p>
+
 <p class="table-caption" id="table1"><strong>Table 1.</strong> Resource directories
 supported inside project {@code res/} directory.</p>
 
@@ -104,6 +110,7 @@
 
   <tr>
     <td><code>drawable/</code></td>
+
     <td><p>Bitmap files ({@code .png}, {@code .9.png}, {@code .jpg}, {@code .gif}) or XML files that
 are compiled into the following drawable resource subtypes:</p>
       <ul>
@@ -119,6 +126,13 @@
   </tr>
 
   <tr>
+    <td><code>mipmap/</code></td>
+    <td>Drawable files for different launcher icon densities. For more information on managing
+    launcher icons with {@code mipmap/} folders, see
+    <a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.</td>
+  </tr>
+
+  <tr>
     <td><code>layout/</code></td>
     <td>XML files that define a user interface layout.
         See <a href="layout-resource.html">Layout Resource</a>.</td>
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index e47c77e..976115e 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -663,20 +663,21 @@
 NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
 // Creates an Intent for the Activity
 Intent notifyIntent =
-        new Intent(new ComponentName(this, ResultActivity.class));
+        new Intent(this, ResultActivity.class);
 // Sets the Activity to start in a new, empty task
-notifyIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
+notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 // Creates the PendingIntent
-PendingIntent notifyIntent =
+PendingIntent notifyPendingIntent =
         PendingIntent.getActivity(
         this,
         0,
-        notifyIntent
+        notifyIntent,
         PendingIntent.FLAG_UPDATE_CURRENT
 );
 
 // Puts the PendingIntent into the notification builder
-builder.setContentIntent(notifyIntent);
+builder.setContentIntent(notifyPendingIntent);
 // Notifications are issued by sending them to the
 // NotificationManager system service.
 NotificationManager mNotificationManager =
@@ -715,7 +716,7 @@
 <h3 id="FixedProgress">Displaying a fixed-duration progress indicator</h3>
 <p>
     To display a determinate progress bar, add the bar to your notification by calling
-    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()
+    {@link android.support.v4.app.NotificationCompat.Builder#setProgress
     setProgress(max, progress, false)} and then issue the notification. As your operation proceeds,
     increment <code>progress</code>, and update the notification. At the end of the operation,
     <code>progress</code> should equal <code>max</code>. A common way to call
@@ -727,7 +728,7 @@
     You can either leave the progress bar showing when the operation is done, or remove it. In
     either case, remember to update the notification text to show that the operation is complete.
     To remove the progress bar, call
-    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()
+    {@link android.support.v4.app.NotificationCompat.Builder#setProgress
     setProgress(0, 0, false)}. For example:
 </p>
 <pre>
@@ -783,8 +784,8 @@
 <p>
     Issue the notification at the beginning of the operation. The animation will run until you
     modify your notification. When the operation is done, call
-    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()
-    setProgress(0, 0, false)} and then update the notification to remove the activity indicator.
+    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)}
+    and then update the notification to remove the activity indicator.
     Always do this; otherwise, the animation will run even when the operation is complete. Also
     remember to change the notification text to indicate that the operation is complete.
 </p>
diff --git a/docs/html/images/exoplayer/adaptive-streaming.png b/docs/html/images/exoplayer/adaptive-streaming.png
index 9fc650c9..50eee70 100644
--- a/docs/html/images/exoplayer/adaptive-streaming.png
+++ b/docs/html/images/exoplayer/adaptive-streaming.png
Binary files differ
diff --git a/docs/html/images/opengl/ogl-triangle-projected.png b/docs/html/images/opengl/ogl-triangle-projected.png
index 4b18b98..a561bc5 100644
--- a/docs/html/images/opengl/ogl-triangle-projected.png
+++ b/docs/html/images/opengl/ogl-triangle-projected.png
Binary files differ
diff --git a/docs/html/images/opengl/ogl-triangle-touch.png b/docs/html/images/opengl/ogl-triangle-touch.png
index 8323dd9..67c4466 100644
--- a/docs/html/images/opengl/ogl-triangle-touch.png
+++ b/docs/html/images/opengl/ogl-triangle-touch.png
Binary files differ
diff --git a/docs/html/images/opengl/ogl-triangle.png b/docs/html/images/opengl/ogl-triangle.png
index 66047ab..f51c0c6 100644
--- a/docs/html/images/opengl/ogl-triangle.png
+++ b/docs/html/images/opengl/ogl-triangle.png
Binary files differ
diff --git a/docs/html/images/tools/projectview-p1.png b/docs/html/images/tools/projectview-p1.png
new file mode 100644
index 0000000..f5fae63
--- /dev/null
+++ b/docs/html/images/tools/projectview-p1.png
Binary files differ
diff --git a/docs/html/images/tools/projectview-p2.png b/docs/html/images/tools/projectview-p2.png
new file mode 100644
index 0000000..9e52540
--- /dev/null
+++ b/docs/html/images/tools/projectview-p2.png
Binary files differ
diff --git a/docs/html/images/tools/studio-mipmap-folders.png b/docs/html/images/tools/studio-mipmap-folders.png
new file mode 100644
index 0000000..3e99180
--- /dev/null
+++ b/docs/html/images/tools/studio-mipmap-folders.png
Binary files differ
diff --git a/docs/html/images/tools/studio-project-layout.png b/docs/html/images/tools/studio-project-layout.png
index 880c233..7339c3f 100644
--- a/docs/html/images/tools/studio-project-layout.png
+++ b/docs/html/images/tools/studio-project-layout.png
Binary files differ
diff --git a/docs/html/images/transitions/transition_sample_video.mp4 b/docs/html/images/transitions/transition_sample_video.mp4
new file mode 100644
index 0000000..37ae685
--- /dev/null
+++ b/docs/html/images/transitions/transition_sample_video.mp4
Binary files differ
diff --git a/docs/html/images/transitions/transition_sample_video.ogv b/docs/html/images/transitions/transition_sample_video.ogv
new file mode 100644
index 0000000..5598814
--- /dev/null
+++ b/docs/html/images/transitions/transition_sample_video.ogv
Binary files differ
diff --git a/docs/html/images/transitions/transition_sample_video.webm b/docs/html/images/transitions/transition_sample_video.webm
new file mode 100644
index 0000000..346ba8c
--- /dev/null
+++ b/docs/html/images/transitions/transition_sample_video.webm
Binary files differ
diff --git a/docs/html/images/transitions/transitions_diagram.png b/docs/html/images/transitions/transitions_diagram.png
new file mode 100644
index 0000000..9363940
--- /dev/null
+++ b/docs/html/images/transitions/transitions_diagram.png
Binary files differ
diff --git a/docs/html/images/tv/app-browse.png b/docs/html/images/tv/app-browse.png
new file mode 100644
index 0000000..7670713
--- /dev/null
+++ b/docs/html/images/tv/app-browse.png
Binary files differ
diff --git a/docs/html/images/tv/card-view.png b/docs/html/images/tv/card-view.png
new file mode 100644
index 0000000..5e907de
--- /dev/null
+++ b/docs/html/images/tv/card-view.png
Binary files differ
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index d712196..1100964 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -482,14 +482,14 @@
 
 <ul>
 <li>GNOME or KDE desktop</li>
-<li>GNU C Library (glibc) 2.11 or later</li>
+<li>GNU C Library (glibc) 2.15 or later</li>
 <li>2 GB RAM minimum, 4 GB RAM recommended</li>
 <li>400 MB hard disk space</li>
 <li>At least 1 GB for Android SDK, emulator system images, and caches</li>
 <li>1280 x 800 minimum screen resolution</li>
 <li>Oracle&reg;  Java Development Kit (JDK) 7 </li>
 </ul>
-<p>Tested on Ubuntu&reg;  12.04, Precise Pangolin (64-bit distribution capable of running
+<p>Tested on Ubuntu&reg;  14.04, Trusty Tahr (64-bit distribution capable of running
 32-bit applications).</p>
 
 
diff --git a/docs/html/sdk/installing/create-project.jd b/docs/html/sdk/installing/create-project.jd
index 5082537..68fd572 100644
--- a/docs/html/sdk/installing/create-project.jd
+++ b/docs/html/sdk/installing/create-project.jd
@@ -71,7 +71,7 @@
 <h3 id="Step2SelectFormFactor">Step 2: Select Form Factors and API Level</h2>
 
 <p>The next window lets you select the form factors supported by your app, such as phone, tablet,
-TV, Wear, and Google Glass. The selected form factors become the application modules witin the
+TV, Wear, and Google Glass. The selected form factors become the application modules within the
 project. For each form factor, you can also select the API Level for that app. To get more information,
 click <strong>Help me choose</strong>.</p>
 
@@ -220,7 +220,7 @@
   along with the other modules. </p>
 
   <p> You can easily change an existing application module to a library module by changing the
-  plugin assignment in the <strong>build.gradle</strong> file to <em>com.android.libary</em>.</p>
+  plugin assignment in the <strong>build.gradle</strong> file to <em>com.android.library</em>.</p>
 
 <pre>
 apply plugin: 'com.android.application'
@@ -287,7 +287,7 @@
 
   <ol>
     <li>Make sure that both the module library and the application module that depends on it are
-      in your proejct. If one of the modules is missing, import it into your project.</li>
+      in your project. If one of the modules is missing, import it into your project.</li>
 
     <li>In the project view, right-click the dependent module and select
     <strong>Open</strong> > <strong>Module Settings</strong>.</li>
@@ -359,39 +359,38 @@
 per resource type.</li>
 </ul>
 
-<div style="float:right;margin-left:30px;width:240px">
-<img src="{@docRoot}images/tools/projectview01.png" alt="" width="220" height="264"/>
-<p class="img-caption"><strong>Figure 9:</strong> Show the Android project view.</p>
-</div>
 
 
-<h2 id="enable-view">Enable and use the Android Project View</h2>
+<h2 id="enable-view">Use the Android Project View</h2>
 
-<p>The Android project view is not yet enabled by default. To show the Android project view,
-click <strong>Project</strong> and select <strong>Android</strong>, as shown in figure 9.</p>
-
-<p>The Android project view shows all the build files at the top level of the project hierarchy
-under <strong>Gradle Scripts</strong>. Each project module appears as a folder at the top
-level of the project hierarchy and contains these three elements at the top level:</p>
+<p>The <em>Android</em> project view is enabled by default and shows all the build files at
+the top level of the project hierarchy under <strong>Gradle Scripts</strong>. The project module
+appears as a folder at the top level of the project hierarchy and contains these three elements
+at the top level:</p>
 
 <ul>
-<li><code>java/</code> - Source files for the module.</li>
 <li><code>manifests/</code> - Manifest files for the module.</li>
+<li><code>java/</code> - Source files for the module.</li>
 <li><code>res/</code> - Resource files for the module.</li>
 </ul>
 
-<p>Figure 10 shows how the Android project view groups all the instances of the
+<p>Notice how the Android project view groups all instances of the
 <code>ic_launcher.png</code> resource for different screen densities under the same element.</p>
 
 <p class="note"><strong>Note:</strong> The Android project view shows a hierarchy that helps you
 work with Android projects by providing a flattened structure that highlights the most commonly
 used files while developing Android applications. However, the project structure on disk differs
-from this representation.</p>
+from this representation and maintains the traditional project structure.</p>
 
-<img src="{@docRoot}images/tools/projectview03.png" alt=""
-     style="margin-top:10px" width="650" height="508"/>
-<p class="img-caption"><strong>Figure 10:</strong> The traditional project view (left) and the
-Android project view (right).</p>
+<img src="{@docRoot}images/tools/projectview-p1.png" alt="" style="width:240px" "/>
+&nbsp;&nbsp;&nbsp;
+<img src="{@docRoot}images/tools/projectview-p2.png" alt="" style="width:240px" " />
+<p class="img-caption"><strong>Figure 10:</strong> Android and Traditional project view </p>
+
+
+
+
+
 
 
 
diff --git a/docs/html/tools/building/plugin-for-gradle.jd b/docs/html/tools/building/plugin-for-gradle.jd
index 77cbfda..54a03fd 100644
--- a/docs/html/tools/building/plugin-for-gradle.jd
+++ b/docs/html/tools/building/plugin-for-gradle.jd
@@ -321,7 +321,7 @@
 machine and on other machines where Android Studio is not installed.</p>
 
 <p class="caution"><strong>Caution:</strong> When you create a project, only use the Gradle wrapper
-scripts and JAR from a trusted source, such as those generated by Android Studio. /p>
+scripts and JAR from a trusted source, such as those generated by Android Studio. </p>
 
 
 <h2 id="buildVariants"> Build variants</h2>
diff --git a/docs/html/tools/devices/emulator.jd b/docs/html/tools/devices/emulator.jd
index 42240b9..5bdd4e2 100644
--- a/docs/html/tools/devices/emulator.jd
+++ b/docs/html/tools/devices/emulator.jd
@@ -122,7 +122,7 @@
 mobile devices, including: </p>
 
 <ul>
-  <li>An ARMv5 CPU and the corresponding memory-management unit (MMU)</li>
+  <li>An ARMv5, ARMv7, or x86 CPU</li>
   <li>A 16-bit LCD display</li>
   <li>One or more keyboards (a Qwerty-based keyboard and associated Dpad/Phone
 buttons)</li>
diff --git a/docs/html/tools/projects/index.jd b/docs/html/tools/projects/index.jd
index 5f4f2cc..8665479 100644
--- a/docs/html/tools/projects/index.jd
+++ b/docs/html/tools/projects/index.jd
@@ -1,4 +1,6 @@
 page.title=Managing Projects Overview
+meta.tags="project, mipmap"
+page.tags="project", "mipmap"
 @jd:body
 
  <div id="qv-wrapper">
@@ -8,7 +10,9 @@
       <ol>
         <li><a href="#ProjectFiles">Android Project Files</a></li>
         <li><a href="#ApplicationModules">Android Application Modules</a></li>
-
+          <ol>
+            <li><a href="#mipmap">Managing Launcher Icons as mipmap Resources</a></li>
+          </ol>
         <li><a href="#LibraryModules">Library Modules</a>
           <ol>
             <li><a href="#considerations">Development considerations</a></li>
@@ -230,7 +234,18 @@
            focused). See the <a href=
            "{@docRoot}guide/topics/resources/drawable-resource.html">Drawable</a> resource type.</dd>
 
-           <dt><code>layout/</code></dt>
+
+           <dt><code>mipmap/</code></dt>
+
+           <dd>For app launcher icons. The Android system retains the resources in this folder
+           (and density-specific folders such as mipmap-xxxhdpi) regardless of the screen resolution
+           of the device where your app is installed. This behavior allows launcher apps to pick
+           the best resolution icon for your app to display on the home screen. For more information
+           about using the <code>mipmap</code> folders, see
+           <a href="#mipmap">Managing Launcher Icons as mipmap Resources</a>. </p>
+
+
+          <dt><code>layout/</code></dt>
 
            <dd>XML files that are compiled into screen layouts (or part of a screen). See the <a href=
            "{@docRoot}guide/topics/resources/layout-resource.html">Layout</a> resource type.</dd>
@@ -304,6 +319,46 @@
 
 
 
+<h2 id="mipmap">Managing Launcher Icons as mipmap Resources</h2>
+
+<p>Different home screen launcher apps on different devices show app launcher icons at various
+resolutions. When app resource optimization techniques remove resources for unused
+screen densities, launcher icons can wind up looking fuzzy because the launcher app has to upscale
+a lower-resolution icon for display. To avoid these display issues, apps should use the
+<code>mipmap/</code> resource folders for launcher icons. The Android system
+preserves these resources regardless of density stripping, and ensures that launcher apps can
+pick icons with the best resolution for display. </p>
+
+<p>Make sure launcher apps show a high-resolution icon for your app by moving all densities of your
+launcher icons to density-specific <code>res/mipmap/</code> folders
+(for example <code>res/mipmap-mdpi/</code> and <code>res/mipmap-xxxhdpi/</code>). The
+<code>mipmap/</code> folders replace the <code>drawable/</code> folders for launcher icons. For
+xxhpdi launcher icons, be sure to add the higher resolution xxxhdpi versions of the
+icons to enhance the visual experience of the icons on higher resolution devices.</p>
+
+<p class="note"><strong>Note:</strong> Even if you build a single APK for all devices, it is still
+best practice to move your launcher icons to the <code>mipmap/</code> folders.</p>
+
+
+<h3>Manifest update</h3>
+
+<p>When you move your launcher icons to the <code>mipmap-[density]</code> folders, change the
+launcher icon references in the <code>AndroidManifest.xml</code> file so your manifest references
+the <code>mipmap/</code> location. This example changes the manifest file to reference the
+<code>ic_launcher</code> icon in the <code>mipmap/</code> folder. </p>
+
+<pre>
+...
+&lt;application android:name="ApplicationTitle"
+         android:label="@string/app_label"
+         android:icon="@mipmap/ic_launcher" &gt;
+         ...
+</pre>
+
+
+
+
+
   <h2 id="LibraryModules">Library Module</h2>
 
   <div class="sidebox-wrapper">
diff --git a/docs/html/tools/revisions/gradle-plugin.jd b/docs/html/tools/revisions/gradle-plugin.jd
new file mode 100644
index 0000000..23170e1
--- /dev/null
+++ b/docs/html/tools/revisions/gradle-plugin.jd
@@ -0,0 +1,153 @@
+page.title=Android Plugin for Gradle Release Notes
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+  <h2>See also</h2>
+  <ol>
+     <li><a href="{@docRoot}sdk/installing/studio-build.html">Build System Overview</a></li>
+     <li><a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plugin for Gradle</a></li>
+  </ol>
+
+</div>
+</div>
+
+
+<p>The Android build system uses the Android Plugin for Gradle to support building Android
+applications with the <a href="http://www.gradle.org/">Gradle</a> build toolkit. The plugin runs
+independent of Android Studio so the plugin and the Gradle build system can be updated
+independently of Android Studio.</p>
+
+<p class="note"><strong>Note:</strong> When you update Android Studio or open a project in a
+previous version of Android Studio, Android Studio prompts you to automatically update the plugin
+and Gradle to the latest available versions. You can choose to accept these updates based
+on your project's build requirements. </p>
+
+
+<h2 id="revisions">Revisions</h2>
+
+<p>The sections below provide notes about successive releases of
+the Android Plugin for Gradle, as denoted by revision number. To determine what revision of the
+plugin you are using, check the version declaration in the project-level
+<strong>build.gradle</strong> file. </p>
+
+<p>For a summary of known issues in Android Plugin for Gradle, see <a
+href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</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=""/>Android Plugin for Gradle, Revision 1.1</a> <em>(February 2015)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Gradle 2.2.1 or higher.</li>
+        <li>Build Tools 21.1.1 or higher.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+    <ul>
+      <li>Fixed issue with Gradle build failure when accessing the
+      <code>extractReleaseAnnotations</code> module.
+      (<a href="http://b.android.com/81638">Issue 81638</a>).</li>
+      <li>Fixed debugging issue when displaying method input parameters at breakpoints.
+      (<a href="http://b.android.com/82031">Issue 82031</a>).</li>
+      <li>Fixed manifest merger issues when importing libraries with a <code>targetSdkVersion</code>
+      less than 16.</li>
+      <li>Fixed density ordering issue when using Android Studio with JDK 8.</li>
+    </ul>
+    </dd>
+  </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=""/>Android Plugin for Gradle, Revision 1.0</a> <em>(December 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Gradle 2.2.1 or higher.</li>
+        <li>Build Tools 21.1.1 or higher.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Initial plugin release.</li>
+      </ul>
+    </dd>
+  </div>
+</div>
+
+
+
+
+<h2>Updating the Android Plugin for Gradle Version</h2>
+<p>The Android Plugin for Gradle version is specified in the
+<strong>File &gt; Project Structure</strong> menu or the project-level
+<code>build.gradle</code> file. The plugin version applies to all modules built in that
+Android Studio project. This example updates the Android Plugin for Gradle to version 1.1:
+<pre>
+...
+     dependencies {
+         classpath 'com.android.tools.build:gradle:1.1'
+     }
+...
+</pre>
+
+
+<p class="caution"><strong>Caution:</strong> You should not use dynamic dependencies (+) in
+version numbers. Using this feature can cause unexpected version updates and difficulty
+resolving version differences.
+</p>
+
+<p>If you're building with Gradle but using not Android Studio, the build process downloads the
+latest Android Plugin for Gradle plugin when it runs. </p>
+
+
+
+<h2>Updating the Gradle Version </h2>
+
+<p>Android Studio requires Gradle version 2.2.1 or later. To view and
+update the Gradle version, edit the Gradle distribution reference in the
+<code>gradle/wrapper/gradle-wrapper.properties</code> file. This example shows the
+Android Plugin for Gradle version set to 2.2.1.</p>
+
+<pre>
+...
+distributionUrl=http\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+...
+</pre>
+
+
+
+
+<p>For more details about the supported Android Plugin for Gradle properties and syntax, click
+the link to the
+<a href="{@docRoot}tools/building/plugin-for-gradle.html">Plugin Language Reference</a>.</p>
+
+
+
+
+
diff --git a/docs/html/tools/revisions/studio.jd b/docs/html/tools/revisions/studio.jd
index 3806933..af25d9c 100644
--- a/docs/html/tools/revisions/studio.jd
+++ b/docs/html/tools/revisions/studio.jd
@@ -29,7 +29,7 @@
 <p>For an introduction to Android Studio, read the
 <a href="{@docRoot}tools/studio/index.html">Android Studio</a> guide.</p>
 
-<p>Periodic updates are pushed to Android Studio without requiring you to update from here. To
+<p>Periodic updates are pushed to Android Studio without requiring you to update. To
 manually check for updates, select <strong>Help > Check for updates</strong> (on Mac, select
 <strong>Android Studio > Check for updates</strong>).</p>
 
@@ -43,6 +43,33 @@
 <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=""/>Android Studio v1.1</a> <em>(February 2015)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+    <p>Various fixes and enhancements:</p>
+    <ul>
+      <li>Added support for the <a href="{@docRoot}design/wear/index.html">Android Wear</a> watch
+      template. </li>
+      <li>Modified new project and module creation to include
+      <a href="{@docRoot}tools/projects/index.html#mipmap"><code>res/mipmap</code></a> folders for
+      density-specific launcher icons. These <code>res/mipmap</code> folders replace the
+      <a href="{@docRoot}guide/topics/resources/drawable-resource.html"><code>res/drawable</code></a>
+      folders for launcher icons.  </li>
+      <li>Updated launcher icons to have a
+      <a href="{@docRoot}design/material/index.html">Material Design</a> look and added an
+      <code>xxxhdpi</code> launcher icon. </li>
+      <li>Added and enhanced <a href="{@docRoot}tools/help/lint.html"><code>lint</code></a> checks
+      for region and language combinations, launcher icons, resource names, and other common
+      code problems.</li>
+      <li>Added support for Best Current Practice (BCP) language tag 47.  </li>
+  </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=""/>Android Studio v1.0.1</a> <em>(December 2014)</em>
   </p>
 
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index 42ab89c..11c1c74 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -10,6 +10,7 @@
       <li><a href="#build-system">Android Build System</a></li>
       <li><a href="#debug-perf">Debug and Performance</a></li>
       <li><a href="#install-updates">Installation, Setup, and Update Management</a></li>
+      <li><a href="#proxy">HTTP Proxy Settings</a></li>
       <li><a href="#other">Other Highlights</a></li>
 
 
@@ -64,7 +65,7 @@
 <h3 id="project-view"><em>Android</em> Project View</h3>
 <p>By default, Android Studio displays your profile files in the <em>Android</em> project view. This
 view shows a flattened version of your project's structure that provides quick access to the key
-source files of Android projects and helps you work with the new
+source files of Android projects and helps you work with the
 <a href="{@docRoot}sdk/installing/studio-build.html">Gradle-based build system</a>.
 The Android project view:</p>
 
@@ -101,7 +102,7 @@
 
 
 
-<h3>New Project and Directory Structure</h3>
+<h3>Android Studio Project and Directory Structure</h3>
 <p>When you use the <em>Project</em> view of a new project in Android Studio, you
 should notice that the project structure appears different than you may be used to in Eclipse. Each
 instance of Android Studio contains a project with one or more application modules. Each
@@ -119,6 +120,7 @@
 <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.</p>
 
 
+
 <h3>Creating new files</h3>
 <p>You can quickly add new code and resource files by clicking the appropriate directory in the
 <strong>Project</strong> pane and pressing <code>ALT + INSERT</code> on Windows and Linux or
@@ -249,23 +251,15 @@
 <strong>Memory Monitor</strong> tab in the lower right corner to launch the memory monitor. </p>
 
     <img src="{@docRoot}images/tools/studio-memory-monitor.png" />
-    <p class="img-caption"><strong>Figure 4.</strong> Memory Monitor</p>
+    <p class="img-caption"><strong>Figure 5.</strong> Memory Monitor</p>
 
 
 
-<h3> New Lint inspections</h3>
-<p>Lint has several new checks to ensure:
-<ul>
-  <li><code> Cipher.getInstance()</code> is used with safe values</li>
-  <li>In custom Views, the associated declare-styleable for the custom view uses the same
-  base name as the class name.</li>
-  <li>Security check for fragment injection.</li>
-  <li>Where ever property assignment no longer works as expected.</li>
-  <li>Gradle plugin version is compatible with the SDK.</li>
-  <li>Right to left validation </li>
-  <li>Required API version</li>
-  <li>many others</li>
-</ul>
+<h3> Lint inspections</h3>
+<p>The Android {@code lint} tool is a static code analysis tool that checks your Android project
+source files for potential bugs and optimization improvements. Choose the <strong>Analyze &gt; 
+Inspect Code</strong> to manually run the inspections. The {@code lint} settings icon in the
+Inspection display provides a complete list of the current inspections.</p>
 
 <p>Hovering over a Lint error displays the full issue explanation inline for easy error
 resolution. There is also a helpful hyperlink at the end of the error message for additional
@@ -294,17 +288,17 @@
 <p>Android Studio allows you to work with layouts in both a <em>Design View</em> </p>
 <p><img src="{@docRoot}images/tools/studio-helloworld-design.png" alt="" />
 </p>
-    <p class="img-caption"><strong>Figure 5.</strong> Hello World App with Design View</p>
+    <p class="img-caption"><strong>Figure 6.</strong> Hello World App with Design View</p>
 
 <p>and a <em>Text View</em>. </p>
 
     <p><img src="{@docRoot}images/tools/studio-helloworld-text.png" alt="" />
-    <pclass="img-caption"><strong>Figure 6.</strong> Hello World App with Text View</p>
+    <pclass="img-caption"><strong>Figure 7.</strong> Hello World App with Text View</p>
 
 <p>Easily select and preview layout changes for different device images, display
 densities, UI modes, locales, and Android versions (multi-API version rendering).
     <p><img src="{@docRoot}images/tools/studio-api-version-rendering.png" /></p>
-    <p class="img-caption"><strong>Figure 7.</strong> API Version Rendering</p>
+    <p class="img-caption"><strong>Figure 8.</strong> API Version Rendering</p>
 
 
 <p>From the Design View, you can drag and drop elements from the Palette to the Preview or
@@ -341,18 +335,18 @@
 an optimized default Android Virtual Device (AVD) based on Android 5 (Lollipop) for speedy and
 reliable emulation. </p>
 <p><img src="{@docRoot}images/tools/studio-setup-wizard.png" /></p>
-<p class="img-caption"><strong>Figure 8.</strong> Setup Wizard</p>
+<p class="img-caption"><strong>Figure 9.</strong> Setup Wizard</p>
 
 
 <h3>Expanded template and form factor support</h3>
-<p>Android Studio supports new templates for Google Services and expands the available device
+<p>Android Studio supports templates for Google Services and expands the available device
 types. </p>
 
     <h4> Android Wear and TV support</h4>
     <p>For easy cross-platform development, the Project Wizard provides new templates for
     creating your apps for Android Wear and TV. </p>
     <p><img src="{@docRoot}images/tools/studio-tvwearsupport.png"  />
-      <p class="img-caption"><strong>Figure 9.</strong> New Form Factors</p>
+      <p class="img-caption"><strong>Figure 10.</strong> Supported Form Factors</p>
     <p>During app creation, the Project Wizard also displays an API Level dialog to help you choose
     the best <em>minSdkVersion</em> for your project.</p>
 
@@ -362,7 +356,7 @@
     and create a cloud end-point is as easy as selecting <em>File > New Module > App Engine Java
     Servlet Module</em> and specifying the module, package, and client names. </p>
     <p><img src="{@docRoot}images/tools/studio-cloudmodule.png" /></p>
-    <p class="img-caption"><strong>Figure 10.</strong> Setup Wizard</p>
+    <p class="img-caption"><strong>Figure 11.</strong> Setup Wizard</p>
 
 
 
@@ -386,6 +380,120 @@
 
 
 
+<h2 id="proxy">Proxy Settings</h2>
+<p>Proxies serve as intermediary connection points between HTTP clients and web servers that add
+security and privacy to internet connections.</p>
+
+<p>To support running Android Studio behind a firewall, set the proxy settings for the
+Android Studio IDE and the SDK Manager. Use the Android Studio IDE HTTP Proxy settings page to set
+the HTTP proxy settings for Android Studio. The SDK Manager has a separate HTTP Proxy settings
+page.</p>
+
+<p>When running the Android Plugin for Gradle from the command line or on machines where
+Android Studio is not installed, such as continuous integration servers, set the proxy settings
+in the Gradle build file.</p>
+
+<p class="note"><strong>Note:</strong> After the initial installation of the Android Studio bundle,
+Android Studio can run with internet access or off-line. However, Android Studio requires an
+internet connection for Setup Wizard synchronization, 3rd-party library access, access to remote
+repositories, Gradle initialization and synchronization, and Android Studio version updates.</p>
+
+
+<h3>Setting up the Android Studio Proxy</h3>
+<p>Android Studio supports HTTP proxy settings so you can run Android Studio behind a firewall or
+secure network. To set the HTTP proxy settings in Android Studio:</p>
+<ol>
+ <li>From the main menu choose <strong>File &gt; Settings &gt; IDE Setting -- HTTP Proxy</strong>.
+
+<li>In Android Studio, open the IDE Settings dialog.
+  <ul>
+     <li>On Windows and Linux, choose 
+     <strong>File &gt; Settings &gt; IDE Setting -- HTTP Proxy</strong>. </li>
+     <li>On Mac, choose 
+     <strong>Android Studio &gt; Preferences &gt; IDE Setting -- HTTP Proxy</strong>. </li>
+   </ul>
+ The HTTP Proxy page appears.</li>
+ <li>Select <strong>auto-detection</strong> to use an auto-configuration URL to configure the
+ proxy settings or <strong>manual</strong> to enter each of the settings. For a detailed explanation
+ of these settings, see
+ <a href="https://www.jetbrains.com/idea/help/http-proxy.html">HTTP Proxy</a>. </li>
+ <li>Click <strong>Apply</strong> to enable the proxy settings. </li>
+</ol>
+
+<h3>Android Plugin for Gradle HTTP proxy settings</h3>
+When running the Android Plugin from the command line or on machines where Android Studio is not
+installed, set the Android Plugin for Gradle proxy settings in the Gradle build file.</p>
+
+<p>For application-specific HTTP proxy settings, set the proxy settings in the
+<strong>build.gradle</strong> file as required for each application module.</p>
+<pre>
+apply plugin: 'com.android.application'
+
+android {
+    ...
+
+    defaultConfig {
+        ...
+        systemProp.http.proxyHost=proxy.company.com
+        systemProp.http.proxyPort=443
+        systemProp.http.proxyUser=userid
+        systemProp.http.proxyPassword=password
+        systemProp.http.auth.ntlm.domain=domain
+    }
+    ...
+}
+</pre>
+
+
+
+<p>For project-wide HTTP proxy settings, set the proxy settings in the
+<code>gradle/gradle.properties</code> file. </p>
+
+<pre>
+# Project-wide Gradle settings.
+...
+
+systemProp.http.proxyHost=proxy.company.com
+systemProp.http.proxyPort=443
+systemProp.http.proxyUser=username
+systemProp.http.proxyPassword=password
+systemProp.http.auth.ntlm.domain=domain
+
+systemProp.https.proxyHost=proxy.company.com
+systemProp.https.proxyPort=443
+systemProp.https.proxyUser=username
+systemProp.https.proxyPassword=password
+systemProp.https.auth.ntlm.domain=domain
+
+...
+</pre>
+
+
+<p>For information about using Gradle properties for proxy settings, see the
+ <a href="http://www.gradle.org/docs/current/userguide/build_environment.html">Gradle User Guide</a>.</p>
+
+<p class="note"><strong>Note:</strong> When using Android Studio, the settings in the Android
+Studio IDE HTTP proxy settings page override the HTTP proxy settings in the
+<strong>gradle.properties</strong> file.</p>
+
+
+
+<h3>SDK Manager HTTP Proxy Settings </h3>
+<p>SDK Manager proxy settings enable proxy internet access for Android package and library
+updates from SDK Manager packages. </p>
+
+<p>To set the SDK Manager settings for proxy internet access, start the SDK Manager and open the
+SDK Manager page. </p>
+
+<ul>
+   <li>On Windows, select <strong>Tools &gt; Options</strong> from the menu bar. </li>
+   <li>On Mac and Linux, choose <strong>Tools &gt; Options</strong> from the system menu bar. </li>
+ </ul>
+
+<p>The Android SDK Manager page appears. Enter the settings and click <strong>Apply</strong>. </p>
+
+
+
 <h2 id="other">Other Highlights</h2>
 
 <h3> Translation Editor</h3>
@@ -399,14 +507,14 @@
 <strong>Open Editor</strong> link.  </p>
 
     <img src="{@docRoot}images/tools/studio-translationeditoropen.png" />
-    <p class="img-caption"><strong>Figure 11.</strong> Translation Editor</p>
+    <p class="img-caption"><strong>Figure 12.</strong> Translation Editor</p>
 
 
 <h3> Editor support for the latest Android APIs</h3>
-<p>Android Studio supports the new
+<p>Android Studio supports the
 <a href="{@docRoot}design/material/index.html">Material Design</a></li> themes, widgets, and
 graphics, such as shadow layers and API version rendering (showing the layout across different
-UI versions). Also, the new drawable XML tags and attributes, such as &lt;ripple&gt;
+UI versions). Also, the drawable XML tags and attributes, such as &lt;ripple&gt;
 and &lt;animated-selector&gt;, are supported.</p>
 
 
@@ -414,10 +522,10 @@
 <p>Clicking <strong>Import Samples</strong> from the <strong>File</strong> menu or Welcome page
 provides seamless access to Google code samples on GitHub.</p>
     <p><img src="{@docRoot}images/tools/studio-samples-githubaccess.png" /></p>
-    <p class="img-caption"><strong>Figure 12.</strong> Code Sample Access</p>
+    <p class="img-caption"><strong>Figure 13.</strong> Code Sample Access</p>
 
 
     <p><img src="{@docRoot}images/tools/studio-sample-in-editor.png" /></p>
-    <p class="img-caption"><strong>Figure 13.</strong> Imported Code Sample</p>
+    <p class="img-caption"><strong>Figure 14.</strong> Imported Code Sample</p>
 
 
diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd
index 079dd71..0f0a0c0 100644
--- a/docs/html/tools/support-library/features.jd
+++ b/docs/html/tools/support-library/features.jd
@@ -143,10 +143,9 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:support-v4:21.0.+
+com.android.support:support-v4:21.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 21.0 prefix.</p>
 
 
 <h2 id="multidex">Multidex Support Library</h2>
@@ -171,10 +170,9 @@
 </p>
 
 <pre>
-com.android.support:multidex:1.0.+
+com.android.support:multidex:1.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 1.0 prefix.</p>
 
 
 <h2 id="v7">v7 Support Libraries</h2>
@@ -226,10 +224,9 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:appcompat-v7:21.0.+
+com.android.support:appcompat-v7:21.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 21.0 prefix.</p>
 
 
 <h3 id="v7-cardview">v7 cardview library</h3>
@@ -249,10 +246,9 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:cardview-v7:21.0.+
+com.android.support:cardview-v7:21.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 21.0 prefix.</p>
 
 
 <h3 id="v7-gridlayout">v7 gridlayout library</h3>
@@ -271,10 +267,9 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:gridlayout-v7:21.0.+
+com.android.support:gridlayout-v7:21.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 21.0 prefix.</p>
 
 
 <h3 id="v7-mediarouter">v7 mediarouter library</h3>
@@ -308,7 +303,7 @@
 where "&lt;revision&gt;" is the minimum revision at which the library is available. For example:</p>
 
 <pre>
-com.android.support:mediarouter-v7:21.0.+
+com.android.support:mediarouter-v7:21.0.0
 </pre>
 
 <p class="caution">The v7 mediarouter library APIs introduced in Support Library
@@ -335,11 +330,9 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:palette-v7:21.0.+
+com.android.support:palette-v7:21.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 21.0 prefix.</p>
-
 
 
 <h3 id="v7-recyclerview">v7 recyclerview library</h3>
@@ -360,11 +353,9 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:recyclerview-v7:21.0.+
+com.android.support:recyclerview-v7:21.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 21.0 prefix.</p>
-
 
 
 <h2 id="v8">v8 Support Library</h2>
@@ -405,11 +396,9 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:support-v13:18.0.+
+com.android.support:support-v13:18.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 18.0 prefix.</p>
-
 
 
 <h2 id="v17-leanback">v17 Leanback Library</h2>
@@ -448,9 +437,8 @@
 <p>The Gradle build script dependency identifier for this library is as follows:</p>
 
 <pre>
-com.android.support:leanback-v17:21.0.+
+com.android.support:leanback-v17:21.0.0
 </pre>
 
-<p>This dependency notation specifies the latest release version with the 21.0 prefix.</p>
 
 
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index ab6c739..62c21a6 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -249,6 +249,9 @@
       <li><a href="<?cs var:toroot ?>tools/revisions/build-tools.html">
         <span class="en">SDK Build Tools</span>
       </a></li>
+      <li><a href="<?cs var:toroot ?>tools/revisions/gradle-plugin.html">
+        <span class="en">Android Plugin for Gradle</span>
+      </a></li>
       <li><a href="<?cs var:toroot ?>tools/revisions/platforms.html">
         <span class="en">SDK Platforms</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/sdk/eclipse-adt.html">
diff --git a/docs/html/training/articles/security-tips.jd b/docs/html/training/articles/security-tips.jd
index e05b44c..3215a0e 100644
--- a/docs/html/training/articles/security-tips.jd
+++ b/docs/html/training/articles/security-tips.jd
@@ -445,7 +445,17 @@
 headers like <code>no-cache</code> can also be used to indicate that an application should
 not cache particular content.</p>
 
-
+<p>Devices running platforms older than Android 4.4 (API level 19)
+use a version of {@link android.webkit webkit} that has a number of security issues.
+As a workaround, if your app is running on these devices, it
+should confirm that {@link android.webkit.WebView} objects display only trusted
+content. You should also use the updatable security {@link
+java.security.Provider Provider} object to make sure your app isn’t exposed to
+potential vulnerabilities in SSL, as described in <a
+href="{@docRoot}training/articles/security-gms-provider.html">Updating Your
+Security Provider to Protect Against SSL Exploits</a>. If your application must
+render content from the open web, consider providing your own renderer so
+you can keep it up to date with the latest security patches.</p>
 
 
 <h3 id="Credentials">Handling Credentials</h3>
diff --git a/docs/html/training/basics/firstapp/creating-project.jd b/docs/html/training/basics/firstapp/creating-project.jd
index bb4d2e1..4bd92ee 100644
--- a/docs/html/training/basics/firstapp/creating-project.jd
+++ b/docs/html/training/basics/firstapp/creating-project.jd
@@ -100,10 +100,13 @@
         Activities</a> for more information.</p>
     </div>
   </div>
-  <li>Under <strong>Add an activity to your project</strong>, select <strong>Blank Activity</strong>
-    and click <strong>Next</strong>.</li>
-  <li>Under <strong>Describe the new activity for your project</strong>, leave the fields as they
-    are and click <strong>Finish</strong>.</li>
+  <li>Under <strong>Add an activity to &lt;<em>template</em>&gt;</strong>, select <strong>Blank
+    Activity</strong> and click <strong>Next</strong>.</li>
+  <li>Under <strong>Choose options for your new file</strong>, change the
+    <strong>Activity Name</strong> to <em>MyActivity</em>. The <strong>Layout Name</strong> changes
+    to <em>activity_my</em>, and the <strong>Title</strong> to <em>MyActivity</em>. The
+    <strong>Menu Resource Name</strong> is <em>menu_my</em>. 
+   <li>Click the <strong>Finish</strong> button to create the project.</li>
 </ol>
 
 <p>Your Android project is now a basic "Hello World" app that contains some default files. Take a
@@ -120,7 +123,7 @@
     select the file you see the class definition for the activity you created. When you build and
     run the app, the {@link android.app.Activity} class starts the activity and loads the layout file
     that says "Hello World!"</dd>
-  <dt><code>app/src/res/AndroidManifest.xml</code></dt>
+  <dt><code>app/src/main/AndroidManifest.xml</code></dt>
   <dd>The <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest file</a> describes
     the fundamental characteristics of the app and defines each of its components. You'll revisit
     this file as you follow these lessons and add more components to your app.</dd>
@@ -156,13 +159,16 @@
 <p>Note also the <code>/res</code> subdirectories that contain the
 <a href="{@docRoot}guide/topics/resources/overview.html">resources</a> for your application:</p>
 <dl>
-  <dt><code>drawable-hdpi/</code></dt>
-    <dd>Directory for drawable objects (such as bitmaps) that are designed for high-density
-    (hdpi) screens. Other drawable directories contain assets designed for other screen densities.
+  <dt><code>drawable<em>&lt;density&gt;</em>/</code></dt>
+    <dd>Directories for drawable objects (such as bitmaps) that are designed for various densities,
+    such as medium-density (mdpi) and high-density (hdpi) screens. Other drawable directories
+    contain assets designed for other screen densities.
     Here you'll find the ic_launcher.png that appears when you run the default app.</dd>
   <dt><code>layout/</code></dt>
     <dd>Directory for files that define your app's user interface like activity_my.xml,
       discussed above, which describes a basic layout for the MyActivity class.</dd>
+  <dt><code>menu/</code></dt>
+    <dd>Directory for files that define your app's menu items.</dd>
   <dt><code>values/</code></dt>
     <dd>Directory for other XML files that contain a collection of resources, such as
       string and color definitions. The strings.xml file defines the "Hello world!" string that
@@ -177,9 +183,9 @@
 using the SDK tools from a command line:</p>
 
 <ol>
-  <li>Change directories into the Android SDK’s <code>tools/</code> path.</li>
+  <li>Change directories into the Android SDK’s <code>sdk/</code> path.</li>
   <li>Execute:
-<pre class="no-pretty-print">android list targets</pre>
+<pre class="no-pretty-print">tools/android list targets</pre>
 <p>This prints a list of the available Android platforms that you’ve downloaded for your SDK. Find
 the platform against which you want to compile your app. Make a note of the target ID. We
 recommend that you select the highest version possible. You can still build your app to
@@ -209,4 +215,3 @@
 
 
 
-
diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd
index 912efb7..6e4605f 100644
--- a/docs/html/training/basics/firstapp/running-app.jd
+++ b/docs/html/training/basics/firstapp/running-app.jd
@@ -83,14 +83,37 @@
 
 <h3>Run the app from a command line</h3>
 
-<ol>
-  <li>Change directories to the root of your Android project and execute:
-<pre class="no-pretty-print">ant debug</pre></li>
-  <li>Make sure the Android SDK <code>platform-tools/</code> directory is included in your
-<code>PATH</code> environment variable, then execute:
-<pre class="no-pretty-print">adb install bin/MyFirstApp-debug.apk</pre></li>
-  <li>On your device, locate <em>MyFirstApp</em> and open it.</li>
-</ol>
+<p>Open a command-line and navigate to the root of your project directory.
+  Use Gradle to build your project in debug mode, invoke the <code>assembleDebug</code> build task
+  using the Gradle wrapper script (<code>gradlew assembleRelease</code>).
+
+  <p>This creates your debug <code>.apk</code> file inside the module <code>build/</code>
+  directory, named <code>MyFirstApp-debug.apk</code>.  </p>
+
+  <p>On Windows platforms, type this command:</p>
+
+<pre>
+> gradlew.bat assembleDebug
+</pre>
+
+<p>On Mac OS and Linux platforms, type these commands:</p>
+
+<pre>
+$ chmod +x gradlew
+$ ./gradlew assembleDebug
+</pre>
+
+  <p>After you build the project, the output APK for the app module is located in
+  <code>app/build/outputs/apk/</code>
+
+  <p class="note"><strong>Note:</strong> The first command (<code>chmod</code>) adds the execution
+  permission to the Gradle wrapper script and is only necessary the first time you build this
+  project from the command line.</p>
+
+  <p>Make sure the Android SDK <code>platform-tools/</code> directory is included in your
+  <code>PATH</code> environment variable, then execute:
+  <pre class="no-pretty-print">adb install app/build/outputs/MyFirstApp-debug.apk</pre><p>
+  <p>On your device, locate <em>MyFirstApp</em> and open it.</p>
 
 <p>That's how you build and run your Android app on a device!
   To start developing, continue to the <a href="building-ui.html">next
@@ -113,11 +136,11 @@
       <li>In Android Studio, select <strong>Tools &gt; Android &gt; AVD Manager</strong>, or click
   the AVD Manager icon <img src="{@docRoot}images/tools/avd-manager-studio.png" style="vertical-align:bottom;margin:0;height:19px"> in the toolbar.</li>
       <li>Or, from the command line, change directories to
-      <code>&lt;sdk>/tools/</code> and execute:
-        <pre class="no-pretty-print">android avd</pre>
+      <code>sdk/</code> and execute:
+        <pre class="no-pretty-print">tools/android avd</pre>
         <p class="note"><strong>Note:</strong> The AVD Manager that appears
         when launched from the command line is different from the version in
-        Android Studio, so the following instructions may not apply.</p>
+        Android Studio, so the following instructions may not all apply.</p>
         </li>
     </ul>
 
@@ -127,7 +150,6 @@
 
   </li>
   <li>On the AVD Manager main screen (figure 1), click <strong>Create Virtual Device</strong>.</li>
-
   <li>In the Select Hardware window, select a device configuration, such as Nexus 6,
   then click <strong>Next</strong>.
   </li>
@@ -143,40 +165,33 @@
 <h3>Run the app from Android Studio</h3>
 <ol>
   <li>In <strong>Android Studio</strong>, select your project and click <strong>Run</strong>
-    <img src="{@docRoot}images/tools/as-run.png" style="vertical-align:baseline;margin:0; max-height:1em" />
-    from the toolbar.</li>
+    <img src="{@docRoot}images/tools/as-run.png" style="vertical-align:baseline;margin:0; max-height:1em" /> from the toolbar.</li>
   <li>In the <strong>Choose Device</strong> window, click the <strong>Launch emulator</strong> radio
     button.</li>
   <li>From the <strong>Android virtual device</strong> pull-down menu, select the emulator
     you created, and click <strong>OK</strong>.</li>
 </ol>
 <p>It can take a few minutes for the emulator to load itself. You may have to unlock the screen.
-  When you do, My First App appears on the emulator screen.</p>
+When you do, <em>My First App</em> appears on the emulator screen.</p>
 
 
 <h3>Run your app from the command line</h3>
-
-<ol>
-  <li>Change directories to the root of your Android project and execute:
-    <pre class="no-pretty-print">ant debug</pre></li>
+ <ol>
+  <li>Build the project from the command line. The output APK for the app module is located in
+  <code>app/build/outputs/apk/</code>.</li>
   <li>Make sure the Android SDK <code>platform-tools/</code> directory is included in your
-    <code>PATH</code> environment variable, then execute:
-    <pre class="no-pretty-print">adb install bin/MyFirstApp-debug.apk</pre></li>
+  <code>PATH</code> environment variable.</li>
+  <li>Execute this command:
+   <p>
+   <pre class="no-pretty-print">adb install app/build/outputs/MyFirstApp-debug.apk</pre>
+   </p> 
+  </li>
   <li>On the emulator, locate <em>MyFirstApp</em> and open it.</li>
-</ol>
+ </ol>
 
 
-<p>That's how you build and run your Android app on the emulator!
+  <p>That's how you build and run your Android app on the emulator!
   To start developing, continue to the <a href="building-ui.html">next
-lesson</a>.</p>
-
-
-
-
-
-
-
-
-
+  lesson</a>.</p>
 
 
diff --git a/docs/html/training/basics/fragments/support-lib.jd b/docs/html/training/basics/fragments/support-lib.jd
deleted file mode 100644
index a1d781b..0000000
--- a/docs/html/training/basics/fragments/support-lib.jd
+++ /dev/null
@@ -1,83 +0,0 @@
-page.title=Using the Support Library
-page.tags=support library
-helpoutsWidget=true
-
-trainingnavtop=true
-
-@jd:body
-
-<div id="tb-wrapper">
-  <div id="tb"> 
-    <h2>This lesson teaches you to</h2>
-    <ol>
-      <li><a href="#Setup">Set Up Your Project with the Support Library</a></li>
-      <li><a href="#Apis">Import the Support Library APIs</a></li>
-    </ol>
-    <h2>You should also read</h2>
-    <ul>
-      <li><a href="{@docRoot}tools/support-library/index.html">Support Library</a></li>
-    </ul>
-  </div>
-</div>
-
-<p>The Android <a href="{@docRoot}tools/support-library/index.html">Support Library</a> provides a JAR
-file with an API library that allows you to use some of the more recent Android APIs in your app
-while running on earlier versions of Android. For instance, the Support Library provides a version
-of the {@link android.app.Fragment} APIs that you can use on Android 1.6 (API level 4) and
-higher.</p>
-
-<p>This lesson shows how to set up your app to use the Support Library in order to use fragments
-to build a dynamic app UI.</p>
-
-
-<h2 id="Setup">Set Up Your Project with the Support Library</h2>
-
-<div class="figure" style="width:527px">
-<img src="{@docRoot}images/training/basics/sdk-manager.png" alt="" />
-<p class="img-caption"><strong>Figure 1.</strong> The Android SDK Manager with the
-Android Support package selected.</p>
-</div>
-
-<p>To set up your project:</p>
-
-<ol>
-  <li>Download the Android Support package using the SDK Manager.</li>
-
-  <li>Create a <code>libs</code> directory at the top level of your Android project.</li>
-  <li>Locate the JAR file for the library you want to use and copy it into the <code>libs/</code>
-directory.
-<p>For example, the library that supports API level 4 and up is located at
-<code>&lt;sdk>/extras/android/support/v4/android-support-v4.jar</code>.</p></li>
-  <li>Update your manifest file to set the minimum API level to <code>4</code> and the target
-API level to the latest release:
-  <pre>&lt;uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" /></pre>
-  </li>
-</ol>
-
-
-<h2 id="Apis">Import the Support Library APIs</h2>
-
-<p>The Support Library includes a variety of APIs that were either added in recent versions of
-Android or don't exist in the platform at all and merely provide additional support to you when
-developing specific application features.</p>
-
-<p>You can find all the API reference documentation for the Support Library in the
-platform docs at {@link android.support.v4.app android.support.v4.*}.</p>
-
-<div class="warning"><p><strong>Warning:</strong> To be sure that you don't accidentally use new
-APIs on an older system version, be certain that you import the {@link
-android.support.v4.app.Fragment} class and related APIs from the {@link android.support.v4.app}
-package:</p>
-<pre>
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-...
-</pre>
-</div>
-
-
-<p>When creating an activity that hosts fragments while using the Support Library, you must also
-extend the {@link android.support.v4.app.FragmentActivity} class instead of the traditional {@link
-android.app.Activity} class. You'll see sample code for the fragment and activity in the next
-lesson.</p>
-
diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd
index 4698ba1..b9463e4 100644
--- a/docs/html/training/basics/intents/sending.jd
+++ b/docs/html/training/basics/intents/sending.jd
@@ -153,7 +153,8 @@
 
 <pre>
 PackageManager packageManager = {@link android.content.Context#getPackageManager()};
-List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+        PackageManager.MATCH_DEFAULT_ONLY);
 boolean isIntentSafe = activities.size() > 0;
 </pre>
 
diff --git a/docs/html/training/graphics/opengl/draw.jd b/docs/html/training/graphics/opengl/draw.jd
index ba00627..a588066 100644
--- a/docs/html/training/graphics/opengl/draw.jd
+++ b/docs/html/training/graphics/opengl/draw.jd
@@ -50,13 +50,21 @@
 for memory and processing efficiency.</p>
 
 <pre>
-public void onSurfaceCreated(GL10 unused, EGLConfig config) {
-    ...
+public class MyGLRenderer implements GLSurfaceView.Renderer {
 
-    // initialize a triangle
-    mTriangle = new Triangle();
-    // initialize a square
-    mSquare = new Square();
+    ...
+    private Triangle mTriangle;
+    private Square   mSquare;
+
+    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+        ...
+
+        // initialize a triangle
+        mTriangle = new Triangle();
+        // initialize a square
+        mSquare = new Square();
+    }
+    ...
 }
 </pre>
 
@@ -77,21 +85,27 @@
 
 <p>You need at least one vertex shader to draw a shape and one fragment shader to color that shape.
 These shaders must be complied and then added to an OpenGL ES program, which is then used to draw
-the shape. Here is an example of how to define basic shaders you can use to draw a shape:</p>
+the shape. Here is an example of how to define basic shaders you can use to draw a shape in the
+<code>Triangle</code> class:</p>
 
 <pre>
-private final String vertexShaderCode =
-    "attribute vec4 vPosition;" +
-    "void main() {" +
-    "  gl_Position = vPosition;" +
-    "}";
+public class Triangle {
 
-private final String fragmentShaderCode =
-    "precision mediump float;" +
-    "uniform vec4 vColor;" +
-    "void main() {" +
-    "  gl_FragColor = vColor;" +
-    "}";
+    private final String vertexShaderCode =
+        "attribute vec4 vPosition;" +
+        "void main() {" +
+        "  gl_Position = vPosition;" +
+        "}";
+
+    private final String fragmentShaderCode =
+        "precision mediump float;" +
+        "uniform vec4 vColor;" +
+        "void main() {" +
+        "  gl_FragColor = vColor;" +
+        "}";
+
+    ...
+}
 </pre>
 
 <p>Shaders contain OpenGL Shading Language (GLSL) code that must be compiled prior to using it in
@@ -125,13 +139,28 @@
 public class Triangle() {
     ...
 
-    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
-    int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+    private final int mProgram;
 
-    mProgram = GLES20.glCreateProgram();             // create empty OpenGL ES Program
-    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
-    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
-    GLES20.glLinkProgram(mProgram);                  // creates OpenGL ES program executables
+    public Triangle() {
+        ...
+
+        int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
+                                        vertexShaderCode);
+        int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
+                                        fragmentShaderCode);
+
+        // create empty OpenGL ES Program
+        mProgram = GLES20.glCreateProgram();
+
+        // add the vertex shader to program
+        GLES20.glAttachShader(mProgram, vertexShader);
+
+        // add the fragment shader to program
+        GLES20.glAttachShader(mProgram, fragmentShader);
+
+        // creates OpenGL ES program executables
+        GLES20.glLinkProgram(mProgram);
+    }
 }
 </pre>
 
@@ -145,6 +174,12 @@
 function.</p>
 
 <pre>
+private int mPositionHandle;
+private int mColorHandle;
+
+private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
+private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
+
 public void draw() {
     // Add program to OpenGL ES environment
     GLES20.glUseProgram(mProgram);
@@ -176,8 +211,17 @@
 
 <p>Once you have all this code in place, drawing this object just requires a call to the
 {@code draw()} method from within your renderer’s {@link
-android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method. When you run the
-application, it should look something like this:</p>
+android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method:
+
+<pre>
+public void onDrawFrame(GL10 unused) {
+    ...
+
+    mTriangle.draw();
+}
+</pre>
+
+<p>When you run the application, it should look something like this:</p>
 
 <img src="{@docRoot}images/opengl/ogl-triangle.png">
 <p class="img-caption">
diff --git a/docs/html/training/graphics/opengl/environment.jd b/docs/html/training/graphics/opengl/environment.jd
index 6b00c76..cf2b64a 100644
--- a/docs/html/training/graphics/opengl/environment.jd
+++ b/docs/html/training/graphics/opengl/environment.jd
@@ -129,28 +129,22 @@
 <pre>
 class MyGLSurfaceView extends GLSurfaceView {
 
+    private final MyGLRenderer mRenderer;
+
     public MyGLSurfaceView(Context context){
         super(context);
 
+        // Create an OpenGL ES 2.0 context
+        setEGLContextClientVersion(2);
+
+        mRenderer = new MyGLRenderer();
+
         // Set the Renderer for drawing on the GLSurfaceView
-        setRenderer(new MyRenderer());
+        setRenderer(mRenderer);
     }
 }
 </pre>
 
-<p>When using OpenGL ES 2.0, you must add another call to your {@link android.opengl.GLSurfaceView}
-constructor, specifying that you want to use the 2.0 API:</p>
-
-<pre>
-// Create an OpenGL ES 2.0 context
-setEGLContextClientVersion(2);
-</pre>
-
-<p class="note"><strong>Note:</strong> If you are using the OpenGL ES 2.0 API, make sure you declare
-this in your application manifest. For more information, see <a href="#manifest">Declare OpenGL ES
-Use
-in the Manifest</a>.</p>
-
 <p>One other optional addition to your {@link android.opengl.GLSurfaceView} implementation is to set
 the render mode to only draw the view when there is a change to your drawing data using the
 {@link android.opengl.GLSurfaceView#RENDERMODE_WHEN_DIRTY GLSurfaceView.RENDERMODE_WHEN_DIRTY}
@@ -186,7 +180,7 @@
 </ul>
 
 <p>Here is a very basic implementation of an OpenGL ES renderer, that does nothing more than draw a
-gray background in the {@link android.opengl.GLSurfaceView}:</p>
+black background in the {@link android.opengl.GLSurfaceView}:</p>
 
 <pre>
 public class MyGLRenderer implements GLSurfaceView.Renderer {
@@ -208,7 +202,7 @@
 </pre>
 
 <p>That’s all there is to it! The code examples above create a simple Android application that
-displays a gray screen using OpenGL. While this code does not do anything very interesting, by
+displays a black screen using OpenGL. While this code does not do anything very interesting, by
 creating these classes, you have laid the foundation you need to start drawing graphic elements with
 OpenGL.</p>
 
diff --git a/docs/html/training/graphics/opengl/motion.jd b/docs/html/training/graphics/opengl/motion.jd
index fbcdd7f..b026a4a 100644
--- a/docs/html/training/graphics/opengl/motion.jd
+++ b/docs/html/training/graphics/opengl/motion.jd
@@ -45,16 +45,17 @@
 
 <h2 id="rotate">Rotate a Shape</h2>
 
-<p>Rotating a drawing object with OpenGL ES 2.0 is relatively simple. You create another
-transformation matrix (a rotation matrix) and then combine it with your projection and
+<p>Rotating a drawing object with OpenGL ES 2.0 is relatively simple. In your renderer, create
+another transformation matrix (a rotation matrix) and then combine it with your projection and
 camera view transformation matrices:</p>
 
 <pre>
 private float[] mRotationMatrix = new float[16];
 public void onDrawFrame(GL10 gl) {
-    ...
     float[] scratch = new float[16];
 
+    ...
+
     // Create a rotation transformation for the triangle
     long time = SystemClock.uptimeMillis() % 4000L;
     float angle = 0.090f * ((int) time);
diff --git a/docs/html/training/graphics/opengl/projection.jd b/docs/html/training/graphics/opengl/projection.jd
index b09e74c..356d5d4 100644
--- a/docs/html/training/graphics/opengl/projection.jd
+++ b/docs/html/training/graphics/opengl/projection.jd
@@ -71,6 +71,11 @@
 android.opengl.Matrix#frustumM Matrix.frustumM()} method:</p>
 
 <pre>
+// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
+private final float[] mMVPMatrix = new float[16];
+private final float[] mProjectionMatrix = new float[16];
+private final float[] mViewMatrix = new float[16];
+
 &#64;Override
 public void onSurfaceChanged(GL10 unused, int width, int height) {
     GLES20.glViewport(0, 0, width, height);
@@ -95,10 +100,10 @@
 <h2 id="camera-view">Define a Camera View</h2>
 
 <p>Complete the process of transforming your drawn objects by adding a camera view transformation as
-part of the drawing process. In the following example code, the camera view transformation is
-calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()} method and then
-combined with the previously calculated projection matrix. The combined transformation matrices
-are then passed to the drawn shape.</p>
+part of the drawing process in your renderer. In the following example code, the camera view
+transformation is calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()}
+method and then combined with the previously calculated projection matrix. The combined
+transformation matrices are then passed to the drawn shape.</p>
 
 <pre>
 &#64;Override
@@ -119,7 +124,32 @@
 <h2 id="#transform">Apply Projection and Camera Transformations</h2>
 
 <p>In order to use the combined projection and camera view transformation matrix shown in the
-previews sections, modify the {@code draw()} method of your graphic objects to accept the combined
+previews sections, first add a matrix variable to the <em>vertex shader</em> previously defined
+in the <code>Triangle</code> class:</p>
+
+<pre>
+public class Triangle {
+
+    private final String vertexShaderCode =
+        // This matrix member variable provides a hook to manipulate
+        // the coordinates of the objects that use this vertex shader
+        <strong>"uniform mat4 uMVPMatrix;" +</strong>
+        "attribute vec4 vPosition;" +
+        "void main() {" +
+        // the matrix must be included as a modifier of gl_Position
+        // Note that the uMVPMatrix factor *must be first* in order
+        // for the matrix multiplication product to be correct.
+        "  gl_Position = <strong>uMVPMatrix</strong> * vPosition;" +
+        "}";
+
+    // Use to access and set the view transformation
+    private int mMVPMatrixHandle;
+
+    ...
+}
+</pre>
+
+<p>Next, modify the {@code draw()} method of your graphic objects to accept the combined
 transformation matrix and apply it to the shape:</p>
 
 <pre>
@@ -127,14 +157,16 @@
     ...
 
     // get handle to shape's transformation matrix
-    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+    <strong>mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");</strong>
 
     // Pass the projection and view transformation to the shader
-    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
+    <strong>GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);</strong>
 
     // Draw the triangle
     GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
-    ...
+
+    // Disable vertex array
+    GLES20.glDisableVertexAttribArray(mPositionHandle);
 }
 </pre>
 
diff --git a/docs/html/training/graphics/opengl/touch.jd b/docs/html/training/graphics/opengl/touch.jd
index 4c9f0c7..089ede7 100644
--- a/docs/html/training/graphics/opengl/touch.jd
+++ b/docs/html/training/graphics/opengl/touch.jd
@@ -50,6 +50,10 @@
 an angle of rotation for a shape.</p>
 
 <pre>
+private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
+private float mPreviousX;
+private float mPreviousY;
+
 &#64;Override
 public boolean onTouchEvent(MotionEvent e) {
     // MotionEvent reports input details from the touch screen
@@ -77,7 +81,7 @@
 
             mRenderer.setAngle(
                     mRenderer.getAngle() +
-                    ((dx + dy) * TOUCH_SCALE_FACTOR);  // = 180.0f / 320
+                    ((dx + dy) * TOUCH_SCALE_FACTOR));
             requestRender();
     }
 
@@ -108,12 +112,22 @@
 <p>The example code above requires that you expose the rotation angle through your renderer by
 adding a public member. Since the renderer code is running on a separate thread from the main user
 interface thread of your application, you must declare this public variable as {@code volatile}.
-Here is the code to do that:</p>
+Here is the code to declare the variable and expose the getter and setter pair:</p>
 
 <pre>
 public class MyGLRenderer implements GLSurfaceView.Renderer {
     ...
+
     public volatile float mAngle;
+
+    public float getAngle() {
+        return mAngle;
+    }
+
+    public void setAngle(float angle) {
+        mAngle = angle;
+    }
+}
 </pre>
 
 
diff --git a/docs/html/training/location/display-address.jd b/docs/html/training/location/display-address.jd
index 621b082..516f14f 100644
--- a/docs/html/training/location/display-address.jd
+++ b/docs/html/training/location/display-address.jd
@@ -1,280 +1,468 @@
 page.title=Displaying a Location Address
-
 trainingnavtop=true
-
 @jd:body
 
-
-
 <div id="tb-wrapper">
-<div id="tb">
+  <div id="tb">
 
-<h2>This lesson teaches you to</h2>
-<ol>
-  <li><a href="#DefineTask">Define the Address Lookup Task</a></li>
-  <li><a href="#DisplayResults">Define a Method to Display the Results</a></li>
-  <li><a href="#RunTask">Run the Lookup Task</a></li>
-</ol>
+    <h2>This lesson teaches you how to</h2>
+    <ol>
+      <li><a href="#connect">Get a Geographic Location</a></li>
+      <li><a href="#fetch-address">Define an Intent Service to Fetch the
+        Address</a></li>
+      <li><a href="#start-intent">Start the Intent Service</a></li>
+      <li><a href="#result-receiver">Receive the Geocoding Results</a></li>
+    </ol>
 
-<h2>You should also read</h2>
-<ul>
-    <li>
-        <a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
-    </li>
-    <li>
-        <a href="retrieve-current.html">Retrieving the Current Location</a>
-    </li>
-    <li>
-        <a href="receive-location-updates.html">Receiving Location Updates</a>
-    </li>
-</ul>
-<h2>Try it out</h2>
+    <h2>You should also read</h2>
+      <ul>
+        <li>
+          <a href="{@docRoot}google/play-services/setup.html">Setting up Google
+          Play Services</a>
+        </li>
+        <li>
+          <a href="retrieve-current.html">Getting the Last Known Location</a>
+        </li>
+        <li>
+          <a href="receive-location-updates.html">Receiving Location Updates</a>
+        </li>
+      </ul>
+    <h2>Try it out</h2>
 
-<div class="download-box">
-<a href="http://developer.android.com/shareables/training/LocationUpdates.zip" class="button">Download
-  the sample app</a>
-<p class="filename">LocationUpdates.zip</p>
+    <ul>
+      <li>
+        <a href="https://github.com/googlesamples/android-play-location/tree/master/LocationAddress" class="external-link">LocationAddress</a>
+      </li>
+    </ul>
+  </div>
 </div>
 
-</div>
-</div>
+<p>The lessons <a href="retrieve-current.html">Getting the Last Known
+  Location</a> and <a href="receive-location-updates.html">Receiving Location
+  Updates</a> describe how to get the user's location in the form of a
+  {@link android.location.Location} object that contains latitude and longitude
+  coordinates. Although latitude and longitude are useful for calculating
+  distance or displaying a map position, in many cases the address of the
+  location is more useful. For example, if you want to let your users know where
+  they are or what is close by, a street address is more meaningful than the
+  geographic coordinates (latitude/longitude) of the location.</p>
 
-<p>
-    The lessons <a href="retrieve-current.html">Retrieving the Current Location</a> and
-    <a href="receive-location-updates.html">Receiving Location Updates</a> describe how to get the
-    user's current location in the form of a {@link android.location.Location} object that
-    contains latitude and longitude coordinates. Although latitude and longitude are useful for
-    calculating distance or displaying a map position, in many cases the address of the location is
-    more useful.
-</p>
-<p>
-    The Android platform API provides a feature that returns an estimated street addresses for
-    latitude and longitude values. This lesson shows you how to use this address lookup feature.
-</p>
-<p class="note">
-    <strong>Note:</strong> Address lookup requires a backend service that is not included in the
-    core Android framework. If this backend service is not available,
-    {@link android.location.Geocoder#getFromLocation Geocoder.getFromLocation()} returns an empty
-    list. The helper method {@link android.location.Geocoder#isPresent isPresent()}, available
-    in API level 9 and later, checks to see if the backend service is available.
-</p>
-<p>
-    The snippets in the following sections assume that your app has already retrieved the
-    current location and stored it as a {@link android.location.Location} object in the global
-    variable {@code mLocation}.
-</p>
-<!--
-    Define the address lookup task
--->
-<h2 id="DefineTask">Define the Address Lookup Task</h2>
-<p>
-To get an address for a given latitude and longitude, call
-{@link android.location.Geocoder#getFromLocation Geocoder.getFromLocation()}, which returns a
-list of addresses. The method is synchronous, and may take a long time to do its work, so you
-should call the method from the {@link android.os.AsyncTask#doInBackground
-doInBackground()} method of an {@link android.os.AsyncTask}.
-</p>
-<p>
-While your app is getting the address, display an indeterminate activity
-indicator to show that your app is working in the background. Set the indicator's initial state
-to {@code android:visibility="gone"}, to make it invisible and remove it from the layout
-hierarchy. When you start the address lookup, you set its visibility to "visible".
-</p>
-<p>
-The following snippet shows how to add an indeterminate {@link android.widget.ProgressBar} to
-your layout file:
-</p>
+<p>Using the {@link android.location.Geocoder} class in the Android framework
+  location APIs, you can convert an address to the corresponding geographic
+  coordinates. This process is called <em>geocoding</em>. Alternatively, you can
+  convert a geographic location to an address. The address lookup feature is
+  also known as <em>reverse geocoding</em>.</p>
+
+<p>This lesson shows you how to use the
+  {@link android.location.Geocoder#getFromLocation getFromLocation()} method to
+  convert a geographic location to an address. The method returns an estimated
+  street address corresponding to a given latitude and longitude.</p>
+
+<h2 id="connect">Get a Geographic Location</h2>
+
+<p>The last known location of the device is a useful starting point for the
+  address lookup feature. The lesson on
+  <a href="retrieve-current.html">Getting the Last Known Location</a> shows you
+  how to use the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>
+  method provided by the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html">fused
+  location provider</a> to find the latest location of the device.</p>
+
+<p>To access the fused location provider, you need to create an instance of the
+  Google Play services API client. To learn how to connect your client, see
+  <a href="{@docRoot}training/location/retrieve-current.html#play-services">Connect
+  to Google Play Services</a>.</p>
+
+<p>In order for the fused location provider to retrieve a precise street
+  address, set the location permission in your app manifest to
+  {@code ACCESS_FINE_LOCATION}, as shown in the following example:</p>
+
 <pre>
-&lt;ProgressBar
-android:id="&#64;+id/address_progress"
-android:layout_width="wrap_content"
-android:layout_height="wrap_content"
-android:layout_centerHorizontal="true"
-android:indeterminate="true"
-android:visibility="gone" /&gt;
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.gms.location.sample.locationupdates" &gt;
+
+  &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;
+&lt;/manifest&gt;
 </pre>
-<p>
-To create the background task, define a subclass of {@link android.os.AsyncTask} that calls
-{@link android.location.Geocoder#getFromLocation getFromLocation()} and returns an address.
-Define a {@link android.widget.TextView} object {@code mAddress} to contain the returned
-address, and a {@link android.widget.ProgressBar} object that allows you to control the
-indeterminate activity indicator. For example:
-</p>
+
+<h2 id="fetch-address">Define an Intent Service to Fetch the Address</h2>
+
+<p>The {@link android.location.Geocoder#getFromLocation getFromLocation()}
+  method provided by the {@link android.location.Geocoder} class accepts a
+  latitude and longitude, and returns a list of addresses. The method is
+  synchronous, and may take a long time to do its work, so you should not call
+  it from the main, user interface (UI) thread of your app.</p>
+
+<p>The {@link android.app.IntentService IntentService} class provides a
+  structure for running a task on a background thread. Using this class, you can
+  handle a long-running operation without affecting your UI's responsiveness.
+  Note that the {@link android.os.AsyncTask AsyncTask} class also allows you to
+  perform background operations, but it's designed for short operations. An
+  {@link android.os.AsyncTask AsyncTask} shouldn't keep a reference to the UI if
+  the activity is recreated, for example when the device is rotated. In
+  contrast, an {@link android.app.IntentService IntentService} doesn't need to
+  be cancelled when the activity is rebuilt.</p>
+
+<p>Define a {@code FetchAddressIntentService} class that extends
+  {@link android.app.IntentService}. This class is your address lookup service.
+  The intent service handles an intent asynchronously on a worker thread, and
+  stops itself when it runs out of work. The intent extras provide the data
+  needed by the service, including a {@link android.location.Location} object
+  for conversion to an address, and a {@link android.os.ResultReceiver} object
+  to handle the results of the address lookup. The service uses a {@link
+  android.location.Geocoder} to fetch the address for the location, and sends
+  the results to the {@link android.os.ResultReceiver}.</p>
+
+<h3>Define the Intent Service in your App Manifest</h3>
+
+<p>Add an entry to your app manifest defining the intent service:</p>
+
 <pre>
-public class MainActivity extends FragmentActivity {
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.gms.location.sample.locationaddress" &gt;
+    &lt;application
+        ...
+        &lt;service
+            android:name=".FetchAddressIntentService"
+            android:exported="false"/&gt;
+    &lt;/application&gt;
     ...
-    private TextView mAddress;
-    private ProgressBar mActivityIndicator;
+&lt;/manifest&gt;
+</pre>
+
+<p class="note"><strong>Note:</strong> The {@code &lt;service&gt;} element in
+  the manifest doesn't need to include an intent filter, because your main
+  activity creates an explicit intent by specifying the name of the class to use
+  for the intent.</p>
+
+<h3>Create a Geocoder</h3>
+
+<p>The process of converting a geographic location to an address is called
+  <em>reverse geocoding</em>. To perform the main work of the intent service,
+  that is, your reverse geocoding request, implement
+  {@link android.app.IntentService#onHandleIntent onHandleIntent()} within the
+  {@code FetchAddressIntentService} class. Create a
+  {@link android.location.Geocoder} object to handle the reverse geocoding.</p>
+
+<p>A locale represents a specific geographical or linguistic region. Locale
+  objects are used to adjust the presentation of information, such as numbers or
+  dates, to suit the conventions in the region represented by the locale. Pass a
+  <a href="{@docRoot}reference/java/util/Locale.html">{@code Locale}</a> object
+  to the {@link android.location.Geocoder} object, to ensure that the resulting
+  address is localized to the user's geographic region.</p>
+
+<pre>
+&#64;Override
+protected void onHandleIntent(Intent intent) {
+    Geocoder geocoder = new Geocoder(this, Locale.getDefault());
+    ...
+}
+</pre>
+
+<h3 id="retrieve-street-address">Retrieve the street address data</h3>
+
+<p>The next step is to retrieve the street address from the geocoder, handle
+  any errors that may occur, and send the results back to the activity that
+  requested the address. To report the results of the geocoding
+  process, you need two numeric constants that indicate success or failure.
+  Define a {@code Constants} class to contain the values, as shown in this code
+  snippet:</p>
+
+<pre>
+public final class Constants {
+    public static final int SUCCESS_RESULT = 0;
+    public static final int FAILURE_RESULT = 1;
+    public static final String PACKAGE_NAME =
+        "com.google.android.gms.location.sample.locationaddress";
+    public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";
+    public static final String RESULT_DATA_KEY = PACKAGE_NAME +
+        ".RESULT_DATA_KEY";
+    public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME +
+        ".LOCATION_DATA_EXTRA";
+}
+</pre>
+
+<p>To get a street address corresponding to a geographical location, call
+  {@link android.location.Geocoder#getFromLocation getFromLocation()},
+  passing it the latitude and longitude from the location object, and the
+  maximum number of addresses you want returned. In this case, you want just one
+  address. The geocoder returns an array of addresses. If no addresses were
+  found to match the given location, it returns an empty list. If there is no
+  backend geocoding service available, the geocoder returns null.</p>
+
+<p>Check for the following errors as shown in the code sample below. If an error
+  occurs, place the corresponding error message in the {@code errorMessage}
+  variable, so you can send it back to the requesting activity:</p>
+
+<ul>
+  <li><strong>No location data provided</strong> - The intent extras do not
+    include the {@link android.location.Location} object required for reverse
+    geocoding.</li>
+  <li><strong>Invalid latitude or longitude used</strong> - The latitude
+    and/or longitude values provided in the {@link android.location.Location}
+    object are invalid.</li>
+  <li><strong>No geocoder available</strong> - The background geocoding service
+    is not available, due to a network error or IO exception.</li>
+  <li><strong>Sorry, no address found</strong> - The geocoder could not find an
+    address for the given latitude/longitude.</li>
+</ul>
+
+<p>To get the individual lines of an address object, use the
+  {@link android.location.Address#getAddressLine getAddressLine()}
+  method provided by the {@link android.location.Address} class. Then join the
+  lines into a list of address fragments ready to return to the activity that
+  requested the address.</p>
+
+<p>To send the results back to the requesting activity, call the
+  {@code deliverResultToReceiver()} method (defined in
+  <a href="#return-address">Return the address to the requestor</a>). The
+  results consist of the previously-mentioned numeric success/failure code and
+  a string. In the case of a successful reverse geocoding, the string contains
+  the address. In the case of a failure, the string contains the error message,
+  as shown in the code sample below:</p>
+
+<pre>
+&#64;Override
+protected void onHandleIntent(Intent intent) {
+    String errorMessage = "";
+
+    // Get the location passed to this service through an extra.
+    Location location = intent.getParcelableExtra(
+            Constants.LOCATION_DATA_EXTRA);
+
+    ...
+
+    List&lt;Address&gt; addresses = null;
+
+    try {
+        addresses = geocoder.getFromLocation(
+                location.getLatitude(),
+                location.getLongitude(),
+                // In this sample, get just a single address.
+                1);
+    } catch (IOException ioException) {
+        // Catch network or other I/O problems.
+        errorMessage = getString(R.string.service_not_available);
+        Log.e(TAG, errorMessage, ioException);
+    } catch (IllegalArgumentException illegalArgumentException) {
+        // Catch invalid latitude or longitude values.
+        errorMessage = getString(R.string.invalid_lat_long_used);
+        Log.e(TAG, errorMessage + ". " +
+                "Latitude = " + location.getLatitude() +
+                ", Longitude = " +
+                location.getLongitude(), illegalArgumentException);
+    }
+
+    // Handle case where no address was found.
+    if (addresses == null || addresses.size()  == 0) {
+        if (errorMessage.isEmpty()) {
+            errorMessage = getString(R.string.no_address_found);
+            Log.e(TAG, errorMessage);
+        }
+        deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
+    } else {
+        Address address = addresses.get(0);
+        ArrayList&lt;String&gt; addressFragments = new ArrayList&lt;String&gt;();
+
+        // Fetch the address lines using {@code getAddressLine},
+        // join them, and send them to the thread.
+        for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
+            addressFragments.add(address.getAddressLine(i));
+        }
+        Log.i(TAG, getString(R.string.address_found));
+        deliverResultToReceiver(Constants.SUCCESS_RESULT,
+                TextUtils.join(System.getProperty("line.separator"),
+                        addressFragments));
+    }
+}
+</pre>
+
+<h3 id="return-address">Return the address to the requestor</h3>
+
+<p>The final thing the intent service must do is send the address back to a
+  {@link android.os.ResultReceiver} in the activity that started the service.
+  The {@link android.os.ResultReceiver} class allows you to send a
+  numeric result code as well as a message containing the result data. The
+  numeric code is useful for reporting the success or failure of the geocoding
+  request. In the case of a successful reverse geocoding, the message contains
+  the address. In the case of a failure, the message contains some text
+  describing the reason for failure.</p>
+
+<p>You have already retrieved the address from the geocoder, trapped any errors
+  that may occur, and called the {@code deliverResultToReceiver()} method. Now
+  you need to define the {@code deliverResultToReceiver()} method that sends
+  a result code and message bundle to the result receiver.</p>
+
+<p>For the result code, use the value that you've passed to the
+  {@code deliverResultToReceiver()} method in the {@code resultCode} parameter.
+  To construct the message bundle, concatenate the {@code RESULT_DATA_KEY}
+  constant from your {@code Constants} class (defined in
+  <a href="#retrieve-street-address">Retrieve the street address data</a>) and
+  the value in the {@code message} parameter passed to the
+  {@code deliverResultToReceiver()} method, as shown in the following sample:
+</p>
+
+<pre>
+public class FetchAddressIntentService extends IntentService {
+    protected ResultReceiver mReceiver;
+    ...
+    private void deliverResultToReceiver(int resultCode, String message) {
+        Bundle bundle = new Bundle();
+        bundle.putString(Constants.RESULT_DATA_KEY, message);
+        mReceiver.send(resultCode, bundle);
+    }
+}
+</pre>
+
+<h2 id="start-intent">Start the Intent Service</h2>
+
+<p>The intent service, as defined in the previous section, runs in the
+  background and is responsible for fetching the address corresponding to a
+  given geographic location. When you start the service, the Android framework
+  instantiates and starts the service if it isn't already running, and creates a
+  process if needed. If the service is already running then it remains running.
+  Because the service extends {@link android.app.IntentService IntentService},
+  it shuts down automatically when all intents have been processed.</p>
+  
+<p>Start the service from your app's main activity,
+  and create an {@link android.content.Intent} to pass data to the service. You
+  need an <em>explicit</em> intent, because you want only your service
+  to respond to the intent. For more information, see
+  <a href="{@docRoot}guide/components/intents-filters.html#Types">Intent
+  Types</a>.</p>
+
+<p>To create an explicit intent, specify the name of the
+  class to use for the service: {@code FetchAddressIntentService.class}.
+  Pass two pieces of information in the intent extras:</p>
+
+<ul>
+  <li>A {@link android.os.ResultReceiver} to handle the results of the address
+    lookup.</li>
+  <li>A {@link android.location.Location} object containing the latitude and
+    longitude that you want to convert to an address.</li>
+</ul>
+
+<p>The following code sample shows you how to start the intent service:</p>
+
+<pre>
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
+
+    protected Location mLastLocation;
+    private AddressResultReceiver mResultReceiver;
+    ...
+
+    protected void startIntentService() {
+        Intent intent = new Intent(this, FetchAddressIntentService.class);
+        intent.putExtra(Constants.RECEIVER, mResultReceiver);
+        intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);
+        startService(intent);
+    }
+}
+</pre>
+
+<p>Call the above {@code startIntentService()} method when the
+  user takes an action that requires a geocoding address lookup. For example,
+  the user may press a <em>Fetch address</em> button on your app's UI. Before
+  starting the intent service, you need to check that the connection to Google
+  Play services is present. The following code snippet shows the call to the
+  {@code startIntentService()} method in the button handler:</p>
+
+<pre>
+public void fetchAddressButtonHandler(View view) {
+    // Only start the service to fetch the address if GoogleApiClient is
+    // connected.
+    if (mGoogleApiClient.isConnected() && mLastLocation != null) {
+        startIntentService();
+    }
+    // If GoogleApiClient isn't connected, process the user's request by
+    // setting mAddressRequested to true. Later, when GoogleApiClient connects,
+    // launch the service to fetch the address. As far as the user is
+    // concerned, pressing the Fetch Address button
+    // immediately kicks off the process of getting the address.
+    mAddressRequested = true;
+    updateUIWidgets();
+}
+</pre>
+
+<p>You must also start the intent service when the connection to Google Play
+  services is established, if the user has already clicked the button on your
+  app's UI. The following code snippet shows the call to the
+  {@code startIntentService()} method in the
+  <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a>
+  callback provided by the Google API Client:</p>
+
+<pre>
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
     ...
     &#64;Override
-    protected void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    ...
-    mAddress = (TextView) findViewById(R.id.address);
-    mActivityIndicator =
-            (ProgressBar) findViewById(R.id.address_progress);
-    }
-    ...
-    /**
-    * A subclass of AsyncTask that calls getFromLocation() in the
-    * background. The class definition has these generic types:
-    * Location - A {@link android.location.Location} object containing
-    * the current location.
-    * Void     - indicates that progress units are not used
-    * String   - An address passed to onPostExecute()
-    */
-    private class GetAddressTask extends
-            AsyncTask&lt;Location, Void, String&gt; {
-        Context mContext;
-        public GetAddressTask(Context context) {
-            super();
-            mContext = context;
-        }
-        ...
-        /**
-         * Get a Geocoder instance, get the latitude and longitude
-         * look up the address, and return it
-         *
-         * &#64;params params One or more Location objects
-         * &#64;return A string containing the address of the current
-         * location, or an empty string if no address can be found,
-         * or an error message
-         */
-        &#64;Override
-        protected String doInBackground(Location... params) {
-            Geocoder geocoder =
-                    new Geocoder(mContext, Locale.getDefault());
-            // Get the current location from the input parameter list
-            Location loc = params[0];
-            // Create a list to contain the result address
-            List&lt;Address&gt; addresses = null;
-            try {
-                /*
-                 * Return 1 address.
-                 */
-                addresses = geocoder.getFromLocation(loc.getLatitude(),
-                        loc.getLongitude(), 1);
-            } catch (IOException e1) {
-            Log.e("LocationSampleActivity",
-                    "IO Exception in getFromLocation()");
-            e1.printStackTrace();
-            return ("IO Exception trying to get address");
-            } catch (IllegalArgumentException e2) {
-            // Error message to post in the log
-            String errorString = "Illegal arguments " +
-                    Double.toString(loc.getLatitude()) +
-                    " , " +
-                    Double.toString(loc.getLongitude()) +
-                    " passed to address service";
-            Log.e("LocationSampleActivity", errorString);
-            e2.printStackTrace();
-            return errorString;
+    public void onConnected(Bundle connectionHint) {
+        // Gets the best and most recent location currently available,
+        // which may be null in rare cases when a location is not available.
+        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
+                mGoogleApiClient);
+
+        if (mLastLocation != null) {
+            // Determine whether a Geocoder is available.
+            if (!Geocoder.isPresent()) {
+                Toast.makeText(this, R.string.no_geocoder_available,
+                        Toast.LENGTH_LONG).show();
+                return;
             }
-            // If the reverse geocode returned an address
-            if (addresses != null &amp;&amp; addresses.size() &gt; 0) {
-                // Get the first address
-                Address address = addresses.get(0);
-                /*
-                 * Format the first line of address (if available),
-                 * city, and country name.
-                 */
-                String addressText = String.format(
-                        "&#037;s, &#037;s, &#037;s",
-                        // If there's a street address, add it
-                        address.getMaxAddressLineIndex() &gt; 0 ?
-                                address.getAddressLine(0) : "",
-                        // Locality is usually a city
-                        address.getLocality(),
-                        // The country of the address
-                        address.getCountryName());
-                // Return the text
-                return addressText;
-            } else {
-                return "No address found";
+
+            if (mAddressRequested) {
+                startIntentService();
             }
         }
-        ...
     }
-    ...
 }
 </pre>
-<p>
-The next section shows you how to display the address in the user interface.
-</p>
-<!-- Define a method to display the address -->
-<h2 id="DisplayResults">Define a Method to Display the Results</h2>
-<p>
-    {@link android.os.AsyncTask#doInBackground doInBackground()} returns the result of the address
-    lookup as a {@link java.lang.String}. This value is passed to
-    {@link android.os.AsyncTask#onPostExecute onPostExecute()}, where you do further processing
-    on the results. Since {@link android.os.AsyncTask#onPostExecute onPostExecute()}
-    runs on the UI thread, it can update the user interface; for example, it can turn off the
-    activity indicator and display the results to the user:
-</p>
+
+<h2 id="result-receiver">Receive the Geocoding Results</h2>
+
+<p>The intent service has handled the geocoding request, and uses a
+  {@link android.os.ResultReceiver} to return the results to the activity that
+  made the request. In the activity that makes the request, define an
+  {@code AddressResultReceiver} that extends {@link android.os.ResultReceiver}
+  to handle the response from {@code FetchAddressIntentService}.</p>
+
+<p>The result includes a numeric result code (<code>resultCode</code>) as well
+  as a message containing the result data (<code>resultData</code>). If the
+  reverse geocoding process was successful, the <code>resultData</code> contains
+  the address. In the case of a failure, the <code>resultData</code> contains
+  text describing the reason for failure. For details of the possible errors,
+  see <a href="#return-address">Return the address to the requestor</a>.</p>
+
+<p>Override the
+  {@link android.os.ResultReceiver#onReceiveResult onReceiveResult()} method
+  to handle the results delivered to the result receiver, as shown in the
+  following code sample:</p>
+
 <pre>
-    private class GetAddressTask extends
-            AsyncTask&lt;Location, Void, String&gt; {
-        ...
-        /**
-         * A method that's called once doInBackground() completes. Turn
-         * off the indeterminate activity indicator and set
-         * the text of the UI element that shows the address. If the
-         * lookup failed, display the error message.
-         */
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
+    ...
+    class AddressResultReceiver extends ResultReceiver {
+        public AddressResultReceiver(Handler handler) {
+            super(handler);
+        }
+
         &#64;Override
-        protected void onPostExecute(String address) {
-            // Set activity indicator visibility to "gone"
-            mActivityIndicator.setVisibility(View.GONE);
-            // Display the results of the lookup.
-            mAddress.setText(address);
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+
+            // Display the address string
+            // or an error message sent from the intent service.
+            mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
+            displayAddressOutput();
+
+            // Show a toast message if an address was found.
+            if (resultCode == Constants.SUCCESS_RESULT) {
+                showToast(getString(R.string.address_found));
+            }
+
         }
-        ...
     }
-</pre>
-<p>
-    The final step is to run the address lookup.
-</p>
-<!-- Get and display the address -->
-<h2 id="RunTask">Run the Lookup Task</h2>
-<p>
-    To get the address, call {@link android.os.AsyncTask#execute execute()}. For example, the
-    following snippet starts the address lookup when the user clicks the "Get Address" button:
-</p>
-<pre>
-public class MainActivity extends FragmentActivity {
-    ...
-    /**
-     * The "Get Address" button in the UI is defined with
-     * android:onClick="getAddress". The method is invoked whenever the
-     * user clicks the button.
-     *
-     * &#64;param v The view object associated with this method,
-     * in this case a Button.
-     */
-    public void getAddress(View v) {
-        // Ensure that a Geocoder services is available
-        if (Build.VERSION.SDK_INT &gt;=
-                Build.VERSION_CODES.GINGERBREAD
-                            &amp;&amp;
-                Geocoder.isPresent()) {
-            // Show the activity indicator
-            mActivityIndicator.setVisibility(View.VISIBLE);
-            /*
-             * Reverse geocoding is long-running and synchronous.
-             * Run it on a background thread.
-             * Pass the current location to the background task.
-             * When the task finishes,
-             * onPostExecute() displays the address.
-             */
-            (new GetAddressTask(this)).execute(mLocation);
-        }
-        ...
-    }
-    ...
 }
 </pre>
-<p>
-    The next lesson, <a href="geofencing.html">Creating and Monitoring Geofences</a>, demonstrates
-    how to define locations of interest called <b>geofences</b> and how to use geofence monitoring
-    to detect the user's proximity to a location of interest.
-</p>
diff --git a/docs/html/training/material/drawables.jd b/docs/html/training/material/drawables.jd
index 820a004..a2de8e9 100644
--- a/docs/html/training/material/drawables.jd
+++ b/docs/html/training/material/drawables.jd
@@ -73,7 +73,7 @@
 <pre>
 dependencies {
     ...
-    compile 'com.android.support:palette-v7:21.0.+'
+    compile 'com.android.support:palette-v7:21.0.0'
 }
 </pre>
 
diff --git a/docs/html/training/multiscreen/screendensities.jd b/docs/html/training/multiscreen/screendensities.jd
index fcb65cc..1fc5904 100644
--- a/docs/html/training/multiscreen/screendensities.jd
+++ b/docs/html/training/multiscreen/screendensities.jd
@@ -28,6 +28,7 @@
 
 <ul>
   <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
+  <li><a href="{@docRoot}design/style/iconography.html">Iconography</a></li>
   <li><a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html">Icon Design
 Guidelines</a></li>
 </ul>
@@ -133,6 +134,28 @@
 <p>Then, any time you reference <code>&#64;drawable/awesomeimage</code>, the system selects the
 appropriate bitmap based on the screen's dpi.</p>
 
+<p>Place your launcher icons in the <code>mipmap/</code> folders. </p>
+
+<pre>res/...
+    mipmap-ldpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-mdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-hdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-xhdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-xxhdpi/...
+        <em>finished_launcher_asset</em>.png
+    mipmap-xxxhdpi/...
+        <em>finished_launcher_asset</em>.png
+</pre>
+
+<p class="note"><strong>Note:</strong> You should place all launcher icons in the
+<code>res/mipmap-[density]/</code> folders, rather than <code>drawable/</code> folders to ensure
+launcher apps use the best resolution icon. For more information about using the mipmap folders, see
+<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.</p>
+
 <p>For more tips and guidelines for creating icon assets for your application, see the <a
 href="{@docRoot}guide/practices/ui_guidelines/icon_design.html">Icon Design
 Guidelines</a>.</p>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 0fcfb9c..c59d8ff 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -437,6 +437,35 @@
           </li>
         </ul>
       </li>
+
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot?>training/transitions/index.html"
+             description=
+             "How to animate state changes in a view hierarchy using transitions."
+            >Animating Views Using Scenes and Transitions</a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/transitions/overview.html">
+            The Transitions Framework
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/transitions/scenes.html">
+            Creating a Scene
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/transitions/transitions.html">
+            Applying a Transition
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/transitions/custom-transitions.html">
+            Creating Custom Transitions
+          </a>
+          </li>
+
+        </ul>
+      </li>
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/animation/index.html"
              description=
@@ -922,6 +951,10 @@
               Creating a Catalog Browser</a>
           </li>
           <li>
+            <a href="<?cs var:toroot ?>training/tv/playback/card.html">
+              Providing a Card View</a>
+          </li>
+          <li>
             <a href="<?cs var:toroot ?>training/tv/playback/details.html"
                ja-lang="詳細ビューをビルドする">
               Building a Details View</a>
@@ -1854,4 +1887,4 @@
     buildToggleLists();
     changeNavLang(getLangPref());
 //-->
-</script>
+</script>
\ No newline at end of file
diff --git a/docs/html/training/transitions/custom-transitions.jd b/docs/html/training/transitions/custom-transitions.jd
new file mode 100644
index 0000000..b64daaeb
--- /dev/null
+++ b/docs/html/training/transitions/custom-transitions.jd
@@ -0,0 +1,189 @@
+page.title=Creating Custom Transitions
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Extend">Extend the Transition Class</a></li>
+  <li><a href="#CaptureProperties">Capture View Property Values</a></li>
+  <li><a href="#CreateAnimator">Create a Custom Animator</a></li>
+  <li><a href="#Apply">Apply a Custom Transition</a></li>
+</ol>
+</div>
+</div>
+
+<p>A custom transition enables you to create an animation that is not available from any of
+the built-in transition classes. For example, you can define a custom transition that turns
+the foreground color of text and input fields to gray to indicate that the fields are disabled
+in the new screen. This type of change helps users see the fields you disabled.</p>
+
+<p>A custom transition, like one of the built-in transition types, applies animations to
+child views of both the starting and ending scenes. Unlike built-in transition types,
+however, you have to provide the code that captures property values and generates animations.
+You may also want to define a subset of target views for your animation.</p>
+
+<p>This lesson teaches you to capture property values and generate animations to create
+custom transitions.</p>
+
+
+
+<h2 id="Extend">Extend the Transition Class</h2>
+
+<p>To create a custom transition, add a class to your project that extends the {@link
+android.transition.Transition} class and override the methods shown in the following snippet:</p>
+
+<pre>
+public class CustomTransition extends Transition {
+
+    &#64;Override
+    public void captureStartValues(TransitionValues values) {}
+
+    &#64;Override
+    public void captureEndValues(TransitionValues values) {}
+
+    &#64;Override
+    public Animator createAnimator(ViewGroup sceneRoot,
+                                   TransitionValues startValues,
+                                   TransitionValues endValues) {}
+}
+</pre>
+
+<p>The following sections explain how to override these methods.</p>
+
+
+
+<h2 id="CaptureProperties">Capture View Property Values</h2>
+
+<p>Transition animations use the property animation system described in
+<a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a>. Property
+animations change a view property between a starting and ending value over a specified
+period of time, so the framework needs to have both the starting and ending value of
+the property to construct the animation.</p>
+
+<p>However, a property animation usually needs only a small subset of all the view's property
+values. For example, a color animation needs color property values, while a movement
+animation needs position property values. Since the property values needed for an animation
+are specific to a transition, the transitions framework does not provide every property value
+to a transition. Instead, the framework invokes callback methods that allow a transition to
+capture only the property values it needs and store them in the framework.</p>
+
+
+<h3 id="StartingValues">Capturing Starting Values</h3>
+
+<p>To pass the starting view values to the framework, implement the
+{@link android.transition.Transition#captureStartValues captureStartValues(transitionValues)}
+method. The framework calls this method for every view in the starting scene. The method
+argument is a {@link android.transition.TransitionValues} object that contains a reference
+to the view and a {@link java.util.Map} instance in which you can store the view values you
+want. In your implementation, retrieve these property values and pass them back to the
+framework by storing them in the map.</p>
+
+<p>To ensure that the key for a property value does not conflict with other {@link
+android.transition.TransitionValues} keys, use the following naming scheme:</p>
+
+<pre>
+package_name:transition_name:property_name
+</pre>
+
+<p>The following snippet shows an implementation of the {@link
+android.transition.Transition#captureStartValues captureStartValues()} method:</p>
+
+<pre>
+public class CustomTransition extends Transition {
+
+    // Define a key for storing a property value in
+    // TransitionValues.values with the syntax
+    // package_name:transition_class:property_name to avoid collisions
+    private static final String PROPNAME_BACKGROUND =
+            "com.example.android.customtransition:CustomTransition:background";
+
+    &#64;Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        // Call the convenience method captureValues
+        captureValues(transitionValues);
+    }
+
+
+    // For the view in transitionValues.view, get the values you
+    // want and put them in transitionValues.values
+    private void captureValues(TransitionValues transitionValues) {
+        // Get a reference to the view
+        View view = transitionValues.view;
+        // Store its background property in the values map
+        transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
+    }
+    ...
+}
+</pre>
+
+
+<h3 id="EndingValues">Capture Ending Values</h3>
+
+<p>The framework calls the {@link android.transition.Transition#captureEndValues} method
+once for every target view in the ending scene. In all other respects, {@link
+android.transition.Transition#captureEndValues captureEndValues()} works the same as {@link
+android.transition.Transition#captureStartValues captureStartValues()}.</p>
+
+<p>The following code snippet shows an implementation of the {@link
+android.transition.Transition#captureEndValues captureEndValues()} method:</p>
+
+<pre>
+&#64;Override
+public void captureEndValues(TransitionValues transitionValues) {
+    captureValues(transitionValues);
+}
+</pre>
+
+<p>In this example, both the {@link android.transition.Transition#captureStartValues
+captureStartValues()} and {@link android.transition.Transition#captureEndValues captureEndValues()}
+methods invoke <code>captureValues()</code> to retrieve and store values. The view property
+that <code>captureValues()</code> retrieves is the same, but it has different values in the
+starting and ending scenes. The framework maintains separate maps for the starting and ending
+states of a view.</p>
+
+
+
+<h2 id="CreateAnimator">Create a Custom Animator</h2>
+
+<p>To animate the changes to a view between its state in the starting scene and its state in
+the ending scene, you provide an animator by overriding the {@link
+android.transition.Transition#createAnimator createAnimator()} method. When the
+framework calls this method, it passes in the scene root view and the {@link
+android.transition.TransitionValues} objects that contain the starting and ending values
+you captured.</p>
+
+<p>The number of times the framework calls the {@link
+android.transition.Transition#createAnimator createAnimator()} method depends on the changes that
+occur between the starting and ending scenes. For example, consider a fade out/fade in animation
+implemented as a custom transition. If the starting scene has five targets of which two are
+removed from the ending scene, and the ending scene has the three targets from the starting
+scene plus a new target, then the framework calls {@link
+android.transition.Transition#createAnimator createAnimator()} six times: three of the calls
+animate the fading out and fading in of the targets that stay in both scene objects; two more calls
+animate the fading out of the targets removed from the ending scene; and one call
+animates the fading in of the new target in the ending scene.</p>
+
+<p>For target views that exist on both the starting and ending scenes, the framework provides
+a {@link android.transition.TransitionValues} object for both the <code>startValues</code> and
+<code>endValues</code> arguments. For target views that only exist in the starting or the
+ending scene, the framework provides a {@link android.transition.TransitionValues} object
+for the corresponding argument and <code>null</code> for the other.</p>
+
+<p>To implement the {@link android.transition.Transition#createAnimator} method when you create
+a custom transition, use the view property values you captured to create an {@link
+android.animation.Animator} object and return it to the framework. For an example implementation,
+see the <a
+href="{@docRoot}samples/CustomTransition/src/com.example.android.customtransition/ChangeColor.html">
+<code>ChangeColor</code></a> class in the <a href="{@docRoot}samples/CustomTransition/index.html">
+CustomTransition</a> sample. For more information about property animators, see
+<a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a>.</p>
+
+
+
+<h2 id="Apply">Apply a Custom Transition</h2>
+
+<p>Custom transitions work the same as built-in transitions. You can apply a custom transition
+using a transition manager, as described in <a
+href="{@docRoot}training/transitions/transitions.html#Apply">Applying a Transition</a>.</p>
diff --git a/docs/html/training/transitions/index.jd b/docs/html/training/transitions/index.jd
new file mode 100644
index 0000000..53faa01
--- /dev/null
+++ b/docs/html/training/transitions/index.jd
@@ -0,0 +1,80 @@
+page.title=Animating Views Using Scenes and Transitions
+
+@jd:body
+
+<!-- Sidebox -->
+<div id="tb-wrapper">
+<div id="tb">
+  <h2>Dependencies and Prerequisites</h2>
+  <ul>
+    <li>Android 4.4.2 (API level 19) or higher</li>
+  </ul>
+  <h2>You should also read</h2>
+  <ul>
+    <li><a href="{@docRoot}guide/topics/ui/how-android-draws.html">
+        How Android Draws Views</a></li>
+  </ul>
+  <h2>Try it out</h2>
+  <ul>
+    <li><a href="{@docRoot}samples/BasicTransition/index.html">BasicTransition</a> sample</li>
+    <li><a href="{@docRoot}samples/CustomTransition/index.html">CustomTransition</a> sample</li>
+  </ul>
+</div>
+</div>
+
+<!-- Video box -->
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=S3H7nJ4QaD8">
+<div>
+  <h3>Video</h3>
+  <p>DevBytes: Android 4.4 Transitions</p>
+</div>
+</a>
+
+<p>The user interface of an activity often changes in response to user input and other events.
+For example, an activity that contains a form where users can type search queries can hide
+the form when the user submits it and show a list of search results in its place.</p>
+
+<p>To provide visual continuity in these situations, you can animate changes between
+different view hierarchies in your user interface. These animations give users feedback on
+their actions and help them learn how your app works.</p>
+
+<p>Android includes the <em>transitions framework</em>, which enables you to easily
+animate changes between two view hierarchies. The framework animates the views at runtime by
+changing some of their property values over time. The framework includes built-in animations
+for common effects and lets you create custom animations and transition lifecycle callbacks.</p>
+
+<p>This class teaches you to use the built-in animations in the transitions framework to
+animate changes between view hierarchies. This class also covers how to create custom
+animations.</p>
+
+<p class="note"><strong>Note:</strong> For Android versions earlier than 4.4.2 (API level 19)
+but greater than or equal to Android 4.0 (API level 14), use the <code>animateLayoutChanges</code>
+attribute to animate layouts. To learn more, see
+<a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a> and
+<a href="{@docRoot}training/animation/layout.html">Animating Layout Changes</a>.</p>
+
+
+<h2>Lessons</h2>
+
+<dl>
+<dt><a href="{@docRoot}training/transitions/overview.html">
+The Transitions Framework</a></dt>
+<dd>
+  Learn the main features and components of the transitions framework.
+</dd>
+<dt><a href="{@docRoot}training/transitions/scenes.html">
+Creating a Scene</a></dt>
+<dd>
+  Learn how to create a scene to store the state of a view hierarchy.
+</dd>
+<dt><a href="{@docRoot}training/transitions/transitions.html">
+Applying a Transition</a></dt>
+<dd>
+  Learn how to apply a transition between two scenes of a view hierarchy.
+</dd>
+<dt><a href="{@docRoot}training/transitions/custom-transitions.html">
+Creating Custom Transitions</a></dt>
+<dd>
+  Learn how to create other animation effects not included in the transitions framework.
+</dd>
+</dl>
diff --git a/docs/html/training/transitions/overview.jd b/docs/html/training/transitions/overview.jd
new file mode 100644
index 0000000..044cf16
--- /dev/null
+++ b/docs/html/training/transitions/overview.jd
@@ -0,0 +1,165 @@
+page.title=The Transitions Framework
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson covers</h2>
+<ol>
+  <li><a href="#Overview">Overview</a></li>
+  <li><a href="#Scenes">Scenes</a></li>
+  <li><a href="#Transitions">Transitions</a></li>
+  <li><a href="#Limitations">Limitations</a></li>
+</ol>
+</div>
+</div>
+
+<p>Animating your app's user interface provides more than just visual appeal. Animations
+highlight changes and provide visual cues that help users learn how your app works.</p>
+
+<p>To help you animate a change between one view hierarchy and another, Android provides the
+transitions framework. This framework applies one or more animations to all the views in the
+hierarchies as it changes between them.</p>
+
+<p>The framework has the following features:</p>
+
+<dl>
+<dt><em>Group-level animations</em></dt>
+<dd>Applies one or more animation effects to all of the views in a view hierarchy.</dd>
+<dt><em>Transition-based animation</em></dt>
+<dd>Runs animations based on the changes between starting and ending view property values.</dd>
+<dt><em>Built-in animations</em></dt>
+<dd>Includes predefined animations for common effects such as fade out or movement.</dd>
+
+<!-- Figure 1 - Transitions video -->
+<div style="float:right;margin-left:30px;margin-top:10px">
+<div class="framed-nexus5-port-span-5" style="clear:left;">
+<video class="play-on-hover" height="442" autoplay="" poster="">
+<source src="{@docRoot}images/transitions/transition_sample_video.mp4" type="video/mp4">
+<source src="{@docRoot}images/transitions/transition_sample_video.ogv" type="video/ogg">
+<source src="{@docRoot}images/transitions/transition_sample_video.webm" type="video/webm">
+</video>
+</div>
+<p class="img-caption" style="margin-top:7px;margin-bottom:0px">
+<strong>Figure 1.</strong> Visual cues using user interface animation.</p>
+<div style="margin-top:5px;margin-bottom:20px;font-size:10pt" class="video-instructions">&nbsp;</div>
+</div>
+
+<dt><em>Resource file support</em></dt>
+<dd>Loads view hierarchies and built-in animations from layout resource files.</dd>
+<dt><em>Lifecycle callbacks</em></dt>
+<dd>Defines callbacks that provide finer control over the animation and hierarchy change
+process.</dd>
+</dl>
+
+
+
+<h2 id="Overview">Overview</h2>
+
+<p>The example in Figure 1 shows how an animation provides visual cues to help the user. As the
+app changes from its search entry screen to its search results screen, it fades out views that
+are no longer in use and fades in new views.</p>
+
+<p>This animation is an example of using the transitions framework. The framework
+animates changes to all the views in two view hierarchies. A view hierarchy can be as simple
+as a single view or as complex as a {@link android.view.ViewGroup} containing an elaborate
+tree of views. The framework animates each view by changing one or more of its property values
+over time between the initial or <em>starting</em> view hierarchy and the final or <em>ending</em>
+view hierarchy.</p>
+
+<p>The transitions framework works in parallel with view hierarchies and animations. The
+purpose of the framework is to store the state of view hierarchies, change between these
+hierarchies in order to modify the appearance of the device screen, and animate the change by
+storing and applying animation definitions.</p>
+
+<p>The diagram in Figure 2 illustrates the relationship between view hierarchies, framework
+objects, and animations:</p>
+
+<!-- Figure 2 - diagram -->
+<img src="{@docRoot}images/transitions/transitions_diagram.png"
+     width="506" height="234" alt="" style="margin-top:7px" />
+<p class="img-caption"><strong>Figure 2.</strong> Relationships in the transitions framework.</p>
+
+<p>The transitions framework provides abstractions for scenes, transitions, and transition
+managers. These are described in detail in the following sections. To use the framework, you
+create scenes for the view hierarchies in your app that you plan to change between. Next, you
+create a transition for each animation you want to use. To start the animation between two
+view hierarchies, you use a transition manager specifying the transition to use and the ending
+scene. This procedure is described in detail in the remaining lessons in this class.</p>
+
+
+
+<h2 id="Scenes">Scenes</h2>
+
+<p>A scene stores the state of a view hierarchy, including all its views and their property
+values. A view hierarchy can be a simple view or a complex tree of views and child layouts.
+Storing the view hierarchy state in a scene enables you to transition into that state from
+another scene. The framework provides the {@link android.transition.Scene} class to represent
+a scene.</p>
+
+<p>The transitions framework lets you create scenes from layout resource files or from
+{@link android.view.ViewGroup} objects in your code. Creating a scene in your code is useful
+if you generated a view hierarchy dynamically or if you are modifying it at runtime.</p>
+
+<p>In most cases, you do not create a starting scene explicitly. If you have applied a
+transition, the framework uses the previous ending scene as the starting scene for any
+subsequent transitions. If you have not applied a transition, the framework collects information
+about the views from the current state of the screen.</p>
+
+<p>A scene can also define its own actions that run when you make a scene change. For example,
+this feature is useful for cleaning up view settings after you transition to a scene.</p>
+
+<p>In addition to the view hierarchy and its property values, a scene also stores a reference
+to the parent of the view hierarchy. This root view is called a <strong>scene root</strong>.
+Changes to the scene and animations that affect the scene occur within the scene root.</p>
+
+<p>To learn how to create scenes, see
+<a href="{@docRoot}training/transitions/scenes.html">Creating a Scene</a>.</p>
+
+
+
+<h2 id="Transitions">Transitions</h2>
+
+<p>In the transitions framework, animations create a series of frames that depict a change
+between the view hierarchies in the starting and ending scenes. Information about the animation
+is stored in a {@link android.transition.Transition} object. To run the animation, you apply the
+transition using a {@link android.transition.TransitionManager} instance. The framework can
+transition between two different scenes or transition to a different state for the current
+scene.</p>
+
+<p>The framework includes a set of built-in transitions for commonly-used animation effects,
+such as fading and resizing views. You can also define your own custom transitions to create
+an animation effect using the APIs in the animations framework. The transitions framework also
+enables you to combine different animation effects in a transition set that contains a group
+of individual built-in or custom transitions.</p>
+
+<p>The transition lifecycle is similar to the activity lifecycle, and it represents the
+transition states that the framework monitors between the start and the completion of an
+animation. At important lifecycle states, the framework invokes callback methods that you can
+implement to make adjustments to your user interface at different phases of the transition.</p>
+
+<p>To learn more about transitions, see
+<a href="{@docRoot}training/transitions/transitions.html">Applying a Transition</a> and
+<a href="{@docRoot}training/transitions/custom-transitions.html">Creating Custom
+Transitions</a>.</p>
+
+
+
+<h2 id="Limitations">Limitations</h2>
+
+<p>This section lists some known limitations of the transitions framework:</p>
+
+<ul>
+<li>Animations applied to a {@link android.view.SurfaceView} may not appear correctly.
+{@link android.view.SurfaceView} instances are updated from a non-UI thread, so the updates
+may be out of sync with the animations of other views.</li>
+<li>Some specific transition types may not produce the desired animation effect when applied
+to a {@link android.view.TextureView}.</li>
+<li>Classes that extend {@link android.widget.AdapterView}, such as
+{@link android.widget.ListView}, manage their child views in ways that are incompatible with
+the transitions framework. If you try to animate a view based on
+{@link android.widget.AdapterView}, the device display may hang.</li>
+<li>If you try to resize a {@link android.widget.TextView} with an animation, the text will
+pop to a new location before the object has completely resized. To avoid this problem, do not
+animate the resizing of views that contain text.</li>
+</ul>
diff --git a/docs/html/training/transitions/scenes.jd b/docs/html/training/transitions/scenes.jd
new file mode 100644
index 0000000..4bf7d0e
--- /dev/null
+++ b/docs/html/training/transitions/scenes.jd
@@ -0,0 +1,211 @@
+page.title=Creating a Scene
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#FromLayout">Create a Scene From a Layout Resource</a></li>
+  <li><a href="#FromCode">Create a Scene in Your Code</a></li>
+  <li><a href="#Actions">Create Scene Actions</a></li>
+</ol>
+</div>
+</div>
+
+<p>Scenes store the state of a view hierarchy, including all its views and their property
+values. The transitions framework can run animations between a starting and an ending scene.
+The starting scene is often determined automatically from the current state of the user
+interface. For the ending scene, the framework enables you to create a scene from a layout
+resource file or from a group of views in your code.</p>
+
+<p>This lesson shows you how to create scenes in your app and how to define scene actions.
+The next lesson shows you how to transition between two scenes.</p>
+
+<p class="note"><strong>Note:</strong> The framework can animate changes in a single view
+hierarchy without using scenes, as described in
+<a href="{@docRoot}training/transitions/transitions.html#NoScenes">Apply a Transition Without
+Scenes</a>. However, understanding this lesson is essential to work with transitions.</p>
+
+
+
+<h2 id="FromLayout">Create a Scene From a Layout Resource</h2>
+
+<p>You can create a {@link android.transition.Scene} instance directly from a layout resource
+file. Use this technique when the view hierarchy in the file is mostly static. The resulting
+scene represents the state of the view hierarchy at the time you created the
+{@link android.transition.Scene} instance. If you change the view hierarchy, you have to
+recreate the scene. The framework creates the scene from the entire view hierarchy in the
+file; you can not create a scene from part of a layout file.</p>
+
+<p>To create a {@link android.transition.Scene} instance from a layout resource file, retrieve
+the scene root from your layout as a {@link android.view.ViewGroup} instance and then call the
+{@link android.transition.Scene#getSceneForLayout Scene.getSceneForLayout()} method with the
+scene root and the resource ID of the layout file that contains the view hierarchy for the
+scene.</p>
+
+<h3>Define Layouts for Scenes</h3>
+
+<p>The code snippets in the rest of this section show you how to create two different scenes
+with the same scene root element. The snippets also demonstrate that you can load multiple
+unrelated {@link android.transition.Scene} objects without implying that they are related to
+each other.</p>
+
+<p>The example consists of the following layout definitions:</p>
+
+<ul>
+<li>The main layout of an activity with a text label and a child layout.</li>
+<li>A relative layout for the first scene with two text fields.</li>
+<li>A relative layout for the second scene with the same two text fields in different order.</li>
+</ul>
+
+<p>The example is designed so that all of the animation occurs within the child layout of the
+main layout for the activity. The text label in the main layout remains static.</p>
+
+<p>The main layout for the activity is defined as follows:</p>
+
+<p class="code-caption">res/layout/activity_main.xml</p>
+
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/master_layout">
+    &lt;TextView
+        android:id="@+id/title"
+        ...
+        android:text="Title"/>
+    &lt;FrameLayout
+        android:id="@+id/scene_root">
+        &lt;include layout="@layout/a_scene" />
+    &lt;/FrameLayout>
+&lt;/LinearLayout>
+</pre>
+
+<p>This layout definition contains a text field and a child layout for the scene root. The
+layout for the first scene is included in the main layout file. This allows the app to display
+it as part of the initial user interface and also to load it into a scene, since the framework
+can load only a whole layout file into a scene.</p>
+
+<p>The layout for the first scene is defined as follows:</p>
+
+<p class="code-caption">res/layout/a_scene.xml</p>
+
+<pre>
+&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/scene_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    &lt;TextView
+        android:id="@+id/text_view1
+        android:text="Text Line 1" />
+    &lt;TextView
+        android:id="@+id/text_view2
+        android:text="Text Line 2" />
+&lt;/RelativeLayout>
+</pre>
+
+<p>The layout for the second scene contains the same two text fields (with the same IDs)
+placed in a different order and is defined as follows:</p>
+
+<p class="code-caption">res/layout/another_scene.xml</p>
+
+<pre>
+&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/scene_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    &lt;TextView
+        android:id="@+id/text_view2
+        android:text="Text Line 2" />
+    &lt;TextView
+        android:id="@+id/text_view1
+        android:text="Text Line 1" />
+&lt;/RelativeLayout>
+</pre>
+
+<h3>Generate Scenes from Layouts</h3>
+
+<p>After you create definitions for the two relative layouts, you can obtain an scene for
+each of them. This enables you to later transition between the two UI configurations.
+To obtain a scene, you need a reference to the scene root and the layout resource ID.</p>
+
+<p>The following code snippet shows you how to get a reference to the scene root and create
+two {@link android.transition.Scene} objects from the layout files:</p>
+
+<pre>
+Scene mAScene;
+Scene mAnotherScene;
+
+// Create the scene root for the scenes in this app
+mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);
+
+// Create the scenes
+mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
+mAnotherScene =
+    Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);
+</pre>
+
+<p>In the app, there are now two {@link android.transition.Scene} objects based on view
+hierarchies. Both scenes use the scene root defined by the
+{@link android.widget.FrameLayout} element in <code>res/layout/activity_main.xml</code>.</p>
+
+
+
+<h2 id="FromCode">Create a Scene in Your Code</h2>
+
+<p>You can also create a {@link android.transition.Scene} instance in your code from a
+{@link android.view.ViewGroup} object. Use this technique when you modify the view hierarchies
+directly in your code or when you generate them dynamically.</p>
+
+<p>To create a scene from a view hierarchy in your code, use the
+{@link android.transition.Scene#Scene(android.view.ViewGroup, android.view.View) Scene(sceneRoot, viewHierarchy)}
+constructor. Calling this constructor is equivalent to calling the
+{@link android.transition.Scene#getSceneForLayout Scene.getSceneForLayout()} method when you
+have already inflated a layout file.</p>
+
+<p>The following code snippet demonstrates how to create a {@link android.transition.Scene}
+instance from the scene root element and the view hierarchy for the scene in your code:</p>
+
+<pre>
+Scene mScene;
+
+// Obtain the scene root element
+mSceneRoot = (ViewGroup) mSomeLayoutElement;
+
+// Obtain the view hierarchy to add as a child of
+// the scene root when this scene is entered
+mViewHierarchy = (ViewGroup) someOtherLayoutElement;
+
+// Create a scene
+mScene = new Scene(mSceneRoot, mViewHierarchy);
+</pre>
+
+
+
+<h2 id="Actions">Create Scene Actions</h2>
+
+<p>The framework enables you to define custom scene actions that the system runs when entering
+or exiting a scene. In many cases, defining custom scene actions is not necessary, since the
+framework animates the change between scenes automatically.</p>
+
+<p>Scene actions are useful for handling these cases:</p>
+
+<ul>
+<li>Animate views that are not in the same hierarchy. You can animate views for both the
+starting and ending scenes using exit and entry scene actions.</li>
+<li>Animate views that the transitions framework cannot animate automatically, such as
+{@link android.widget.ListView} objects. For more information, see
+<a href="{@docRoot}training/transitions/overview.html#Limitations">Limitations</a>.</li>
+</ul>
+
+<p>To provide custom scene actions, define your actions as {@link java.lang.Runnable} objects
+and pass them to the {@link android.transition.Scene#setExitAction Scene.setExitAction()} or
+{@link android.transition.Scene#setEnterAction Scene.setEnterAction()} methods. The framework
+calls the {@link android.transition.Scene#setExitAction setExitAction()} method on the starting
+scene before running the transition animation and the {@link
+android.transition.Scene#setEnterAction setEnterAction()} method on the ending scene after
+running the transition animation.</p>
+
+<p class="note"><strong>Note:</strong> Do not use scene actions to pass data between views in
+the starting and ending scenes. For more information, see
+<a href="{@docRoot}training/transitions/transitions.html#Callbacks">Defining Transition
+Lifecycle Callbacks</a>.</p>
diff --git a/docs/html/training/transitions/transitions.jd b/docs/html/training/transitions/transitions.jd
new file mode 100644
index 0000000..489e291
--- /dev/null
+++ b/docs/html/training/transitions/transitions.jd
@@ -0,0 +1,315 @@
+page.title=Applying a Transition
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Create">Create a Transition</a></li>
+  <li><a href="#Apply">Apply a Transition</a></li>
+  <li><a href="#Targets">Choose Specific Target Views</a></li>
+  <li><a href="#Multiple">Specify Multiple Transitions</a></li>
+  <li><a href="#NoScenes">Apply a Transition Without Scenes</a></li>
+  <li><a href="#Callbacks">Define Transition Lifecycle Callbacks</a></li>
+</ol>
+</div>
+</div>
+
+<p>In the transitions framework, animations create a series of frames that depict a change
+between the view hierarchies in the starting and ending scenes. The framework represents
+these animations as transition objects, which contain information about an animation. To
+run an animation, you provide the transition to use and the ending scene to a transition
+manager.</p>
+
+<p>This lesson teaches you run an animation between two scenes using built-in transitions
+to move, resize, and fade views. The next lesson shows you how to define custom transitions.</p>
+
+
+
+<h2 id="Create">Create a Transition</h2>
+
+<p>In the previous lesson, you learned how to create scenes that represent the state of
+different view hierarchies. Once you have defined the starting scene and the ending scene you
+want to change between, you need to create a {@link android.transition.Transition} object
+that defines an animation. The framework enables you to specify a built-in transition in a
+resource file and inflate it in your code or to create an instance of a built-in transition
+directly in your code.</p>
+
+<!-- Built in transition table -->
+<p class="table-caption" id="table1"><strong>Table 1.</strong> Built-in transition types.</p>
+<table>
+<tr>
+  <th scope="col">Class</th>
+  <th scope="col">Tag</th>
+  <th scope="col">Attributes</th>
+  <th scope="col">Effect</th>
+</tr>
+<tr>
+  <td><code><a href="/reference/android/transition/AutoTransition.html">AutoTransition</a></code></td>
+  <td>&lt;autoTransition/&gt;</td>
+  <td style="text-align=center;"> - </td>
+  <td>Default transition. Fade out, move and resize, and fade in views, in that order.</td>
+</tr>
+<tr>
+  <td><code><a href="/reference/android/transition/Fade.html">Fade</a></code></td>
+  <td>&lt;fade/&gt;</td>
+  <td><code>android:fadingMode="[fade_in |<br> fade_out |<br> fade_in_out]"</code></td>
+  <td>
+    <code>fade_in</code> fades in views<br>
+    <code>fade_out</code> fades out views<br>
+    <code>fade_in_out</code> (default) does a <code>fade_out</code> followed by a <code>fade_in</code>.
+  </td>
+</tr>
+<tr>
+  <td><code><a href="/reference/android/transition/ChangeBounds.html">ChangeBounds</a></code></td>
+  <td>&lt;changeBounds/&gt;</td>
+  <td style="text-align=center;"> - </td>
+  <td>Moves and resizes views.</td>
+</tr>
+</table>
+
+
+<h3 id="FromFile">Create a transition instance from a resource file</h3>
+
+<p>This technique enables you to modify your transition definition without having to change
+the code of your activity. This technique is also useful to separate complex transition
+definitions from your application code, as shown in <a href="#Multiple">Specify Multiple
+Transitions</a>.</p>
+
+<p>To specify a built-in transition in a resource file, follow these steps:</p>
+
+<ol>
+<li>Add the <code>res/transition/</code> directory to your project.</li>
+<li>Create a new XML resource file inside this directory.</li>
+<li>Add an XML node for one of the built-in transitions.</li>
+</ol>
+
+<p>For example, the following resource file specifies the {@link android.transition.Fade}
+transition:</p>
+
+<p class="code-caption">res/transition/fade_transition.xml</p>
+
+<pre>
+&lt;fade xmlns:android="http://schemas.android.com/apk/res/android" />
+</pre>
+
+<p>The following code snippet shows how to inflate a {@link android.transition.Transition}
+instance inside your activity from a resource file:</p>
+
+<pre>
+Transition mFadeTransition =
+        TransitionInflater.from(this).
+        inflateTransition(R.transition.fade_transition);
+</pre>
+
+
+<h3 id="FromCode">Create a transition instance in your code</h3>
+
+<p>This technique is useful for creating transition objects dynamically if you modify the user
+interface in your code, and to create simple built-in transition instances with few or
+no parameters.</p>
+
+<p>To create an instance of a built-in transition, invoke one of the public constructors in
+the subclasses of the {@link android.transition.Transition} class. For example, the following
+code snippet creates an instance of the {@link android.transition.Fade} transition:</p>
+
+<pre>
+Transition mFadeTransition = new Fade();
+</pre>
+
+
+
+<h2 id="Apply">Apply a Transition</h2>
+
+<p>You typically apply a transition to change between different view hierarchies in response
+to an event, such as a user action. For example, consider a search app: when the user enters
+a search term and clicks the search button, the app changes to the scene that represents the
+results layout while applying a transition that fades out the search button and fades in the
+search results.</p>
+
+<p>To make a scene change while applying a transition in response to some event in your
+activity, call the {@link android.transition.TransitionManager#go TransitionManager.go()}
+static method with the ending scene and the transition instance to use for the animation,
+as shown in the following snippet:</p>
+
+<pre>
+TransitionManager.go(mEndingScene, mFadeTransition);
+</pre>
+
+<p>The framework changes the view hierarchy inside the scene root with the view hierarchy
+from the ending scene while running the animation specified by the transition instance. The
+starting scene is the ending scene from the last transition. If there was no previous
+transition, the starting scene is determined automatically from the current state of the
+user interface.</p>
+
+<p>If you do not specify a transition instance, the transition manager can apply an automatic
+transition that does something reasonable for most situations. For more information, see the
+API reference for the {@link android.transition.TransitionManager} class.</p>
+
+
+
+<h2 id="Targets">Choose Specific Target Views</h2>
+
+<p>The framework applies transitions to all views in the starting and ending scenes by
+default. In some cases, you may only want  to apply an animation to a subset of views in a
+scene. For example, the framework does not support animating changes to
+{@link android.widget.ListView} objects, so you should not try to animate them during a
+transition. The framework enables you to select specific views you want to animate.</p>
+
+<p>Each view that the transition animates is called a <em>target</em>. You can only
+select targets that are part of the view hierarchy associated with a scene.</p>
+
+<p>To remove one or more views from the list of targets, call the {@link
+android.transition.Transition#removeTarget removeTarget()} method before starting
+the transition. To add only the views you specify to the list of targets, call the
+{@link android.transition.Transition#addTarget addTarget()} method. For more
+information, see the API reference for the {@link android.transition.Transition} class.</p>
+
+
+
+<h2 id="Multiple">Specify Multiple Transitions</h2>
+
+<p>To get the most impact from an animation, you should match it to the type of changes
+that occur between the scenes. For example, if you are removing some views and adding others
+between scenes, a fade out/fade in animation provides a noticeable indication that some views
+are no longer available. If you are moving views to different points on the screen, a better
+choice would be to animate the movement so that users notice the new location of the views.</p>
+
+<p>You do not have to choose only one animation, since the transitions framework enables you
+to combine animation effects in a transition set that contains a group of individual built-in
+or custom transitions.</p>
+
+<p>To define a transition set from a collection of transitions in XML, create a resource file
+in the <code>res/transitions/</code> directory and list the transitions under the
+<code>transitionSet</code> element. For example, the following snippet shows how to specify a
+transition set that has the same behaviour as the {@link android.transition.AutoTransition}
+class:</p>
+
+<pre>
+&lt;transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
+    android:transitionOrdering="sequential">
+    &lt;fade android:fadingMode="fade_out" />
+    &lt;changeBounds />
+    &lt;fade android:fadingMode="fade_in" />
+&lt;/transitionSet>
+</pre>
+
+<p>To inflate the transition set into a {@link android.transition.TransitionSet} object in
+your code, call the {@link android.transition.TransitionInflater#from TransitionInflater.from()}
+method in your activity. The {@link android.transition.TransitionSet} class extends from the
+{@link android.transition.Transition} class, so you can use it with a transition manager just
+like any other {@link android.transition.Transition} instance.</p>
+
+
+
+<h2 id="NoScenes">Apply a Transition Without Scenes</h2>
+
+<p>Changing view hierarchies is not the only way to modify your user interface. You can also
+make changes by adding, modifying, and removing child views within the current hierarchy. For
+example, you can implement a search interaction with just a single layout. Start with the
+layout showing a search entry field and a search icon. To change the user interface to show
+the results, remove the search button when the user clicks it by calling the {@link
+android.view.ViewGroup#removeView ViewGroup.removeView()} method, and add the search results by
+calling {@link android.view.ViewGroup#addView ViewGroup.addView()} method.</p>
+
+<p>You may want to use this approach if the alternative is to have two hierarchies that are
+nearly identical. Rather than having to create and maintain two separate layout files for a
+minor difference in the user interface, you can have one layout file containing a view
+hierarchy that you modify in code.</p>
+
+<p>If you make changes within the current view hierarchy in this fashion, you do not need to
+create a scene. Instead, you can create and apply a transition between two states of a view
+hierarchy using a <em>delayed transition</em>. This feature of the transitions framework
+starts with the current view hierarchy state, records changes you make to its views, and applies
+a transition that animates the changes when the system redraws the user interface.</p>
+
+<p>To create a delayed transition within a single view hierarchy, follow these steps:</p>
+
+<ol>
+<li>When the event that triggers the transition occurs, call the {@link
+android.transition.TransitionManager#beginDelayedTransition
+TransitionManager.beginDelayedTransition()} method providing the parent view of all the views
+you want to change and the transition to use. The framework stores the current state of the
+child views and their property values.</li>
+<li>Make changes to the child views as required by your use case. The framework records
+the changes you make to the child views and their properties.</li>
+<li>When the system redraws the user interface according to your changes, the framework
+animates the changes between the original state and the new state.</li>
+</ol>
+
+<p>The following example shows how to animate the addition of a text view to a view hierarchy
+using a delayed transition. The first snippet shows the layout definition file:</p>
+
+<p class="code-caption">res/layout/activity_main.xml</p>
+
+<pre>
+&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/mainLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    &lt;EditText
+        android:id="@+id/inputText"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+    ...
+&lt;/RelativeLayout>
+</pre>
+
+<p>The next snippet shows the code that animates the addition of the text view:</p>
+
+<p class="code-caption">MainActivity.java</p>
+
+<pre>
+private TextView mLabelText;
+private Fade mFade;
+private ViewGroup mRootView;
+...
+
+// Load the layout
+this.setContentView(R.layout.activity_main);
+...
+
+// Create a new TextView and set some View properties
+mLabelText = new TextView();
+mLabelText.setText("Label").setId("1");
+
+// Get the root view and create a transition
+mRootView = (ViewGroup) findViewById(R.id.mainLayout);
+mFade = new Fade(IN);
+
+// Start recording changes to the view hierarchy
+TransitionManager.beginDelayedTransition(mRootView, mFade);
+
+// Add the new TextView to the view hierarchy
+mRootView.addView(mLabelText);
+
+// When the system redraws the screen to show this update,
+// the framework will animate the addition as a fade in
+</pre>
+
+
+
+<h2 id="Callbacks">Define Transition Lifecycle Callbacks</h2>
+
+<p>The transition lifecycle is similar to the activity lifecycle. It represents the transition
+states that the framework monitors during the time between a call to the {@link
+android.transition.TransitionManager#go TransitionManager.go()} method and the completion of
+the animation. At important lifecycle states, the framework invokes callbacks defined by
+the {@link android.transition.Transition.TransitionListener TransitionListener}
+interface.</p>
+
+<p>Transition lifecycle callbacks are useful, for example, for copying a view property value
+from the starting view hierarchy to the ending view hierarchy during a scene change. You
+cannot simply copy the value from its starting view to the view in the ending view hierarchy,
+because the ending view hierarchy is not inflated until the transition is completed.
+Instead, you need to store the value in a variable and then copy it into the ending view
+hierarchy when the framework has finished the transition. To get notified when the transition
+is completed, you can implement the {@link
+android.transition.Transition.TransitionListener#onTransitionEnd
+TransitionListener.onTransitionEnd()} method in your activity.</p>
+
+<p>For more information, see the API reference for the {@link
+android.transition.Transition.TransitionListener TransitionListener} class.</p>
diff --git a/docs/html/training/tv/playback/card.jd b/docs/html/training/tv/playback/card.jd
new file mode 100644
index 0000000..8ac75fd
--- /dev/null
+++ b/docs/html/training/tv/playback/card.jd
@@ -0,0 +1,156 @@
+page.title=Providing a Card View
+page.tags="card"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+  <h2>This lesson teaches you to</h2>
+  <ol>
+    <li><a href="#presenter">Create a Card Presenter</a></li>
+    <li><a href="#card-view">Create a Card View</a></li>
+  </ol>
+  <h2>Try it out</h2>
+  <ul>
+    <li><a class="external-link" href="https://github.com/googlesamples/androidtv-Leanback">Android
+    Leanback sample app</a></li>
+  </ul>
+</div>
+</div>
+
+<p>In the previous lesson, you created a catalog browser, implemented in a browse fragment, that
+displays a list of media items. In this lesson, you create the card views for your media items and
+present them in the browse fragment.</p>
+
+<p>The {@link android.support.v17.leanback.widget.BaseCardView} class and subclasses display the meta
+data associated with a media item. The {@link android.support.v17.leanback.widget.ImageCardView}
+class used in this lesson displays an image for the content along with the media item's title.</p>
+
+<p>This lesson describes code from the <a href="https://github.com/googlesamples/androidtv-Leanback">
+Android Leanback sample app</a>, available on GitHub. Use this sample code to start your own
+app.</p>
+
+<img itemprop="image" src="{@docRoot}images/tv/app-browse.png" alt="App main screen"/>
+<p class="img-caption"><b>Figure 1.</b> The <a href="https://github.com/googlesamples/androidtv-Leanback">
+Leanback sample app</a> browse fragment with a card presenter displaying card view objects.</p>
+
+<h2 id="presenter">Create a Card Presenter</h2>
+
+<p>A {@link android.support.v17.leanback.widget.Presenter} generates views and binds objects to them
+on demand. In the browse fragment where your app presents its content to the user, you create a
+{@link android.support.v17.leanback.widget.Presenter} for the content cards and pass it to the adapter
+that adds the content to the screen. In the following code, the <code>CardPresenter</code> is created
+in the {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished(android.support.v4.content.Loader, java.lang.Object) onLoadFinished()}
+callback of the {@link android.support.v4.app.LoaderManager}.</p>
+
+<pre>
+&#64;Override
+public void onLoadFinished(Loader&lt;HashMap&lt;String, List&lt;Movie&gt;&gt;&gt; arg0,
+                           HashMap&lt;String, List&lt;Movie&gt;&gt; data) {
+
+    mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+    CardPresenter cardPresenter = new CardPresenter();
+
+    int i = 0;
+
+    for (Map.Entry&lt;String, List&lt;Movie&gt;&gt; entry : data.entrySet()) {
+        ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+        List&lt;Movie&gt; list = entry.getValue();
+
+        for (int j = 0; j &lt; list.size(); j++) {
+            listRowAdapter.add(list.get(j));
+        }
+        HeaderItem header = new HeaderItem(i, entry.getKey(), null);
+        i++;
+        mRowsAdapter.add(new ListRow(header, listRowAdapter));
+    }
+
+    HeaderItem gridHeader = new HeaderItem(i, getString(R.string.more_samples),
+            null);
+
+    GridItemPresenter gridPresenter = new GridItemPresenter();
+    ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
+    gridRowAdapter.add(getString(R.string.grid_view));
+    gridRowAdapter.add(getString(R.string.error_fragment));
+    gridRowAdapter.add(getString(R.string.personal_settings));
+    mRowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));
+
+    setAdapter(mRowsAdapter);
+
+    updateRecommendations();
+}
+</pre>
+
+<h2 id="card-view">Create a Card View</h2>
+
+<p>In this step, you build the card presenter with a view holder for the card view that describes
+your media content items. Note that each presenter must only create one view type. If you have two
+different card view types then you need two different card presenters.</p>
+
+<p>In the {@link android.support.v17.leanback.widget.Presenter}, implement an
+{@link android.support.v17.leanback.widget.Presenter#onCreateViewHolder(android.view.ViewGroup) onCreateViewHolder()}
+callback that creates a view holder that can be used to display a content item.</p>
+
+<pre>
+&#64;Override
+public class CardPresenter extends Presenter {
+
+    private Context mContext;
+    private static int CARD_WIDTH = 313;
+    private static int CARD_HEIGHT = 176;
+    private Drawable mDefaultCardImage;
+
+    &#64;Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent) {
+        mContext = parent.getContext();
+        mDefaultCardImage = mContext.getResources().getDrawable(R.drawable.movie);
+...
+</pre>
+
+<p>In the {@link android.support.v17.leanback.widget.Presenter#onCreateViewHolder(android.view.ViewGroup)
+onCreateViewHolder()} method, create a card view for content items. The sample below uses an
+{@link android.support.v17.leanback.widget.ImageCardView}.</p>
+
+<p>When a card is selected, the default behavior expands it to a larger size. If you want to designate
+a different color for the selected card, call {@link android.support.v17.leanback.widget.BaseCardView#setSelected(boolean)
+setSelected()}
+as shown here.</p>
+
+<pre>
+...
+    ImageCardView cardView = new ImageCardView(mContext) {
+        &#64;Override
+        public void setSelected(boolean selected) {
+            int selected_background = mContext.getResources().getColor(R.color.detail_background);
+            int default_background = mContext.getResources().getColor(R.color.default_background);
+            int color = selected ? selected_background : default_background;
+            findViewById(R.id.info_field).setBackgroundColor(color);
+            super.setSelected(selected);
+        }
+    };
+...
+</pre>
+
+<p>When the user opens your app, the {@link android.support.v17.leanback.widget.Presenter.ViewHolder}
+displays the <code>CardView</code> objects for your content items. You need to set these to receive
+focus from the D-pad controller by calling {@link android.view.View#setFocusable(boolean) setFocusable(true)}
+and {@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode(true)}.</p>
+
+<pre>
+...
+    cardView.setFocusable(true);
+    cardView.setFocusableInTouchMode(true);
+    return new ViewHolder(cardView);
+}
+</pre>
+
+<p>When the user selects the {@link android.support.v17.leanback.widget.ImageCardView}, it expands
+to reveal its text area with the background color you specify, as shown in figure 2.</p>
+
+<img itemprop="image" src="{@docRoot}images/tv/card-view.png" alt="App card view"/>
+<p class="img-caption"><b>Figure 2.</b> The <a href="https://github.com/googlesamples/androidtv-Leanback">
+Leanback sample app</a> image card view when selected.</p>
+
+
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index 5427d48..0e9c5ec 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -56,6 +56,9 @@
     <dd>Learn how to use the Leanback support library to build a browsing interface for media
       catalogs.</dd>
 
+  <dt><b><a href="details.html">Providing a Card View</a></b></dt>
+    <dd>Learn how to use the Leanback support library to build a card view for content items.</dd>
+
   <dt><b><a href="details.html">Building a Details View</a></b></dt>
     <dd>Learn how to use the Leanback support library to build a details page for media items.</dd>
 
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
index 177ea7a..a378096 100644
--- a/docs/html/training/tv/start/layouts.jd
+++ b/docs/html/training/tv/start/layouts.jd
@@ -119,8 +119,8 @@
 
 <p>
   Avoid screen elements being clipped due to overscan and by incorporating a 10% margin
-  on all sides of your layout. This translates into a 27dp margin on the left and right edges and
-  a 48dp margin on the top and bottom of your base layouts for activities. The following
+  on all sides of your layout. This translates into a 48dp margin on the left and right edges and
+  a 27dp margin on the top and bottom of your base layouts for activities. The following
   example layout demonstrates how to set these margins in the root layout for a TV app:
 </p>
 
diff --git a/docs/html/training/wearables/data-layer/data-items.jd b/docs/html/training/wearables/data-layer/data-items.jd
index 12babbf..49a8d32 100644
--- a/docs/html/training/wearables/data-layer/data-items.jd
+++ b/docs/html/training/wearables/data-layer/data-items.jd
@@ -46,7 +46,7 @@
 </ol>
 
 <p>
-However, instead of working with raw bytes using <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html#setData(byte[])">setData()</a>,
+However, instead of working with raw bytes using <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html#setData(byte[])"><code>setData()</code></a>,
 we recommend you <a href="#SyncData">use a data map</a>, which exposes
 a data item in an easy-to-use {@link android.os.Bundle}-like interface.
 </p>
@@ -88,39 +88,121 @@
   </li>
 </ol>
 
-<p>The following example shows how to create a data map and put data on it:</p>
+<p>The <code>increaseCounter()</code> method in the following example shows how to create a
+data map and put data in it:</p>
 
 <pre>
-PutDataMapRequest dataMap = PutDataMapRequest.create("/count");
-dataMap.getDataMap().putInt(COUNT_KEY, count++);
-PutDataRequest request = dataMap.asPutDataRequest();
-PendingResult&lt;DataApi.DataItemResult&gt; pendingResult = Wearable.DataApi
-        .putDataItem(mGoogleApiClient, request);
-</pre>
+public class MainActivity extends Activity implements
+        DataApi.DataListener,
+        GoogleApiClient.ConnectionCallbacks,
+        GoogleApiClient.OnConnectionFailedListener {
 
-<h2 id="ListenEvents">Listen for Data Item Events</h2>
-If one side of the data layer connection changes a data item, you probably want
-to be notified of any changes on the other side of the connection.
-You can do this by implementing a listener for data item events.
+    private static final String COUNT_KEY = "com.example.key.count";
 
-<p>For example, here's what a typical callback looks like to carry out certain actions
-when data changes:</p>
+    private GoogleApiClient mGoogleApiClient;
+    private int count = 0;
 
-<pre>
-&#64;Override
-public void onDataChanged(DataEventBuffer dataEvents) {
-    for (DataEvent event : dataEvents) {
-        if (event.getType() == DataEvent.TYPE_DELETED) {
-            Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
-        } else if (event.getType() == DataEvent.TYPE_CHANGED) {
-             Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
-        }
+    ...
+
+    // Create a data map and put data in it
+    private void <strong>increaseCounter</strong>() {
+        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
+        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
+        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
+        PendingResult&lt;DataApi.DataItemResult> pendingResult =
+                Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
     }
+
+    ...
 }
 </pre>
-<p>
-This is just a snippet that requires more implementation details. Learn about
-how to implement a full listener service or activity in
+
+<p>For more information about handling the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html">
+<code>PendingResult</code></a> object, see
+<a href="{@docRoot}training/wearables/data-layer/events.html#Wait">Wait for the Status of Data
+Layer Calls</a>.</p>
+
+
+<h2 id="ListenEvents">Listen for Data Item Events</h2>
+
+<p>If one side of the data layer connection changes a data item, you probably want
+to be notified of any changes on the other side of the connection.
+You can do this by implementing a listener for data item events.</p>
+
+<p>The code snippet in the following example notifies your app when the value of the
+counter defined in the previous example changes:</p>
+
+<pre>
+public class MainActivity extends Activity implements
+        DataApi.DataListener,
+        GoogleApiClient.ConnectionCallbacks,
+        GoogleApiClient.OnConnectionFailedListener {
+
+    private static final String COUNT_KEY = "com.example.key.count";
+
+    private GoogleApiClient mGoogleApiClient;
+    private int count = 0;
+
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        mGoogleApiClient = new GoogleApiClient.Builder(this)
+                .addApi(Wearable.API)
+                .addConnectionCallbacks(this)
+                .addOnConnectionFailedListener(this)
+                .build();
+    }
+
+    &#64;Override
+    protected void onResume() {
+        super.onStart();
+        mGoogleApiClient.connect();
+    }
+
+    &#64;Override
+    public void onConnected(Bundle bundle) {
+        <strong>Wearable.DataApi.addListener</strong>(mGoogleApiClient, this);
+    }
+
+    &#64;Override
+    protected void onPause() {
+        super.onPause();
+        <strong>Wearable.DataApi.removeListener</strong>(mGoogleApiClient, this);
+        mGoogleApiClient.disconnect();
+    }
+
+    &#64;Override
+    public void <strong>onDataChanged</strong>(DataEventBuffer dataEvents) {
+        for (DataEvent event : dataEvents) {
+            if (event.getType() == DataEvent.TYPE_CHANGED) {
+                // DataItem changed
+                DataItem item = event.getDataItem();
+                if (item.getUri().getPath().compareTo("/count") == 0) {
+                    DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
+                    updateCount(dataMap.getInt(COUNT_KEY));
+                }
+            } else if (event.getType() == DataEvent.TYPE_DELETED) {
+                // DataItem deleted
+            }
+        }
+    }
+
+    // Our method to update the count
+    private void updateCount(int c) { ... }
+
+    ...
+}
+</pre>
+
+<p>This activity implements the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html">
+<code>DataItem.DataListener</code></a> interface. This activity adds itself as a listener
+for data item events inside the <code>onConnected()</code> method and removes the listener
+in the <code>onPause()</code> method.</p>
+
+<p>You can also implement the listener as a service. For more information, see
 <a href="{@docRoot}training/wearables/data-layer/events.html#Listen">Listen for Data Layer
-Events</a>.
-</p>
\ No newline at end of file
+Events</a>.</p>
diff --git a/docs/html/training/wearables/data-layer/events.jd b/docs/html/training/wearables/data-layer/events.jd
index 6a3949a..c797f68 100644
--- a/docs/html/training/wearables/data-layer/events.jd
+++ b/docs/html/training/wearables/data-layer/events.jd
@@ -267,6 +267,8 @@
 public class MainActivity extends Activity implements
         DataApi.DataListener, ConnectionCallbacks, OnConnectionFailedListener {
 
+    private GoogleApiClient mGoogleApiClient;
+
     &#64;Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -314,4 +316,5 @@
             }
         }
     }
+}
 </pre>
diff --git a/docs/html/training/wearables/data-layer/messages.jd b/docs/html/training/wearables/data-layer/messages.jd
index 822e395..0ca55ba 100644
--- a/docs/html/training/wearables/data-layer/messages.jd
+++ b/docs/html/training/wearables/data-layer/messages.jd
@@ -39,16 +39,24 @@
 </p>
 
 <pre>
-Node node; // the connected device to send the message to
 GoogleApiClient mGoogleApiClient;
-public static final START_ACTIVITY_PATH = "/start/MainActivity";
+public static final String START_ACTIVITY_PATH = "/start/MainActivity";
 ...
 
-    SendMessageResult result = Wearable.MessageApi.sendMessage(
-            mGoogleApiClient, node, START_ACTIVITY_PATH, null).await();
-    if (!result.getStatus().isSuccess()) {
-        Log.e(TAG, "ERROR: failed to send Message: " + result.getStatus());
-    }
+private void sendStartActivityMessage(String nodeId) {
+    Wearable.MessageApi.sendMessage(
+      mGoogleApiClient, nodeId, START_ACTIVITY_PATH, new byte[0]).setResultCallback(
+          new ResultCallback&lt;SendMessageResult>() {
+              &#64;Override
+              public void onResult(SendMessageResult sendMessageResult) {
+                  if (!sendMessageResult.getStatus().isSuccess()) {
+                      Log.e(TAG, "Failed to send message with status code: "
+                              + sendMessageResult.getStatus().getStatusCode());
+                  }
+              }
+          }
+      );
+}
 </pre>
 
 <p>
diff --git a/docs/html/training/wearables/watch-faces/configuration.jd b/docs/html/training/wearables/watch-faces/configuration.jd
index edc7eac..5a4585d 100644
--- a/docs/html/training/wearables/watch-faces/configuration.jd
+++ b/docs/html/training/wearables/watch-faces/configuration.jd
@@ -92,7 +92,7 @@
         &lt;action android:name=
             "com.example.android.wearable.watchface.CONFIG_DIGITAL" />
         &lt;category android:name=
-       "com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION" />
+        <strong>"com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION"</strong> />
         &lt;category android:name="android.intent.category.DEFAULT" />
     &lt;/intent-filter>
 &lt;/activity>
@@ -119,8 +119,21 @@
 present users with elaborate color pickers to select the background color of a watch face.</p>
 
 <p>To create a companion configuration activity, add a new activity to your handheld app module and
-declare the same intent filter for this activity as the one in <a href="#WearableActivity">Create
-a Wearable Configuration Activity</a>.</p>
+declare the following intent filter in the manifest file of the handheld app:</p>
+
+<pre>
+&lt;activity
+    android:name=".DigitalWatchFaceCompanionConfigActivity"
+    android:label="@string/app_name">
+    &lt;intent-filter>
+        &lt;action android:name=
+            "com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+        &lt;category android:name=
+        <strong>"com.google.android.wearable.watchface.category.COMPANION_CONFIGURATION"</strong> />
+        &lt;category android:name="android.intent.category.DEFAULT" />
+    &lt;/intent-filter>
+&lt;/activity>
+</pre>
 
 <p>In your configuration activity, build a UI that provides options to customize all the
 configurable elements of your watch face. When users make a selection, use the <a
diff --git a/docs/html/training/wearables/watch-faces/drawing.jd b/docs/html/training/wearables/watch-faces/drawing.jd
index 9afdd80..3c5da34 100644
--- a/docs/html/training/wearables/watch-faces/drawing.jd
+++ b/docs/html/training/wearables/watch-faces/drawing.jd
@@ -192,13 +192,14 @@
 
 <h3 id="Timer">Initialize the custom timer</h3>
 
-<p>As a watch face developer, you can decide how often you want to update your watch face by
+<p>As a watch face developer, you decide how often you want to update your watch face by
 providing a custom timer that ticks with the required frequency while the device is in
-interactive mode. This enables you to create custom animations and other visual effects. In
-ambient mode, you should disable the timer to let the CPU sleep and update the watch face
-only when the time changes. For more information, see
-<a href="{@docRoot}training/wearables/watch-faces/performance.html">Optimizing Performance and
-Battery Life</a>.</p>
+interactive mode. This enables you to create custom animations and other visual effects.
+</p>
+
+<p class="note"><strong>Note:</strong> In ambient mode, the system does not reliably call the
+custom timer. To update the watch face in ambient mode, see <a href="#TimeTick">Update the watch
+face in ambient mode</a>.</p>
 
 <p>An example timer definition from the <code>AnalogWatchFaceService</code> class that ticks once
 every second is shown in <a href="#Variables">Declare variables</a>. In the
@@ -210,9 +211,8 @@
 <li>The device is in interactive mode.</li>
 </ul>
 
-<p>The timer should not run under any other conditions, since this watch face does not
-draw the second hand in ambient mode to conserve power. The <code>AnalogWatchFaceService</code>
-class schedules the next timer tick if required as follows:</p>
+<p>The <code>AnalogWatchFaceService</code> class schedules the next timer tick if required as
+follows:</p>
 
 <pre>
 private void updateTimer() {
@@ -281,15 +281,15 @@
 
 
 
-<h3 id="TimeTick">Invalidate the canvas when the time changes</h3>
+<h3 id="TimeTick">Update the watch face in ambient mode</h3>
 
-<p>The system calls the <code>Engine.onTimeTick()</code> method every minute. In ambient mode,
-it is usually sufficient to update your watch face once per minute. To update your watch face
-more often while in interactive mode, you provide a custom timer as described in
+<p>In ambient mode, the system calls the <code>Engine.onTimeTick()</code> method every minute.
+It is usually sufficient to update your watch face once per minute in this mode. To update your
+watch face while in interactive mode, you must provide a custom timer as described in
 <a href="#Timer">Initialize the custom timer</a>.</p>
 
-<p>Most watch face implementations just invalidate the canvas to redraw the watch face when
-the time changes:</p>
+<p>In ambient mode, most watch face implementations simply invalidate the canvas to redraw the watch
+face in the <code>Engine.onTimeTick()</code> method:</p>
 
 <pre>
 &#64;Override
@@ -402,20 +402,17 @@
 &#64;Override
 public void onAmbientModeChanged(boolean inAmbientMode) {
 
-    boolean wasInAmbientMode = isInAmbientMode();
     super.onAmbientModeChanged(inAmbientMode);
 
-    if (inAmbientMode != wasInAmbientMode) {
-        if (mLowBitAmbient) {
-            boolean antiAlias = !inAmbientMode;
-            mHourPaint.setAntiAlias(antiAlias);
-            mMinutePaint.setAntiAlias(antiAlias);
-            mSecondPaint.setAntiAlias(antiAlias);
-            mTickPaint.setAntiAlias(antiAlias);
-        }
-        invalidate();
-        updateTimer();
+    if (mLowBitAmbient) {
+        boolean antiAlias = !inAmbientMode;
+        mHourPaint.setAntiAlias(antiAlias);
+        mMinutePaint.setAntiAlias(antiAlias);
+        mSecondPaint.setAntiAlias(antiAlias);
+        mTickPaint.setAntiAlias(antiAlias);
     }
+    invalidate();
+    updateTimer();
 }
 </pre>
 
@@ -478,7 +475,7 @@
     float hrLength = centerX - 80;
 
     // Only draw the second hand in interactive mode.
-    if (!mAmbient) {
+    if (!isInAmbientMode()) {
         float secX = (float) Math.sin(secRot) * secLength;
         float secY = (float) -Math.cos(secRot) * secLength;
         canvas.drawLine(centerX, centerY, centerX + secX, centerY +
diff --git a/docs/html/training/wearables/watch-faces/index.jd b/docs/html/training/wearables/watch-faces/index.jd
index c7affd1..453c30e 100644
--- a/docs/html/training/wearables/watch-faces/index.jd
+++ b/docs/html/training/wearables/watch-faces/index.jd
@@ -21,6 +21,14 @@
   </div>
 </a>
 
+<a class="notice-developers-video wide"
+    href="https://www.youtube.com/watch?v=AK38PJZmIW8">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Watch Faces for Android Wear</p>
+</div>
+</a>
+
 <p>Watch faces in Android Wear leverage a dynamic digital canvas to tell time using colors,
 animations, and relevant contextual information. The <a
 href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app">Android
diff --git a/docs/html/training/wearables/watch-faces/service.jd b/docs/html/training/wearables/watch-faces/service.jd
index 7ab575e..35366c5 100644
--- a/docs/html/training/wearables/watch-faces/service.jd
+++ b/docs/html/training/wearables/watch-faces/service.jd
@@ -64,42 +64,15 @@
 
 <h3 id="Dependencies">Dependencies</h3>
 
-<p>For the handheld app, edit the <code>build.gradle</code> file in the <code>mobile</code> module
-to add these dependencies:</p>
-
-<pre>
-apply plugin: 'com.android.application'
-
-android { ... }
-
-dependencies {
-    ...
-    wearApp project(':wear')
-    compile 'com.google.android.gms:play-services:6.5.+'
-}
-</pre>
-
-<p>For the wearable app, edit the <code>build.gradle</code> file in the <code>wear</code> module
-to add these dependencies:</p>
-
-<pre>
-apply plugin: 'com.android.application'
-
-android { ... }
-
-dependencies {
-    ...
-    compile 'com.google.android.support:wearable:1.1.+'
-    compile 'com.google.android.gms:play-services-wearable:6.5.+'
-}
-</pre>
-
 <p>The Wearable Support Library provides the necessary classes that you extend to create watch
 face implementations. The Google Play services client libraries (<code>play-services</code> and
 <code>play-services-wearable</code>) are required to sync data items between the companion device
 and the wearable with the <a href="{@docRoot}training/wearables/data-layer/index.html">Wearable
 Data Layer API</a>.</p>
 
+<p>Android Studio automatically adds the required entries in your <code>build.gradle</code>
+files when you create the project in the instructions above.</p>
+
 <h3 id="Reference">Wearable Support Library API Reference</h3>
 
 <p>The reference documentation provides detailed information about the classes you use to