diff --git a/tools/droiddoc/templates-sdk-dev/assets/js/android_3p-bundle.js b/tools/droiddoc/templates-sdk-dev/assets/js/android_3p-bundle.js
index a67b5b0..70d6c2f 100644
--- a/tools/droiddoc/templates-sdk-dev/assets/js/android_3p-bundle.js
+++ b/tools/droiddoc/templates-sdk-dev/assets/js/android_3p-bundle.js
@@ -2763,4 +2763,10 @@
 * https://github.com/jquery/jquery-ui
 * Includes: jquery.effects.transfer.js
 * Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);;
\ No newline at end of file
+(function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);;
+/*! (c) 2012 Airbnb, Inc.
+*
+* polyglot.js 0.4.3 may be freely distributed under the terms of the BSD
+* license. For all licensing information, details, and documention:
+* http://airbnb.github.com/polyglot.js */
+(function(e,t){typeof define=="function"&&define.amd?define([],function(){return t(e)}):typeof exports=="object"?module.exports=t(e):e.Polyglot=t(e)})(this,function(e){"use strict";function t(e){e=e||{},this.phrases={},this.extend(e.phrases||{}),this.currentLocale=e.locale||"en",this.allowMissing=!!e.allowMissing,this.warn=e.warn||c}function s(e){var t,n,r,i={};for(t in e)if(e.hasOwnProperty(t)){n=e[t];for(r in n)i[n[r]]=t}return i}function o(e){var t=/^\s+|\s+$/g;return e.replace(t,"")}function u(e,t,r){var i,s,u;return r!=null&&e?(s=e.split(n),u=s[f(t,r)]||s[0],i=o(u)):i=e,i}function a(e){var t=s(i);return t[e]||t.en}function f(e,t){return r[a(e)](t)}function l(e,t){for(var n in t)n!=="_"&&t.hasOwnProperty(n)&&(e=e.replace(new RegExp("%\\{"+n+"\\}","g"),t[n]));return e}function c(t){e.console&&e.console.warn&&e.console.warn("WARNING: "+t)}function h(e){var t={};for(var n in e)t[n]=e[n];return t}t.VERSION="0.4.3",t.prototype.locale=function(e){return e&&(this.currentLocale=e),this.currentLocale},t.prototype.extend=function(e,t){var n;for(var r in e)e.hasOwnProperty(r)&&(n=e[r],t&&(r=t+"."+r),typeof n=="object"?this.extend(n,r):this.phrases[r]=n)},t.prototype.clear=function(){this.phrases={}},t.prototype.replace=function(e){this.clear(),this.extend(e)},t.prototype.t=function(e,t){var n,r;return t=t==null?{}:t,typeof t=="number"&&(t={smart_count:t}),typeof this.phrases[e]=="string"?n=this.phrases[e]:typeof t._=="string"?n=t._:this.allowMissing?n=e:(this.warn('Missing translation for key: "'+e+'"'),r=e),typeof n=="string"&&(t=h(t),r=u(n,this.currentLocale,t.smart_count),r=l(r,t)),r},t.prototype.has=function(e){return e in this.phrases};var n="||||",r={chinese:function(e){return 0},german:function(e){return e!==1?1:0},french:function(e){return e>1?1:0},russian:function(e){return e%10===1&&e%100!==11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2},czech:function(e){return e===1?0:e>=2&&e<=4?1:2},polish:function(e){return e===1?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2},icelandic:function(e){return e%10!==1||e%100===11?1:0}},i={chinese:["fa","id","ja","ko","lo","ms","th","tr","zh"],german:["da","de","en","es","fi","el","he","hu","it","nl","no","pt","sv"],french:["fr","tl","pt-br"],russian:["hr","ru"],czech:["cs"],polish:["pl"],icelandic:["is"]};return t});
diff --git a/tools/droiddoc/templates-sdk-dev/assets/js/docs.js b/tools/droiddoc/templates-sdk-dev/assets/js/docs.js
index ee3ebee..9afed71 100644
--- a/tools/droiddoc/templates-sdk-dev/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk-dev/assets/js/docs.js
@@ -1,16 +1,9 @@
-var classesNav;
-var devdocNav;
-var sidenav;
 var cookie_namespace = 'android_developer';
-var NAV_PREF_TREE = "tree";
-var NAV_PREF_PANELS = "panels";
-var nav_pref;
 var isMobile = false; // true if mobile, so we can adjust some layout
 var mPagePath; // initialized in ready() function
 
 var basePath = getBaseUri(location.pathname);
-var SITE_ROOT = toRoot + basePath.substring(1,basePath.indexOf("/",1));
-var GOOGLE_DATA; // combined data for google service apis, used for search suggest
+var SITE_ROOT = toRoot + basePath.substring(1, basePath.indexOf("/", 1));
 
 // Ensure that all ajax getScript() requests allow caching
 $.ajaxSetup({
@@ -21,102 +14,12 @@
 
 $(document).ready(function() {
 
-  // show lang dialog if the URL includes /intl/
-  //if (location.pathname.substring(0,6) == "/intl/") {
-  //  var lang = location.pathname.split('/')[2];
-   // if (lang != getLangPref()) {
-   //   $("#langMessage a.yes").attr("onclick","changeLangPref('" + lang
-   //       + "', true); $('#langMessage').hide(); return false;");
-  //    $("#langMessage .lang." + lang).show();
-   //   $("#langMessage").show();
-   // }
-  //}
-
-  // load json file for JD doc search suggestions
-  $.getScript(toRoot + 'jd_lists_unified.js');
-  // load json file for Android API search suggestions
-  $.getScript(toRoot + 'reference/lists.js');
-  // load json files for Google services API suggestions
-  $.getScript(toRoot + 'reference/gcm_lists.js', function(data, textStatus, jqxhr) {
-      // once the GCM json (GCM_DATA) is loaded, load the GMS json (GMS_DATA) and merge the data
-      if(jqxhr.status === 200) {
-          $.getScript(toRoot + 'reference/gms_lists.js', function(data, textStatus, jqxhr) {
-              if(jqxhr.status === 200) {
-                  // combine GCM and GMS data
-                  GOOGLE_DATA = GMS_DATA;
-                  var start = GOOGLE_DATA.length;
-                  for (var i=0; i<GCM_DATA.length; i++) {
-                      GOOGLE_DATA.push({id:start+i, label:GCM_DATA[i].label,
-                              link:GCM_DATA[i].link, type:GCM_DATA[i].type});
-                  }
-              }
-          });
-      }
-  });
-
-  // setup keyboard listener for search shortcut
-  $('body').keyup(function(event) {
-    if (event.which == 191 && $(event.target).is(':not(:input)')) {
-      $('#search_autocomplete').focus();
-    }
-  });
-
-  // init the fullscreen toggle click event
-  $('#nav-swap .fullscreen').click(function(){
-    if ($(this).hasClass('disabled')) {
-      toggleFullscreen(true);
-    } else {
-      toggleFullscreen(false);
-    }
-  });
-
-  // initialize the divs with custom scrollbars
-  if (window.innerWidth >= 720) {
-    $('.scroll-pane').jScrollPane({verticalGutter: 0});
-  }
-
-  // set up the search close button
-  $('#search-close').on('click touchend', function() {
-    $searchInput = $('#search_autocomplete');
-    $searchInput.attr('value', '');
-    $(this).addClass("hide");
-    $("#search-container").removeClass('active');
-    $("#search_autocomplete").blur();
-    search_focus_changed($searchInput.get(), false);
-    hideResults();
-  });
-
-
-  //Set up search
-  $("#search_autocomplete").focus(function() {
-    $("#search-container").addClass('active');
-  })
-  $("#search-container").on('mouseover touchend', function(e) {
-    if ($(e.target).is('#search-close')) { return; }
-    $("#search-container").addClass('active');
-    $("#search_autocomplete").focus();
-  })
-  $("#search-container").mouseout(function() {
-    if ($("#search_autocomplete").is(":focus")) return;
-    if ($("#search_autocomplete").val() == '') {
-      setTimeout(function(){
-        $("#search-container").removeClass('active');
-        $("#search_autocomplete").blur();
-      },250);
-    }
-  })
-  $("#search_autocomplete").blur(function() {
-    if ($("#search_autocomplete").val() == '') {
-      $("#search-container").removeClass('active');
-    }
-  })
-
-
   // prep nav expandos
-  var pagePath = document.location.pathname;
+  var pagePath = devsite ?
+      location.href.replace(location.hash, '') : document.location.pathname;
   // account for intl docs by removing the intl/*/ path
   if (pagePath.indexOf("/intl/") == 0) {
-    pagePath = pagePath.substr(pagePath.indexOf("/",6)); // start after intl/ to get last /
+    pagePath = pagePath.substr(pagePath.indexOf("/", 6)); // start after intl/ to get last /
   }
 
   if (pagePath.indexOf(SITE_ROOT) == 0) {
@@ -147,97 +50,10 @@
     // Otherwise the page path is already an absolute URL
   }
 
-  // Highlight the header tabs...
-  // highlight Design tab
-  var urlSegments = pagePathOriginal.split('/');
-  var navEl = $(".dac-nav-list");
-  var subNavEl = navEl.find(".dac-nav-secondary");
-  var parentNavEl;
-
-  if ($("body").hasClass("design")) {
-    navEl.find("> li.design > a").addClass("selected");
-  // highlight About tabs
-  } else if ($("body").hasClass("about")) {
-    if (urlSegments[1] == "about" || urlSegments[1] == "wear" || urlSegments[1] == "tv" || urlSegments[1] == "auto") {
-      navEl.find("> li.home > a").addClass('has-subnav');
-      subNavEl.find("li." + urlSegments[1] + " > a").addClass("selected");
-    } else {
-      navEl.find("> li.home > a").addClass('selected');
-    }
-
-// highlight NDK tabs
-  } else if ($("body").hasClass("ndk")) {
-    parentNavEl = navEl.find("> li.ndk > a");
-    parentNavEl.addClass('has-subnav');
-    if ($("body").hasClass("guide")) {
-      navEl.find("> li.guides > a").addClass("selected ndk");
-    } else if ($("body").hasClass("reference")) {
-      navEl.find("> li.reference > a").addClass("selected ndk");
-    } else if ($("body").hasClass("samples")) {
-      navEl.find("> li.samples > a").addClass("selected ndk");
-    } else if ($("body").hasClass("downloads")) {
-      navEl.find("> li.downloads > a").addClass("selected ndk");
-    }
-
-  // highlight Develop tab
-  } else if ($("body").hasClass("develop") || $("body").hasClass("google")) {
-    parentNavEl = navEl.find("> li.develop > a");
-    parentNavEl.addClass('has-subnav');
-
-    // In Develop docs, also highlight appropriate sub-tab
-    if (urlSegments[1] == "training") {
-      subNavEl.find("li.training > a").addClass("selected");
-    } else if (urlSegments[1] == "guide") {
-      subNavEl.find("li.guide > a").addClass("selected");
-    } else if (urlSegments[1] == "reference") {
-      // If the root is reference, but page is also part of Google Services, select Google
-      if ($("body").hasClass("google")) {
-        subNavEl.find("li.google > a").addClass("selected");
-      } else {
-        subNavEl.find("li.reference > a").addClass("selected");
-      }
-    } else if ((urlSegments[1] == "tools") || (urlSegments[1] == "sdk")) {
-      subNavEl.find("li.tools > a").addClass("selected");
-    } else if ($("body").hasClass("google")) {
-      subNavEl.find("li.google > a").addClass("selected");
-    } else if ($("body").hasClass("samples")) {
-      subNavEl.find("li.samples > a").addClass("selected");
-    } else if ($("body").hasClass("preview")) {
-      subNavEl.find("li.preview > a").addClass("selected");
-    } else {
-      parentNavEl.removeClass('has-subnav').addClass("selected");
-    }
-  // highlight Distribute tab
-  } else if ($("body").hasClass("distribute")) {
-    parentNavEl = navEl.find("> li.distribute > a");
-    parentNavEl.addClass('has-subnav');
-
-    if (urlSegments[2] == "users") {
-      subNavEl.find("li.users > a").addClass("selected");
-    } else if (urlSegments[2] == "engage") {
-      subNavEl.find("li.engage > a").addClass("selected");
-    } else if (urlSegments[2] == "monetize") {
-      subNavEl.find("li.monetize > a").addClass("selected");
-    } else if (urlSegments[2] == "analyze") {
-      subNavEl.find("li.analyze > a").addClass("selected");
-    } else if (urlSegments[2] == "tools") {
-      subNavEl.find("li.essentials > a").addClass("selected");
-    } else if (urlSegments[2] == "stories") {
-      subNavEl.find("li.stories > a").addClass("selected");
-    } else if (urlSegments[2] == "essentials") {
-      subNavEl.find("li.essentials > a").addClass("selected");
-    } else if (urlSegments[2] == "googleplay") {
-      subNavEl.find("li.googleplay > a").addClass("selected");
-    } else {
-      parentNavEl.removeClass('has-subnav').addClass("selected");
-    }
-  }
-
   // set global variable so we can highlight the sidenav a bit later (such as for google reference)
   // and highlight the sidenav
   mPagePath = pagePath;
   highlightSidenav();
-  buildBreadcrumbs();
 
   // set up prev/next links if they exist
   var $selNavLink = $('#nav').find('a[href="' + pagePath + '"]');
@@ -266,8 +82,8 @@
 
       // except if cross boundaries aren't allowed, and we're at the top of a section already
       // (and there's another parent)
-      if (!crossBoundaries && $parentListItem.hasClass('nav-section')
-                           && $selListItem.hasClass('nav-section')) {
+      if (!crossBoundaries && $parentListItem.hasClass('nav-section') &&
+                           $selListItem.hasClass('nav-section')) {
         $prevLink = [];
       }
     }
@@ -282,7 +98,7 @@
       $nextLink = $selListItem.find('ul:eq(0)').find('a:eq(0)');
 
       // if there aren't any children, go to the next section (required for About pages)
-      if($nextLink.length == 0) {
+      if ($nextLink.length == 0) {
         $nextLink = $selListItem.next('li').find('a');
       } else if ($('.topic-start-link').length) {
         // as long as there's a child link and there is a "topic start link" (we're on a landing)
@@ -306,7 +122,7 @@
           $nextLink = $selListItem.parents('li:eq(1)').next('li.nav-section').find('a:eq(0)');
           if ($nextLink.length == 0) {
             // if that doesn't work, we're at the end of the list, so disable NEXT link
-            $('.next-page-link').attr('href','').addClass("disabled")
+            $('.next-page-link').attr('href', '').addClass("disabled")
                                 .click(function() { return false; });
             // and completely hide the one in the footer
             $('.content-footer .next-page-link').hide();
@@ -325,22 +141,27 @@
       }
     } else if (isCrossingBoundary && !$('body.design').length) {  // Design always crosses boundaries
       $('.content-footer.next-class').show();
-      $('.next-page-link').attr('href','')
+      $('.next-page-link').attr('href', '')
                           .removeClass("hide").addClass("disabled")
                           .click(function() { return false; });
       // and completely hide the one in the footer
       $('.content-footer .next-page-link').hide();
+      $('.content-footer .prev-page-link').hide();
+
       if ($nextLink.length) {
-        $('.next-class-link').attr('href',$nextLink.attr('href'))
-                             .removeClass("hide")
-                             .append(": " + $nextLink.html());
+        $('.next-class-link').attr('href', $nextLink.attr('href'))
+                             .removeClass("hide");
+
+        $('.content-footer .next-class-link').append($nextLink.html());
+
         $('.next-class-link').find('.new').empty();
       }
     } else {
       $('.next-page-link').attr('href', $nextLink.attr('href'))
                           .removeClass("hide");
-      // for the footer link, also add the next page title
-      $('.content-footer .next-page-link').append(": " + $nextLink.html());
+      // for the footer link, also add the previous and next page titles
+      $('.content-footer .prev-page-link').append($prevLink.html());
+      $('.content-footer .next-page-link').append($nextLink.html());
     }
 
     if (!startClass && $prevLink.length) {
@@ -354,8 +175,6 @@
 
   }
 
-
-
   // Set up the course landing pages for Training with class names and descriptions
   if ($('body.trainingcourse').length) {
     var $classLinks = $selListItem.find('ul li a').not('#nav .nav-section .nav-section ul a');
@@ -382,7 +201,7 @@
     var $liLesson;
     $classLinks.each(function(index) {
       $liClass  = $('<li class="clearfix"></li>');
-      $h2Title  = $('<a class="title" href="'+$(this).attr('href')+'"><h2 class="norule">' + $(this).html()+'</h2><span></span></a>');
+      $h2Title  = $('<a class="title" href="' + $(this).attr('href') + '"><h2 class="norule">' + $(this).html() + '</h2><span></span></a>');
       $pSummary = $('<p class="description">' + $classDescriptions[index] + '</p>');
 
       $olLessons  = $('<ol class="lesson-list"></ol>');
@@ -391,7 +210,7 @@
 
       if ($lessons.length) {
         $lessons.each(function(index) {
-          $olLessons.append('<li><a href="'+$(this).attr('href')+'">' + $(this).html()+'</a></li>');
+          $olLessons.append('<li><a href="' + $(this).attr('href') + '">' + $(this).html() + '</a></li>');
         });
       } else {
         $pSummary.addClass('article');
@@ -400,35 +219,14 @@
       $liClass.append($h2Title).append($pSummary).append($olLessons);
       $olClasses.append($liClass);
     });
-    $('.jd-descr').append($olClasses);
+    $('#classes').append($olClasses);
   }
 
   // Set up expand/collapse behavior
   initExpandableNavItems("#nav");
 
-
-  $(".scroll-pane").scroll(function(event) {
-      event.preventDefault();
-      return false;
-  });
-
-  /* Resize nav height when window height changes */
-  $(window).resize(function() {
-    if ($('#side-nav').length == 0) return;
-    setNavBarDimensions(); // do this even if sidenav isn't fixed because it could become fixed
-    // make sidenav behave when resizing the window and side-scolling is a concern
-    updateSideNavDimensions();
-    checkSticky();
-    resizeNav(250);
-  });
-
-  if ($('#devdoc-nav').length) {
-    setNavBarDimensions();
-  }
-
-
   // Set up play-on-hover <video> tags.
-  $('video.play-on-hover').bind('click', function(){
+  $('video.play-on-hover').bind('click', function() {
     $(this).get(0).load(); // in case the video isn't seekable
     $(this).get(0).play();
   });
@@ -476,220 +274,31 @@
   });
 
   //Loads the +1 button
-  var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
-  po.src = 'https://apis.google.com/js/plusone.js';
-  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
-
-  $(".scroll-pane").removeAttr("tabindex"); // get rid of tabindex added by jscroller
-
-  if ($(".scroll-pane").length > 1) {
-    // Check if there's a user preference for the panel heights
-    var cookieHeight = readCookie("reference_height");
-    if (cookieHeight) {
-      restoreHeight(cookieHeight);
-    }
-  }
-
-  // Resize once loading is finished
-  resizeNav();
-  // Check if there's an anchor that we need to scroll into view.
-  // A delay is needed, because some browsers do not immediately scroll down to the anchor
-  window.setTimeout(offsetScrollForSticky, 100);
-
-  /* init the language selector based on user cookie for lang */
-  loadLangPref();
-  changeNavLang(getLangPref());
-
-  /* setup event handlers to ensure the overflow menu is visible while picking lang */
-  $("#language select")
-      .mousedown(function() {
-        $("div.morehover").addClass("hover"); })
-      .blur(function() {
-        $("div.morehover").removeClass("hover"); });
-
-  /* some global variable setup */
-  resizePackagesNav = $("#resize-packages-nav");
-  classesNav = $("#classes-nav");
-  devdocNav = $("#devdoc-nav");
-
-  var cookiePath = "";
-  if (location.href.indexOf("/reference/") != -1) {
-    cookiePath = "reference_";
-  } else if (location.href.indexOf("/guide/") != -1) {
-    cookiePath = "guide_";
-  } else if (location.href.indexOf("/tools/") != -1) {
-    cookiePath = "tools_";
-  } else if (location.href.indexOf("/training/") != -1) {
-    cookiePath = "training_";
-  } else if (location.href.indexOf("/design/") != -1) {
-    cookiePath = "design_";
-  } else if (location.href.indexOf("/distribute/") != -1) {
-    cookiePath = "distribute_";
-  }
-
-
-  /* setup shadowbox for any videos that want it */
-  var $videoLinks = $("a.video-shadowbox-button, a.notice-developers-video");
-  if ($videoLinks.length) {
-    // if there's at least one, add the shadowbox HTML to the body
-    $('body').prepend(
-'<div id="video-container">'+
-  '<div id="video-frame">'+
-    '<div class="video-close">'+
-      '<span id="icon-video-close" onclick="closeVideo()">&nbsp;</span>'+
-    '</div>'+
-    '<div id="youTubePlayer"></div>'+
-  '</div>'+
-'</div>');
-
-    // loads the IFrame Player API code asynchronously.
-    $.getScript("https://www.youtube.com/iframe_api");
-
-    $videoLinks.each(function() {
-      var videoId = $(this).attr('href').split('?v=')[1];
-      $(this).click(function(event) {
-        event.preventDefault();
-        startYouTubePlayer(videoId);
-      });
-    });
-  }
+  //var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
+  //po.src = 'https://apis.google.com/js/plusone.js';
+  //var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
 });
 // END of the onload event
 
-
-var youTubePlayer;
-function onYouTubeIframeAPIReady() {
-}
-
-/* Returns the height the shadowbox video should be. It's based on the current
-   height of the "video-frame" element, which is 100% height for the window.
-   Then minus the margin so the video isn't actually the full window height. */
-function getVideoHeight() {
-  var frameHeight = $("#video-frame").height();
-  var marginTop = $("#video-frame").css('margin-top').split('px')[0];
-  return frameHeight - (marginTop * 2);
-}
-
-var mPlayerPaused = false;
-
-function startYouTubePlayer(videoId) {
-  $("#video-container").show();
-  $("#video-frame").show();
-  mPlayerPaused = false;
-
-  // compute the size of the player so it's centered in window
-  var maxWidth = 940;  // the width of the web site content
-  var videoAspect = .5625; // based on 1280x720 resolution
-  var maxHeight = maxWidth * videoAspect;
-  var videoHeight = getVideoHeight();
-  var videoWidth = videoHeight / videoAspect;
-  if (videoWidth > maxWidth) {
-    videoWidth = maxWidth;
-    videoHeight = maxHeight;
-  }
-  $("#video-frame").css('width', videoWidth);
-
-  // check if we've already created this player
-  if (youTubePlayer == null) {
-    // check if there's a start time specified
-    var idAndHash = videoId.split("#");
-    var startTime = 0;
-    if (idAndHash.length > 1) {
-      startTime = idAndHash[1].split("t=")[1] != undefined ? idAndHash[1].split("t=")[1] : 0;
-    }
-    // enable localized player
-    var lang = getLangPref();
-    var captionsOn = lang == 'en' ? 0 : 1;
-
-    youTubePlayer = new YT.Player('youTubePlayer', {
-      height: videoHeight,
-      width: videoWidth,
-      videoId: idAndHash[0],
-      playerVars: {start: startTime, hl: lang, cc_load_policy: captionsOn},
-      events: {
-        'onReady': onPlayerReady,
-        'onStateChange': onPlayerStateChange
-      }
-    });
-  } else {
-    // reset the size in case the user adjusted the window since last play
-    youTubePlayer.setSize(videoWidth, videoHeight);
-    // if a video different from the one already playing was requested, cue it up
-    if (videoId != youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0]) {
-      youTubePlayer.cueVideoById(videoId);
-    }
-    youTubePlayer.playVideo();
-  }
-}
-
-function onPlayerReady(event) {
-  event.target.playVideo();
-  mPlayerPaused = false;
-}
-
-function closeVideo() {
-  try {
-    youTubePlayer.pauseVideo();
-  } catch(e) {
-  }
-  $("#video-container").fadeOut(200);
-}
-
-/* Track youtube playback for analytics */
-function onPlayerStateChange(event) {
-    // Video starts, send the video ID
-    if (event.data == YT.PlayerState.PLAYING) {
-      if (mPlayerPaused) {
-        ga('send', 'event', 'Videos', 'Resume',
-            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0]);
-      } else {
-        // track the start playing event so we know from which page the video was selected
-        ga('send', 'event', 'Videos', 'Start: ' +
-            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
-            'on: ' + document.location.href);
-      }
-      mPlayerPaused = false;
-    }
-    // Video paused, send video ID and video elapsed time
-    if (event.data == YT.PlayerState.PAUSED) {
-      ga('send', 'event', 'Videos', 'Paused',
-            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
-            youTubePlayer.getCurrentTime());
-      mPlayerPaused = true;
-    }
-    // Video finished, send video ID and video elapsed time
-    if (event.data == YT.PlayerState.ENDED) {
-      ga('send', 'event', 'Videos', 'Finished',
-            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
-            youTubePlayer.getCurrentTime());
-      mPlayerPaused = true;
-    }
-}
-
-
-
 function initExpandableNavItems(rootTag) {
   $(rootTag + ' li.nav-section .nav-section-header').click(function() {
     var section = $(this).closest('li.nav-section');
     if (section.hasClass('expanded')) {
-    /* hide me and descendants */
+      /* hide me and descendants */
       section.find('ul').slideUp(250, function() {
         // remove 'expanded' class from my section and any children
         section.closest('li').removeClass('expanded');
         $('li.nav-section', section).removeClass('expanded');
-        resizeNav();
       });
     } else {
-    /* show me */
+      /* show me */
       // first hide all other siblings
       var $others = $('li.nav-section.expanded', $(this).closest('ul')).not('.sticky');
       $others.removeClass('expanded').children('ul').slideUp(250);
 
       // now expand me
       section.closest('li').addClass('expanded');
-      section.children('ul').slideDown(250, function() {
-        resizeNav();
-      });
+      section.children('ul').slideDown(250);
     }
   });
 
@@ -702,35 +311,6 @@
   });
 }
 
-
-/** Create the list of breadcrumb links in the sticky header */
-function buildBreadcrumbs() {
-  var $breadcrumbUl =  $(".dac-header-crumbs");
-  var primaryNavLink = ".dac-nav-list > .dac-nav-item > .dac-nav-link";
-
-  // Add the secondary horizontal nav item, if provided
-  var $selectedSecondNav = $(".dac-nav-secondary .dac-nav-link.selected").clone()
-    .attr('class', 'dac-header-crumbs-link');
-
-  if ($selectedSecondNav.length) {
-    $breadcrumbUl.prepend($('<li class="dac-header-crumbs-item">').append($selectedSecondNav));
-  }
-
-  // Add the primary horizontal nav
-  var $selectedFirstNav = $(primaryNavLink + ".selected, " + primaryNavLink + ".has-subnav").clone()
-    .attr('class', 'dac-header-crumbs-link');
-
-  // If there's no header nav item, use the logo link and title from alt text
-  if ($selectedFirstNav.length < 1) {
-    $selectedFirstNav = $('<a class="dac-header-crumbs-link">')
-        .attr('href', $("div#header .logo a").attr('href'))
-        .text($("div#header .logo img").attr('alt'));
-  }
-  $breadcrumbUl.prepend($('<li class="dac-header-crumbs-item">').append($selectedFirstNav));
-}
-
-
-
 /** Highlight the current page in sidenav, expanding children as appropriate */
 function highlightSidenav() {
   // if something is already highlighted, undo it. This is for dynamic navigation (Samples index)
@@ -746,6 +326,8 @@
   }
 
   var $selListItem;
+  var breadcrumb = [];
+
   if ($selNavLink.length) {
     // Find this page's <li> in sidenav and set selected
     $selListItem = $selNavLink.closest('li');
@@ -755,8 +337,20 @@
     $selNavLink.parents('li.nav-section').each(function() {
       $(this).addClass('expanded');
       $(this).children('ul').show();
+
+      var link = $(this).find('a').first();
+
+      if (!$(this).is($selListItem)) {
+        breadcrumb.unshift(link)
+      }
     });
+
+    $('#nav').scrollIntoView($selNavLink);
   }
+
+  breadcrumb.forEach(function(link) {
+    link.dacCrumbs();
+  });
 }
 
 function unHighlightSidenav() {
@@ -764,59 +358,6 @@
   $('ul#nav li.nav-section.expanded').removeClass('expanded').children('ul').hide();
 }
 
-function toggleFullscreen(enable) {
-  var delay = 20;
-  var enabled = true;
-  var stylesheet = $('link[rel="stylesheet"][class="fullscreen"]');
-  if (enable) {
-    // Currently NOT USING fullscreen; enable fullscreen
-    stylesheet.removeAttr('disabled');
-    $('#nav-swap .fullscreen').removeClass('disabled');
-    $('#devdoc-nav').css({left:''});
-    setTimeout(updateSidenavFullscreenWidth,delay); // need to wait a moment for css to switch
-    enabled = true;
-  } else {
-    // Currently USING fullscreen; disable fullscreen
-    stylesheet.attr('disabled', 'disabled');
-    $('#nav-swap .fullscreen').addClass('disabled');
-    setTimeout(updateSidenavFixedWidth,delay); // need to wait a moment for css to switch
-    enabled = false;
-  }
-  writeCookie("fullscreen", enabled, null);
-  setNavBarDimensions();
-  resizeNav(delay);
-  updateSideNavDimensions();
-  setTimeout(initSidenavHeightResize,delay);
-}
-
-// TODO: Refactor into a closure.
-var navBarLeftPos;
-var navBarWidth;
-function setNavBarDimensions() {
-  navBarLeftPos = $('#body-content').offset().left;
-  navBarWidth = $('#side-nav').width();
-}
-
-
-function updateSideNavDimensions() {
-  var newLeft = $(window).scrollLeft() - navBarLeftPos;
-  $('#devdoc-nav').css({left: -newLeft, width: navBarWidth});
-  $('#devdoc-nav .totop').css({left: -(newLeft - parseInt($('#side-nav').css('padding-left')))});
-}
-
-// TODO: use $(document).ready instead
-function addLoadEvent(newfun) {
-  var current = window.onload;
-  if (typeof window.onload != 'function') {
-    window.onload = newfun;
-  } else {
-    window.onload = function() {
-      current();
-      newfun();
-    }
-  }
-}
-
 var agent = navigator['userAgent'].toLowerCase();
 // If a mobile phone, set flag and do mobile setup
 if ((agent.indexOf("mobile") != -1) ||      // android, iphone, ipod
@@ -826,195 +367,23 @@
   isMobile = true;
 }
 
-
 $(document).ready(function() {
   $("pre:not(.no-pretty-print)").addClass("prettyprint");
   prettyPrint();
 });
 
-
-
-
-/* ######### RESIZE THE SIDENAV ########## */
-
-function resizeNav(delay) {
-  var $nav = $("#devdoc-nav");
-  var $window = $(window);
-  var navHeight;
-
-  // Get the height of entire window and the total header height.
-  // Then figure out based on scroll position whether the header is visible
-  var windowHeight = $window.height();
-  var scrollTop = $window.scrollTop();
-  var headerHeight = $('#header-wrapper').outerHeight();
-  var headerVisible = scrollTop < stickyTop;
-
-  // get the height of space between nav and top of window.
-  // Could be either margin or top position, depending on whether the nav is fixed.
-  var topMargin = (parseInt($nav.css('top')) || 20) + 1;
-  // add 1 for the #side-nav bottom margin
-
-  // Depending on whether the header is visible, set the side nav's height.
-  if (headerVisible) {
-    // The sidenav height grows as the header goes off screen
-    navHeight = windowHeight - (headerHeight - scrollTop) - topMargin;
-  } else {
-    // Once header is off screen, the nav height is almost full window height
-    navHeight = windowHeight - topMargin;
-  }
-
-
-
-  $scrollPanes = $(".scroll-pane");
-  if ($window.width() < 720) {
-    $nav.css('height', '');
-  } else if ($scrollPanes.length > 1) {
-    // subtract the height of the api level widget and nav swapper from the available nav height
-    navHeight -= ($('#api-nav-header').outerHeight(true) + $('#nav-swap').outerHeight(true));
-
-    $("#swapper").css({height:navHeight + "px"});
-    if ($("#nav-tree").is(":visible")) {
-      $("#nav-tree").css({height:navHeight});
-    }
-
-    var classesHeight = navHeight - parseInt($("#resize-packages-nav").css("height")) - 10 + "px";
-    //subtract 10px to account for drag bar
-
-    // if the window becomes small enough to make the class panel height 0,
-    // then the package panel should begin to shrink
-    if (parseInt(classesHeight) <= 0) {
-      $("#resize-packages-nav").css({height:navHeight - 10}); //subtract 10px for drag bar
-      $("#packages-nav").css({height:navHeight - 10});
-    }
-
-    $("#classes-nav").css({'height':classesHeight, 'margin-top':'10px'});
-    $("#classes-nav .jspContainer").css({height:classesHeight});
-
-
-  } else {
-    $nav.height(navHeight);
-  }
-
-  if (delay) {
-    updateFromResize = true;
-    delayedReInitScrollbars(delay);
-  } else {
-    reInitScrollbars();
-  }
-
-}
-
-var updateScrollbars = false;
-var updateFromResize = false;
-
-/* Re-initialize the scrollbars to account for changed nav size.
- * This method postpones the actual update by a 1/4 second in order to optimize the
- * scroll performance while the header is still visible, because re-initializing the
- * scroll panes is an intensive process.
- */
-function delayedReInitScrollbars(delay) {
-  // If we're scheduled for an update, but have received another resize request
-  // before the scheduled resize has occured, just ignore the new request
-  // (and wait for the scheduled one).
-  if (updateScrollbars && updateFromResize) {
-    updateFromResize = false;
-    return;
-  }
-
-  // We're scheduled for an update and the update request came from this method's setTimeout
-  if (updateScrollbars && !updateFromResize) {
-    reInitScrollbars();
-    updateScrollbars = false;
-  } else {
-    updateScrollbars = true;
-    updateFromResize = false;
-    setTimeout('delayedReInitScrollbars()',delay);
-  }
-}
-
-/* Re-initialize the scrollbars to account for changed nav size. */
-function reInitScrollbars() {
-  var pane = $(".scroll-pane").each(function(){
-    var api = $(this).data('jsp');
-    if (!api) {return;}
-    api.reinitialise( {verticalGutter:0} );
-  });
-  $(".scroll-pane").removeAttr("tabindex"); // get rid of tabindex added by jscroller
-}
-
-
-/* Resize the height of the nav panels in the reference,
- * and save the new size to a cookie */
-function saveNavPanels() {
-  var basePath = getBaseUri(location.pathname);
-  var section = basePath.substring(1,basePath.indexOf("/",1));
-  writeCookie("height", resizePackagesNav.css("height"), section);
-}
-
-
-
-function restoreHeight(packageHeight) {
-    $("#resize-packages-nav").height(packageHeight);
-    $("#packages-nav").height(packageHeight);
-  //  var classesHeight = navHeight - packageHeight;
- //   $("#classes-nav").css({height:classesHeight});
-  //  $("#classes-nav .jspContainer").css({height:classesHeight});
-}
-
-
-
-/* ######### END RESIZE THE SIDENAV HEIGHT ########## */
-
-
-
-
-
-/** Scroll the jScrollPane to make the currently selected item visible
-    This is called when the page finished loading. */
-function scrollIntoView(nav) {
-  return;
-  var $nav = $("#"+nav);
-  var element = $nav.jScrollPane({/* ...settings... */});
-  var api = element.data('jsp');
-
-  if ($nav.is(':visible')) {
-    var $selected = $(".selected", $nav);
-    if ($selected.length == 0) {
-      // If no selected item found, exit
-      return;
-    }
-    // get the selected item's offset from its container nav by measuring the item's offset
-    // relative to the document then subtract the container nav's offset relative to the document
-    var selectedOffset = $selected.offset().top - $nav.offset().top + 60;
-    if (selectedOffset > $nav.height() * .8) { // multiply nav height by .8 so we move up the item
-                                               // if it's more than 80% down the nav
-      // scroll the item up by an amount equal to 80% the container nav's height
-      api.scrollTo(0, selectedOffset - ($nav.height() * .8), false);
-    }
-  }
-}
-
-
-
-
-
-
 /* Show popup dialogs */
 function showDialog(id) {
-  $dialog = $("#"+id);
+  $dialog = $("#" + id);
   $dialog.prepend('<div class="box-border"><div class="top"> <div class="left"></div> <div class="right"></div></div><div class="bottom"> <div class="left"></div> <div class="right"></div> </div> </div>');
   $dialog.wrapInner('<div/>');
   $dialog.removeClass("hide");
 }
 
-
-
-
-
 /* #########    COOKIES!     ########## */
 
 function readCookie(cookie) {
-  var myCookie = cookie_namespace+"_"+cookie+"=";
+  var myCookie = cookie_namespace + "_" + cookie + "=";
   if (document.cookie) {
     var index = document.cookie.indexOf(myCookie);
     if (index != -1) {
@@ -1031,98 +400,16 @@
 }
 
 function writeCookie(cookie, val, section) {
-  if (val==undefined) return;
-  section = section == null ? "_" : "_"+section+"_";
-  var age = 2*365*24*60*60; // set max-age to 2 years
-  var cookieValue = cookie_namespace + section + cookie + "=" + val
-                    + "; max-age=" + age +"; path=/";
+  if (val == undefined) return;
+  section = section == null ? "_" : "_" + section + "_";
+  var age = 2 * 365 * 24 * 60 * 60; // set max-age to 2 years
+  var cookieValue = cookie_namespace + section + cookie + "=" + val +
+                    "; max-age=" + age + "; path=/";
   document.cookie = cookieValue;
 }
 
 /* #########     END COOKIES!     ########## */
 
-
-var sticky = false;
-var stickyTop;
-var prevScrollLeft = 0; // used to compare current position to previous position of horiz scroll
-/* Sets the vertical scoll position at which the sticky bar should appear.
-   This method is called to reset the position when search results appear or hide */
-function setStickyTop() {
-  stickyTop = $('#header-wrapper').outerHeight() - $('#header > .dac-header-inner').outerHeight();
-}
-
-/*
- * Displays sticky nav bar on pages when dac header scrolls out of view
- */
-$(window).scroll(function(event) {
-  // Exit if the mouse target is a DIV, because that means the event is coming
-  // from a scrollable div and so there's no need to make adjustments to our layout
-  if ($(event.target).nodeName == "DIV") {
-    return;
-  }
-
-  checkSticky();
-});
-
-function checkSticky() {
-  setStickyTop();
-  var $headerEl = $('#header');
-  // Exit if there's no sidenav
-  if ($('#side-nav').length == 0) return;
-
-  var top = $(window).scrollTop();
-  // we set the navbar fixed when the scroll position is beyond the height of the site header...
-  var shouldBeSticky = top > stickyTop;
-  // ... except if the document content is shorter than the sidenav height.
-  // (this is necessary to avoid crazy behavior on OSX Lion due to overscroll bouncing)
-  if ($("#doc-col").height() < $("#side-nav").height()) {
-    shouldBeSticky = false;
-  }
-  // Nor on mobile
-  if (window.innerWidth < 720) {
-    shouldBeSticky = false;
-  }
-  // Account for horizontal scroll
-  var scrollLeft = $(window).scrollLeft();
-  // When the sidenav is fixed and user scrolls horizontally, reposition the sidenav to match
-  if (sticky && (scrollLeft != prevScrollLeft)) {
-    updateSideNavDimensions();
-    prevScrollLeft = scrollLeft;
-  }
-
-  // Don't continue if the header is sufficently far away
-  // (to avoid intensive resizing that slows scrolling)
-  if (sticky == shouldBeSticky) {
-    return;
-  }
-
-  // If sticky header visible and position is now near top, hide sticky
-  if (sticky && !shouldBeSticky) {
-    sticky = false;
-    // make the sidenav static again
-    $('#devdoc-nav')
-      .removeClass('fixed')
-      .css({'width':'auto','margin':''});
-    // delay hide the sticky
-    $headerEl.removeClass('is-sticky');
-
-    // update the sidenaav position for side scrolling
-    updateSideNavDimensions();
-  } else if (!sticky && shouldBeSticky) {
-    sticky = true;
-    $headerEl.addClass('is-sticky');
-
-    // make the sidenav fixed
-    $('#devdoc-nav')
-      .addClass('fixed');
-
-    // update the sidenaav position for side scrolling
-    updateSideNavDimensions();
-
-  }
-  resizeNav(250); // pass true in order to delay the scrollbar re-initialization for performance
-}
-
 /*
  * Manages secion card states and nav resize to conclude loading
  */
@@ -1132,7 +419,7 @@
     // Stack hover states
     $('.section-card-menu').each(function(index, el) {
       var height = $(el).height();
-      $(el).css({height:height+'px', position:'relative'});
+      $(el).css({height:height + 'px', position:'relative'});
       var $cardInfo = $(el).find('.card-info');
 
       $cardInfo.css({position: 'absolute', bottom:'0px', left:'0px', right:'0px', overflow:'visible'});
@@ -1142,25 +429,8 @@
 
 })();
 
-
-
-
-
-
-
-
-
-
-
-
-
-
 /*      MISC LIBRARY FUNCTIONS     */
 
-
-
-
-
 function toggle(obj, slide) {
   var ul = $("ul:first", obj);
   var li = ul.parent();
@@ -1181,7 +451,6 @@
   }
 }
 
-
 function buildToggleLists() {
   $(".toggle-list").each(
     function(i) {
@@ -1190,12 +459,10 @@
     });
 }
 
-
-
 function hideNestedItems(list, toggle) {
   $list = $(list);
   // hide nested lists
-  if($list.hasClass('showing')) {
+  if ($list.hasClass('showing')) {
     $("li ol", $list).hide('fast');
     $list.removeClass('showing');
   // show nested lists
@@ -1203,207 +470,47 @@
     $("li ol", $list).show('fast');
     $list.addClass('showing');
   }
-  $(".more,.less",$(toggle)).toggle();
+  $(".more,.less", $(toggle)).toggle();
 }
 
-
 /* Call this to add listeners to a <select> element for Studio/Eclipse/Other docs */
 function setupIdeDocToggle() {
-  $( "select.ide" ).change(function() {
+  $("select.ide").change(function() {
     var selected = $(this).find("option:selected").attr("value");
     $(".select-ide").hide();
-    $(".select-ide."+selected).show();
+    $(".select-ide." + selected).show();
 
     $("select.ide").val(selected);
   });
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*      REFERENCE NAV SWAP     */
-
-
-function getNavPref() {
-  var v = readCookie('reference_nav');
-  if (v != NAV_PREF_TREE) {
-    v = NAV_PREF_PANELS;
-  }
-  return v;
-}
-
-function chooseDefaultNav() {
-  nav_pref = getNavPref();
-  if (nav_pref == NAV_PREF_TREE) {
-    $("#nav-panels").toggle();
-    $("#panel-link").toggle();
-    $("#nav-tree").toggle();
-    $("#tree-link").toggle();
-  }
-}
-
-function swapNav() {
-  if (nav_pref == NAV_PREF_TREE) {
-    nav_pref = NAV_PREF_PANELS;
-  } else {
-    nav_pref = NAV_PREF_TREE;
-    init_default_navtree(toRoot);
-  }
-  writeCookie("nav", nav_pref, "reference");
-
-  $("#nav-panels").toggle();
-  $("#panel-link").toggle();
-  $("#nav-tree").toggle();
-  $("#tree-link").toggle();
-
-  resizeNav();
-
-  // Gross nasty hack to make tree view show up upon first swap by setting height manually
-  $("#nav-tree .jspContainer:visible")
-      .css({'height':$("#nav-tree .jspContainer .jspPane").height() +'px'});
-  // Another nasty hack to make the scrollbar appear now that we have height
-  resizeNav();
-
-  if ($("#nav-tree").is(':visible')) {
-    scrollIntoView("nav-tree");
-  } else {
-    scrollIntoView("packages-nav");
-    scrollIntoView("classes-nav");
-  }
-}
-
-
-
-/* ############################################ */
-/* ##########     LOCALIZATION     ############ */
-/* ############################################ */
-
-function getBaseUri(uri) {
-  var intlUrl = (uri.substring(0,6) == "/intl/");
-  if (intlUrl) {
-    base = uri.substring(uri.indexOf('intl/')+5,uri.length);
-    base = base.substring(base.indexOf('/')+1, base.length);
-      //alert("intl, returning base url: /" + base);
-    return ("/" + base);
-  } else {
-      //alert("not intl, returning uri as found.");
-    return uri;
-  }
-}
-
-function requestAppendHL(uri) {
-//append "?hl=<lang> to an outgoing request (such as to blog)
-  var lang = getLangPref();
-  if (lang) {
-    var q = 'hl=' + lang;
-    uri += '?' + q;
-    window.location = uri;
-    return false;
-  } else {
-    return true;
-  }
-}
-
-
-function changeNavLang(lang) {
-  if (lang === 'en') { return; }
-
-  var $links = $("a[" + lang + "-lang],p[" + lang + "-lang]");
-  $links.each(function(){ // for each link with a translation
-    var $link = $(this);
-    // put the desired language from the attribute as the text
-    $link.text($link.attr(lang + '-lang'))
-  });
-}
-
-function changeLangPref(lang, submit) {
-  writeCookie("pref_lang", lang, null);
-
-  //  #######  TODO:  Remove this condition once we're stable on devsite #######
-  //  This condition is only needed if we still need to support legacy GAE server
-  if (devsite) {
-    // Switch language when on Devsite server
-    if (submit) {
-      $("#setlang").submit();
-    }
-  } else {
-    // Switch language when on legacy GAE server
-    if (submit) {
-      window.location = getBaseUri(location.pathname);
-    }
-  }
-}
-
-function loadLangPref() {
-  var lang = readCookie("pref_lang");
-  if (lang != 0) {
-    $("#language").find("option[value='"+lang+"']").attr("selected",true);
-  }
-}
-
-function getLangPref() {
-  var lang = $("#language").find(":selected").attr("value");
-  if (!lang) {
-    lang = readCookie("pref_lang");
-  }
-  return (lang != 0) ? lang : 'en';
-}
-
-/* ##########     END LOCALIZATION     ############ */
-
-
-
-
-
-
 /* Used to hide and reveal supplemental content, such as long code samples.
    See the companion CSS in android-developer-docs.css */
 function toggleContent(obj) {
   var div = $(obj).closest(".toggle-content");
-  var toggleMe = $(".toggle-content-toggleme:eq(0)",div);
+  var toggleMe = $(".toggle-content-toggleme:eq(0)", div);
   if (div.hasClass("closed")) { // if it's closed, open it
     toggleMe.slideDown();
     $(".toggle-content-text:eq(0)", obj).toggle();
     div.removeClass("closed").addClass("open");
-    $(".toggle-content-img:eq(0)", div).attr("title", "hide").attr("src", toRoot
-                  + "assets/images/styles/disclosure_up.png");
+    $(".toggle-content-img:eq(0)", div).attr("title", "hide").attr("src", toRoot +
+                  "assets/images/triangle-opened.png");
   } else { // if it's open, close it
     toggleMe.slideUp('fast', function() {  // Wait until the animation is done before closing arrow
       $(".toggle-content-text:eq(0)", obj).toggle();
       div.removeClass("open").addClass("closed");
       div.find(".toggle-content").removeClass("open").addClass("closed")
               .find(".toggle-content-toggleme").hide();
-      $(".toggle-content-img", div).attr("title", "show").attr("src", toRoot
-                  + "assets/images/styles/disclosure_down.png");
+      $(".toggle-content-img", div).attr("title", "show").attr("src", toRoot +
+                  "assets/images/triangle-closed.png");
     });
   }
   return false;
 }
 
-
 /* New version of expandable content */
-function toggleExpandable(link,id) {
-  if($(id).is(':visible')) {
+function toggleExpandable(link, id) {
+  if ($(id).is(':visible')) {
     $(id).slideUp();
     $(link).removeClass('expanded');
   } else {
@@ -1417,10 +524,6 @@
   $(ids).prev('h4').find('a.expandable').removeClass('expanded');
 }
 
-
-
-
-
 /*
  *  Slideshow 1.0
  *  Used on /index.html and /develop/index.html for carousel
@@ -1460,169 +563,164 @@
  *
  */
 
- (function($) {
- $.fn.dacSlideshow = function(o) {
+(function($) {
+  $.fn.dacSlideshow = function(o) {
 
-     //Options - see above
-     o = $.extend({
-         btnPrev:   null,
-         btnNext:   null,
-         btnPause:  null,
-         auto:      true,
-         speed:     500,
-         autoTime:  12000,
-         easing:    null,
-         start:     0,
-         scroll:    1,
-         pagination: true
+    //Options - see above
+    o = $.extend({
+      btnPrev:   null,
+      btnNext:   null,
+      btnPause:  null,
+      auto:      true,
+      speed:     500,
+      autoTime:  12000,
+      easing:    null,
+      start:     0,
+      scroll:    1,
+      pagination: true
 
-     }, o || {});
+    }, o || {});
 
-     //Set up a carousel for each
-     return this.each(function() {
+    //Set up a carousel for each
+    return this.each(function() {
 
-         var running = false;
-         var animCss = o.vertical ? "top" : "left";
-         var sizeCss = o.vertical ? "height" : "width";
-         var div = $(this);
-         var ul = $("ul", div);
-         var tLi = $("li", ul);
-         var tl = tLi.size();
-         var timer = null;
+      var running = false;
+      var animCss = o.vertical ? "top" : "left";
+      var sizeCss = o.vertical ? "height" : "width";
+      var div = $(this);
+      var ul = $("ul", div);
+      var tLi = $("li", ul);
+      var tl = tLi.size();
+      var timer = null;
 
-         var li = $("li", ul);
-         var itemLength = li.size();
-         var curr = o.start;
+      var li = $("li", ul);
+      var itemLength = li.size();
+      var curr = o.start;
 
-         li.css({float: o.vertical ? "none" : "left"});
-         ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
-         div.css({position: "relative", "z-index": "2", left: "0px"});
+      li.css({float: o.vertical ? "none" : "left"});
+      ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
+      div.css({position: "relative", "z-index": "2", left: "0px"});
 
-         var liSize = o.vertical ? height(li) : width(li);
-         var ulSize = liSize * itemLength;
-         var divSize = liSize;
+      var liSize = o.vertical ? height(li) : width(li);
+      var ulSize = liSize * itemLength;
+      var divSize = liSize;
 
-         li.css({width: li.width(), height: li.height()});
-         ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));
+      li.css({width: li.width(), height: li.height()});
+      ul.css(sizeCss, ulSize + "px").css(animCss, -(curr * liSize));
 
-         div.css(sizeCss, divSize+"px");
+      div.css(sizeCss, divSize + "px");
 
-         //Pagination
-         if (o.pagination) {
-             var pagination = $("<div class='pagination'></div>");
-             var pag_ul = $("<ul></ul>");
-             if (tl > 1) {
-               for (var i=0;i<tl;i++) {
-                    var li = $("<li>"+i+"</li>");
-                    pag_ul.append(li);
-                    if (i==o.start) li.addClass('active');
-                        li.click(function() {
-                        go(parseInt($(this).text()));
-                    })
-                }
-                pagination.append(pag_ul);
-                div.append(pagination);
-             }
-         }
+      //Pagination
+      if (o.pagination) {
+        var pagination = $("<div class='pagination'></div>");
+        var pag_ul = $("<ul></ul>");
+        if (tl > 1) {
+          for (var i = 0; i < tl; i++) {
+            var li = $("<li>" + i + "</li>");
+            pag_ul.append(li);
+            if (i == o.start) li.addClass('active');
+            li.click(function() {
+              go(parseInt($(this).text()));
+            })
+          }
+          pagination.append(pag_ul);
+          div.append(pagination);
+        }
+      }
 
-         //Previous button
-         if(o.btnPrev)
+      //Previous button
+      if (o.btnPrev)
              $(o.btnPrev).click(function(e) {
-                 e.preventDefault();
-                 return go(curr-o.scroll);
+               e.preventDefault();
+               return go(curr - o.scroll);
              });
 
-         //Next button
-         if(o.btnNext)
+      //Next button
+      if (o.btnNext)
              $(o.btnNext).click(function(e) {
-                 e.preventDefault();
-                 return go(curr+o.scroll);
+               e.preventDefault();
+               return go(curr + o.scroll);
              });
 
-         //Pause button
-         if(o.btnPause)
+      //Pause button
+      if (o.btnPause)
              $(o.btnPause).click(function(e) {
-                 e.preventDefault();
-                 if ($(this).hasClass('paused')) {
-                     startRotateTimer();
-                 } else {
-                     pauseRotateTimer();
-                 }
+               e.preventDefault();
+               if ($(this).hasClass('paused')) {
+                 startRotateTimer();
+               } else {
+                 pauseRotateTimer();
+               }
              });
 
-         //Auto rotation
-         if(o.auto) startRotateTimer();
+      //Auto rotation
+      if (o.auto) startRotateTimer();
 
-         function startRotateTimer() {
-             clearInterval(timer);
-             timer = setInterval(function() {
-                  if (curr == tl-1) {
-                    go(0);
-                  } else {
-                    go(curr+o.scroll);
-                  }
-              }, o.autoTime);
-             $(o.btnPause).removeClass('paused');
-         }
+      function startRotateTimer() {
+        clearInterval(timer);
+        timer = setInterval(function() {
+          if (curr == tl - 1) {
+            go(0);
+          } else {
+            go(curr + o.scroll);
+          }
+        }, o.autoTime);
+        $(o.btnPause).removeClass('paused');
+      }
 
-         function pauseRotateTimer() {
-             clearInterval(timer);
-             $(o.btnPause).addClass('paused');
-         }
+      function pauseRotateTimer() {
+        clearInterval(timer);
+        $(o.btnPause).addClass('paused');
+      }
 
-         //Go to an item
-         function go(to) {
-             if(!running) {
+      //Go to an item
+      function go(to) {
+        if (!running) {
 
-                 if(to<0) {
-                    to = itemLength-1;
-                 } else if (to>itemLength-1) {
-                    to = 0;
-                 }
-                 curr = to;
+          if (to < 0) {
+            to = itemLength - 1;
+          } else if (to > itemLength - 1) {
+            to = 0;
+          }
+          curr = to;
 
-                 running = true;
+          running = true;
 
-                 ul.animate(
-                     animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
+          ul.animate(
+              animCss == "left" ? {left: -(curr * liSize)} : {top: -(curr * liSize)} , o.speed, o.easing,
                      function() {
-                         running = false;
+                       running = false;
                      }
                  );
 
-                 $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
-                 $( (curr-o.scroll<0 && o.btnPrev)
-                     ||
-                    (curr+o.scroll > itemLength && o.btnNext)
-                     ||
-                    []
-                  ).addClass("disabled");
+          $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
+          $((curr - o.scroll < 0 && o.btnPrev)              ||
+             (curr + o.scroll > itemLength && o.btnNext)              ||
+             []
+           ).addClass("disabled");
 
+          var nav_items = $('li', pagination);
+          nav_items.removeClass('active');
+          nav_items.eq(to).addClass('active');
 
-                 var nav_items = $('li', pagination);
-                 nav_items.removeClass('active');
-                 nav_items.eq(to).addClass('active');
+        }
+        if (o.auto) startRotateTimer();
+        return false;
+      };
+    });
+  };
 
+  function css(el, prop) {
+    return parseInt($.css(el[0], prop)) || 0;
+  };
+  function width(el) {
+    return el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
+  };
+  function height(el) {
+    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
+  };
 
-             }
-             if(o.auto) startRotateTimer();
-             return false;
-         };
-     });
- };
-
- function css(el, prop) {
-     return parseInt($.css(el[0], prop)) || 0;
- };
- function width(el) {
-     return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
- };
- function height(el) {
-     return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
- };
-
- })(jQuery);
-
+})(jQuery);
 
 /*
  *  dacSlideshow 1.0
@@ -1661,1204 +759,68 @@
  *  pagination: whether or not to include dotted pagination
  *
  */
- (function($) {
- $.fn.dacTabbedList = function(o) {
+(function($) {
+  $.fn.dacTabbedList = function(o) {
 
-     //Options - see above
-     o = $.extend({
-         speed : 250,
-         easing: null,
-         nav_id: null,
-         frame_id: null
-     }, o || {});
+    //Options - see above
+    o = $.extend({
+      speed : 250,
+      easing: null,
+      nav_id: null,
+      frame_id: null
+    }, o || {});
 
-     //Set up a carousel for each
-     return this.each(function() {
+    //Set up a carousel for each
+    return this.each(function() {
 
-         var curr = 0;
-         var running = false;
-         var animCss = "margin-left";
-         var sizeCss = "width";
-         var div = $(this);
+      var curr = 0;
+      var running = false;
+      var animCss = "margin-left";
+      var sizeCss = "width";
+      var div = $(this);
 
-         var nav = $(o.nav_id, div);
-         var nav_li = $("li", nav);
-         var nav_size = nav_li.size();
-         var frame = div.find(o.frame_id);
-         var content_width = $(frame).find('ul').width();
-         //Buttons
-         $(nav_li).click(function(e) {
+      var nav = $(o.nav_id, div);
+      var nav_li = $("li", nav);
+      var nav_size = nav_li.size();
+      var frame = div.find(o.frame_id);
+      var content_width = $(frame).find('ul').width();
+      //Buttons
+      $(nav_li).click(function(e) {
            go($(nav_li).index($(this)));
          })
 
-         //Go to an item
-         function go(to) {
-             if(!running) {
-                 curr = to;
-                 running = true;
+      //Go to an item
+      function go(to) {
+        if (!running) {
+          curr = to;
+          running = true;
 
-                 frame.animate({ 'margin-left' : -(curr*content_width) }, o.speed, o.easing,
+          frame.animate({'margin-left' : -(curr * content_width)}, o.speed, o.easing,
                      function() {
-                         running = false;
+                       running = false;
                      }
                  );
 
+          nav_li.removeClass('active');
+          nav_li.eq(to).addClass('active');
 
-                 nav_li.removeClass('active');
-                 nav_li.eq(to).addClass('active');
-
-
-             }
-             return false;
-         };
-     });
- };
-
- function css(el, prop) {
-     return parseInt($.css(el[0], prop)) || 0;
- };
- function width(el) {
-     return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
- };
- function height(el) {
-     return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
- };
-
- })(jQuery);
-
-
-
-
-
-/* ######################################################## */
-/* ################  SEARCH SUGGESTIONS  ################## */
-/* ######################################################## */
-
-
-
-var gSelectedIndex = -1;  // the index position of currently highlighted suggestion
-var gSelectedColumn = -1;  // which column of suggestion lists is currently focused
-
-var gMatches = new Array();
-var gLastText = "";
-var gInitialized = false;
-var ROW_COUNT_FRAMEWORK = 20;       // max number of results in list
-var gListLength = 0;
-
-
-var gGoogleMatches = new Array();
-var ROW_COUNT_GOOGLE = 15;          // max number of results in list
-var gGoogleListLength = 0;
-
-var gDocsMatches = new Array();
-var ROW_COUNT_DOCS = 100;          // max number of results in list
-var gDocsListLength = 0;
-
-function onSuggestionClick(link) {
-  // When user clicks a suggested document, track it
-  ga('send', 'event', 'Suggestion Click', 'clicked: ' + $(link).attr('href'),
-                'query: ' + $("#search_autocomplete").val().toLowerCase());
-}
-
-function set_item_selected($li, selected)
-{
-    if (selected) {
-        $li.attr('class','jd-autocomplete jd-selected');
-    } else {
-        $li.attr('class','jd-autocomplete');
-    }
-}
-
-function set_item_values(toroot, $li, match)
-{
-    var $link = $('a',$li);
-    $link.html(match.__hilabel || match.label);
-    $link.attr('href',toroot + match.link);
-}
-
-function set_item_values_jd(toroot, $li, match)
-{
-    var $link = $('a',$li);
-    $link.html(match.title);
-    $link.attr('href',toroot + match.url);
-}
-
-function new_suggestion($list) {
-    var $li = $("<li class='jd-autocomplete'></li>");
-    $list.append($li);
-
-    $li.mousedown(function() {
-        window.location = this.firstChild.getAttribute("href");
-    });
-    $li.mouseover(function() {
-        $('.search_filtered_wrapper li').removeClass('jd-selected');
-        $(this).addClass('jd-selected');
-        gSelectedColumn = $(".search_filtered:visible").index($(this).closest('.search_filtered'));
-        gSelectedIndex = $("li", $(".search_filtered:visible")[gSelectedColumn]).index(this);
-    });
-    $li.append("<a onclick='onSuggestionClick(this)'></a>");
-    $li.attr('class','show-item');
-    return $li;
-}
-
-function sync_selection_table(toroot)
-{
-    var $li; //list item jquery object
-    var i; //list item iterator
-
-    // if there are NO results at all, hide all columns
-    if (!(gMatches.length > 0) && !(gGoogleMatches.length > 0) && !(gDocsMatches.length > 0)) {
-        $('.suggest-card').hide(300);
-        return;
-    }
-
-    // if there are api results
-    if ((gMatches.length > 0) || (gGoogleMatches.length > 0)) {
-      // reveal suggestion list
-      $('.suggest-card.reference').show();
-      var listIndex = 0; // list index position
-
-      // reset the lists
-      $(".suggest-card.reference li").remove();
-
-      // ########### ANDROID RESULTS #############
-      if (gMatches.length > 0) {
-
-          // determine android results to show
-          gListLength = gMatches.length < ROW_COUNT_FRAMEWORK ?
-                        gMatches.length : ROW_COUNT_FRAMEWORK;
-          for (i=0; i<gListLength; i++) {
-              var $li = new_suggestion($(".suggest-card.reference ul"));
-              set_item_values(toroot, $li, gMatches[i]);
-              set_item_selected($li, i == gSelectedIndex);
-          }
-      }
-
-      // ########### GOOGLE RESULTS #############
-      if (gGoogleMatches.length > 0) {
-          // show header for list
-          $(".suggest-card.reference ul").append("<li class='header'>in Google Services:</li>");
-
-          // determine google results to show
-          gGoogleListLength = gGoogleMatches.length < ROW_COUNT_GOOGLE ? gGoogleMatches.length : ROW_COUNT_GOOGLE;
-          for (i=0; i<gGoogleListLength; i++) {
-              var $li = new_suggestion($(".suggest-card.reference ul"));
-              set_item_values(toroot, $li, gGoogleMatches[i]);
-              set_item_selected($li, i == gSelectedIndex);
-          }
-      }
-    } else {
-      $('.suggest-card.reference').hide();
-    }
-
-    // ########### JD DOC RESULTS #############
-    if (gDocsMatches.length > 0) {
-        // reset the lists
-        $(".suggest-card:not(.reference) li").remove();
-
-        // determine google results to show
-        // NOTE: The order of the conditions below for the sugg.type MUST BE SPECIFIC:
-        // The order must match the reverse order that each section appears as a card in
-        // the suggestion UI... this may be only for the "develop" grouped items though.
-        gDocsListLength = gDocsMatches.length < ROW_COUNT_DOCS ? gDocsMatches.length : ROW_COUNT_DOCS;
-        for (i=0; i<gDocsListLength; i++) {
-            var sugg = gDocsMatches[i];
-            var $li;
-            if (sugg.type == "design") {
-                $li = new_suggestion($(".suggest-card.design ul"));
-            } else
-            if (sugg.type == "distribute") {
-                $li = new_suggestion($(".suggest-card.distribute ul"));
-            } else
-            if (sugg.type == "samples") {
-                $li = new_suggestion($(".suggest-card.develop .child-card.samples"));
-            } else
-            if (sugg.type == "training") {
-                $li = new_suggestion($(".suggest-card.develop .child-card.training"));
-            } else
-            if (sugg.type == "about"||"guide"||"tools"||"google") {
-                $li = new_suggestion($(".suggest-card.develop .child-card.guides"));
-            } else {
-              continue;
-            }
-
-            set_item_values_jd(toroot, $li, sugg);
-            set_item_selected($li, i == gSelectedIndex);
-        }
-
-        // add heading and show or hide card
-        if ($(".suggest-card.design li").length > 0) {
-          $(".suggest-card.design ul").prepend("<li class='header'>Design:</li>");
-          $(".suggest-card.design").show(300);
-        } else {
-          $('.suggest-card.design').hide(300);
-        }
-        if ($(".suggest-card.distribute li").length > 0) {
-          $(".suggest-card.distribute ul").prepend("<li class='header'>Distribute:</li>");
-          $(".suggest-card.distribute").show(300);
-        } else {
-          $('.suggest-card.distribute').hide(300);
-        }
-        if ($(".child-card.guides li").length > 0) {
-          $(".child-card.guides").prepend("<li class='header'>Guides:</li>");
-          $(".child-card.guides li").appendTo(".suggest-card.develop ul");
-        }
-        if ($(".child-card.training li").length > 0) {
-          $(".child-card.training").prepend("<li class='header'>Training:</li>");
-          $(".child-card.training li").appendTo(".suggest-card.develop ul");
-        }
-        if ($(".child-card.samples li").length > 0) {
-          $(".child-card.samples").prepend("<li class='header'>Samples:</li>");
-          $(".child-card.samples li").appendTo(".suggest-card.develop ul");
-        }
-
-        if ($(".suggest-card.develop li").length > 0) {
-          $(".suggest-card.develop").show(300);
-        } else {
-          $('.suggest-card.develop').hide(300);
-        }
-
-    } else {
-      $('.suggest-card:not(.reference)').hide(300);
-    }
-}
-
-/** Called by the search input's onkeydown and onkeyup events.
-  * Handles navigation with keyboard arrows, Enter key to invoke search,
-  * otherwise invokes search suggestions on key-up event.
-  * @param e       The JS event
-  * @param kd      True if the event is key-down
-  * @param toroot  A string for the site's root path
-  * @returns       True if the event should bubble up
-  */
-function search_changed(e, kd, toroot)
-{
-    var currentLang = getLangPref();
-    var search = document.getElementById("search_autocomplete");
-    var text = search.value.replace(/(^ +)|( +$)/g, '');
-    // get the ul hosting the currently selected item
-    gSelectedColumn = gSelectedColumn >= 0 ? gSelectedColumn :  0;
-    var $columns = $(".search_filtered_wrapper").find(".search_filtered:visible");
-    var $selectedUl = $columns[gSelectedColumn];
-
-    // show/hide the close button
-    if (text != '') {
-        $("#search-close").removeClass("hide");
-    } else {
-        $("#search-close").addClass("hide");
-    }
-    // 27 = esc
-    if (e.keyCode == 27) {
-        // close all search results
-        if (kd) $('#search-close').trigger('click');
-        return true;
-    }
-    // 13 = enter
-    else if (e.keyCode == 13) {
-        if (gSelectedIndex < 0) {
-            $('.suggest-card').hide();
-            if ($("#searchResults").is(":hidden") && (search.value != "")) {
-              // if results aren't showing (and text not empty), return true to allow search to execute
-              $('body,html').animate({scrollTop:0}, '500', 'swing');
-              return true;
-            } else {
-              // otherwise, results are already showing, so allow ajax to auto refresh the results
-              // and ignore this Enter press to avoid the reload.
-              return false;
-            }
-        } else if (kd && gSelectedIndex >= 0) {
-            // click the link corresponding to selected item
-            $("a",$("li",$selectedUl)[gSelectedIndex]).get()[0].click();
-            return false;
-        }
-    }
-    // If Google results are showing, return true to allow ajax search to execute
-    else if ($("#searchResults").is(":visible")) {
-        // Also, if search_results is scrolled out of view, scroll to top to make results visible
-        if ((sticky ) && (search.value != "")) {
-          $('body,html').animate({scrollTop:0}, '500', 'swing');
-        }
-        return true;
-    }
-    // 38 UP ARROW
-    else if (kd && (e.keyCode == 38)) {
-        // if the next item is a header, skip it
-        if ($($("li", $selectedUl)[gSelectedIndex-1]).hasClass("header")) {
-            gSelectedIndex--;
-        }
-        if (gSelectedIndex >= 0) {
-            $('li', $selectedUl).removeClass('jd-selected');
-            gSelectedIndex--;
-            $('li:nth-child('+(gSelectedIndex+1)+')', $selectedUl).addClass('jd-selected');
-            // If user reaches top, reset selected column
-            if (gSelectedIndex < 0) {
-              gSelectedColumn = -1;
-            }
         }
         return false;
-    }
-    // 40 DOWN ARROW
-    else if (kd && (e.keyCode == 40)) {
-        // if the next item is a header, skip it
-        if ($($("li", $selectedUl)[gSelectedIndex+1]).hasClass("header")) {
-            gSelectedIndex++;
-        }
-        if ((gSelectedIndex < $("li", $selectedUl).length-1) ||
-                        ($($("li", $selectedUl)[gSelectedIndex+1]).hasClass("header"))) {
-            $('li', $selectedUl).removeClass('jd-selected');
-            gSelectedIndex++;
-            $('li:nth-child('+(gSelectedIndex+1)+')', $selectedUl).addClass('jd-selected');
-        }
-        return false;
-    }
-    // Consider left/right arrow navigation
-    // NOTE: Order of suggest columns are reverse order (index position 0 is on right)
-    else if (kd && $columns.length > 1 && gSelectedColumn >= 0) {
-      // 37 LEFT ARROW
-      // go left only if current column is not left-most column (last column)
-      if (e.keyCode == 37 && gSelectedColumn < $columns.length - 1) {
-        $('li', $selectedUl).removeClass('jd-selected');
-        gSelectedColumn++;
-        $selectedUl = $columns[gSelectedColumn];
-        // keep or reset the selected item to last item as appropriate
-        gSelectedIndex = gSelectedIndex >
-                $("li", $selectedUl).length-1 ?
-                $("li", $selectedUl).length-1 : gSelectedIndex;
-        // if the corresponding item is a header, move down
-        if ($($("li", $selectedUl)[gSelectedIndex]).hasClass("header")) {
-          gSelectedIndex++;
-        }
-        // set item selected
-        $('li:nth-child('+(gSelectedIndex+1)+')', $selectedUl).addClass('jd-selected');
-        return false;
-      }
-      // 39 RIGHT ARROW
-      // go right only if current column is not the right-most column (first column)
-      else if (e.keyCode == 39 && gSelectedColumn > 0) {
-        $('li', $selectedUl).removeClass('jd-selected');
-        gSelectedColumn--;
-        $selectedUl = $columns[gSelectedColumn];
-        // keep or reset the selected item to last item as appropriate
-        gSelectedIndex = gSelectedIndex >
-                $("li", $selectedUl).length-1 ?
-                $("li", $selectedUl).length-1 : gSelectedIndex;
-        // if the corresponding item is a header, move down
-        if ($($("li", $selectedUl)[gSelectedIndex]).hasClass("header")) {
-          gSelectedIndex++;
-        }
-        // set item selected
-        $('li:nth-child('+(gSelectedIndex+1)+')', $selectedUl).addClass('jd-selected');
-        return false;
-      }
-    }
-
-    // if key-up event and not arrow down/up/left/right,
-    // read the search query and add suggestions to gMatches
-    else if (!kd && (e.keyCode != 40)
-                 && (e.keyCode != 38)
-                 && (e.keyCode != 37)
-                 && (e.keyCode != 39)) {
-        gSelectedIndex = -1;
-        gMatches = new Array();
-        matchedCount = 0;
-        gGoogleMatches = new Array();
-        matchedCountGoogle = 0;
-        gDocsMatches = new Array();
-        matchedCountDocs = 0;
-
-        // Search for Android matches
-        for (var i=0; i<DATA.length; i++) {
-            var s = DATA[i];
-            if (text.length != 0 &&
-                  s.label.toLowerCase().indexOf(text.toLowerCase()) != -1) {
-                gMatches[matchedCount] = s;
-                matchedCount++;
-            }
-        }
-        rank_autocomplete_api_results(text, gMatches);
-        for (var i=0; i<gMatches.length; i++) {
-            var s = gMatches[i];
-        }
-
-
-        // Search for Google matches
-        for (var i=0; i<GOOGLE_DATA.length; i++) {
-            var s = GOOGLE_DATA[i];
-            if (text.length != 0 &&
-                  s.label.toLowerCase().indexOf(text.toLowerCase()) != -1) {
-                gGoogleMatches[matchedCountGoogle] = s;
-                matchedCountGoogle++;
-            }
-        }
-        rank_autocomplete_api_results(text, gGoogleMatches);
-        for (var i=0; i<gGoogleMatches.length; i++) {
-            var s = gGoogleMatches[i];
-        }
-
-        highlight_autocomplete_result_labels(text);
-
-
-
-        // Search for matching JD docs
-        if (text.length >= 2) {
-          // match only the beginning of a word
-          var queryStr = text.toLowerCase();
-
-          // Search for Training classes
-          for (var i=0; i<TRAINING_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = TRAINING_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Don't consider doc title for lessons (only for class landing pages),
-            // unless the lesson has a tag that already matches
-            if ((s.lang == currentLang) &&
-                  (!(s.type == "training" && s.url.indexOf("index.html") == -1) || matched)) {
-              // it matches the doc title
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-
-          // Search for API Guides
-          for (var i=0; i<GUIDE_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = GUIDE_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-
-          // Search for Tools Guides
-          for (var i=0; i<TOOLS_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = TOOLS_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-                if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title
-                if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-
-          // Search for About docs
-          for (var i=0; i<ABOUT_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = ABOUT_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-
-          // Search for Design guides
-          for (var i=0; i<DESIGN_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = DESIGN_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-
-          // Search for Distribute guides
-          for (var i=0; i<DISTRIBUTE_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = DISTRIBUTE_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-
-          // Search for Google guides
-          for (var i=0; i<GOOGLE_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = GOOGLE_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-
-          // Search for Samples
-          for (var i=0; i<SAMPLES_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = SAMPLES_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title.t
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-          // Search for Preview Guides
-          for (var i=0; i<PREVIEW_RESOURCES.length; i++) {
-            // current search comparison, with counters for tag and title,
-            // used later to improve ranking
-            var s = PREVIEW_RESOURCES[i];
-            s.matched_tag = 0;
-            s.matched_title = 0;
-            var matched = false;
-
-            // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.keywords.length - 1; j >= 0; j--) {
-              // it matches a tag
-              if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_tag = j + 1; // add 1 to index position
-              }
-            }
-            // Check if query matches the doc title, but only for current language
-            if (s.lang == currentLang) {
-              // if query matches the doc title
-              if (s.title.toLowerCase().indexOf(queryStr) == 0) {
-                matched = true;
-                s.matched_title = 1;
-              }
-            }
-            if (matched) {
-              gDocsMatches[matchedCountDocs] = s;
-              matchedCountDocs++;
-            }
-          }
-
-          // Rank/sort all the matched pages
-          rank_autocomplete_doc_results(text, gDocsMatches);
-        }
-
-        // draw the suggestions
-        sync_selection_table(toroot);
-        return true; // allow the event to bubble up to the search api
-    }
-}
-
-/* Order the jd doc result list based on match quality */
-function rank_autocomplete_doc_results(query, matches) {
-    query = query || '';
-    if (!matches || !matches.length)
-      return;
-
-    var _resultScoreFn = function(match) {
-        var score = 1.0;
-
-        // if the query matched a tag
-        if (match.matched_tag > 0) {
-          // multiply score by factor relative to position in tags list (max of 3)
-          score *= 3 / match.matched_tag;
-
-          // if it also matched the title
-          if (match.matched_title > 0) {
-            score *= 2;
-          }
-        } else if (match.matched_title > 0) {
-          score *= 3;
-        }
-
-        return score;
-    };
-
-    for (var i=0; i<matches.length; i++) {
-        matches[i].__resultScore = _resultScoreFn(matches[i]);
-    }
-
-    matches.sort(function(a,b){
-        var n = b.__resultScore - a.__resultScore;
-        if (n == 0) // lexicographical sort if scores are the same
-            n = (a.label < b.label) ? -1 : 1;
-        return n;
+      };
     });
-}
-
-/* Order the result list based on match quality */
-function rank_autocomplete_api_results(query, matches) {
-    query = query || '';
-    if (!matches || !matches.length)
-      return;
-
-    // helper function that gets the last occurence index of the given regex
-    // in the given string, or -1 if not found
-    var _lastSearch = function(s, re) {
-      if (s == '')
-        return -1;
-      var l = -1;
-      var tmp;
-      while ((tmp = s.search(re)) >= 0) {
-        if (l < 0) l = 0;
-        l += tmp;
-        s = s.substr(tmp + 1);
-      }
-      return l;
-    };
-
-    // helper function that counts the occurrences of a given character in
-    // a given string
-    var _countChar = function(s, c) {
-      var n = 0;
-      for (var i=0; i<s.length; i++)
-        if (s.charAt(i) == c) ++n;
-      return n;
-    };
-
-    var queryLower = query.toLowerCase();
-    var queryAlnum = (queryLower.match(/\w+/) || [''])[0];
-    var partPrefixAlnumRE = new RegExp('\\b' + queryAlnum);
-    var partExactAlnumRE = new RegExp('\\b' + queryAlnum + '\\b');
-
-    var _resultScoreFn = function(result) {
-        // scores are calculated based on exact and prefix matches,
-        // and then number of path separators (dots) from the last
-        // match (i.e. favoring classes and deep package names)
-        var score = 1.0;
-        var labelLower = result.label.toLowerCase();
-        var t;
-        t = _lastSearch(labelLower, partExactAlnumRE);
-        if (t >= 0) {
-            // exact part match
-            var partsAfter = _countChar(labelLower.substr(t + 1), '.');
-            score *= 200 / (partsAfter + 1);
-        } else {
-            t = _lastSearch(labelLower, partPrefixAlnumRE);
-            if (t >= 0) {
-                // part prefix match
-                var partsAfter = _countChar(labelLower.substr(t + 1), '.');
-                score *= 20 / (partsAfter + 1);
-            }
-        }
-
-        return score;
-    };
-
-    for (var i=0; i<matches.length; i++) {
-        // if the API is deprecated, default score is 0; otherwise, perform scoring
-        if (matches[i].deprecated == "true") {
-          matches[i].__resultScore = 0;
-        } else {
-          matches[i].__resultScore = _resultScoreFn(matches[i]);
-        }
-    }
-
-    matches.sort(function(a,b){
-        var n = b.__resultScore - a.__resultScore;
-        if (n == 0) // lexicographical sort if scores are the same
-            n = (a.label < b.label) ? -1 : 1;
-        return n;
-    });
-}
-
-/* Add emphasis to part of string that matches query */
-function highlight_autocomplete_result_labels(query) {
-    query = query || '';
-    if ((!gMatches || !gMatches.length) && (!gGoogleMatches || !gGoogleMatches.length))
-      return;
-
-    var queryLower = query.toLowerCase();
-    var queryAlnumDot = (queryLower.match(/[\w\.]+/) || [''])[0];
-    var queryRE = new RegExp(
-        '(' + queryAlnumDot.replace(/\./g, '\\.') + ')', 'ig');
-    for (var i=0; i<gMatches.length; i++) {
-        gMatches[i].__hilabel = gMatches[i].label.replace(
-            queryRE, '<b>$1</b>');
-    }
-    for (var i=0; i<gGoogleMatches.length; i++) {
-        gGoogleMatches[i].__hilabel = gGoogleMatches[i].label.replace(
-            queryRE, '<b>$1</b>');
-    }
-}
-
-function search_focus_changed(obj, focused)
-{
-    if (!focused) {
-        if(obj.value == ""){
-          $("#search-close").addClass("hide");
-        }
-        $(".suggest-card").hide();
-    }
-}
-
-function submit_search() {
-  var query = escapeHTML(document.getElementById('search_autocomplete').value);
-  location.hash = 'q=' + query;
-  searchControl.query = query;
-  searchControl.init();
-  searchControl.trackSearchRequest(query);
-  $("#searchResults").slideDown('slow', setStickyTop);
-  return false;
-}
-
-function hideResults() {
-  $("#searchResults").slideUp('fast', setStickyTop);
-  $("#search-close").addClass("hide");
-  location.hash = '';
-
-  $("#search_autocomplete").val("").blur();
-
-  // reset the ajax search callback to nothing, so results don't appear unless ENTER
-  searchControl.reset();
-
-  return false;
-}
-
-/* ########################################################## */
-/* ################  CUSTOM SEARCH ENGINE  ################## */
-/* ########################################################## */
-var searchControl = null;
-var dacsearch = dacsearch || {};
-
-/**
- * The custom search engine API.
- * @constructor
- */
-dacsearch.CustomSearchEngine = function() {
-  /**
-   * The last response from Google CSE.
-   * @private {Object}
-   */
-  this.resultQuery_ = {};
-
-  /** @private {?Element} */
-  this.searchResultEl_ = null;
-
-  /** @private {?Element} */
-  this.searchInputEl_ = null;
-
-  /** @private {string} */
-  this.query = '';
-};
-
-/**
- * Initializes DAC's Google custom search engine.
- * @export
- */
-dacsearch.CustomSearchEngine.prototype.init = function() {
-  this.searchResultEl_ = $('#leftSearchControl');
-  this.searchResultEl_.empty();
-  this.searchInputEl_ = $('#search_autocomplete');
-  this.searchInputEl_.focus().val(this.query);
-  this.getResults_();
-  this.bindEvents_();
-};
-
-
-/**
- * Binds the keyup event to the search input.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.bindEvents_ = function() {
-  this.searchInputEl_.keyup(this.debounce_(function(e) {
-    var code = e.which;
-    if (code != 13) {
-      this.query = escapeHTML(this.searchInputEl_.val());
-      location.hash = 'q=' + encodeURI(this.query);
-      this.searchResultEl_.empty();
-      this.getResults_();
-    }
-  }.bind(this), 250));
-};
-
-
-/**
- * Resets the search control.
- */
-dacsearch.CustomSearchEngine.prototype.reset = function() {
-  this.query = '';
-  this.searchInputEl_.off('keyup');
-  this.searchResultEl_.empty();
-  this.updateResultTitle_();
-};
-
-
-/**
- * Updates the search query text at the top of the results.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.updateResultTitle_ = function() {
-  $("#searchTitle").html("Results for <em>" + this.query + "</em>");
-};
-
-
-/**
- * Makes the CSE api call and gets the results.
- * @param {number=} opt_start The optional start index.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.getResults_ = function(opt_start) {
-  var lang = getLangPref();
-  // Fix zh-cn to be zh-CN.
-  lang = lang.replace(/-\w+/, function(m) { return m.toUpperCase(); });
-  var cseUrl = 'https://content.googleapis.com/customsearch/v1?';
-  var searchParams = {
-    cx: '000521750095050289010:zpcpi1ea4s8',
-    key: 'AIzaSyCFhbGnjW06dYwvRCU8h_zjdpS4PYYbEe8',
-    q: this.query,
-    start: opt_start || 1,
-    num: 6,
-    hl: lang,
-    fields: 'queries,items(pagemap,link,title,htmlSnippet,formattedUrl)'
   };
 
-  $.get(cseUrl + $.param(searchParams), function(data) {
-    this.resultQuery_ = data;
-    this.renderResults_(data);
-    this.updateResultTitle_(this.query);
-  }.bind(this));
-};
-
-
-/**
- * Renders the results.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.renderResults_ = function(results) {
-  var el = this.searchResultEl_;
-
-  if (!results.items) {
-    el.append($('<div>').text('No results'));
-    return;
-  }
-
-  for (var i = 0; i < results.items.length; i++) {
-    var item = results.items[i];
-    var hasImage = item.pagemap && item.pagemap.cse_thumbnail;
-    var sectionMatch = item.link.match(/developer\.android\.com\/(\w*)/);
-    var section = (sectionMatch && sectionMatch[1]) || 'blog';
-
-    var entry = $('<div>').addClass('dac-custom-search-entry cols');
-
-    if (hasImage) {
-      var image = item.pagemap.cse_thumbnail[0];
-      entry.append($('<div>').addClass('col-1of6')
-        .append($('<div>').addClass('dac-custom-search-image').css(
-        'background-image', 'url(' + image.src + ')')));
-    }
-
-    var linkTitleEl = $('<a>').text(item.title).attr('href', item.link);
-    linkTitleEl.click(function(e) {
-      ga('send', 'event', 'Google Custom Search',
-          'clicked: ' + linkTitleEl.attr('href'),
-          'query: ' + $("#search_autocomplete").val().toLowerCase());
-    });
-
-    var linkUrlEl = $('<a>').addClass('dac-custom-search-link').text(
-        item.formattedUrl).attr('href', item.link);
-    linkUrlEl.click(function(e) {
-      ga('send', 'event', 'Google Custom Search',
-          'clicked: ' + linkUrlEl.attr('href'),
-          'query: ' + $("#search_autocomplete").val().toLowerCase());
-    });
-
-
-    entry.append($('<div>').addClass(hasImage ? 'col-5of6' : 'col-6of6')
-      .append($('<p>').addClass('dac-custom-search-section').text(section))
-      .append(
-        linkTitleEl.wrap('<h2>').parent().addClass('dac-custom-search-title'))
-      .append($('<p>').addClass('dac-custom-search-snippet')
-      .html(item.htmlSnippet.replace(/<br>/g, ''))).append(linkUrlEl));
-
-    el.append(entry);
-  }
-
-  if ($('#dac-custom-search-load-more')) {
-    $('#dac-custom-search-load-more').remove();
-  }
-
-  if (results.queries.nextPage) {
-    var loadMoreButton = $('<button id="dac-custom-search-load-more">')
-      .addClass('dac-custom-search-load-more')
-      .text('Load more')
-      .click(function() {
-        this.loadMoreResults_();
-      }.bind(this));
-
-    el.append(loadMoreButton);
-  }
-};
-
-
-/**
- * Loads more results.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.loadMoreResults_ = function() {
-  this.query = this.resultQuery_.queries.request[0].searchTerms;
-  var start = this.resultQuery_.queries.nextPage[0].startIndex;
-  var loadMoreButton = this.searchResultEl_.find(
-      '#dac-custom-search-load-more');
-  loadMoreButton.text('Loading more...');
-  this.getResults_(start);
-  this.trackSearchRequest(this.query + ' startIndex = ' + start);
-};
-
-
-/**
- * Tracks a search request.
- * @param {string} query The query for the request,
- *                       includes start index if loading more results.
- */
-dacsearch.CustomSearchEngine.prototype.trackSearchRequest = function(query) {
-  ga('send', 'event', 'Google Custom Search Submit', 'submit search query',
-      'query: ' + query);
-};
-
-
-/**
- * Returns a function, that, as long as it continues to be invoked, will not
- * be triggered. The function will be called after it stops being called for
- * N milliseconds.
- * @param {Function} func The function to debounce.
- * @param {number} wait The number of milliseconds to wait before calling the function.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.debounce_ = function(func, wait) {
-  var timeout;
-  return function() {
-    var context = this, args = arguments;
-    var later = function() {
-      timeout = null;
-      func.apply(context, args);
-    };
-   clearTimeout(timeout);
-   timeout = setTimeout(later, wait);
+  function css(el, prop) {
+    return parseInt($.css(el[0], prop)) || 0;
   };
-};
+  function width(el) {
+    return el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
+  };
+  function height(el) {
+    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
+  };
 
-
-google.setOnLoadCallback(function(){
-  searchControl = new dacsearch.CustomSearchEngine();
-  if (location.hash.indexOf("q=") == -1) {
-    // if there's no query in the url, don't search and make sure results are hidden
-    $('#searchResults').hide();
-    return;
-  } else {
-    // first time loading search results for this page
-    searchControl.query = escapeHTML(decodeURI(location.hash.split('q=')[1]));
-    searchControl.init();
-    searchControl.trackSearchRequest(searchControl.query);
-    $('#searchResults').slideDown('slow', setStickyTop);
-    $("#search-close").removeClass("hide");
-  }
-}, true);
-
-/* Adjust the scroll position to account for sticky header, only if the hash matches an id.
-   This does not handle <a name=""> tags. Some CSS fixes those, but only for reference docs. */
-function offsetScrollForSticky() {
-  // Ignore if there's no search bar (some special pages have no header)
-  if ($("#search-container").length < 1) return;
-
-  var hash = escape(location.hash.substr(1));
-  var $matchingElement = $("#"+hash);
-  // Sanity check that there's an element with that ID on the page
-  if ($matchingElement.length) {
-    // If the position of the target element is near the top of the page (<20px, where we expect it
-    // to be because we need to move it down 60px to become in view), then move it down 60px
-    if (Math.abs($matchingElement.offset().top - $(window).scrollTop()) < 20) {
-      $(window).scrollTop($(window).scrollTop() - 60);
-    }
-  }
-}
-
-// when an event on the browser history occurs (back, forward, load) requery hash and do search
-$(window).hashchange( function(){
-  // Ignore if there's no search bar (some special pages have no header)
-  if ($("#search-container").length < 1) return;
-
-  // If the hash isn't a search query or there's an error in the query,
-  // then adjust the scroll position to account for sticky header, then exit.
-  if ((location.hash.indexOf("q=") == -1) || (searchControl.query == "undefined")) {
-    // If the results pane is open, close it.
-    if (!$("#searchResults").is(":hidden")) {
-      hideResults();
-    }
-    offsetScrollForSticky();
-    return;
-  }
-
-  $('#searchResults').slideDown('slow', setStickyTop);
-  $("#search_autocomplete").focus();
-  $("#search-close").removeClass("hide");
-});
-
-/* returns the given string with all HTML brackets converted to entities
-    TODO: move this to the site's JS library */
-function escapeHTML(string) {
-  return string.replace(/</g,"&lt;")
-                .replace(/>/g,"&gt;");
-}
-
-
-
-
-
-
+})(jQuery);
 
 /* ######################################################## */
 /* #################  JAVADOC REFERENCE ################### */
@@ -2866,14 +828,13 @@
 
 /* Initialize some droiddoc stuff, but only if we're in the reference */
 if (location.pathname.indexOf("/reference") == 0) {
-  if(!(location.pathname.indexOf("/reference-gms/packages.html") == 0)
-    && !(location.pathname.indexOf("/reference-gcm/packages.html") == 0)
-    && !(location.pathname.indexOf("/reference/com/google") == 0)) {
+  if (!(location.pathname.indexOf("/reference-gms/packages.html") == 0) &&
+    !(location.pathname.indexOf("/reference-gcm/packages.html") == 0) &&
+    !(location.pathname.indexOf("/reference/com/google") == 0)) {
     $(document).ready(function() {
       // init available apis based on user pref
       changeApiLevel();
-      initSidenavHeightResize()
-      });
+    });
   }
 }
 
@@ -2881,45 +842,6 @@
 var minLevel = 1;
 var maxLevel = 1;
 
-/******* SIDENAV DIMENSIONS ************/
-
-  function initSidenavHeightResize() {
-    // Change the drag bar size to nicely fit the scrollbar positions
-    var $dragBar = $(".ui-resizable-s");
-    $dragBar.css({'width': $dragBar.parent().width() - 5 + "px"});
-
-    $( "#resize-packages-nav" ).resizable({
-      containment: "#nav-panels",
-      handles: "s",
-      alsoResize: "#packages-nav",
-      resize: function(event, ui) { resizeNav(); }, /* resize the nav while dragging */
-      stop: function(event, ui) { saveNavPanels(); } /* once stopped, save the sizes to cookie  */
-      });
-
-  }
-
-function updateSidenavFixedWidth() {
-  if (!sticky) return;
-  $('#devdoc-nav').css({
-    'width' : $('#side-nav').css('width'),
-    'margin' : $('#side-nav').css('margin')
-  });
-  $('#devdoc-nav a.totop').css({'display':'block','width':$("#nav").innerWidth()+'px'});
-
-  initSidenavHeightResize();
-}
-
-function updateSidenavFullscreenWidth() {
-  if (!sticky) return;
-  $('#devdoc-nav').css({
-    'width' : $('#side-nav').css('width'),
-    'margin' : $('#side-nav').css('margin')
-  });
-  $('#devdoc-nav .totop').css({'left': 'inherit'});
-
-  initSidenavHeightResize();
-}
-
 function buildApiLevelSelector() {
   maxLevel = SINCE_DATA.length;
   var userApiLevel = parseInt(readCookie(API_LEVEL_COOKIE));
@@ -2933,15 +855,15 @@
     minLevel = maxLevel;
   }
   var select = $("#apiLevelSelector").html("").change(changeApiLevel);
-  for (var i = maxLevel-1; i >= 0; i--) {
-    var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]);
-  //  if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
+  for (var i = maxLevel - 1; i >= 0; i--) {
+    var option = $("<option />").attr("value", "" + SINCE_DATA[i]).append("" + SINCE_DATA[i]);
+    //  if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
     select.append(option);
   }
 
   // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
-  var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
-  selectedLevelItem.setAttribute('selected',true);
+  var selectedLevelItem = $("#apiLevelSelector option[value='" + userApiLevel + "']").get(0);
+  selectedLevelItem.setAttribute('selected', true);
 }
 
 function changeApiLevel() {
@@ -2954,30 +876,29 @@
   writeCookie(API_LEVEL_COOKIE, selectedLevel, null);
 
   if (selectedLevel < minLevel) {
-    var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
-    $("#naMessage").show().html("<div><p><strong>This " + thing
-              + " requires API level " + minLevel + " or higher.</strong></p>"
-              + "<p>This document is hidden because your selected API level for the documentation is "
-              + selectedLevel + ". You can change the documentation API level with the selector "
-              + "above the left navigation.</p>"
-              + "<p>For more information about specifying the API level your app requires, "
-              + "read <a href='" + toRoot + "training/basics/supporting-devices/platforms.html'"
-              + ">Supporting Different Platform Versions</a>.</p>"
-              + "<input type='button' value='OK, make this page visible' "
-              + "title='Change the API level to " + minLevel + "' "
-              + "onclick='$(\"#apiLevelSelector\").val(\"" + minLevel + "\");changeApiLevel();' />"
-              + "</div>");
+    $("#naMessage").show().html("<div><p><strong>This API" +
+              " requires API level " + minLevel + " or higher.</strong></p>" +
+              "<p>This document is hidden because your selected API level for the documentation is " +
+              selectedLevel + ". You can change the documentation API level with the selector " +
+              "above the left navigation.</p>" +
+              "<p>For more information about specifying the API level your app requires, " +
+              "read <a href='" + toRoot + "training/basics/supporting-devices/platforms.html'" +
+              ">Supporting Different Platform Versions</a>.</p>" +
+              "<input type='button' value='OK, make this page visible' " +
+              "title='Change the API level to " + minLevel + "' " +
+              "onclick='$(\"#apiLevelSelector\").val(\"" + minLevel + "\");changeApiLevel();' />" +
+              "</div>");
   } else {
     $("#naMessage").hide();
   }
 }
 
 function toggleVisisbleApis(selectedLevel, context) {
-  var apis = $(".api",context);
+  var apis = $(".api", context);
   apis.each(function(i) {
     var obj = $(this);
     var className = obj.attr("class");
-    var apiLevelIndex = className.lastIndexOf("-")+1;
+    var apiLevelIndex = className.lastIndexOf("-") + 1;
     var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
     apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
     var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
@@ -2990,236 +911,21 @@
     var selectedLevelNum = parseInt(selectedLevel)
     var apiLevelNum = parseInt(apiLevel);
     if (isNaN(apiLevelNum)) {
-        apiLevelNum = maxLevel;
+      apiLevelNum = maxLevel;
     }
 
     // Grey things out that aren't available and give a tooltip title
     if (apiLevelNum > selectedLevelNum) {
-      obj.addClass("absent").attr("title","Requires API Level \""
-            + apiLevel + "\" or higher. To reveal, change the target API level "
-              + "above the left navigation.");
-    }
-    else obj.removeClass("absent").removeAttr("title");
+      obj.addClass("absent").attr("title", "Requires API Level \"" +
+            apiLevel + "\" or higher. To reveal, change the target API level " +
+              "above the left navigation.");
+    } else obj.removeClass("absent").removeAttr("title");
   });
 }
 
-
-
-
 /* #################  SIDENAV TREE VIEW ################### */
-
-function new_node(me, mom, text, link, children_data, api_level)
-{
-  var node = new Object();
-  node.children = Array();
-  node.children_data = children_data;
-  node.depth = mom.depth + 1;
-
-  node.li = document.createElement("li");
-  mom.get_children_ul().appendChild(node.li);
-
-  node.label_div = document.createElement("div");
-  node.label_div.className = "label";
-  if (api_level != null) {
-    $(node.label_div).addClass("api");
-    $(node.label_div).addClass("api-level-"+api_level);
-  }
-  node.li.appendChild(node.label_div);
-
-  if (children_data != null) {
-    node.expand_toggle = document.createElement("a");
-    node.expand_toggle.href = "javascript:void(0)";
-    node.expand_toggle.onclick = function() {
-          if (node.expanded) {
-            $(node.get_children_ul()).slideUp("fast");
-            node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
-            node.expanded = false;
-          } else {
-            expand_node(me, node);
-          }
-       };
-    node.label_div.appendChild(node.expand_toggle);
-
-    node.plus_img = document.createElement("img");
-    node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
-    node.plus_img.className = "plus";
-    node.plus_img.width = "8";
-    node.plus_img.border = "0";
-    node.expand_toggle.appendChild(node.plus_img);
-
-    node.expanded = false;
-  }
-
-  var a = document.createElement("a");
-  node.label_div.appendChild(a);
-  node.label = document.createTextNode(text);
-  a.appendChild(node.label);
-  if (link) {
-    a.href = me.toroot + link;
-  } else {
-    if (children_data != null) {
-      a.className = "nolink";
-      a.href = "javascript:void(0)";
-      a.onclick = node.expand_toggle.onclick;
-      // This next line shouldn't be necessary.  I'll buy a beer for the first
-      // person who figures out how to remove this line and have the link
-      // toggle shut on the first try. --joeo@android.com
-      node.expanded = false;
-    }
-  }
-
-
-  node.children_ul = null;
-  node.get_children_ul = function() {
-      if (!node.children_ul) {
-        node.children_ul = document.createElement("ul");
-        node.children_ul.className = "children_ul";
-        node.children_ul.style.display = "none";
-        node.li.appendChild(node.children_ul);
-      }
-      return node.children_ul;
-    };
-
-  return node;
-}
-
-
-
-
-function expand_node(me, node)
-{
-  if (node.children_data && !node.expanded) {
-    if (node.children_visited) {
-      $(node.get_children_ul()).slideDown("fast");
-    } else {
-      get_node(me, node);
-      if ($(node.label_div).hasClass("absent")) {
-        $(node.get_children_ul()).addClass("absent");
-      }
-      $(node.get_children_ul()).slideDown("fast");
-    }
-    node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png";
-    node.expanded = true;
-
-    // perform api level toggling because new nodes are new to the DOM
-    var selectedLevel = $("#apiLevelSelector option:selected").val();
-    toggleVisisbleApis(selectedLevel, "#side-nav");
-  }
-}
-
-function get_node(me, mom)
-{
-  mom.children_visited = true;
-  for (var i in mom.children_data) {
-    var node_data = mom.children_data[i];
-    mom.children[i] = new_node(me, mom, node_data[0], node_data[1],
-        node_data[2], node_data[3]);
-  }
-}
-
-function this_page_relative(toroot)
-{
-  var full = document.location.pathname;
-  var file = "";
-  if (toroot.substr(0, 1) == "/") {
-    if (full.substr(0, toroot.length) == toroot) {
-      return full.substr(toroot.length);
-    } else {
-      // the file isn't under toroot.  Fail.
-      return null;
-    }
-  } else {
-    if (toroot != "./") {
-      toroot = "./" + toroot;
-    }
-    do {
-      if (toroot.substr(toroot.length-3, 3) == "../" || toroot == "./") {
-        var pos = full.lastIndexOf("/");
-        file = full.substr(pos) + file;
-        full = full.substr(0, pos);
-        toroot = toroot.substr(0, toroot.length-3);
-      }
-    } while (toroot != "" && toroot != "/");
-    return file.substr(1);
-  }
-}
-
-function find_page(url, data)
-{
-  var nodes = data;
-  var result = null;
-  for (var i in nodes) {
-    var d = nodes[i];
-    if (d[1] == url) {
-      return new Array(i);
-    }
-    else if (d[2] != null) {
-      result = find_page(url, d[2]);
-      if (result != null) {
-        return (new Array(i).concat(result));
-      }
-    }
-  }
-  return null;
-}
-
-function init_default_navtree(toroot) {
-  // load json file for navtree data
-  $.getScript(toRoot + 'navtree_data.js', function(data, textStatus, jqxhr) {
-      // when the file is loaded, initialize the tree
-      if(jqxhr.status === 200) {
-          init_navtree("tree-list", toroot, NAVTREE_DATA);
-      }
-  });
-
-  // perform api level toggling because because the whole tree is new to the DOM
-  var selectedLevel = $("#apiLevelSelector option:selected").val();
-  toggleVisisbleApis(selectedLevel, "#side-nav");
-}
-
-function init_navtree(navtree_id, toroot, root_nodes)
-{
-  var me = new Object();
-  me.toroot = toroot;
-  me.node = new Object();
-
-  me.node.li = document.getElementById(navtree_id);
-  me.node.children_data = root_nodes;
-  me.node.children = new Array();
-  me.node.children_ul = document.createElement("ul");
-  me.node.get_children_ul = function() { return me.node.children_ul; };
-  //me.node.children_ul.className = "children_ul";
-  me.node.li.appendChild(me.node.children_ul);
-  me.node.depth = 0;
-
-  get_node(me, me.node);
-
-  me.this_page = this_page_relative(toroot);
-  me.breadcrumbs = find_page(me.this_page, root_nodes);
-  if (me.breadcrumbs != null && me.breadcrumbs.length != 0) {
-    var mom = me.node;
-    for (var i in me.breadcrumbs) {
-      var j = me.breadcrumbs[i];
-      mom = mom.children[j];
-      expand_node(me, mom);
-    }
-    mom.label_div.className = mom.label_div.className + " selected";
-    addLoadEvent(function() {
-      scrollIntoView("nav-tree");
-      });
-  }
-}
-
-
-
-
-
-
-
-
 /* TODO: eliminate redundancy with non-google functions */
-function init_google_navtree(navtree_id, toroot, root_nodes)
-{
+function init_google_navtree(navtree_id, toroot, root_nodes) {
   var me = new Object();
   me.toroot = toroot;
   me.node = new Object();
@@ -3240,8 +946,7 @@
   get_google_node(me, me.node);
 }
 
-function new_google_node(me, mom, text, link, children_data, api_level)
-{
+function new_google_node(me, mom, text, link, children_data, api_level) {
   var node = new Object();
   var child;
   node.children = Array();
@@ -3259,28 +964,25 @@
 
   mom.get_children_ul().appendChild(node.li);
 
-
-  if(link) {
+  if (link) {
     child = document.createElement("a");
 
-  }
-  else {
+  } else {
     child = document.createElement("span");
     child.className = "tree-list-subtitle";
 
   }
   if (children_data != null) {
-    node.li.className="nav-section";
+    node.li.className = "nav-section";
     node.label_div = document.createElement("div");
     node.label_div.className = "nav-section-header-ref";
     node.li.appendChild(node.label_div);
     get_google_node(me, node);
     node.label_div.appendChild(child);
-  }
-  else {
+  } else {
     node.li.appendChild(child);
   }
-  if(link) {
+  if (link) {
     child.href = me.toroot + link;
   }
   node.label = document.createTextNode(text);
@@ -3291,27 +993,21 @@
   return node;
 }
 
-function get_google_node(me, mom)
-{
+function get_google_node(me, mom) {
   mom.children_visited = true;
   var linkText;
   for (var i in mom.children_data) {
     var node_data = mom.children_data[i];
     linkText = node_data[0];
 
-    if(linkText.match("^"+"com.google.android")=="com.google.android"){
+    if (linkText.match("^" + "com.google.android") == "com.google.android") {
       linkText = linkText.substr(19, linkText.length);
     }
-      mom.children[i] = new_google_node(me, mom, linkText, node_data[1],
-          node_data[2], node_data[3]);
+    mom.children[i] = new_google_node(me, mom, linkText, node_data[1],
+        node_data[2], node_data[3]);
   }
 }
 
-
-
-
-
-
 /****** NEW version of script to build google and sample navs dynamically ******/
 // TODO: update Google reference docs to tolerate this new implementation
 
@@ -3321,9 +1017,8 @@
 var NODE_TAGS = 3;
 var NODE_CHILDREN = 4;
 
-function init_google_navtree2(navtree_id, data)
-{
-  var $containerUl = $("#"+navtree_id);
+function init_google_navtree2(navtree_id, data) {
+  var $containerUl = $("#" + navtree_id);
   for (var i in data) {
     var node_data = data[i];
     $containerUl.append(new_google_node2(node_data));
@@ -3332,23 +1027,22 @@
   // Make all third-generation list items 'sticky' to prevent them from collapsing
   $containerUl.find('li li li.nav-section').addClass('sticky');
 
-  initExpandableNavItems("#"+navtree_id);
+  initExpandableNavItems("#" + navtree_id);
 }
 
-function new_google_node2(node_data)
-{
+function new_google_node2(node_data) {
   var linkText = node_data[NODE_NAME];
-  if(linkText.match("^"+"com.google.android")=="com.google.android"){
+  if (linkText.match("^" + "com.google.android") == "com.google.android") {
     linkText = linkText.substr(19, linkText.length);
   }
   var $li = $('<li>');
   var $a;
   if (node_data[NODE_HREF] != null) {
-    $a = $('<a href="' + toRoot + node_data[NODE_HREF] + '" title="' + linkText + '" >'
-        + linkText + '</a>');
+    $a = $('<a href="' + toRoot + node_data[NODE_HREF] + '" title="' + linkText + '" >' +
+        linkText + '</a>');
   } else {
-    $a = $('<a href="#" onclick="return false;" title="' + linkText + '" >'
-        + linkText + '/</a>');
+    $a = $('<a href="#" onclick="return false;" title="' + linkText + '" >' +
+        linkText + '/</a>');
   }
   var $childUl = $('<ul>');
   if (node_data[NODE_CHILDREN] != null) {
@@ -3367,16 +1061,6 @@
   return $li;
 }
 
-
-
-
-
-
-
-
-
-
-
 function showGoogleRefTree() {
   init_default_google_navtree(toRoot);
   init_default_gcm_navtree(toRoot);
@@ -3385,49 +1069,22 @@
 function init_default_google_navtree(toroot) {
   // load json file for navtree data
   $.getScript(toRoot + 'gms_navtree_data.js', function(data, textStatus, jqxhr) {
-      // when the file is loaded, initialize the tree
-      if(jqxhr.status === 200) {
-          init_google_navtree("gms-tree-list", toroot, GMS_NAVTREE_DATA);
-          highlightSidenav();
-          resizeNav();
-      }
+    // when the file is loaded, initialize the tree
+    if (jqxhr.status === 200) {
+      init_google_navtree("gms-tree-list", toroot, GMS_NAVTREE_DATA);
+      highlightSidenav();
+    }
   });
 }
 
 function init_default_gcm_navtree(toroot) {
   // load json file for navtree data
   $.getScript(toRoot + 'gcm_navtree_data.js', function(data, textStatus, jqxhr) {
-      // when the file is loaded, initialize the tree
-      if(jqxhr.status === 200) {
-          init_google_navtree("gcm-tree-list", toroot, GCM_NAVTREE_DATA);
-          highlightSidenav();
-          resizeNav();
-      }
-  });
-}
-
-function showSamplesRefTree() {
-  init_default_samples_navtree(toRoot);
-}
-
-function init_default_samples_navtree(toroot) {
-  // load json file for navtree data
-  $.getScript(toRoot + 'samples_navtree_data.js', function(data, textStatus, jqxhr) {
-      // when the file is loaded, initialize the tree
-      if(jqxhr.status === 200) {
-          // hack to remove the "about the samples" link then put it back in
-          // after we nuke the list to remove the dummy static list of samples
-          var $firstLi = $("#nav.samples-nav > li:first-child").clone();
-          $("#nav.samples-nav").empty();
-          $("#nav.samples-nav").append($firstLi);
-
-          init_google_navtree2("nav.samples-nav", SAMPLES_NAVTREE_DATA);
-          highlightSidenav();
-          resizeNav();
-          if ($("#jd-content #samples").length) {
-            showSamples();
-          }
-      }
+    // when the file is loaded, initialize the tree
+    if (jqxhr.status === 200) {
+      init_google_navtree("gcm-tree-list", toroot, GCM_NAVTREE_DATA);
+      highlightSidenav();
+    }
   });
 }
 
@@ -3439,25 +1096,25 @@
  *                'null' to simply toggle.
  */
 function toggleInherited(linkObj, expand) {
-    var base = linkObj.getAttribute("id");
-    var list = document.getElementById(base + "-list");
-    var summary = document.getElementById(base + "-summary");
-    var trigger = document.getElementById(base + "-trigger");
-    var a = $(linkObj);
-    if ( (expand == null && a.hasClass("closed")) || expand ) {
-        list.style.display = "none";
-        summary.style.display = "block";
-        trigger.src = toRoot + "assets/images/styles/disclosure_up.png";
-        a.removeClass("closed");
-        a.addClass("opened");
-    } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) {
-        list.style.display = "block";
-        summary.style.display = "none";
-        trigger.src = toRoot + "assets/images/styles/disclosure_down.png";
-        a.removeClass("opened");
-        a.addClass("closed");
-    }
-    return false;
+  var base = linkObj.getAttribute("id");
+  var list = document.getElementById(base + "-list");
+  var summary = document.getElementById(base + "-summary");
+  var trigger = document.getElementById(base + "-trigger");
+  var a = $(linkObj);
+  if ((expand == null && a.hasClass("closed")) || expand) {
+    list.style.display = "none";
+    summary.style.display = "block";
+    trigger.src = toRoot + "assets/images/styles/disclosure_up.png";
+    a.removeClass("closed");
+    a.addClass("opened");
+  } else if ((expand == null && a.hasClass("opened")) || (expand == false)) {
+    list.style.display = "block";
+    summary.style.display = "none";
+    trigger.src = toRoot + "assets/images/styles/disclosure_down.png";
+    a.removeClass("opened");
+    a.addClass("closed");
+  }
+  return false;
 }
 
 /* Toggle all inherited classes in a single table (e.g. all inherited methods)
@@ -3469,12 +1126,12 @@
   var a = $(linkObj);
   var table = $(a.parent().parent().parent()); // ugly way to get table/tbody
   var expandos = $(".jd-expando-trigger", table);
-  if ( (expand == null && a.text() == "[Expand]") || expand ) {
+  if ((expand == null && a.text() == "[Expand]") || expand) {
     expandos.each(function(i) {
       toggleInherited(this, true);
     });
     a.text("[Collapse]");
-  } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
+  } else if ((expand == null && a.text() == "[Collapse]") || (expand == false)) {
     expandos.each(function(i) {
       toggleInherited(this, false);
     });
@@ -3511,25 +1168,19 @@
   $("#toggleAllClassInherited").text("[Collapse All]");
 }
 
-
 /* HANDLE KEY EVENTS
  * - Listen for Ctrl+F (Cmd on Mac) and expand all inherited members (to aid page search)
  */
 var agent = navigator['userAgent'].toLowerCase();
 var mac = agent.indexOf("macintosh") != -1;
 
-$(document).keydown( function(e) {
-var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
+$(document).keydown(function(e) {
+  var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
   if (control && e.which == 70) {  // 70 is "F"
     ensureAllInheritedExpanded();
   }
 });
 
-
-
-
-
-
 /* On-demand functions */
 
 /** Move sample code line numbers out of PRE block and into non-copyable column */
@@ -3553,40 +1204,39 @@
     // highlight the line when hovering on the number
     $("#codesample-line-numbers a.number").mouseover(function() {
       var id = $(this).attr('href');
-      $(id).css('background','#e7e7e7');
+      $(id).css('background', '#e7e7e7');
     });
     $("#codesample-line-numbers a.number").mouseout(function() {
       var id = $(this).attr('href');
-      $(id).css('background','none');
+      $(id).css('background', 'none');
     });
   });
 }
 
 // create SHIFT key binder to avoid the selectText method when selecting multiple lines
 var shifted = false;
-$(document).bind('keyup keydown', function(e){shifted = e.shiftKey; return true;} );
+$(document).bind('keyup keydown', function(e) {
+  shifted = e.shiftKey; return true;
+});
 
 // courtesy of jasonedelman.com
 function selectText(element) {
-    var doc = document
-        , range, selection
-    ;
-    if (doc.body.createTextRange) { //ms
-        range = doc.body.createTextRange();
-        range.moveToElementText(element);
-        range.select();
-    } else if (window.getSelection) { //all others
-        selection = window.getSelection();
-        range = doc.createRange();
-        range.selectNodeContents(element);
-        selection.removeAllRanges();
-        selection.addRange(range);
-    }
+  var doc = document      ,
+        range, selection
+  ;
+  if (doc.body.createTextRange) { //ms
+    range = doc.body.createTextRange();
+    range.moveToElementText(element);
+    range.select();
+  } else if (window.getSelection) { //all others
+    selection = window.getSelection();
+    range = doc.createRange();
+    range.selectNodeContents(element);
+    selection.removeAllRanges();
+    selection.addRange(range);
+  }
 }
 
-
-
-
 /** Display links and other information about samples that match the
     group specified by the URL */
 function showSamples() {
@@ -3597,16 +1247,14 @@
   $selectedLi = $("#nav li.selected");
 
   $selectedLi.children("ul").children("li").each(function() {
-      var $li = $("<li>").append($(this).find("a").first().clone());
-      $ul.append($li);
+    var $li = $("<li>").append($(this).find("a").first().clone());
+    $ul.append($li);
   });
 
   $("#samples").append($ul);
 
 }
 
-
-
 /* ########################################################## */
 /* ###################  RESOURCE CARDS  ##################### */
 /* ########################################################## */
@@ -3615,78 +1263,75 @@
     jd_tag_helpers.js and the *_unified_data.js to be loaded. */
 
 (function() {
-  // Prevent the same resource from being loaded more than once per page.
-  var addedPageResources = {};
-
   $(document).ready(function() {
     // Need to initialize hero carousel before other sections for dedupe
     // to work correctly.
     $('[data-carousel-query]').dacCarouselQuery();
 
-    $('.resource-widget').each(function() {
-      initResourceWidget(this);
-    });
-
-    /* Pass the line height to ellipsisfade() to adjust the height of the
-    text container to show the max number of lines possible, without
-    showing lines that are cut off. This works with the css ellipsis
-    classes to fade last text line and apply an ellipsis char. */
-
-    //card text currently uses 20px line height.
-    var lineHeight = 20;
-    $('.card-info .text').ellipsisfade(lineHeight);
+    // Iterate over all instances and initialize a resource widget.
+    $('.resource-widget').resourceWidget();
   });
 
-  /*
-    Three types of resource layouts:
-    Flow - Uses a fixed row-height flow using float left style.
-    Carousel - Single card slideshow all same dimension absolute.
-    Stack - Uses fixed columns and flexible element height.
-  */
-  function initResourceWidget(widget) {
-    var $widget = $(widget);
-    var isFlow = $widget.hasClass('resource-flow-layout'),
-        isCarousel = $widget.hasClass('resource-carousel-layout'),
-        isStack = $widget.hasClass('resource-stack-layout');
-
-    // remove illegal col-x class which is not relevant anymore thanks to responsive styles.
-    var m = $widget.get(0).className.match(/\bcol-(\d+)\b/);
-    if (m && !$widget.is('.cols > *')) {
-      $widget.removeClass('col-' + m[1]);
-    }
-
-    var opts = {
-      cardSizes: ($widget.data('cardsizes') || '').split(','),
-      maxResults: parseInt($widget.data('maxresults') || '100', 10),
-      initialResults: $widget.data('initialResults'),
-      itemsPerPage: $widget.data('itemsperpage'),
-      sortOrder: $widget.data('sortorder'),
-      query: $widget.data('query'),
-      section: $widget.data('section'),
+  $.fn.widgetOptions = function() {
+    return {
+      cardSizes: (this.data('cardsizes') || '').split(','),
+      maxResults: parseInt(this.data('maxresults'), 10) || Infinity,
+      initialResults: this.data('initialResults'),
+      itemsPerPage: this.data('itemsPerPage'),
+      sortOrder: this.data('sortorder'),
+      query: this.data('query'),
+      section: this.data('section'),
       /* Added by LFL 6/6/14 */
-      resourceStyle: $widget.data('resourcestyle') || 'card',
-      stackSort: $widget.data('stacksort') || 'true'
+      resourceStyle: this.data('resourcestyle') || 'card',
+      stackSort: this.data('stacksort') || 'true',
+      // For filter based resources
+      allowDuplicates: this.data('allow-duplicates') || 'false'
     };
+  };
 
-    // run the search for the set of resources to show
+  $.fn.deprecateOldGridStyles = function() {
+    var m = this.get(0).className.match(/\bcol-(\d+)\b/);
+    if (m && !this.is('.cols > *')) {
+      this.removeClass('col-' + m[1]);
+    }
+    return this;
+  }
 
-    var resources = buildResourceList(opts);
+  /*
+   * Three types of resource layouts:
+   * Flow - Uses a fixed row-height flow using float left style.
+   * Carousel - Single card slideshow all same dimension absolute.
+   * Stack - Uses fixed columns and flexible element height.
+   */
+  function initResourceWidget(widget, resources, opts) {
+    var $widget = $(widget).deprecateOldGridStyles();
+    var isFlow = $widget.hasClass('resource-flow-layout');
+    var isCarousel = $widget.hasClass('resource-carousel-layout');
+    var isStack = $widget.hasClass('resource-stack-layout');
+
+    opts = opts || $widget.widgetOptions();
+    resources = resources || metadata.query(opts);
+
+    if (opts.maxResults !== undefined) {
+      resources = resources.slice(0, opts.maxResults);
+    }
 
     if (isFlow) {
       drawResourcesFlowWidget($widget, opts, resources);
     } else if (isCarousel) {
       drawResourcesCarouselWidget($widget, opts, resources);
     } else if (isStack) {
-      /* Looks like this got removed and is not used, so repurposing for the
-          homepage style layout.
-          Modified by LFL 6/6/14
-      */
-      //var sections = buildSectionList(opts);
-      opts['numStacks'] = $widget.data('numstacks');
-      drawResourcesStackWidget($widget, opts, resources/*, sections*/);
+      opts.numStacks = $widget.data('numstacks');
+      drawResourcesStackWidget($widget, opts, resources);
     }
   }
 
+  $.fn.resourceWidget = function(resources, options) {
+    return this.each(function() {
+      initResourceWidget(this, resources, options);
+    });
+  };
+
   /* Initializes a Resource Carousel Widget */
   function drawResourcesCarouselWidget($widget, opts, resources) {
     $widget.empty();
@@ -3696,15 +1341,15 @@
       .append($('<a>').addClass('slideshow-prev').text('Prev'))
       .append($('<a>').addClass('slideshow-next').text('Next'));
 
-    var css = { 'width': $widget.width() + 'px',
-                'height': $widget.height() + 'px' };
+    var css = {'width': $widget.width() + 'px',
+                'height': $widget.height() + 'px'};
 
     var $ul = $('<ul>');
 
     for (var i = 0; i < resources.length; ++i) {
       var $card = $('<a>')
         .attr('href', cleanUrl(resources[i].url))
-        .decorateResourceCard(resources[i],plusone);
+        .decorateResourceCard(resources[i], plusone);
 
       $('<li>').css(css)
           .append($card)
@@ -3720,7 +1365,7 @@
       btnPrev: '.slideshow-prev',
       btnNext: '.slideshow-next'
     });
-  };
+  }
 
   /* Initializes a Resource Card Stack Widget (column-based layout)
      Modified by LFL 6/6/14
@@ -3732,7 +1377,6 @@
     var cards = $widget.find('.resource-card').detach().toArray();
     var numStacks = opts.numStacks || 1;
     var $stacks = [];
-    var urlString;
 
     for (var i = 0; i < numStacks; ++i) {
       $stacks[i] = $('<div>').addClass('resource-card-stack')
@@ -3743,21 +1387,21 @@
 
     // Extract any subsections that are actually resource cards
     if (sections) {
-      for (var i = 0; i < sections.length; ++i) {
+      for (i = 0; i < sections.length; ++i) {
         if (!sections[i].sections || !sections[i].sections.length) {
           // Render it as a resource card
           sectionResources.push(
             $('<a>')
               .addClass('resource-card section-card')
               .attr('href', cleanUrl(sections[i].resource.url))
-              .decorateResourceCard(sections[i].resource,plusone)[0]
+              .decorateResourceCard(sections[i].resource, plusone)[0]
           );
 
         } else {
           cards.push(
             $('<div>')
               .addClass('resource-card section-card-menu')
-              .decorateResourceSection(sections[i],plusone)[0]
+              .decorateResourceSection(sections[i], plusone)[0]
           );
         }
       }
@@ -3765,7 +1409,7 @@
 
     cards = cards.concat(sectionResources);
 
-    for (var i = 0; i < resources.length; ++i) {
+    for (i = 0; i < resources.length; ++i) {
       var $card = createResourceElement(resources[i], opts);
 
       if (opts.resourceStyle.indexOf('related') > -1) {
@@ -3775,8 +1419,8 @@
       cards.push($card[0]);
     }
 
-    if (opts.stackSort != 'false') {
-      for (var i = 0; i < cards.length; ++i) {
+    if (opts.stackSort !== 'false') {
+      for (i = 0; i < cards.length; ++i) {
         // Find the stack with the shortest height, but give preference to
         // left to right order.
         var minHeight = $stacks[0].height();
@@ -3793,8 +1437,7 @@
         $stacks[minIndex].append($(cards[i]));
       }
     }
-
-  };
+  }
 
   /*
     Create a resource card using the given resource object and a list of html
@@ -3807,7 +1450,7 @@
     // so its a div instead of an a tag, also the generic one is not given
     // the resource-card class so it appears with a transparent background
     // and can be styled in whatever way the css setup.
-    if (opts.resourceStyle == 'generic') {
+    if (opts.resourceStyle === 'generic') {
       $el = $('<div>')
         .addClass('resource')
         .attr('href', cleanUrl(resource.url))
@@ -3833,39 +1476,54 @@
       column.addClass('col-tablet-1of1');
     }
     if (cardWidth < 18) {
-      column.addClass('col-mobile-1of1')
+      column.addClass('col-mobile-1of1');
     }
     return column;
   }
 
   /* Initializes a flow widget, see distribute.scss for generating accompanying css */
   function drawResourcesFlowWidget($widget, opts, resources) {
+    // We'll be doing our own modifications to opts.
+    opts = $.extend({}, opts);
+
     $widget.empty().addClass('cols');
-    var cardSizes = opts.cardSizes || ['6x6'];
-    var initialResults = opts.initialResults || resources.length;
-    var i = 0, j = 0;
+    if (opts.itemsPerPage) {
+      $('<div class="col-1of1 dac-section-links dac-text-center">')
+        .append(
+          $('<div class="dac-section-link dac-show-less" data-toggle="show-less">Less<i class="dac-sprite dac-auto-unfold-less"></i></div>'),
+          $('<div class="dac-section-link dac-show-more" data-toggle="show-more">More<i class="dac-sprite dac-auto-unfold-more"></i></div>')
+        )
+        .appendTo($widget);
+    }
+
+    $widget.data('options.resourceflow', opts);
+    $widget.data('resources.resourceflow', resources);
+
+    drawResourceFlowPage($widget, opts, resources);
+  }
+
+  function drawResourceFlowPage($widget, opts, resources) {
+    var cardSizes = opts.cardSizes || ['6x6']; // 2015-08-09: dynamic card sizes are deprecated
+    var i = opts.currentIndex || 0;
+    var j = 0;
     var plusone = false; // stop showing plusone buttons on cards
-    var cardParent = $widget;
+    var firstPage = i === 0;
+    var initialResults = opts.initialResults || opts.itemsPerPage || resources.length;
+    var max = firstPage ? initialResults : i + opts.itemsPerPage;
+    max = Math.min(resources.length, max);
 
-    while (i < resources.length) {
+    var page = $('<div class="resource-flow-page">');
+    if (opts.itemsPerPage) {
+      $widget.find('.dac-section-links').before(page);
+    } else {
+      $widget.append(page);
+    }
 
-      if (i === initialResults && initialResults < resources.length) {
-        // Toggle remaining cards
-        cardParent = $('<div class="dac-toggle-content clearfix">').appendTo($widget);
-        $widget.addClass('dac-toggle');
-        $('<div class="col-1of1 dac-section-links dac-text-center">')
-          .append(
-            $('<div class="dac-section-link" data-toggle="section">')
-              .append('<span class="dac-toggle-expand">More<i class="dac-sprite dac-auto-unfold-more"></i></span>')
-              .append('<span class="dac-toggle-collapse">Less<i class="dac-sprite dac-auto-unfold-less"></i></span>')
-          )
-          .appendTo($widget)
-      }
-
+    while (i < max) {
       var cardSize = cardSizes[j++ % cardSizes.length];
-      cardSize = cardSize.replace(/^\s+|\s+$/,'');
+      cardSize = cardSize.replace(/^\s+|\s+$/, '');
 
-      var column = createResponsiveFlowColumn(cardSize).appendTo(cardParent);
+      var column = createResponsiveFlowColumn(cardSize).appendTo(page);
 
       // A stack has a third dimension which is the number of stacked items
       var isStack = cardSize.match(/(\d+)x(\d+)x(\d+)/);
@@ -3875,8 +1533,8 @@
       if (isStack) {
         // Create a stack container which should have the dimensions defined
         // by the product of the items inside.
-        $stackDiv = $('<div>').addClass('resource-card-stack resource-card-' + isStack[1]
-            + 'x' + isStack[2] * isStack[3]) .appendTo(column);
+        $stackDiv = $('<div>').addClass('resource-card-stack resource-card-' + isStack[1] +
+          'x' + isStack[2] * isStack[3]) .appendTo(column);
       }
 
       // Build each stack item or just a single item
@@ -3886,11 +1544,11 @@
         var $card = createResourceElement(resources[i], opts, plusone);
 
         $card.addClass('resource-card-' + cardSize +
-          ' resource-card-' + resource.type);
+          ' resource-card-' + resource.type.toLowerCase());
 
         if (isStack) {
           $card.addClass('resource-card-' + isStack[1] + 'x' + isStack[2]);
-          if (++stackCount == parseInt(isStack[3])) {
+          if (++stackCount === parseInt(isStack[3])) {
             $card.addClass('resource-card-row-stack-last');
             stackCount = 0;
           }
@@ -3900,8 +1558,47 @@
 
         $card.appendTo($stackDiv || column);
 
-      } while (++i < resources.length && stackCount > 0);
+      } while (++i < max && stackCount > 0);
+
+      // Record number of pages viewed in analytics.
+      if (!firstPage) {
+        var clicks = Math.ceil((i - initialResults) / opts.itemsPerPage);
+        ga('send', 'event', 'Cards', 'Click More', clicks);
+      }
     }
+
+    opts.currentIndex = i;
+    $widget.toggleClass('dac-has-more', i < resources.length);
+    $widget.toggleClass('dac-has-less', !firstPage);
+
+    $widget.trigger('dac:domchange');
+    if (opts.onRenderPage) {
+      opts.onRenderPage(page);
+    }
+  }
+
+  function drawResourceFlowReset($widget, opts, resources) {
+    $widget.find('.resource-flow-page')
+        .slice(1)
+        .remove();
+    $widget.toggleClass('dac-has-more', true);
+    $widget.toggleClass('dac-has-less', false);
+
+    opts.currentIndex = Math.min(opts.initialResults, resources.length);
+
+    ga('send', 'event', 'Cards', 'Click Less');
+  }
+
+  /* A decorator for event functions which finds the surrounding widget and it's options */
+  function wrapWithWidget(func) {
+    return function(e) {
+      if (e) e.preventDefault();
+
+      var $widget = $(this).closest('.resource-flow-layout');
+      var opts = $widget.data('options.resourceflow');
+      var resources = $widget.data('resources.resourceflow');
+      func($widget, opts, resources);
+    };
   }
 
   /* Build a site map of resources using a section as a root. */
@@ -3912,139 +1609,7 @@
     return [];
   }
 
-  function buildResourceList(opts) {
-    return $.queryResources(opts);
-  }
-
-  $.queryResources = function(opts) {
-    var maxResults = opts.maxResults || 100;
-
-    var query = opts.query || '';
-    var expressions = parseResourceQuery(query);
-    var addedResourceIndices = {};
-    var results = [];
-
-    for (var i = 0; i < expressions.length; i++) {
-      var clauses = expressions[i];
-
-      // build initial set of resources from first clause
-      var firstClause = clauses[0];
-      var resources = [];
-      switch (firstClause.attr) {
-        case 'type':
-          resources = ALL_RESOURCES_BY_TYPE[firstClause.value];
-          break;
-        case 'lang':
-          resources = ALL_RESOURCES_BY_LANG[firstClause.value];
-          break;
-        case 'tag':
-          resources = ALL_RESOURCES_BY_TAG[firstClause.value];
-          break;
-        case 'collection':
-          var urls = RESOURCE_COLLECTIONS[firstClause.value].resources || [];
-          resources = urls.map(function(url){ return ALL_RESOURCES_BY_URL[url]; });
-          break;
-        case 'section':
-          var urls = SITE_MAP[firstClause.value].sections || [];
-          resources = urls.map(function(url){ return ALL_RESOURCES_BY_URL[url]; });
-          break;
-      }
-      // console.log(firstClause.attr + ':' + firstClause.value);
-      resources = resources || [];
-
-      // use additional clauses to filter corpus
-      if (clauses.length > 1) {
-        var otherClauses = clauses.slice(1);
-        resources = resources.filter(getResourceMatchesClausesFilter(otherClauses));
-      }
-
-      // filter out resources already added
-      if (i > 1) {
-        resources = resources.filter(getResourceNotAlreadyAddedFilter(addedResourceIndices));
-      }
-
-      // add to list of already added indices
-      for (var j = 0; j < resources.length; j++) {
-        if (resources[j]) {
-          addedResourceIndices[resources[j].index] = 1;
-        }
-      }
-
-      // concat to final results list
-      results = results.concat(resources);
-    }
-
-    if (opts.sortOrder && results.length) {
-      var attr = opts.sortOrder;
-
-      if (opts.sortOrder == 'random') {
-        var i = results.length, j, temp;
-        while (--i) {
-          j = Math.floor(Math.random() * (i + 1));
-          temp = results[i];
-          results[i] = results[j];
-          results[j] = temp;
-        }
-      } else {
-        var desc = attr.charAt(0) == '-';
-        if (desc) {
-          attr = attr.substring(1);
-        }
-        results = results.sort(function(x,y) {
-          return (desc ? -1 : 1) * (parseInt(x[attr], 10) - parseInt(y[attr], 10));
-        });
-      }
-    }
-
-    results = results.filter(getResourceNotAlreadyAddedFilter(addedPageResources));
-    results = results.slice(0, maxResults);
-
-    for (var j = 0; j < results.length; ++j) {
-      addedPageResources[results[j].index] = 1;
-    }
-
-    return results;
-  }
-
-
-  function getResourceNotAlreadyAddedFilter(addedResourceIndices) {
-    return function(resource) {
-      return resource && !addedResourceIndices[resource.index];
-    };
-  }
-
-
-  function getResourceMatchesClausesFilter(clauses) {
-    return function(resource) {
-      return doesResourceMatchClauses(resource, clauses);
-    };
-  }
-
-
-  function doesResourceMatchClauses(resource, clauses) {
-    for (var i = 0; i < clauses.length; i++) {
-      var map;
-      switch (clauses[i].attr) {
-        case 'type':
-          map = IS_RESOURCE_OF_TYPE[clauses[i].value];
-          break;
-        case 'lang':
-          map = IS_RESOURCE_IN_LANG[clauses[i].value];
-          break;
-        case 'tag':
-          map = IS_RESOURCE_TAGGED[clauses[i].value];
-          break;
-      }
-
-      if (!map || (!!clauses[i].negative ? map[resource.index] : !map[resource.index])) {
-        return clauses[i].negative;
-      }
-    }
-    return true;
-  }
-
-  function cleanUrl(url)
-  {
+  function cleanUrl(url) {
     if (url && url.indexOf('//') === -1) {
       url = toRoot + url;
     }
@@ -4052,53 +1617,16 @@
     return url;
   }
 
-
-  function parseResourceQuery(query) {
-    // Parse query into array of expressions (expression e.g. 'tag:foo + type:video')
-    var expressions = [];
-    var expressionStrs = query.split(',') || [];
-    for (var i = 0; i < expressionStrs.length; i++) {
-      var expr = expressionStrs[i] || '';
-
-      // Break expression into clauses (clause e.g. 'tag:foo')
-      var clauses = [];
-      var clauseStrs = expr.split(/(?=[\+\-])/);
-      for (var j = 0; j < clauseStrs.length; j++) {
-        var clauseStr = clauseStrs[j] || '';
-
-        // Get attribute and value from clause (e.g. attribute='tag', value='foo')
-        var parts = clauseStr.split(':');
-        var clause = {};
-
-        clause.attr = parts[0].replace(/^\s+|\s+$/g,'');
-        if (clause.attr) {
-          if (clause.attr.charAt(0) == '+') {
-            clause.attr = clause.attr.substring(1);
-          } else if (clause.attr.charAt(0) == '-') {
-            clause.negative = true;
-            clause.attr = clause.attr.substring(1);
-          }
-        }
-
-        if (parts.length > 1) {
-          clause.value = parts[1].replace(/^\s+|\s+$/g,'');
-        }
-
-        clauses.push(clause);
-      }
-
-      if (!clauses.length) {
-        continue;
-      }
-
-      expressions.push(clauses);
-    }
-
-    return expressions;
-  }
+  // Delegated events for resources.
+  $(document).on('click', '.resource-flow-layout [data-toggle="show-more"]', wrapWithWidget(drawResourceFlowPage));
+  $(document).on('click', '.resource-flow-layout [data-toggle="show-less"]', wrapWithWidget(drawResourceFlowReset));
 })();
 
 (function($) {
+  // A mapping from category and type values to new values or human presentable strings.
+  var SECTION_MAP = {
+    googleplay: 'google play'
+  };
 
   /*
     Utility method for creating dom for the description area of a card.
@@ -4127,10 +1655,10 @@
     return $description;
   }
 
-
   /* Simple jquery function to create dom for a standard resource card */
-  $.fn.decorateResourceCard = function(resource,plusone) {
-    var section = resource.group || resource.type;
+  $.fn.decorateResourceCard = function(resource, plusone) {
+    var section = resource.category || resource.type;
+    section = (SECTION_MAP[section] || section).toLowerCase();
     var imgUrl = resource.image ||
       'assets/images/resource-card-default-android.jpg';
 
@@ -4138,7 +1666,7 @@
       imgUrl = toRoot + imgUrl;
     }
 
-    if (resource.type === 'youtube') {
+    if (resource.type === 'youtube' || resource.type === 'video') {
       $('<div>').addClass('play-button')
         .append($('<i class="dac-sprite dac-play-white">'))
         .appendTo(this);
@@ -4151,7 +1679,8 @@
 
     $('<div>').addClass('card-info' + (!resource.summary ? ' empty-desc' : ''))
       .append($('<div>').addClass('section').text(section))
-      .append($('<div>').addClass('title').html(resource.title))
+      .append($('<div>').addClass('title' + (resource.title_highlighted ? ' highlighted' : ''))
+        .html(resource.title_highlighted || resource.title))
       .append(buildResourceCardDescription(resource, plusone))
       .appendTo(this);
 
@@ -4159,7 +1688,7 @@
   };
 
   /* Simple jquery function to create dom for a resource section card (menu) */
-  $.fn.decorateResourceSection = function(section,plusone) {
+  $.fn.decorateResourceSection = function(section, plusone) {
     var resource = section.resource;
     //keep url clean for matching and offline mode handling
     var urlPrefix = resource.image.indexOf("//") > -1 ? "" : toRoot;
@@ -4237,9 +1766,6 @@
     return this;
   };
 
-
-
-
   /* Render other types of resource styles that are not cards. */
   $.fn.decorateResource = function(resource, opts) {
     var imgUrl = resource.image ||
@@ -4258,7 +1784,7 @@
       $('<div>').addClass('image')
         .css('background-image', 'url(' + imgUrl + ')'),
       $('<div>').addClass('info').append(
-        $('<h4>').addClass('title').html(resource.title),
+        $('<h4>').addClass('title').html(resource.title_highlighted || resource.title),
         $('<p>').addClass('summary').html(resource.summary),
         $('<a>').attr('href', linkUrl).addClass('cta').html('Learn More')
       )
@@ -4268,31 +1794,6 @@
   };
 })(jQuery);
 
-
-/* Calculate the vertical area remaining */
-(function($) {
-    $.fn.ellipsisfade= function(lineHeight) {
-        this.each(function() {
-            // get element text
-            var $this = $(this);
-            var remainingHeight = $this.parent().parent().height();
-            $this.parent().siblings().each(function ()
-            {
-              if ($(this).is(":visible")) {
-                var h = $(this).outerHeight(true);
-                remainingHeight = remainingHeight - h;
-              }
-            });
-
-            adjustedRemainingHeight = ((remainingHeight)/lineHeight>>0)*lineHeight
-            $this.parent().css({'height': adjustedRemainingHeight});
-            $this.css({'height': "auto"});
-        });
-
-        return this;
-    };
-}) (jQuery);
-
 /*
   Fullscreen Carousel
 
@@ -4383,10 +1884,6 @@
   }
 })();
 
-
-
-
-
 /*
   Tab Carousel
 
@@ -4492,7 +1989,7 @@
     // add HRs below all H2s (except for a few other h2 variants)
     // Consider doing this with css instead.
     h2Titles = $('h2').not('#qv h2, #tb h2, .sidebox h2, #devdoc-nav h2, h2.norule');
-    h2Titles.css({marginBottom:0}).after('<hr/>');
+    h2Titles.css({paddingBottom:0}).after('<hr/>');
 
     // Exit early if on older browser.
     if (!window.matchMedia) {
@@ -4525,7 +2022,7 @@
       // Find all the relevant nodes.
       var $title = $(this);
       var $hr = $title.next();
-      var $contents = $hr.nextUntil('h2, .next-docs');
+      var $contents = allNextUntil($hr[0], 'h2, .next-docs');
       var $section = $($title)
         .add($hr)
         .add($title.prev('a[name]'))
@@ -4554,7 +2051,9 @@
 
       // Wrap in magic markup.
       $section = $section.wrapAll('<div class="dac-toggle dac-mobile">').parent();
-      $contents.wrapAll('<div class="dac-toggle-content"><div>'); // extra div used for max-height calculation.
+
+      // extra div used for max-height calculation.
+      $contents.wrapAll('<div class="dac-toggle-content dac-expand"><div>');
 
       // Pre-expand section if requested.
       if ($title.hasClass('is-expanded')) {
@@ -4571,11 +2070,511 @@
     });
   }
 
+  // Similar to $.fn.nextUntil() except we need all nodes, jQuery skips text nodes.
+  function allNextUntil(elem, until) {
+    var matched = [];
+
+    while ((elem = elem.nextSibling) && elem.nodeType !== 9) {
+      if (elem.nodeType === 1 && jQuery(elem).is(until)) {
+        break;
+      }
+      matched.push(elem);
+    }
+    return $(matched);
+  }
+
   $(function() {
     initWidget();
   });
 })(jQuery);
 
+(function($, window) {
+  'use strict';
+
+  // Blogger API info
+  var apiUrl = 'https://www.googleapis.com/blogger/v3';
+  var apiKey = 'AIzaSyCFhbGnjW06dYwvRCU8h_zjdpS4PYYbEe8';
+
+  // Blog IDs can be found in the markup of the blog posts
+  var blogs = {
+    'android-developers': {
+      id: '6755709643044947179',
+      title: 'Android Developers Blog'
+    }
+  };
+  var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
+      'July', 'August', 'September', 'October', 'November', 'December'];
+
+  var BlogReader = (function() {
+    var reader;
+
+    function BlogReader() {
+      this.doneSetup = false;
+    }
+
+    /**
+     * Initialize the blog reader and modal.
+     */
+    BlogReader.prototype.setup = function() {
+      $('#jd-content').append(
+          '<div id="blog-reader" data-modal="blog-reader" class="dac-modal dac-has-small-header">' +
+            '<div class="dac-modal-container">' +
+              '<div class="dac-modal-window">' +
+                '<header class="dac-modal-header">' +
+                  '<div class="dac-modal-header-actions">' +
+                    '<a href="" class="dac-modal-header-open" target="_blank">' +
+                      '<i class="dac-sprite dac-open-in-new"></i>' +
+                    '</a>' +
+                    '<button class="dac-modal-header-close" data-modal-toggle>' +
+                    '</button>' +
+                  '</div>' +
+                  '<h2 class="norule dac-modal-header-title"></h2>' +
+                '</header>' +
+                '<div class="dac-modal-content dac-blog-reader">' +
+                  '<time class="dac-blog-reader-date" pubDate></time>' +
+                  '<h3 class="dac-blog-reader-title"></h3>' +
+                  '<div class="dac-blog-reader-text clearfix"></div>' +
+                '</div>' +
+              '</div>' +
+            '</div>' +
+          '</div>');
+
+      this.blogReader = $('#blog-reader').dacModal();
+
+      this.doneSetup = true;
+    };
+
+    BlogReader.prototype.openModal_ = function(blog, post) {
+      var published = new Date(post.published);
+      var formattedDate = monthNames[published.getMonth()] + ' ' + published.getDay() + ' ' + published.getFullYear();
+      this.blogReader.find('.dac-modal-header-open').attr('href', post.url);
+      this.blogReader.find('.dac-modal-header-title').text(blog.title);
+      this.blogReader.find('.dac-blog-reader-title').html(post.title);
+      this.blogReader.find('.dac-blog-reader-date').html(formattedDate);
+      this.blogReader.find('.dac-blog-reader-text').html(post.content);
+      this.blogReader.trigger('modal-open');
+    };
+
+    /**
+     * Show a blog post in a modal
+     * @param  {string} blogName - The name of the Blogspot blog.
+     * @param  {string} postPath - The path to the blog post.
+     * @param  {bool} secondTry - Has it failed once?
+     */
+    BlogReader.prototype.showPost = function(blogName, postPath, secondTry) {
+      var blog = blogs[blogName];
+      var postUrl = 'https://' + blogName + '.blogspot.com' + postPath;
+
+      var url = apiUrl + '/blogs/' + blog.id + '/posts/bypath?path=' + encodeURIComponent(postPath) + '&key=' + apiKey;
+      $.ajax(url, {timeout: 650}).done(this.openModal_.bind(this, blog)).fail(function(error) {
+        // Retry once if we get an error
+        if (error.status === 500 && !secondTry) {
+          this.showPost(blogName, postPath, true);
+        } else {
+          window.location.href = postUrl;
+        }
+      }.bind(this));
+    };
+
+    return {
+      getReader: function() {
+        if (!reader) {
+          reader = new BlogReader();
+        }
+        return reader;
+      }
+    };
+  })();
+
+  var blogReader = BlogReader.getReader();
+
+  function wrapLinkWithReader(e) {
+    var el = $(e.currentTarget);
+    if (el.hasClass('dac-modal-header-open')) {
+      return;
+    }
+
+    // Only catch links on blogspot.com
+    var matches = el.attr('href').match(/https?:\/\/([^\.]*).blogspot.com([^$]*)/);
+    if (matches && matches.length === 3) {
+      var blogName = matches[1];
+      var postPath = matches[2];
+
+      // Check if we have information about the blog
+      if (!blogs[blogName]) {
+        return;
+      }
+
+      // Setup the first time it's used
+      if (!blogReader.doneSetup) {
+        blogReader.setup();
+      }
+
+      e.preventDefault();
+      blogReader.showPost(blogName, postPath);
+    }
+  }
+
+  $(document).on('click.blog-reader', 'a[href*="blogspot.com/"]', wrapLinkWithReader);
+})(jQuery, window);
+
+(function($) {
+  $.fn.debounce = function(func, wait, immediate) {
+    var timeout;
+
+    return function() {
+      var context = this;
+      var args = arguments;
+
+      var later = function() {
+        timeout = null;
+        if (!immediate) {
+          func.apply(context, args);
+        }
+      };
+
+      var callNow = immediate && !timeout;
+      clearTimeout(timeout);
+      timeout = setTimeout(later, wait);
+
+      if (callNow) {
+        func.apply(context, args);
+      }
+    };
+  };
+})(jQuery);
+
+/* Calculate the vertical area remaining */
+(function($) {
+  $.fn.ellipsisfade = function() {
+    // Only fetch line-height of first element to avoid recalculate style.
+    // Will be NaN if no elements match, which is ok.
+    var lineHeight = parseInt(this.css('line-height'), 10);
+
+    this.each(function() {
+      // get element text
+      var $this = $(this);
+      var remainingHeight = $this.parent().parent().height();
+      $this.parent().siblings().each(function() {
+        var elHeight;
+        if ($(this).is(':visible')) {
+          elHeight = $(this).outerHeight(true);
+          remainingHeight = remainingHeight - elHeight;
+        }
+      });
+
+      var adjustedRemainingHeight = ((remainingHeight) / lineHeight >> 0) * lineHeight;
+      $this.parent().css({height: adjustedRemainingHeight});
+      $this.css({height: 'auto'});
+    });
+
+    return this;
+  };
+
+  /* Pass the line height to ellipsisfade() to adjust the height of the
+   text container to show the max number of lines possible, without
+   showing lines that are cut off. This works with the css ellipsis
+   classes to fade last text line and apply an ellipsis char. */
+  function updateEllipsis(context) {
+    if (!(context instanceof jQuery)) {
+      context = $('html');
+    }
+
+    context.find('.card-info .text').ellipsisfade();
+  }
+
+  $(window).on('resize', $.fn.debounce(updateEllipsis, 500));
+  $(updateEllipsis);
+  $('html').on('dac:domchange', function(e) { updateEllipsis($(e.target)); });
+})(jQuery);
+
+/* Filter */
+(function($) {
+  'use strict';
+
+  /**
+   * A single filter item content.
+   * @type {string} - Element template.
+   * @private
+   */
+  var ITEM_STR_ = '<input type="checkbox" value="{{value}}" class="dac-form-checkbox" id="{{id}}">' +
+      '<label for="{{id}}" class="dac-form-checkbox-button"></label>' +
+      '<label for="{{id}}" class="dac-form-label">{{name}}</label>';
+
+  /**
+   * Template for a chip element.
+   * @type {*|HTMLElement}
+   * @private
+   */
+  var CHIP_BASE_ = $('<li class="dac-filter-chip">' +
+    '<button class="dac-filter-chip-close">' +
+      '<i class="dac-sprite dac-close-black dac-filter-chip-close-icon"></i>' +
+    '</button>' +
+  '</li>');
+
+  /**
+   * Component to handle narrowing down resources.
+   * @param {HTMLElement} el - The DOM element.
+   * @param {Object} options
+   * @constructor
+   */
+  function Filter(el, options) {
+    this.el = $(el);
+    this.options = $.extend({}, Filter.DEFAULTS_, options);
+    this.init();
+  }
+
+  Filter.DEFAULTS_ = {
+    activeClass: 'dac-active',
+    chipsDataAttr: 'filter-chips',
+    nameDataAttr: 'filter-name',
+    countDataAttr: 'filter-count',
+    tabViewDataAttr: 'tab-view',
+    valueDataAttr: 'filter-value'
+  };
+
+  /**
+   * Draw resource cards.
+   * @param {Array} resources
+   * @private
+   */
+  Filter.prototype.draw_ = function(resources) {
+    var that = this;
+
+    if (resources.length === 0) {
+      this.containerEl_.html('<p class="dac-filter-message">Nothing matches selected filters.</p>');
+      return;
+    }
+
+    // Draw resources.
+    that.containerEl_.resourceWidget(resources, that.data_.options);
+  };
+
+  /**
+   * Initialize a Filter component.
+   */
+  Filter.prototype.init = function() {
+    this.containerEl_ = $(this.options.filter);
+
+    // Setup data settings
+    this.data_ = {};
+    this.data_.chips = {};
+    this.data_.options = this.containerEl_.widgetOptions();
+    this.data_.all = window.metadata.query(this.data_.options);
+
+    // Initialize filter UI
+    this.initUi();
+  };
+
+  /**
+   * Generate a chip for a given filter item.
+   * @param {Object} item - A single filter option (checkbox container).
+   * @returns {HTMLElement} A new Chip element.
+   */
+  Filter.prototype.chipForItem = function(item) {
+    var chip = CHIP_BASE_.clone();
+    chip.prepend(this.data_.chips[item.data('filter-value')]);
+    chip.data('item.dac-filter', item);
+    item.data('chip.dac-filter', chip);
+    this.addToItemValue(item, 1);
+    return chip[0];
+  };
+
+  /**
+   * Update count of checked filter items.
+   * @param {Object} item - A single filter option (checkbox container).
+   * @param {Number} value - Either -1 or 1.
+   */
+  Filter.prototype.addToItemValue = function(item, value) {
+    var tab = item.parent().data(this.options.tabViewDataAttr);
+    var countEl = this.countEl_.filter('[data-' + this.options.countDataAttr + '="' + tab + '"]');
+    var count = value + parseInt(countEl.text(), 10);
+    countEl.text(count);
+    countEl.toggleClass('dac-disabled', count === 0);
+  };
+
+  /**
+   * Set event listeners.
+   * @private
+   */
+  Filter.prototype.setEventListeners_ = function() {
+    this.chipsEl_.on('click.dac-filter', '.dac-filter-chip-close', this.closeChipHandler_.bind(this));
+    this.tabViewEl_.on('change.dac-filter', ':checkbox', this.toggleCheckboxHandler_.bind(this));
+  };
+
+  /**
+   * Check filter items that are active by default.
+   */
+  Filter.prototype.activateInitialFilters_ = function() {
+    var id = (new Date()).getTime();
+    var initiallyCheckedValues = this.data_.options.query.replace(/,\s*/g, '+').split('+');
+    var chips = document.createDocumentFragment();
+    var that = this;
+
+    this.items_.each(function(i) {
+      var item = $(this);
+      var opts = item.data();
+      that.data_.chips[opts.filterValue] = opts.filterName;
+
+      var checkbox = $(ITEM_STR_.replace(/\{\{name\}\}/g, opts.filterName)
+        .replace(/\{\{value\}\}/g, opts.filterValue)
+        .replace(/\{\{id\}\}/g, 'filter-' + id + '-' + (i + 1)));
+
+      if (initiallyCheckedValues.indexOf(opts.filterValue) > -1) {
+        checkbox[0].checked = true;
+        chips.appendChild(that.chipForItem(item));
+      }
+
+      item.append(checkbox);
+    });
+
+    this.chipsEl_.append(chips);
+  };
+
+  /**
+   * Initialize the Filter view
+   */
+  Filter.prototype.initUi = function() {
+    // Cache DOM elements
+    this.chipsEl_ = this.el.find('[data-' + this.options.chipsDataAttr + ']');
+    this.countEl_ = this.el.find('[data-' + this.options.countDataAttr + ']');
+    this.tabViewEl_ = this.el.find('[data-' + this.options.tabViewDataAttr + ']');
+    this.items_ = this.el.find('[data-' + this.options.nameDataAttr + ']');
+
+    // Setup UI
+    this.draw_(this.data_.all);
+    this.activateInitialFilters_();
+    this.setEventListeners_();
+  };
+
+  /**
+   * @returns {[types|Array, tags|Array, category|Array]}
+   */
+  Filter.prototype.getActiveClauses = function() {
+    var tags = [];
+    var types = [];
+    var categories = [];
+
+    this.items_.find(':checked').each(function(i, checkbox) {
+      // Currently, there is implicit business logic here that `tag` is AND'ed together
+      // while `type` is OR'ed. So , and + do the same thing here. It would be great to
+      // reuse the same query engine for filters, but it would need more powerful syntax.
+      // Probably parenthesis, to support "tag:dog + tag:cat + (type:video, type:blog)"
+      var expression = $(checkbox).val();
+      var regex = /(\w+):(\w+)/g;
+      var match;
+
+      while (match = regex.exec(expression)) {
+        switch (match[1]) {
+          case 'category':
+            categories.push(match[2]);
+            break;
+          case 'tag':
+            tags.push(match[2]);
+            break;
+          case 'type':
+            types.push(match[2]);
+            break;
+        }
+      }
+    });
+
+    return [types, tags, categories];
+  };
+
+  /**
+   * Actual filtering logic.
+   * @returns {Array}
+   */
+  Filter.prototype.filteredResources = function() {
+    var data = this.getActiveClauses();
+    var types = data[0];
+    var tags = data[1];
+    var categories = data[2];
+    var resources = [];
+    var resource = {};
+    var tag = '';
+    var shouldAddResource = true;
+
+    for (var resourceIndex = 0; resourceIndex < this.data_.all.length; resourceIndex++) {
+      resource = this.data_.all[resourceIndex];
+      shouldAddResource = types.indexOf(resource.type) > -1;
+
+      if (categories && categories.length > 0) {
+        shouldAddResource = shouldAddResource && categories.indexOf(resource.category) > -1;
+      }
+
+      for (var tagIndex = 0; shouldAddResource && tagIndex < tags.length; tagIndex++) {
+        tag = tags[tagIndex];
+        shouldAddResource = resource.tags.indexOf(tag) > -1;
+      }
+
+      if (shouldAddResource) {
+        resources.push(resource);
+      }
+    }
+
+    return resources;
+  };
+
+  /**
+   * Close Chip Handler
+   * @param {Event} event - Click event
+   * @private
+   */
+  Filter.prototype.closeChipHandler_ = function(event) {
+    var chip = $(event.currentTarget).parent();
+    var checkbox = chip.data('item.dac-filter').find(':first-child')[0];
+    checkbox.checked = false;
+    this.changeStateForCheckbox(checkbox);
+  };
+
+  /**
+   * Handle filter item state change.
+   * @param {Event} event - Change event
+   * @private
+   */
+  Filter.prototype.toggleCheckboxHandler_ = function(event) {
+    this.changeStateForCheckbox(event.currentTarget);
+  };
+
+  /**
+   * Redraw resource view based on new state.
+   * @param checkbox
+   */
+  Filter.prototype.changeStateForCheckbox = function(checkbox) {
+    var item = $(checkbox).parent();
+
+    if (checkbox.checked) {
+      this.chipsEl_.append(this.chipForItem(item));
+      ga('send', 'event', 'Filters', 'Check', $(checkbox).val());
+    } else {
+      item.data('chip.dac-filter').remove();
+      this.addToItemValue(item, -1);
+      ga('send', 'event', 'Filters', 'Uncheck', $(checkbox).val());
+    }
+
+    this.draw_(this.filteredResources());
+  };
+
+  /**
+   * jQuery plugin
+   */
+  $.fn.dacFilter = function() {
+    return this.each(function() {
+      var el = $(this);
+      new Filter(el, el.data());
+    });
+  };
+
+  /**
+   * Data Attribute API
+   */
+  $(function() {
+    $('[data-filter]').dacFilter();
+  });
+})(jQuery);
+
 (function($) {
   'use strict';
 
@@ -4632,97 +2631,188 @@
   });
 })(jQuery);
 
-/* global toRoot, CAROUSEL_OVERRIDE */
 (function($) {
-  // Ordering matters
-  var TAG_MAP = [
-    {from: 'developerstory', to: 'Android Developer Story'},
-    {from: 'googleplay', to: 'Google Play'}
-  ];
+  'use strict';
 
-  function DacCarouselQuery(el) {
+  /**
+   * @param {HTMLElement} el - The DOM element.
+   * @param {Object} options
+   * @constructor
+   */
+  function Crumbs(selected, options) {
+    this.options = $.extend({}, Crumbs.DEFAULTS_, options);
+    this.el = $(this.options.container);
+
+    // Do not build breadcrumbs for landing site.
+    if (!selected || location.pathname === '/index.html' || location.pathname === '/') {
+      return;
+    }
+
+    // Cache navigation resources
+    this.selected = $(selected);
+    this.selectedParent = this.selected.closest('.dac-nav-secondary').siblings('a');
+
+    // Build the breadcrumb list.
+    this.init();
+  }
+
+  Crumbs.DEFAULTS_ = {
+    container: '.dac-header-crumbs',
+    crumbItem: $('<li class="dac-header-crumbs-item">'),
+    linkClass: 'dac-header-crumbs-link'
+  };
+
+  Crumbs.prototype.init = function() {
+    Crumbs.buildCrumbForLink(this.selected.clone()).appendTo(this.el);
+
+    if (this.selectedParent.length) {
+      Crumbs.buildCrumbForLink(this.selectedParent.clone()).prependTo(this.el);
+    }
+
+    // Reveal the breadcrumbs
+    this.el.addClass('dac-has-content');
+  };
+
+  /**
+   * Build a HTML structure for a breadcrumb.
+   * @param {string} link
+   * @return {jQuery}
+   */
+  Crumbs.buildCrumbForLink = function(link) {
+    link.find('br').replaceWith(' ');
+
+    var crumbLink = $('<a>')
+      .attr('class', Crumbs.DEFAULTS_.linkClass)
+      .attr('href', link.attr('href'))
+      .text(link.text());
+
+    return Crumbs.DEFAULTS_.crumbItem.clone().append(crumbLink);
+  };
+
+  /**
+   * jQuery plugin
+   */
+  $.fn.dacCrumbs = function(options) {
+    return this.each(function() {
+      new Crumbs(this, options);
+    });
+  };
+})(jQuery);
+
+(function($) {
+  'use strict';
+
+  /**
+   * @param {HTMLElement} el - The DOM element.
+   * @param {Object} options
+   * @constructor
+   */
+  function SearchInput(el, options) {
     this.el = $(el);
+    this.options = $.extend({}, SearchInput.DEFAULTS_, options);
+    this.body = $('body');
+    this.input = this.el.find('input');
+    this.close = this.el.find(this.options.closeButton);
+    this.clear = this.el.find(this.options.clearButton);
+    this.icon = this.el.find('.' + this.options.iconClass);
+    this.init();
+  }
 
-    var opts = this.el.data();
+  SearchInput.DEFAULTS_ = {
+    activeClass: 'dac-active',
+    activeIconClass: 'dac-search',
+    closeButton: '[data-search-close]',
+    clearButton: '[data-search-clear]',
+    hiddenClass: 'dac-hidden',
+    iconClass: 'dac-header-search-icon',
+    searchModeClass: 'dac-search-mode',
+    transitionDuration: 250
+  };
+
+  SearchInput.prototype.init = function() {
+    this.input.on('focus.dac-search', this.setActiveState.bind(this))
+              .on('input.dac-search', this.checkInputValue.bind(this));
+    this.close.on('click.dac-search', this.unsetActiveStateHandler_.bind(this));
+    this.clear.on('click.dac-search', this.clearInput.bind(this));
+  };
+
+  SearchInput.prototype.setActiveState = function() {
+    var that = this;
+
+    this.clear.addClass(this.options.hiddenClass);
+    this.body.addClass(this.options.searchModeClass);
+    this.checkInputValue();
+
+    // Set icon to black after background has faded to white.
+    setTimeout(function() {
+      that.icon.addClass(that.options.activeIconClass);
+    }, this.options.transitionDuration);
+  };
+
+  SearchInput.prototype.unsetActiveStateHandler_ = function(event) {
+    event.preventDefault();
+    this.unsetActiveState();
+  };
+
+  SearchInput.prototype.unsetActiveState = function() {
+    this.icon.removeClass(this.options.activeIconClass);
+    this.clear.addClass(this.options.hiddenClass);
+    this.body.removeClass(this.options.searchModeClass);
+  };
+
+  SearchInput.prototype.clearInput = function(event) {
+    event.preventDefault();
+    this.input.val('');
+    this.clear.addClass(this.options.hiddenClass);
+  };
+
+  SearchInput.prototype.checkInputValue = function() {
+    if (this.input.val().length) {
+      this.clear.removeClass(this.options.hiddenClass);
+    } else {
+      this.clear.addClass(this.options.hiddenClass);
+    }
+  };
+
+  /**
+   * jQuery plugin
+   * @param {object} options - Override default options.
+   */
+  $.fn.dacSearchInput = function() {
+    return this.each(function() {
+      var el = $(this);
+      el.data('search-input.dac', new SearchInput(el, el.data()));
+    });
+  };
+
+  /**
+   * Data Attribute API
+   */
+  $(function() {
+    $('[data-search]').dacSearchInput();
+  });
+})(jQuery);
+
+/* global METADATA */
+(function($) {
+  function DacCarouselQuery(el) {
+    el = $(el);
+
+    var opts = el.data();
     opts.maxResults = parseInt(opts.maxResults || '100', 10);
     opts.query = opts.carouselQuery;
-    var resources = $.queryResources(opts);
+    var resources = window.metadata.query(opts);
 
-    this.el.empty();
-    $(resources).map(function() {
-      var resource = $.extend({}, this, CAROUSEL_OVERRIDE[this.url]);
-      var slide = $('<article class="dac-expand dac-hero">');
-      var image = cleanUrl(resource.heroImage || resource.image);
-      var fullBleed = image && !resource.heroColor;
-
-      // Configure background
-      slide.css({
-        backgroundImage: fullBleed ? 'url(' + image + ')' : '',
-        backgroundColor: resource.heroColor || ''
-      });
-
-      // Should copy be inverted
-      slide.toggleClass('dac-invert', resource.heroInvert || fullBleed);
-      slide.toggleClass('dac-darken', fullBleed);
-
-      // Should be clickable
-      slide.append($('<a class="dac-hero-carousel-action">').attr('href', cleanUrl(resource.url)));
-
-      var cols = $('<div class="cols dac-hero-content">');
-
-      // inline image column
-      var rightCol = $('<div class="col-1of2 col-push-1of2 dac-hero-figure">')
-        .appendTo(cols);
-
-      if (!fullBleed && image) {
-        rightCol.append($('<img>').attr('src', image));
-      }
-
-      // info column
-      $('<div class="col-1of2 col-pull-1of2">')
-        .append($('<div class="dac-hero-tag">').text(formatTag(resource)))
-        .append($('<h1 class="dac-hero-title">').text(formatTitle(resource)))
-        .append($('<p class="dac-hero-description">').text(resource.summary))
-        .append($('<a class="dac-hero-cta">')
-          .text(formatCTA(resource))
-          .attr('href', cleanUrl(resource.url))
-          .prepend($('<span class="dac-sprite dac-auto-chevron">'))
-        )
-        .appendTo(cols);
-
-      slide.append(cols.wrap('<div class="wrap">').parent());
-      return slide[0];
-    }).prependTo(this.el);
+    el.empty();
+    $(resources).each(function() {
+      var resource = $.extend({}, this, METADATA.carousel[this.url]);
+      el.dacHero(resource);
+    });
 
     // Pagination element.
-    this.el.append('<div class="dac-hero-carousel-pagination"><div class="wrap" data-carousel-pagination>');
+    el.append('<div class="dac-hero-carousel-pagination"><div class="wrap" data-carousel-pagination>');
 
-    this.el.dacCarousel();
-  }
-
-  function cleanUrl(url) {
-    if (url && url.indexOf('//') === -1) {
-      url = toRoot + url;
-    }
-    return url;
-  }
-
-  function formatTag(resource) {
-    // Hmm, need a better more scalable solution for this.
-    for (var i = 0, mapping; mapping = TAG_MAP[i]; i++) {
-      if (resource.tags.indexOf(mapping.from) > -1) {
-        return mapping.to;
-      }
-    }
-    return resource.type;
-  }
-
-  function formatTitle(resource) {
-    return resource.title.replace(/android developer story: /i, '');
-  }
-
-  function formatCTA(resource) {
-    return resource.type === 'youtube' ? 'Watch the video' : 'Learn more';
+    el.dacCarousel();
   }
 
   // jQuery plugin
@@ -4917,16 +3007,884 @@
   });
 })(jQuery);
 
+/* global toRoot */
+
+(function($) {
+  // Ordering matters
+  var TAG_MAP = [
+    {from: 'developerstory', to: 'Android Developer Story'},
+    {from: 'googleplay', to: 'Google Play'}
+  ];
+
+  function DacHero(el, resource, isSearch) {
+    var slide = $('<article>');
+    slide.addClass(isSearch ? 'dac-search-hero' : 'dac-expand dac-hero');
+    var image = cleanUrl(resource.heroImage || resource.image);
+    var fullBleed = image && !resource.heroColor;
+
+    if (!isSearch) {
+      // Configure background
+      slide.css({
+        backgroundImage: fullBleed ? 'url(' + image + ')' : '',
+        backgroundColor: resource.heroColor || ''
+      });
+
+      // Should copy be inverted
+      slide.toggleClass('dac-invert', resource.heroInvert || fullBleed);
+      slide.toggleClass('dac-darken', fullBleed);
+
+      // Should be clickable
+      slide.append($('<a class="dac-hero-carousel-action">').attr('href', cleanUrl(resource.url)));
+    }
+
+    var cols = $('<div class="cols dac-hero-content">');
+
+    // inline image column
+    var rightCol = $('<div class="col-1of2 col-push-1of2 dac-hero-figure">')
+      .appendTo(cols);
+
+    if ((!fullBleed || isSearch) && image) {
+      rightCol.append($('<img>').attr('src', image));
+    }
+
+    // info column
+    $('<div class="col-1of2 col-pull-1of2">')
+      .append($('<div class="dac-hero-tag">').text(formatTag(resource)))
+      .append($('<h1 class="dac-hero-title">').text(formatTitle(resource)))
+      .append($('<p class="dac-hero-description">').text(resource.summary))
+      .append($('<a class="dac-hero-cta">')
+        .text(formatCTA(resource))
+        .attr('href', cleanUrl(resource.url))
+        .prepend($('<span class="dac-sprite dac-auto-chevron">'))
+      )
+      .appendTo(cols);
+
+    slide.append(cols.wrap('<div class="wrap">').parent());
+    el.append(slide);
+  }
+
+  function cleanUrl(url) {
+    if (url && url.indexOf('//') === -1) {
+      url = toRoot + url;
+    }
+    return url;
+  }
+
+  function formatTag(resource) {
+    // Hmm, need a better more scalable solution for this.
+    for (var i = 0, mapping; mapping = TAG_MAP[i]; i++) {
+      if (resource.tags.indexOf(mapping.from) > -1) {
+        return mapping.to;
+      }
+    }
+    return resource.type;
+  }
+
+  function formatTitle(resource) {
+    return resource.title.replace(/android developer story: /i, '');
+  }
+
+  function formatCTA(resource) {
+    return resource.type === 'youtube' ? 'Watch the video' : 'Learn more';
+  }
+
+  // jQuery plugin
+  $.fn.dacHero = function(resource, isSearch) {
+    return this.each(function() {
+      var el = $(this);
+      return new DacHero(el, resource, isSearch);
+    });
+  };
+})(jQuery);
+
+(function($) {
+  'use strict';
+
+  function highlightString(label, query) {
+    query = query || '';
+    //query = query.replace('<wbr>', '').replace('.', '\\.');
+    var queryRE = new RegExp('(' + query + ')', 'ig');
+    return label.replace(queryRE, '<em>$1</em>');
+  }
+
+  $.fn.highlightMatches = function(query) {
+    return this.each(function() {
+      var el = $(this);
+      var label = el.html();
+      var highlighted = highlightString(label, query);
+      el.html(highlighted);
+      el.addClass('highlighted');
+    });
+  };
+})(jQuery);
+
+/**
+ * History tracking.
+ * Track visited urls in localStorage.
+ */
+(function($) {
+  var PAGES_TO_STORE_ = 100;
+  var MIN_NUMBER_OF_PAGES_TO_DISPLAY_ = 6;
+  var CONTAINER_SELECTOR_ = '.dac-search-results-history-wrap';
+
+  /**
+   * Generate resource cards for visited pages.
+   * @param {HTMLElement} el
+   * @constructor
+   */
+  function HistoryQuery(el) {
+    this.el = $(el);
+
+    // Only show history component if enough pages have been visited.
+    if (getVisitedPages().length < MIN_NUMBER_OF_PAGES_TO_DISPLAY_) {
+      this.el.closest(CONTAINER_SELECTOR_).addClass('dac-hidden');
+      return;
+    }
+
+    // Rename query
+    this.el.data('query', this.el.data('history-query'));
+
+    // jQuery method to populate cards.
+    this.el.resourceWidget();
+  }
+
+  /**
+   * Fetch from localStorage an array of visted pages
+   * @returns {Array}
+   */
+  function getVisitedPages() {
+    var visited = localStorage.getItem('visited-pages');
+    return visited ? JSON.parse(visited) : [];
+  }
+
+  /**
+   * Return a page corresponding to cuurent pathname. If none exists, create one.
+   * @param {Array} pages
+   * @param {String} path
+   * @returns {Object} Page
+   */
+  function getPageForPath(pages, path) {
+    var page;
+
+    // Backwards lookup for current page, last pages most likely to be visited again.
+    for (var i = pages.length - 1; i >= 0; i--) {
+      if (pages[i].path === path) {
+        page = pages[i];
+
+        // Remove page object from pages list to ensure correct ordering.
+        pages.splice(i, 1);
+
+        return page;
+      }
+    }
+
+    // If storage limit is exceeded, remove last visited path.
+    if (pages.length >= PAGES_TO_STORE_) {
+      pages.shift();
+    }
+
+    return {path: path};
+  }
+
+  /**
+   * Add current page to back of visited array, increase hit count by 1.
+   */
+  function addCurrectPage() {
+    var path = location.pathname;
+
+    // Do not track frontpage visits.
+    if (path === '/' || path === '/index.html') {return;}
+
+    var pages = getVisitedPages();
+    var page = getPageForPath(pages, path);
+
+    // New page visits have no hit count.
+    page.hit = ~~page.hit + 1;
+
+    // Most recently visted pages are located at the end of the visited array.
+    pages.push(page);
+
+    localStorage.setItem('visited-pages', JSON.stringify(pages));
+  }
+
+  /**
+   * Hit count compare function.
+   * @param {Object} a - page
+   * @param {Object} b - page
+   * @returns {number}
+   */
+  function byHit(a, b) {
+    if (a.hit > b.hit) {
+      return -1;
+    } else if (a.hit < b.hit) {
+      return 1;
+    }
+
+    return 0;
+  }
+
+  /**
+   * Return a list of visited urls in a given order.
+   * @param {String} order - (recent|most-visited)
+   * @returns {Array}
+   */
+  $.dacGetVisitedUrls = function(order) {
+    var pages = getVisitedPages();
+
+    if (order === 'recent') {
+      pages.reverse();
+    } else {
+      pages.sort(byHit);
+    }
+
+    return pages.map(function(page) {
+      return page.path.replace(/^\//, '');
+    });
+  };
+
+  // jQuery plugin
+  $.fn.dacHistoryQuery = function() {
+    return this.each(function() {
+      var el = $(this);
+      var data = el.data('dac.recentlyVisited');
+
+      if (!data) {
+        el.data('dac.recentlyVisited', (data = new HistoryQuery(el)));
+      }
+    });
+  };
+
+  $(function() {
+    $('[data-history-query]').dacHistoryQuery();
+    // Do not block page rendering.
+    setTimeout(addCurrectPage, 0);
+  });
+})(jQuery);
+
+/* ############################################ */
+/* ##########     LOCALIZATION     ############ */
+/* ############################################ */
+/**
+ * Global helpers.
+ */
+function getBaseUri(uri) {
+  var intlUrl = (uri.substring(0, 6) === '/intl/');
+  if (intlUrl) {
+    var base = uri.substring(uri.indexOf('intl/') + 5, uri.length);
+    base = base.substring(base.indexOf('/') + 1, base.length);
+    return '/' + base;
+  } else {
+    return uri;
+  }
+}
+
+function changeLangPref(targetLang, submit) {
+  window.writeCookie('pref_lang', targetLang, null);
+//DD
+  $('#language').find('option[value="' + targetLang + '"]').attr('selected', true);
+  //  #######  TODO:  Remove this condition once we're stable on devsite #######
+  //  This condition is only needed if we still need to support legacy GAE server
+  if (window.devsite) {
+    // Switch language when on Devsite server
+    if (submit) {
+      $('#setlang').submit();
+    }
+  } else {
+    // Switch language when on legacy GAE server
+    if (submit) {
+      window.location = getBaseUri(location.pathname);
+    }
+  }
+}
+// Redundant usage to appease jshint.
+window.changeLangPref = changeLangPref;
+
+(function() {
+  /**
+   * Whitelisted locales. Should match choices in language dropdown. Repeated here
+   * as a lot of i18n logic happens before page load and dropdown is ready.
+   */
+  var LANGUAGES = [
+    'en',
+    'es',
+    'in',
+    'ja',
+    'ko',
+    'pt-br',
+    'ru',
+    'vi',
+    'zh-cn',
+    'zh-tw'
+  ];
+
+  /**
+   * Master list of translated strings for template files.
+   */
+  var PHRASES = {
+    'newsletter': {
+      'title': 'Get the latest Android developer news and tips that will help you find success on Google Play.',
+      'requiredHint': '* Required Fields',
+      'name': 'Full name',
+      'email': 'Email address',
+      'company': 'Company / developer name',
+      'appUrl': 'One of your Play Store app URLs',
+      'business': {
+        'label': 'Which best describes your business:',
+        'apps': 'Apps',
+        'games': 'Games',
+        'both': 'Apps & Games'
+      },
+      'confirmMailingList': 'Add me to the mailing list for the monthly newsletter and occasional emails about ' +
+                            'development and Google Play opportunities.',
+      'privacyPolicy': 'I acknowledge that the information provided in this form will be subject to Google\'s ' +
+                       '<a href="https://www.google.com/policies/privacy/" target="_blank">privacy policy</a>.',
+      'languageVal': 'English',
+      'successTitle': 'Hooray!',
+      'successDetails': 'You have successfully signed up for the latest Android developer news and tips.',
+      'languageValTarget': {
+        'en': 'English',
+        'ar': 'Arabic (العربيّة)',
+        'in': 'Indonesian (Bahasa)',
+        'fr': 'French (français)',
+        'de': 'German (Deutsch)',
+        'ja': 'Japanese (日本語)',
+        'ko': 'Korean (한국어)',
+        'ru': 'Russian (Русский)',
+        'es': 'Spanish (español)',
+        'th': 'Thai (ภาษาไทย)',
+        'tr': 'Turkish (Türkçe)',
+        'vi': 'Vietnamese (tiếng Việt)',
+        'pt-br': 'Brazilian Portuguese (Português Brasileiro)',
+        'zh-cn': 'Simplified Chinese (简体中文)',
+        'zh-tw': 'Traditional Chinese (繁體中文)',
+      },
+      'resetLangTitle': "Browse this site in %{targetLang}?",
+      'resetLangTextIntro': 'You requested a page in %{targetLang}, but your language preference for this site is %{lang}.',
+      'resetLangTextCta': 'Would you like to change your language preference and browse this site in %{targetLang}? ' +
+                          'If you want to change your language preference later, use the language menu at the bottom of each page.',
+      'resetLangButtonYes': 'Change Language',
+      'resetLangButtonNo': 'Not Now'
+    }
+  };
+
+  /**
+   * Current locale.
+   */
+  var locale = (function() {
+    var lang = window.readCookie('pref_lang');
+    if (lang === 0 || LANGUAGES.indexOf(lang) === -1) {
+      lang = 'en';
+    }
+    return lang;
+  })();
+  var localeTarget = (function() {
+    var localeTarget = locale;
+    if (window.devsite) {
+      if (getQueryVariable('hl')) {
+        var target = getQueryVariable('hl');
+        if (!(target === 0) || (LANGUAGES.indexOf(target) === -1)) {
+          localeTarget = target;
+        }
+      }
+    } else {
+      if (location.pathname.substring(0,6) == "/intl/") {
+        var target = location.pathname.split('/')[2];
+        if (!(target === 0) || (LANGUAGES.indexOf(target) === -1)) {
+          localeTarget = target;
+        }
+      }
+    }
+
+    return localeTarget;
+  })();
+
+  /**
+   * Global function shims for backwards compatibility
+   */
+  window.changeNavLang = function() {
+    // Already done.
+  };
+
+  window.loadLangPref = function() {
+    // Languages pref already loaded.
+  };
+
+  window.getLangPref = function() {
+    return locale;
+  };
+
+  window.getLangTarget = function() {
+    return localeTarget;
+  };
+
+  // Expose polyglot instance for advanced localization.
+  var polyglot = window.polyglot = new window.Polyglot({
+    locale: locale,
+    phrases: PHRASES
+  });
+
+  // When DOM is ready.
+  $(function() {
+    // Mark current locale in language picker.
+    $('#language').find('option[value="' + locale + '"]').attr('selected', true);
+
+    $('html').dacTranslate().on('dac:domchange', function(e) {
+      $(e.target).dacTranslate();
+    });
+  });
+
+  $.fn.dacTranslate = function() {
+    // Translate strings in template markup:
+
+    // OLD
+    // Having all translations in HTML does not scale well and bloats every page.
+    // Need to migrate this to data-l JS translations below.
+    if (locale !== 'en') {
+      var $links = this.find('a[' + locale + '-lang]');
+      $links.each(function() { // for each link with a translation
+        var $link = $(this);
+        // put the desired language from the attribute as the text
+        $link.text($link.attr(locale + '-lang'));
+      });
+    }
+
+    // NEW
+    // A simple declarative api for JS translations. Feel free to extend as appropriate.
+
+    // Miscellaneous string compilations
+    // Build full strings from localized substrings:
+    var myLocaleTarget = window.getLangTarget();
+    var myTargetLang = window.polyglot.t("newsletter.languageValTarget." + myLocaleTarget);
+    var myLang = window.polyglot.t("newsletter.languageVal");
+    var myTargetLangTitleString = window.polyglot.t("newsletter.resetLangTitle", {targetLang: myTargetLang});
+    var myResetLangTextIntro = window.polyglot.t("newsletter.resetLangTextIntro", {targetLang: myTargetLang, lang: myLang});
+    var myResetLangTextCta = window.polyglot.t("newsletter.resetLangTextCta", {targetLang: myTargetLang});
+    //var myResetLangButtonYes = window.polyglot.t("newsletter.resetLangButtonYes", {targetLang: myTargetLang});
+
+    // Inject strings as text values in dialog components:
+    $("#langform .dac-modal-header-title").text(myTargetLangTitleString);
+    $("#langform #resetLangText").text(myResetLangTextIntro);
+    $("#langform #resetLangCta").text(myResetLangTextCta);
+    //$("#resetLangButtonYes").attr("data-t", window.polyglot.t(myResetLangButtonYes));
+
+    // Text: <div data-t="nav.home"></div>
+    // HTML: <div data-t="privacy" data-t-html></html>
+    this.find('[data-t]').each(function() {
+      var el = $(this);
+      var data = el.data();
+      if (data.t) {
+        el[data.tHtml === '' ? 'html' : 'text'](polyglot.t(data.t));
+      }
+    });
+
+    return this;
+  };
+})();
+/* ##########     END LOCALIZATION     ############ */
+
+// Translations. These should eventually be moved into language-specific files and loaded on demand.
+// jshint nonbsp:false
+switch (window.getLangPref()) {
+  case 'ar':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Google Play. يمكنك الحصول على آخر الأخبار والنصائح من مطوّري تطبيقات Android، مما يساعدك ' +
+          'على تحقيق النجاح على',
+        'requiredHint': '* حقول مطلوبة',
+        'name': '. الاسم بالكامل ',
+        'email': '. عنوان البريد الإلكتروني ',
+        'company': '. اسم الشركة / اسم مطوّر البرامج',
+        'appUrl': '. أحد عناوين URL لتطبيقاتك في متجر Play',
+        'business': {
+          'label': '. ما العنصر الذي يوضح طبيعة نشاطك التجاري بدقة؟ ',
+          'apps': 'التطبيقات',
+          'games': 'الألعاب',
+          'both': 'التطبيقات والألعاب'
+        },
+        'confirmMailingList': 'إضافتي إلى القائمة البريدية للنشرة الإخبارية الشهرية والرسائل الإلكترونية التي يتم' +
+          ' إرسالها من حين لآخر بشأن التطوير وفرص Google Play.',
+        'privacyPolicy': 'أقر بأن المعلومات المقدَّمة في هذا النموذج تخضع لسياسة خصوصية ' +
+          '<a href="https://www.google.com/intl/ar/policies/privacy/" target="_blank">Google</a>.',
+        'languageVal': 'Arabic (العربيّة)',
+        'successTitle': 'رائع!',
+        'successDetails': 'لقد اشتركت بنجاح للحصول على آخر الأخبار والنصائح من مطوّري برامج Android.'
+      }
+    });
+    break;
+  case 'zh-cn':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': '获取最新的 Android 开发者资讯和提示，助您在 Google Play 上取得成功。',
+        'requiredHint': '* 必填字段',
+        'name': '全名',
+        'email': '电子邮件地址',
+        'company': '公司/开发者名称',
+        'appUrl': '您的某个 Play 商店应用网址',
+        'business': {
+          'label': '哪一项能够最准确地描述您的业务？',
+          'apps': '应用',
+          'games': '游戏',
+          'both': '应用和游戏'
+        },
+        'confirmMailingList': '将我添加到邮寄名单，以便接收每月简报以及不定期发送的关于开发和 Google Play 商机的电子邮件。',
+        'privacyPolicy': '我确认自己了解在此表单中提供的信息受 <a href="https://www.google.com/intl/zh-CN/' +
+        'policies/privacy/" target="_blank">Google</a> 隐私权政策的约束。',
+        'languageVal': 'Simplified Chinese (简体中文)',
+        'successTitle': '太棒了！',
+        'successDetails': '您已成功订阅最新的 Android 开发者资讯和提示。'
+      }
+    });
+    break;
+  case 'zh-tw':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': '獲得 Android 開發人員的最新消息和各項秘訣，讓您在 Google Play 上輕鬆邁向成功之路。',
+        'requiredHint': '* 必要欄位',
+        'name': '全名',
+        'email': '電子郵件地址',
+        'company': '公司/開發人員名稱',
+        'appUrl': '您其中一個 Play 商店應用程式的網址',
+        'business': {
+          'label': '為您的商家選取最合適的產品類別。',
+          'apps': '應用程式',
+          'games': '遊戲',
+          'both': '應用程式和遊戲'
+        },
+        'confirmMailingList': '我想加入 Google Play 的郵寄清單，以便接收每月電子報和 Google Play 不定期寄送的電子郵件，' +
+          '瞭解關於開發和 Google Play 商機的資訊。',
+        'privacyPolicy': '我瞭解，我在這張表單中提供的資訊將受到 <a href="' +
+        'https://www.google.com/intl/zh-TW/policies/privacy/" target="_blank">Google</a> 隱私權政策.',
+        'languageVal': 'Traditional Chinese (繁體中文)',
+        'successTitle': '太棒了！',
+        'successDetails': '您已經成功訂閱 Android 開發人員的最新消息和各項秘訣。'
+      }
+    });
+    break;
+  case 'fr':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Recevez les dernières actualités destinées aux développeurs Android, ainsi que des conseils qui ' +
+          'vous mèneront vers le succès sur Google Play.',
+        'requiredHint': '* Champs obligatoires',
+        'name': 'Nom complet',
+        'email': 'Adresse e-mail',
+        'company': 'Nom de la société ou du développeur',
+        'appUrl': 'Une de vos URL Play Store',
+        'business': {
+          'label': 'Quelle option décrit le mieux votre activité ?',
+          'apps': 'Applications',
+          'games': 'Jeux',
+          'both': 'Applications et jeux'
+        },
+        'confirmMailingList': 'Ajoutez-moi à la liste de diffusion de la newsletter mensuelle et tenez-moi informé ' +
+          'par des e-mails occasionnels de l\'évolution et des opportunités de Google Play.',
+        'privacyPolicy': 'Je comprends que les renseignements fournis dans ce formulaire seront soumis aux <a href="' +
+        'https://www.google.com/intl/fr/policies/privacy/" target="_blank">règles de confidentialité</a> de Google.',
+        'languageVal': 'French (français)',
+        'successTitle': 'Super !',
+        'successDetails': 'Vous êtes bien inscrit pour recevoir les actualités et les conseils destinés aux ' +
+          'développeurs Android.'
+      }
+    });
+    break;
+  case 'de':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Abonniere aktuelle Informationen und Tipps für Android-Entwickler und werde noch erfolgreicher ' +
+          'bei Google Play.',
+        'requiredHint': '* Pflichtfelder',
+        'name': 'Vollständiger Name',
+        'email': 'E-Mail-Adresse',
+        'company': 'Unternehmens-/Entwicklername',
+        'appUrl': 'Eine der URLs deiner Play Store App',
+        'business': {
+          'label': 'Welche der folgenden Kategorien beschreibt dein Unternehmen am besten?',
+          'apps': 'Apps',
+          'games': 'Spiele',
+          'both': 'Apps und Spiele'
+        },
+        'confirmMailingList': 'Meine E-Mail-Adresse soll zur Mailingliste hinzugefügt werden, damit ich den ' +
+          'monatlichen Newsletter sowie gelegentlich E-Mails zu Entwicklungen und Optionen bei Google Play erhalte.',
+        'privacyPolicy': 'Ich bestätige, dass die in diesem Formular bereitgestellten Informationen gemäß der ' +
+          '<a href="https://www.google.com/intl/de/policies/privacy/" target="_blank">Datenschutzerklärung</a> von ' +
+          'Google verwendet werden dürfen.',
+        'languageVal': 'German (Deutsch)',
+        'successTitle': 'Super!',
+        'successDetails': 'Du hast dich erfolgreich angemeldet und erhältst jetzt aktuelle Informationen und Tipps ' +
+          'für Android-Entwickler.'
+      }
+    });
+    break;
+  case 'in':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Receba as dicas e as notícias mais recentes para os desenvolvedores Android e seja bem-sucedido ' +
+        'no Google Play.',
+        'requiredHint': '* Bidang Wajib Diisi',
+        'name': 'Nama lengkap',
+        'email': 'Alamat email',
+        'company': 'Nama pengembang / perusahaan',
+        'appUrl': 'Salah satu URL aplikasi Play Store Anda',
+        'business': {
+          'label': 'Dari berikut ini, mana yang paling cocok dengan bisnis Anda?',
+          'apps': 'Aplikasi',
+          'games': 'Game',
+          'both': 'Aplikasi dan Game'
+        },
+        'confirmMailingList': 'Tambahkan saya ke milis untuk mendapatkan buletin bulanan dan email sesekali mengenai ' +
+          'perkembangan dan kesempatan yang ada di Google Play.',
+        'privacyPolicy': 'Saya memahami bahwa informasi yang diberikan dalam formulir ini tunduk pada <a href="' +
+        'https://www.google.com/intl/in/policies/privacy/" target="_blank">kebijakan privasi</a> Google.',
+        'languageVal': 'Indonesian (Bahasa)',
+        'successTitle': 'Hore!',
+        'successDetails': 'Anda berhasil mendaftar untuk kiat dan berita pengembang Android terbaru.'
+      }
+    });
+    break;
+  case 'it':
+    //window.polyglot.extend({
+    //  'newsletter': {
+    //    'title': 'Receba as dicas e as notícias mais recentes para os desenvolvedores Android e seja bem-sucedido ' +
+    //    'no Google Play.',
+    //    'requiredHint': '* Campos obrigatórios',
+    //    'name': 'Nome completo',
+    //    'email': 'Endereço de Email',
+    //    'company': 'Nome da empresa / do desenvolvedor',
+    //    'appUrl': 'URL de um dos seus apps da Play Store',
+    //    'business': {
+    //      'label': 'Qual das seguintes opções melhor descreve sua empresa?',
+    //      'apps': 'Apps',
+    //      'games': 'Jogos',
+    //      'both': 'Apps e Jogos'
+    //    },
+    //    'confirmMailingList': 'Inscreva-me na lista de e-mails para que eu receba o boletim informativo mensal, ' +
+    //    'bem como e-mails ocasionais sobre o desenvolvimento e as oportunidades do Google Play.',
+    //    'privacyPolicy': 'Reconheço que as informações fornecidas neste formulário estão sujeitas à <a href="' +
+    //    'https://www.google.com.br/policies/privacy/" target="_blank">Política de Privacidade</a> do Google.',
+    //    'languageVal': 'Italian (italiano)',
+    //    'successTitle': 'Uhu!',
+    //    'successDetails': 'Você se inscreveu para receber as notícias e as dicas mais recentes para os ' +
+    //    'desenvolvedores Android.',
+    //  }
+    //});
+    break;
+  case 'ja':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Google Play での成功に役立つ Android デベロッパー向けの最新ニュースやおすすめの情報をお届けします。',
+        'requiredHint': '* 必須',
+        'name': '氏名',
+        'email': 'メールアドレス',
+        'company': '会社名 / デベロッパー名',
+        'appUrl': 'Play ストア アプリの URL（いずれか 1 つ）',
+        'business': {
+          'label': 'お客様のビジネスに最もよく当てはまるものをお選びください。',
+          'apps': 'アプリ',
+          'games': 'ゲーム',
+          'both': 'アプリとゲーム'
+        },
+        'confirmMailingList': '開発や Google Play の最新情報に関する毎月発行のニュースレターや不定期発行のメールを受け取る',
+        'privacyPolicy': 'このフォームに入力した情報に <a href="https://www.google.com/intl/ja/policies/privacy/" ' +
+          'target="_blank">Google</a> のプライバシー ポリシーが適用',
+        'languageVal': 'Japanese (日本語)',
+        'successTitle': '完了です！',
+        'successDetails': 'Android デベロッパー向けの最新ニュースやおすすめの情報の配信登録が完了しました。'
+      }
+    });
+    break;
+  case 'ko':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Google Play에서 성공을 거두는 데 도움이 되는 최신 Android 개발자 소식 및 도움말을 받아 보세요.',
+        'requiredHint': '* 필수 입력란',
+        'name': '이름',
+        'email': '이메일 주소',
+        'company': '회사/개발자 이름',
+        'appUrl': 'Play 스토어 앱 URL 중 1개',
+        'business': {
+          'label': '다음 중 내 비즈니스를 가장 잘 설명하는 단어는 무엇인가요?',
+          'apps': '앱',
+          'games': '게임',
+          'both': '앱 및 게임'
+        },
+        'confirmMailingList': '개발 및 Google Play 관련 소식에 관한 월별 뉴스레터 및 비정기 이메일을 받아보겠습니다.',
+        'privacyPolicy': '이 양식에 제공한 정보는 <a href="https://www.google.com/intl/ko/policies/privacy/" ' +
+          'target="_blank">Google의</a> 개인정보취급방침에 따라 사용됨을',
+        'languageVal':'Korean (한국어)',
+        'successTitle': '축하합니다!',
+        'successDetails': '최신 Android 개발자 뉴스 및 도움말을 받아볼 수 있도록 가입을 완료했습니다.'
+      }
+    });
+    break;
+  case 'pt-br':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Receba as dicas e as notícias mais recentes para os desenvolvedores Android e seja bem-sucedido ' +
+        'no Google Play.',
+        'requiredHint': '* Campos obrigatórios',
+        'name': 'Nome completo',
+        'email': 'Endereço de Email',
+        'company': 'Nome da empresa / do desenvolvedor',
+        'appUrl': 'URL de um dos seus apps da Play Store',
+        'business': {
+          'label': 'Qual das seguintes opções melhor descreve sua empresa?',
+          'apps': 'Apps',
+          'games': 'Jogos',
+          'both': 'Apps e Jogos'
+        },
+        'confirmMailingList': 'Inscreva-me na lista de e-mails para que eu receba o boletim informativo mensal, ' +
+        'bem como e-mails ocasionais sobre o desenvolvimento e as oportunidades do Google Play.',
+        'privacyPolicy': 'Reconheço que as informações fornecidas neste formulário estão sujeitas à <a href="' +
+        'https://www.google.com.br/policies/privacy/" target="_blank">Política de Privacidade</a> do Google.',
+        'languageVal': 'Brazilian Portuguese (Português Brasileiro)',
+        'successTitle': 'Uhu!',
+        'successDetails': 'Você se inscreveu para receber as notícias e as dicas mais recentes para os ' +
+        'desenvolvedores Android.'
+      }
+    });
+    break;
+  case 'ru':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Хотите получать последние новости и советы для разработчиков Google Play? Заполните эту форму.',
+        'requiredHint': '* Обязательные поля',
+        'name': 'Полное имя',
+        'email': 'Адрес электронной почты',
+        'company': 'Название компании или имя разработчика',
+        'appUrl': 'Ссылка на любое ваше приложение в Google Play',
+        'business': {
+          'label': 'Что вы создаете?',
+          'apps': 'Приложения',
+          'games': 'Игры',
+          'both': 'Игры и приложения'
+        },
+        'confirmMailingList': 'Я хочу получать ежемесячную рассылку для разработчиков и другие полезные новости ' +
+          'Google Play.',
+        'privacyPolicy': 'Я предоставляю эти данные в соответствии с <a href="' +
+          'https://www.google.com/intl/ru/policies/privacy/" target="_blank">Политикой конфиденциальности</a> Google.',
+        'languageVal': 'Russian (Русский)',
+        'successTitle': 'Поздравляем!',
+        'successDetails': 'Теперь вы подписаны на последние новости и советы для разработчиков Android.'
+      }
+    });
+    break;
+  case 'es':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Recibe las últimas noticias y sugerencias para programadores de Android y logra tener éxito en ' +
+          'Google Play.',
+        'requiredHint': '* Campos obligatorios',
+        'name': 'Dirección de correo electrónico',
+        'email': 'Endereço de Email',
+        'company': 'Nombre de la empresa o del programador',
+        'appUrl': 'URL de una de tus aplicaciones de Play Store',
+        'business': {
+          'label': '¿Qué describe mejor a tu empresa?',
+          'apps': 'Aplicaciones',
+          'games': 'Juegos',
+          'both': 'Juegos y aplicaciones'
+        },
+        'confirmMailingList': 'Deseo unirme a la lista de distribución para recibir el boletín informativo mensual ' +
+          'y correos electrónicos ocasionales sobre desarrollo y oportunidades de Google Play.',
+        'privacyPolicy': 'Acepto que la información que proporcioné en este formulario cumple con la <a href="' +
+        'https://www.google.com/intl/es/policies/privacy/" target="_blank">política de privacidad</a> de Google.',
+        'languageVal': 'Spanish (español)',
+        'successTitle': '¡Felicitaciones!',
+        'successDetails': 'El registro para recibir las últimas noticias y sugerencias para programadores de Android ' +
+          'se realizó correctamente.'
+      }
+    });
+    break;
+  case 'th':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'รับข่าวสารล่าสุดสำหรับนักพัฒนาซอฟต์แวร์ Android ตลอดจนเคล็ดลับที่จะช่วยให้คุณประสบความสำเร็จบน ' +
+          'Google Play',
+        'requiredHint': '* ช่องที่ต้องกรอก',
+        'name': 'ชื่อและนามสกุล',
+        'email': 'ที่อยู่อีเมล',
+        'company': 'ชื่อบริษัท/นักพัฒนาซอฟต์แวร์',
+        'appUrl': 'URL แอปใดแอปหนึ่งของคุณใน Play สโตร์',
+        'business': {
+          'label': 'ข้อใดตรงกับธุรกิจของคุณมากที่สุด',
+          'apps': 'แอป',
+          'games': 'เกม',
+          'both': 'แอปและเกม'
+        },
+        'confirmMailingList': 'เพิ่มฉันลงในรายชื่ออีเมลเพื่อรับจดหมายข่าวรายเดือนและอีเมลเป็นครั้งคราวเกี่ยวกับก' +
+          'ารพัฒนาซอฟต์แวร์และโอกาสใน Google Play',
+        'privacyPolicy': 'ฉันรับทราบว่าข้อมูลที่ให้ไว้ในแบบฟอร์มนี้จะเป็นไปตามนโยบายส่วนบุคคลของ ' +
+          '<a href="https://www.google.com/intl/th/policies/privacy/" target="_blank">Google</a>',
+        'languageVal': 'Thai (ภาษาไทย)',
+        'successTitle': 'ไชโย!',
+        'successDetails': 'คุณลงชื่อสมัครรับข่าวสารและเคล็ดลับล่าสุดสำหรับนักพัฒนาซอฟต์แวร์ Android เสร็จเรียบร้อยแล้ว'
+      }
+    });
+    break;
+  case 'tr':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Google Play\'de başarılı olmanıza yardımcı olacak en son Android geliştirici haberleri ve ipuçları.',
+        'requiredHint': '* Zorunlu Alanlar',
+        'name': 'Tam ad',
+        'email': 'E-posta adresi',
+        'company': 'Şirket / geliştirici adı',
+        'appUrl': 'Play Store uygulama URL\'lerinizden biri',
+        'business': {
+          'label': 'İşletmenizi en iyi hangisi tanımlar?',
+          'apps': 'Uygulamalar',
+          'games': 'Oyunlar',
+          'both': 'Uygulamalar ve Oyunlar'
+        },
+        'confirmMailingList': 'Beni, geliştirme ve Google Play fırsatlarıyla ilgili ara sıra gönderilen e-posta ' +
+          'iletilerine ilişkin posta listesine ve aylık haber bültenine ekle.',
+        'privacyPolicy': 'Bu formda sağlanan bilgilerin Google\'ın ' +
+          '<a href="https://www.google.com/intl/tr/policies/privacy/" target="_blank">Gizlilik Politikası\'na</a> ' +
+          'tabi olacağını kabul ediyorum.',
+        'languageVal': 'Turkish (Türkçe)',
+        'successTitle': 'Yaşasın!',
+        'successDetails': 'En son Android geliştirici haberleri ve ipuçlarına başarıyla kaydoldunuz.'
+      }
+    });
+    break;
+  case 'vi':
+    window.polyglot.extend({
+      'newsletter': {
+        'title': 'Nhận tin tức và mẹo mới nhất dành cho nhà phát triển Android sẽ giúp bạn tìm thấy thành công trên ' +
+          'Google Play.',
+        'requiredHint': '* Các trường bắt buộc',
+        'name': 'Tên đầy đủ',
+        'email': 'Địa chỉ email',
+        'company': 'Tên công ty/nhà phát triển',
+        'appUrl': 'Một trong số các URL ứng dụng trên cửa hàng Play của bạn',
+        'business': {
+          'label': 'Lựa chọn nào sau đây mô tả chính xác nhất doanh nghiệp của bạn?',
+          'apps': 'Ứng dụng',
+          'games': 'Trò chơi',
+          'both': 'Ứng dụng và trò chơi'
+        },
+        'confirmMailingList': 'Thêm tôi vào danh sách gửi thư cho bản tin hàng tháng và email định kỳ về việc phát ' +
+          'triển và cơ hội của Google Play.',
+        'privacyPolicy': 'Tôi xác nhận rằng thông tin được cung cấp trong biểu mẫu này tuân thủ chính sách bảo mật ' +
+          'của <a href="https://www.google.com/intl/vi/policies/privacy/" target="_blank">Google</a>.',
+        'languageVal': 'Vietnamese (tiếng Việt)',
+        'successTitle': 'Thật tuyệt!',
+        'successDetails': 'Bạn đã đăng ký thành công nhận tin tức và mẹo mới nhất dành cho nhà phát triển của Android.'
+      }
+    });
+    break;
+}
+
 (function($) {
   'use strict';
 
   function Modal(el, options) {
     this.el = $(el);
-    this.options = $.extend({}, ToggleModal.DEFAULTS_, options);
+    this.options = $.extend({}, options);
     this.isOpen = false;
 
     this.el.on('click', function(event) {
-      if (!$.contains($('.dac-modal-window')[0], event.target)) {
+      if (!$.contains(this.el.find('.dac-modal-window')[0], event.target)) {
         return this.el.trigger('modal-close');
       }
     }.bind(this));
@@ -4957,19 +3915,14 @@
     this.isOpen = true;
   };
 
-  function ToggleModal(el, options) {
-    this.el = $(el);
-    this.options = $.extend({}, ToggleModal.DEFAULTS_, options);
-    this.modal = this.options.modalToggle ? $('[data-modal="' + this.options.modalToggle + '"]') :
-      this.el.closest('[data-modal]');
-
-    this.el.on('click', this.clickHandler_.bind(this));
-  }
-
-  ToggleModal.prototype.clickHandler_ = function(event) {
+  function onClickToggleModal(event) {
     event.preventDefault();
-    this.modal.trigger('modal-toggle');
-  };
+    var toggle = $(event.currentTarget);
+    var options = toggle.data();
+    var modal = options.modalToggle ? $('[data-modal="' + options.modalToggle + '"]') :
+      toggle.closest('[data-modal]');
+    modal.trigger('modal-toggle');
+  }
 
   /**
    * jQuery plugin
@@ -4995,71 +3948,626 @@
       $(this).dacModal($(this).data());
     });
 
-    $('[data-modal-toggle]').each(function() {
-      $(this).dacToggleModal($(this).data());
-    });
+    $('html').on('click.modal', '[data-modal-toggle]', onClickToggleModal);
+
+    // Check if url anchor is targetting a toggle to open the modal.
+    if (location.hash) {
+      $(location.hash + '[data-modal-toggle]').trigger('click');
+    }
+
+    if (window.getLangTarget() !== window.getLangPref()) {
+          $('#langform').trigger('modal-open');
+          $("#langform button.yes").attr("onclick","window.changeLangPref('" + window.getLangTarget() + "', true);  return false;");
+          $("#langform button.no").attr("onclick","window.changeLangPref('" + window.getLangPref() + "', true); return false;");
+    }
   });
 })(jQuery);
 
+/* Fullscreen - Toggle fullscreen mode for reference pages */
+(function($) {
+  'use strict';
+
+  /**
+   * @param {HTMLElement} el - The DOM element.
+   * @constructor
+   */
+  function Fullscreen(el) {
+    this.el = $(el);
+    this.html = $('html');
+    this.icon = this.el.find('.dac-sprite');
+    this.isFullscreen = window.readCookie(Fullscreen.COOKIE_) === 'true';
+    this.activate_();
+    this.el.on('click.dac-fullscreen', this.toggleHandler_.bind(this));
+  }
+
+  /**
+   * Cookie name for storing the state
+   * @type {string}
+   * @private
+   */
+  Fullscreen.COOKIE_ = 'fullscreen';
+
+  /**
+   * Classes to modify the DOM
+   * @type {{mode: string, fullscreen: string, fullscreenExit: string}}
+   * @private
+   */
+  Fullscreen.CLASSES_ = {
+    mode: 'dac-fullscreen-mode',
+    fullscreen: 'dac-fullscreen',
+    fullscreenExit: 'dac-fullscreen-exit'
+  };
+
+  /**
+   * Event listener for toggling fullscreen mode
+   * @param {MouseEvent} event
+   * @private
+   */
+  Fullscreen.prototype.toggleHandler_ = function(event) {
+    event.stopPropagation();
+    this.toggle(!this.isFullscreen, true);
+  };
+
+  /**
+   * Change the DOM based on current state.
+   * @private
+   */
+  Fullscreen.prototype.activate_ = function() {
+    this.icon.toggleClass(Fullscreen.CLASSES_.fullscreen, !this.isFullscreen);
+    this.icon.toggleClass(Fullscreen.CLASSES_.fullscreenExit, this.isFullscreen);
+    this.html.toggleClass(Fullscreen.CLASSES_.mode, this.isFullscreen);
+  };
+
+  /**
+   * Toggle fullscreen mode and store the state in a cookie.
+   */
+  Fullscreen.prototype.toggle = function() {
+    this.isFullscreen = !this.isFullscreen;
+    window.writeCookie(Fullscreen.COOKIE_, this.isFullscreen, null);
+    this.activate_();
+  };
+
+  /**
+   * jQuery plugin
+   */
+  $.fn.dacFullscreen = function() {
+    return this.each(function() {
+      new Fullscreen($(this));
+    });
+  };
+})(jQuery);
+
+(function($) {
+  'use strict';
+
+  /**
+   * @param {HTMLElement} selected - The link that is selected in the nav.
+   * @constructor
+   */
+  function HeaderTabs(selected) {
+
+    // Don't highlight any tabs on the index page
+    if (location.pathname === '/index.html' || location.pathname === '/') {
+      //return;
+    }
+
+    this.selected = $(selected);
+    this.selectedParent = this.selected.closest('.dac-nav-secondary').siblings('a');
+    this.links = $('.dac-header-tabs a');
+
+    this.selectActiveTab();
+  }
+
+  HeaderTabs.prototype.selectActiveTab = function() {
+    var section = null;
+
+    if (this.selectedParent.length) {
+      section = this.selectedParent.text();
+    } else {
+      section = this.selected.text();
+    }
+
+    if (section) {
+      this.links.removeClass('selected');
+
+      this.links.filter(function() {
+        return $(this).text() === $.trim(section);
+      }).addClass('selected');
+    }
+  };
+
+  /**
+   * jQuery plugin
+   */
+  $.fn.dacHeaderTabs = function() {
+    return this.each(function() {
+      new HeaderTabs(this);
+    });
+  };
+})(jQuery);
+
+(function($) {
+  'use strict';
+  var icon = $('<i/>').addClass('dac-sprite dac-nav-forward');
+  var config = JSON.parse(window.localStorage.getItem('global-navigation') || '{}');
+  var forwardLink = $('<span/>')
+    .addClass('dac-nav-link-forward')
+    .html(icon)
+    .on('click', swap_);
+
+  /**
+   * @constructor
+   */
+  function Nav(navigation) {
+    $('.dac-nav-list').dacCurrentPage().dacHeaderTabs().dacSidebarToggle($('body'));
+
+    navigation.find('[data-reference-tree]').dacReferenceNav();
+
+    setupViews_(navigation.children().eq(0).children());
+
+    initCollapsedNavs(navigation.find('.dac-nav-sub-slider'));
+
+    $('#dac-main-navigation').scrollIntoView('.selected')
+  }
+
+  function updateStore(icon) {
+    var navClass = getCurrentLandingPage_(icon);
+    var isExpanded = icon.hasClass('dac-expand-less-black');
+    var expandedNavs = config.expanded || [];
+    if (isExpanded) {
+      expandedNavs.push(navClass);
+    } else {
+      expandedNavs = expandedNavs.filter(function(item) {
+        return item !== navClass;
+      });
+    }
+    config.expanded = expandedNavs;
+    window.localStorage.setItem('global-navigation', JSON.stringify(config));
+  }
+
+  function toggleSubNav_(icon) {
+    var isExpanded = icon.hasClass('dac-expand-less-black');
+    icon.toggleClass('dac-expand-less-black', !isExpanded);
+    icon.toggleClass('dac-expand-more-black', isExpanded);
+    icon.data('sub-navigation.dac').slideToggle(200);
+
+    updateStore(icon);
+  }
+
+  function handleSubNavToggle_(event) {
+    event.preventDefault();
+    var icon = $(event.target);
+    toggleSubNav_(icon);
+  }
+
+  function getCurrentLandingPage_(icon) {
+    return icon.closest('li')[0].className.replace('dac-nav-item ', '');
+  }
+
+  // Setup sub navigation collapse/expand
+  function initCollapsedNavs(toggleIcons) {
+    toggleIcons.each(setInitiallyActive_($('body')));
+    toggleIcons.on('click', handleSubNavToggle_);
+
+  }
+
+  function setInitiallyActive_(body) {
+    var expandedNavs = config.expanded || [];
+    return function(i, icon) {
+      icon = $(icon);
+      var subNav = icon.next();
+
+      if (!subNav.length) {
+        return;
+      }
+
+      var landingPageClass = getCurrentLandingPage_(icon);
+      var expanded = expandedNavs.indexOf(landingPageClass) >= 0;
+      landingPageClass = landingPageClass === 'home' ? 'about' : landingPageClass;
+
+      // TODO: Should read from localStorage
+      var visible = body.hasClass(landingPageClass) || expanded;
+
+      icon.data('sub-navigation.dac', subNav);
+      icon.toggleClass('dac-expand-less-black', visible);
+      icon.toggleClass('dac-expand-more-black', !visible);
+      subNav.toggle(visible);
+    };
+  }
+
+  function setupViews_(views) {
+    if (views.length === 1) {
+      // Active tier 1 nav.
+      views.addClass('dac-active');
+    } else {
+      // Activate back button and tier 2 nav.
+      views.slice(0, 2).addClass('dac-active');
+      var selectedNav = views.eq(2).find('.selected').after(forwardLink);
+      var langAttr = selectedNav.attr(window.getLangPref() + '-lang');
+      //form the label from locale attr if possible, else set to selectedNav text value
+      if ((typeof langAttr !== typeof undefined &&  langAttr !== false) && (langAttr !== '')) {
+        $('.dac-nav-back-title').text(langAttr);
+      } else {
+        $('.dac-nav-back-title').text(selectedNav.text());
+      }
+    }
+
+    // Navigation should animate.
+    setTimeout(function() {
+      views.removeClass('dac-no-anim');
+    }, 10);
+  }
+
+  function swap_(event) {
+    event.preventDefault();
+    $(event.currentTarget).trigger('swap-content');
+  }
+
+  /**
+   * jQuery plugin
+   */
+  $.fn.dacNav = function() {
+    return this.each(function() {
+      new Nav($(this));
+    });
+  };
+})(jQuery);
+
+/* global NAVTREE_DATA */
+(function($) {
+  /**
+   * Build the reference navigation with namespace dropdowns.
+   * @param {jQuery} el - The DOM element.
+   */
+  function buildReferenceNav(el) {
+    var namespaceList = el.find('[data-reference-namespaces]');
+    var resources = el.find('[data-reference-resources]');
+    var selected = namespaceList.find('.selected');
+
+    // Links should be toggleable.
+    namespaceList.find('a').addClass('dac-reference-nav-toggle dac-closed');
+
+    // Load in all resources
+    $.getScript('/navtree_data.js', function(data, textStatus, xhr) {
+      if (xhr.status === 200) {
+        namespaceList.on('click', 'a.dac-reference-nav-toggle', toggleResourcesHandler);
+      }
+    });
+
+    // No setup required if no resources are present
+    if (!resources.length) {
+      return;
+    }
+
+    // The resources should be a part of selected namespace.
+    var overview = addResourcesToView(resources, selected);
+
+    // Currently viewing Overview
+    if (location.pathname === overview.attr('href')) {
+      overview.parent().addClass('selected');
+    }
+
+    // Open currently selected resource
+    var listsToOpen = selected.children().eq(1);
+    listsToOpen = listsToOpen.add(listsToOpen.find('.selected').parent()).show();
+
+    // Mark dropdowns as open
+    listsToOpen.prev().removeClass('dac-closed');
+
+    // Scroll into view
+    namespaceList.scrollIntoView(selected);
+  }
+
+  /**
+   * Handles the toggling of resources.
+   * @param {Event} event
+   */
+  function toggleResourcesHandler(event) {
+    event.preventDefault();
+    var el = $(this);
+
+    // If resources for given namespace is not present, fetch correct data.
+    if (this.tagName === 'A' && !this.hasResources) {
+      addResourcesToView(buildResourcesViewForData(getDataForNamespace(el.text())), el.parent());
+    }
+
+    el.toggleClass('dac-closed').next().slideToggle(200);
+  }
+
+  /**
+   * @param {String} namespace
+   * @returns {Array} namespace data
+   */
+  function getDataForNamespace(namespace) {
+    var namespaceData = NAVTREE_DATA.filter(function(data) {
+      return data[0] === namespace;
+    });
+
+    return namespaceData.length ? namespaceData[0][2] : [];
+  }
+
+  /**
+   * Build a list item for a resource
+   * @param {Array} resource
+   * @returns {String}
+   */
+  function buildResourceItem(resource) {
+    return '<li class="api apilevel-' + resource[3] + '"><a href="/' + resource[1] + '">' + resource[0] + '</a></li>';
+  }
+
+  /**
+   * Build resources list items.
+   * @param {Array} resources
+   * @returns {String}
+   */
+  function buildResourceList(resources) {
+    return '<li><h2>' + resources[0] + '</h2><ul>' + resources[2].map(buildResourceItem).join('') + '</ul>';
+  }
+
+  /**
+   * Build a resources view
+   * @param {Array} data
+   * @returns {jQuery} resources in an unordered list.
+   */
+  function buildResourcesViewForData(data) {
+    return $('<ul>' + data.map(buildResourceList).join('') + '</ul>');
+  }
+
+  /**
+   * Add resources to a containing view.
+   * @param {jQuery} resources
+   * @param {jQuery} view
+   * @returns {jQuery} the overview link.
+   */
+  function addResourcesToView(resources, view) {
+    var namespace = view.children().eq(0);
+    var overview = $('<a href="' + namespace.attr('href') + '">Overview</a>');
+
+    // Mark namespace with content;
+    namespace[0].hasResources = true;
+
+    // Add correct classes / event listeners to resources.
+    resources.prepend($('<li>').html(overview))
+      .find('a')
+        .addClass('dac-reference-nav-resource')
+      .end()
+        .find('h2')
+        .addClass('dac-reference-nav-toggle dac-closed')
+        .on('click', toggleResourcesHandler)
+      .end()
+        .add(resources.find('ul'))
+        .addClass('dac-reference-nav-resources')
+      .end()
+        .appendTo(view);
+
+    return overview;
+  }
+
+  /**
+   * jQuery plugin
+   */
+  $.fn.dacReferenceNav = function() {
+    return this.each(function() {
+      buildReferenceNav($(this));
+    });
+  };
+})(jQuery);
+
+/** Scroll a container to make a target element visible
+ This is called when the page finished loading. */
+$.fn.scrollIntoView = function(target) {
+  if ('string' === typeof target) {
+    target = this.find(target);
+  }
+  if (this.is(':visible')) {
+    if (target.length == 0) {
+      // If no selected item found, exit
+      return;
+    }
+
+    // get the target element's offset from its container nav by measuring the element's offset
+    // relative to the document then subtract the container nav's offset relative to the document
+    var targetOffset = target.offset().top - this.offset().top;
+    var containerHeight = this.height();
+    if (targetOffset > containerHeight * .8) { // multiply nav height by .8 so we move up the item
+      // if it's more than 80% down the nav
+      // scroll the item up by an amount equal to 80% the container height
+      this.scrollTop(targetOffset - (containerHeight * .8));
+    }
+  }
+};
+
+(function($) {
+  $.fn.dacCurrentPage = function() {
+    // Highlight the header tabs...
+    // highlight Design tab
+    var baseurl = getBaseUri(window.location.pathname);
+    var urlSegments = baseurl.split('/');
+    var navEl = this;
+    var body = $('body');
+    var subNavEl = navEl.find('.dac-nav-secondary');
+    var parentNavEl;
+    var selected;
+    // In NDK docs, highlight appropriate sub-nav
+    if (body.hasClass('ndk')) {
+      if (body.hasClass('guide')) {
+        selected = navEl.find('> li.guides > a').addClass('selected');
+      } else if (body.hasClass('reference')) {
+        selected = navEl.find('> li.reference > a').addClass('selected');
+      } else if (body.hasClass('samples')) {
+        selected = navEl.find('> li.samples > a').addClass('selected');
+      } else if (body.hasClass('downloads')) {
+        selected = navEl.find('> li.downloads > a').addClass('selected');
+      }
+    } else if (body.hasClass('studio')) {
+      if (body.hasClass('features')) {
+        selected = navEl.find('> li.features > a').addClass('selected');
+      } else if (body.hasClass('guide')) {
+        selected = navEl.find('> li.guide > a').addClass('selected');
+      } else if (body.hasClass('preview')) {
+        selected = navEl.find('> li.preview > a').addClass('selected');
+      }
+    } else if (body.hasClass('design')) {
+      selected = navEl.find('> li.design > a').addClass('selected');
+      // highlight Home nav
+    } else if (body.hasClass('about')) {
+      parentNavEl = navEl.find('> li.home > a');
+      parentNavEl.addClass('has-subnav');
+      // In Home docs, also highlight appropriate sub-nav
+      if (urlSegments[1] === 'wear' || urlSegments[1] === 'tv' ||
+        urlSegments[1] === 'auto') {
+        selected = subNavEl.find('li.' + urlSegments[1] + ' > a').addClass('selected');
+      } else if (urlSegments[1] === 'about') {
+        selected = subNavEl.find('li.versions > a').addClass('selected');
+      } else {
+        selected = parentNavEl.removeClass('has-subnav').addClass('selected');
+      }
+      // highlight Develop nav
+    } else if (body.hasClass('develop') || body.hasClass('google')) {
+      parentNavEl = navEl.find('> li.develop > a');
+      parentNavEl.addClass('has-subnav');
+      // In Develop docs, also highlight appropriate sub-nav
+      if (urlSegments[1] === 'training') {
+        selected = subNavEl.find('li.training > a').addClass('selected');
+      } else if (urlSegments[1] === 'guide') {
+        selected = subNavEl.find('li.guide > a').addClass('selected');
+      } else if (urlSegments[1] === 'reference') {
+        // If the root is reference, but page is also part of Google Services, select Google
+        if (body.hasClass('google')) {
+          selected = subNavEl.find('li.google > a').addClass('selected');
+        } else {
+          selected = subNavEl.find('li.reference > a').addClass('selected');
+        }
+      } else if ((urlSegments[1] === 'tools') || (urlSegments[1] === 'sdk')) {
+        selected = subNavEl.find('li.tools > a').addClass('selected');
+      } else if (body.hasClass('google')) {
+        selected = subNavEl.find('li.google > a').addClass('selected');
+      } else if (body.hasClass('samples')) {
+        selected = subNavEl.find('li.samples > a').addClass('selected');
+      } else {
+        selected = parentNavEl.removeClass('has-subnav').addClass('selected');
+      }
+      // highlight Distribute nav
+    } else if (body.hasClass('distribute')) {
+      parentNavEl = navEl.find('> li.distribute > a');
+      parentNavEl.addClass('has-subnav');
+      // In Distribute docs, also highlight appropriate sub-nav
+      if (urlSegments[2] === 'users') {
+        selected = subNavEl.find('li.users > a').addClass('selected');
+      } else if (urlSegments[2] === 'engage') {
+        selected = subNavEl.find('li.engage > a').addClass('selected');
+      } else if (urlSegments[2] === 'monetize') {
+        selected = subNavEl.find('li.monetize > a').addClass('selected');
+      } else if (urlSegments[2] === 'analyze') {
+        selected = subNavEl.find('li.analyze > a').addClass('selected');
+      } else if (urlSegments[2] === 'tools') {
+        selected = subNavEl.find('li.disttools > a').addClass('selected');
+      } else if (urlSegments[2] === 'stories') {
+        selected = subNavEl.find('li.stories > a').addClass('selected');
+      } else if (urlSegments[2] === 'essentials') {
+        selected = subNavEl.find('li.essentials > a').addClass('selected');
+      } else if (urlSegments[2] === 'googleplay') {
+        selected = subNavEl.find('li.googleplay > a').addClass('selected');
+      } else {
+        selected = parentNavEl.removeClass('has-subnav').addClass('selected');
+      }
+    } else if (body.hasClass('preview')) {
+      selected = navEl.find('> li.preview > a').addClass('selected');
+    }
+    return $(selected);
+  };
+})(jQuery);
+
 (function($) {
   'use strict';
 
   /**
    * Toggle the visabilty of the mobile navigation.
    * @param {HTMLElement} el - The DOM element.
-   * @param options
+   * @param {Object} options
    * @constructor
    */
   function ToggleNav(el, options) {
     this.el = $(el);
     this.options = $.extend({}, ToggleNav.DEFAULTS_, options);
-    this.options.target = [this.options.navigation];
-
-    if (this.options.body) {this.options.target.push('body')}
-    if (this.options.dimmer) {this.options.target.push(this.options.dimmer)}
-
+    this.body = $(document.body);
+    this.navigation_ = this.body.find(this.options.navigation);
     this.el.on('click', this.clickHandler_.bind(this));
   }
 
+  ToggleNav.BREAKPOINT_ = 980;
+
+  /**
+   * Open on correct sizes
+   */
+  function toggleSidebarVisibility(body) {
+    var wasClosed = ('' + localStorage.getItem('navigation-open')) === 'false';
+
+    if (wasClosed) {
+      body.removeClass(ToggleNav.DEFAULTS_.activeClass);
+    } else if (window.innerWidth >= ToggleNav.BREAKPOINT_) {
+      body.addClass(ToggleNav.DEFAULTS_.activeClass);
+    } else {
+      body.removeClass(ToggleNav.DEFAULTS_.activeClass);
+    }
+  }
+
   /**
    * ToggleNav Default Settings
-   * @type {{body: boolean, dimmer: string, navigation: string, toggleClass: string}}
+   * @type {{body: boolean, dimmer: string, navigation: string, activeClass: string}}
    * @private
    */
   ToggleNav.DEFAULTS_ = {
     body: true,
     dimmer: '.dac-nav-dimmer',
+    animatingClass: 'dac-nav-animating',
     navigation: '[data-dac-nav]',
-    toggleClass: 'dac-nav-open'
+    activeClass: 'dac-nav-open'
   };
 
   /**
    * The actual toggle logic.
-   * @param event
+   * @param {Event} event
    * @private
    */
   ToggleNav.prototype.clickHandler_ = function(event) {
     event.preventDefault();
-    $(this.options.target.join(', ')).toggleClass(this.options.toggleClass);
+    var animatingClass = this.options.animatingClass;
+    var body = this.body;
+
+    body.addClass(animatingClass);
+    body.toggleClass(this.options.activeClass);
+
+    setTimeout(function() {
+      body.removeClass(animatingClass);
+    }, this.navigation_.transitionDuration());
+
+    if (window.innerWidth >= ToggleNav.BREAKPOINT_) {
+      localStorage.setItem('navigation-open', body.hasClass(this.options.activeClass));
+    }
   };
 
   /**
    * jQuery plugin
    * @param  {object} options - Override default options.
    */
-  $.fn.dacToggleMobileNav = function(options) {
+  $.fn.dacToggleMobileNav = function() {
     return this.each(function() {
-      new ToggleNav(this, options);
+      var el = $(this);
+      new ToggleNav(el, el.data());
     });
   };
 
+  $.fn.dacSidebarToggle = function(body) {
+    toggleSidebarVisibility(body);
+    $(window).on('resize', toggleSidebarVisibility.bind(null, body));
+  };
+
   /**
    * Data Attribute API
    */
-  $(window).on('load.aranja', function() {
-    $('[data-dac-toggle-nav]').each(function() {
-      $(this).dacToggleMobileNav($(this).data());
-    });
+  $(function() {
+    $('[data-dac-toggle-nav]').dacToggleMobileNav();
   });
 })(jQuery);
 
@@ -5078,6 +4586,7 @@
       .attr('name', 'dac-newsletter-iframe')
       .attr('src', '')
       .insertBefore(this.form);
+    this.el.find('[data-newsletter-language]').val(window.polyglot.t('newsletter.languageVal'));
     this.form.on('submit', this.submitHandler_.bind(this));
   }
 
@@ -5136,6 +4645,613 @@
   });
 })(jQuery);
 
+/* globals METADATA, YOUTUBE_RESOURCES, BLOGGER_RESOURCES */
+window.metadata = {};
+
+/**
+ * Prepare metadata and indices for querying.
+ */
+window.metadata.prepare = (function() {
+  // Helper functions.
+  function mergeArrays() {
+    return Array.prototype.concat.apply([], arguments);
+  }
+
+  /**
+   * Creates lookup maps for a resource index.
+   * I.e. where MAP['some tag'][resource.id] === true when that resource has 'some tag'.
+   * @param resourceDict
+   * @returns {{}}
+   */
+  function buildResourceLookupMap(resourceDict) {
+    var map = {};
+    for (var key in resourceDict) {
+      var dictForKey = {};
+      var srcArr = resourceDict[key];
+      for (var i = 0; i < srcArr.length; i++) {
+        dictForKey[srcArr[i].index] = true;
+      }
+      map[key] = dictForKey;
+    }
+    return map;
+  }
+
+  /**
+   * Merges metadata maps for english and the current language into the global store.
+   */
+  function mergeMetadataMap(name, locale) {
+    if (locale && locale !== 'en' && METADATA[locale]) {
+      METADATA[name] = $.extend(METADATA.en[name], METADATA[locale][name]);
+    } else {
+      METADATA[name] = METADATA.en[name];
+    }
+  }
+
+  /**
+   * Index all resources by type, url, tag and category.
+   * @param resources
+   */
+  function createIndices(resources) {
+    // URL, type, tag and category lookups
+    var byType = METADATA.byType = {};
+    var byUrl = METADATA.byUrl = {};
+    var byTag = METADATA.byTag = {};
+    var byCategory = METADATA.byCategory = {};
+
+    for (var i = 0; i < resources.length; i++) {
+      var res = resources[i];
+
+      // Store index.
+      res.index = i;
+
+      // Index by type.
+      var type = res.type;
+      if (type) {
+        byType[type] = byType[type] || [];
+        byType[type].push(res);
+      }
+
+      // Index by tag.
+      var tags = res.tags || [];
+      for (var j = 0; j < tags.length; j++) {
+        var tag = tags[j];
+        if (tag) {
+          byTag[tag] = byTag[tag] || [];
+          byTag[tag].push(res);
+        }
+      }
+
+      // Index by category.
+      var category = res.category;
+      if (category) {
+        byCategory[category] = byCategory[category] || [];
+        byCategory[category].push(res);
+      }
+
+      // Index by url.
+      var url = res.url;
+      if (url) {
+        res.baseUrl = url.replace(/^intl\/\w+[\/]/, '');
+        byUrl[res.baseUrl] = res;
+      }
+    }
+    METADATA.hasType = buildResourceLookupMap(byType);
+    METADATA.hasTag = buildResourceLookupMap(byTag);
+    METADATA.hasCategory = buildResourceLookupMap(byCategory);
+  }
+
+  return function() {
+    // Only once.
+    if (METADATA.all) { return; }
+
+    // Get current language.
+    var locale = getLangPref();
+
+    // Merge english resources.
+    METADATA.all = mergeArrays(
+      METADATA.en.about,
+      METADATA.en.design,
+      METADATA.en.distribute,
+      METADATA.en.develop,
+      YOUTUBE_RESOURCES,
+      BLOGGER_RESOURCES,
+      METADATA.en.extras
+    );
+
+    // Merge local language resources.
+    if (locale !== 'en' && METADATA[locale]) {
+      METADATA.all = mergeArrays(
+        METADATA.all,
+        METADATA[locale].about,
+        METADATA[locale].design,
+        METADATA[locale].distribute,
+        METADATA[locale].develop,
+        METADATA[locale].extras
+      );
+    }
+
+    mergeMetadataMap('collections', locale);
+    mergeMetadataMap('searchHeroCollections', locale);
+    mergeMetadataMap('carousel', locale);
+
+    // Create query indicies for resources.
+    createIndices(METADATA.all, locale);
+
+    // Reference metadata.
+    METADATA.androidReference = window.DATA;
+    METADATA.googleReference = mergeArrays(window.GMS_DATA, window.GCM_DATA);
+  };
+})();
+
+/* global METADATA, util */
+window.metadata.query = (function($) {
+  var pageMap = {};
+
+  function buildResourceList(opts) {
+    window.metadata.prepare();
+    var expressions = parseResourceQuery(opts.query || '');
+    var instanceMap = {};
+    var results = [];
+
+    for (var i = 0; i < expressions.length; i++) {
+      var clauses = expressions[i];
+
+      // Get all resources for first clause
+      var resources = getResourcesForClause(clauses.shift());
+
+      // Concat to final results list
+      results = results.concat(resources.map(filterResources(clauses, i > 0, instanceMap)).filter(filterEmpty));
+    }
+
+    // Set correct order
+    if (opts.sortOrder && results.length) {
+      results = opts.sortOrder === 'random' ? util.shuffle(results) : results.sort(sortResultsByKey(opts.sortOrder));
+    }
+
+    // Slice max results.
+    if (opts.maxResults !== Infinity) {
+      results = results.slice(0, opts.maxResults);
+    }
+
+    // Remove page level duplicates
+    if (opts.allowDuplicates === undefined || opts.allowDuplicates === 'false') {
+      results = results.filter(removePageLevelDuplicates);
+
+      for (var index = 0; index < results.length; ++index) {
+        pageMap[results[index].index] = 1;
+      }
+    }
+
+    return results;
+  }
+
+  function filterResources(clauses, removeDuplicates, map) {
+    return function(resource) {
+      var resourceIsAllowed = true;
+
+      // References must be defined.
+      if (resource === undefined) {
+        return;
+      }
+
+      // Get canonical (localized) version of resource if possible.
+      resource = METADATA.byUrl[resource.baseUrl] || METADATA.byUrl[resource.url] || resource;
+
+      // Filter out resources already used
+      if (removeDuplicates) {
+        resourceIsAllowed = !map[resource.index];
+      }
+
+      // Must fulfill all criteria
+      if (clauses.length > 0) {
+        resourceIsAllowed = resourceIsAllowed && doesResourceMatchClauses(resource, clauses);
+      }
+
+      // Mark resource as used.
+      if (resourceIsAllowed) {
+        map[resource.index] = 1;
+      }
+
+      return resourceIsAllowed && resource;
+    };
+  }
+
+  function filterEmpty(resource) {
+    return resource;
+  }
+
+  function sortResultsByKey(key) {
+    var desc = key.charAt(0) === '-';
+
+    if (desc) {
+      key = key.substring(1);
+    }
+
+    return function(x, y) {
+      return (desc ? -1 : 1) * (parseInt(x[key], 10) - parseInt(y[key], 10));
+    };
+  }
+
+  function getResourcesForClause(clause) {
+    switch (clause.attr) {
+      case 'type':
+        return METADATA.byType[clause.value];
+      case 'tag':
+        return METADATA.byTag[clause.value];
+      case 'collection':
+        var resources = METADATA.collections[clause.value] || {};
+        return getResourcesByUrlCollection(resources.resources);
+      case 'history':
+        return getResourcesByUrlCollection($.dacGetVisitedUrls(clause.value));
+      case 'section':
+        return getResourcesByUrlCollection([clause.value].sections);
+      default:
+        return [];
+    }
+  }
+
+  function getResourcesByUrlCollection(resources) {
+    return (resources || []).map(function(url) {
+      return METADATA.byUrl[url];
+    });
+  }
+
+  function removePageLevelDuplicates(resource) {
+    return resource && !pageMap[resource.index];
+  }
+
+  function doesResourceMatchClauses(resource, clauses) {
+    for (var i = 0; i < clauses.length; i++) {
+      var map;
+      switch (clauses[i].attr) {
+        case 'type':
+          map = METADATA.hasType[clauses[i].value];
+          break;
+        case 'tag':
+          map = METADATA.hasTag[clauses[i].value];
+          break;
+      }
+
+      if (!map || (!!clauses[i].negative ? map[resource.index] : !map[resource.index])) {
+        return clauses[i].negative;
+      }
+    }
+
+    return true;
+  }
+
+  function parseResourceQuery(query) {
+    // Parse query into array of expressions (expression e.g. 'tag:foo + type:video')
+    var expressions = [];
+    var expressionStrs = query.split(',') || [];
+    for (var i = 0; i < expressionStrs.length; i++) {
+      var expr = expressionStrs[i] || '';
+
+      // Break expression into clauses (clause e.g. 'tag:foo')
+      var clauses = [];
+      var clauseStrs = expr.split(/(?=[\+\-])/);
+      for (var j = 0; j < clauseStrs.length; j++) {
+        var clauseStr = clauseStrs[j] || '';
+
+        // Get attribute and value from clause (e.g. attribute='tag', value='foo')
+        var parts = clauseStr.split(':');
+        var clause = {};
+
+        clause.attr = parts[0].replace(/^\s+|\s+$/g, '');
+        if (clause.attr) {
+          if (clause.attr.charAt(0) === '+') {
+            clause.attr = clause.attr.substring(1);
+          } else if (clause.attr.charAt(0) === '-') {
+            clause.negative = true;
+            clause.attr = clause.attr.substring(1);
+          }
+        }
+
+        if (parts.length > 1) {
+          clause.value = parts[1].replace(/^\s+|\s+$/g, '');
+        }
+
+        clauses.push(clause);
+      }
+
+      if (!clauses.length) {
+        continue;
+      }
+
+      expressions.push(clauses);
+    }
+
+    return expressions;
+  }
+
+  return buildResourceList;
+})(jQuery);
+
+/* global METADATA, getLangPref */
+
+window.metadata.search = (function() {
+  'use strict';
+
+  var currentLang = getLangPref();
+
+  function search(query) {
+    window.metadata.prepare();
+    return {
+      android: findDocsMatches(query, METADATA.androidReference),
+      docs: findDocsMatches(query, METADATA.googleReference),
+      resources: findResourceMatches(query)
+    };
+  }
+
+  function findDocsMatches(query, data) {
+    var results = [];
+
+    for (var i = 0; i < data.length; i++) {
+      var s = data[i];
+      if (query.length !== 0 && s.label.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
+        results.push(s);
+      }
+    }
+
+    rankAutocompleteApiResults(query, results);
+
+    return results;
+  }
+
+  function findResourceMatches(query) {
+    var results = [];
+
+    // Search for matching JD docs
+    if (query.length >= 2) {
+      /* In some langs, spaces may be optional between certain non-Ascii word-glyphs. For
+       * those langs, only match query at word boundaries if query includes Ascii chars only.
+       */
+      var NO_BOUNDARY_LANGUAGES = ['ja','ko','vi','zh-cn','zh-tw'];
+      var isAsciiOnly = /^[\u0000-\u007f]*$/.test(query);
+      var noBoundaries = (NO_BOUNDARY_LANGUAGES.indexOf(window.getLangPref()) !== -1);
+      var exprBoundary = (!isAsciiOnly && noBoundaries) ? '' : '(?:^|\\s)';
+      var queryRegex = new RegExp(exprBoundary + query.toLowerCase(), 'g');
+
+      var all = METADATA.all;
+      for (var i = 0; i < all.length; i++) {
+        // current search comparison, with counters for tag and title,
+        // used later to improve ranking
+        var s = all[i];
+        s.matched_tag = 0;
+        s.matched_title = 0;
+        var matched = false;
+
+        // Check if query matches any tags; work backwards toward 1 to assist ranking
+        if (s.keywords) {
+          for (var j = s.keywords.length - 1; j >= 0; j--) {
+            // it matches a tag
+            if (s.keywords[j].toLowerCase().match(queryRegex)) {
+              matched = true;
+              s.matched_tag = j + 1; // add 1 to index position
+            }
+          }
+        }
+
+        // Check if query matches doc title
+        if (s.title.toLowerCase().match(queryRegex)) {
+          matched = true;
+          s.matched_title = 1;
+        }
+
+        // Remember the doc if it matches either
+        if (matched) {
+          results.push(s);
+        }
+      }
+
+      // Improve the current results
+      results = lookupBetterResult(results);
+
+      // Rank/sort all the matched pages
+      rankAutocompleteDocResults(results);
+
+      return results;
+    }
+  }
+
+  // Replaces a match with another resource by url, if it exists.
+  function lookupReplacementByUrl(match, url) {
+    var replacement = METADATA.byUrl[url];
+
+    // Replacement resource does not exists.
+    if (!replacement) { return; }
+
+    replacement.matched_title = Math.max(replacement.matched_title, match.matched_title);
+    replacement.matched_tag = Math.max(replacement.matched_tag, match.matched_tag);
+
+    return replacement;
+  }
+
+  // Find the localized version of a page if it exists.
+  function lookupLocalizedVersion(match) {
+    return METADATA.byUrl[match.baseUrl] || METADATA.byUrl[match.url];
+  }
+
+  // Find the main page for a tutorial when matching a subpage.
+  function lookupTutorialIndex(match) {
+    // Guard for non index tutorial pages.
+    if (match.type !== 'training' || match.url.indexOf('index.html') >= 0) { return; }
+
+    var indexUrl = match.url.replace(/[^\/]+$/, 'index.html');
+    return lookupReplacementByUrl(match, indexUrl);
+  }
+
+  // Find related results which are a better match for the user.
+  function lookupBetterResult(matches) {
+    var newMatches = [];
+
+    matches = matches.filter(function(match) {
+      var newMatch = match;
+      newMatch = lookupTutorialIndex(newMatch) || newMatch;
+      newMatch = lookupLocalizedVersion(newMatch) || newMatch;
+
+      if (newMatch !== match) {
+        newMatches.push(newMatch);
+      }
+
+      return newMatch === match;
+    });
+
+    return toUnique(newMatches.concat(matches));
+  }
+
+  /* Order the jd doc result list based on match quality */
+  function rankAutocompleteDocResults(matches) {
+    if (!matches || !matches.length) {
+      return;
+    }
+
+    var _resultScoreFn = function(match) {
+      var score = 1.0;
+
+      // if the query matched a tag
+      if (match.matched_tag > 0) {
+        // multiply score by factor relative to position in tags list (max of 3)
+        score *= 3 / match.matched_tag;
+
+        // if it also matched the title
+        if (match.matched_title > 0) {
+          score *= 2;
+        }
+      } else if (match.matched_title > 0) {
+        score *= 3;
+      }
+
+      if (match.lang === currentLang) {
+        score *= 5;
+      }
+
+      return score;
+    };
+
+    for (var i = 0; i < matches.length; i++) {
+      matches[i].__resultScore = _resultScoreFn(matches[i]);
+    }
+
+    matches.sort(function(a, b) {
+      var n = b.__resultScore - a.__resultScore;
+
+      if (n === 0) {
+        // lexicographical sort if scores are the same
+        n = (a.title < b.title) ? -1 : 1;
+      }
+
+      return n;
+    });
+  }
+
+  /* Order the result list based on match quality */
+  function rankAutocompleteApiResults(query, matches) {
+    query = query || '';
+    if (!matches || !matches.length) {
+      return;
+    }
+
+    // helper function that gets the last occurence index of the given regex
+    // in the given string, or -1 if not found
+    var _lastSearch = function(s, re) {
+      if (s === '') {
+        return -1;
+      }
+      var l = -1;
+      var tmp;
+      while ((tmp = s.search(re)) >= 0) {
+        if (l < 0) {
+          l = 0;
+        }
+        l += tmp;
+        s = s.substr(tmp + 1);
+      }
+      return l;
+    };
+
+    // helper function that counts the occurrences of a given character in
+    // a given string
+    var _countChar = function(s, c) {
+      var n = 0;
+      for (var i = 0; i < s.length; i++) {
+        if (s.charAt(i) === c) {
+          ++n;
+        }
+      }
+      return n;
+    };
+
+    var queryLower = query.toLowerCase();
+    var queryAlnum = (queryLower.match(/\w+/) || [''])[0];
+    var partPrefixAlnumRE = new RegExp('\\b' + queryAlnum);
+    var partExactAlnumRE = new RegExp('\\b' + queryAlnum + '\\b');
+
+    var _resultScoreFn = function(result) {
+      // scores are calculated based on exact and prefix matches,
+      // and then number of path separators (dots) from the last
+      // match (i.e. favoring classes and deep package names)
+      var score = 1.0;
+      var labelLower = result.label.toLowerCase();
+      var t;
+      var partsAfter;
+      t = _lastSearch(labelLower, partExactAlnumRE);
+      if (t >= 0) {
+        // exact part match
+        partsAfter = _countChar(labelLower.substr(t + 1), '.');
+        score *= 200 / (partsAfter + 1);
+      } else {
+        t = _lastSearch(labelLower, partPrefixAlnumRE);
+        if (t >= 0) {
+          // part prefix match
+          partsAfter = _countChar(labelLower.substr(t + 1), '.');
+          score *= 20 / (partsAfter + 1);
+        }
+      }
+
+      return score;
+    };
+
+    for (var i = 0; i < matches.length; i++) {
+      // if the API is deprecated, default score is 0; otherwise, perform scoring
+      if (matches[i].deprecated === 'true') {
+        matches[i].__resultScore = 0;
+      } else {
+        matches[i].__resultScore = _resultScoreFn(matches[i]);
+      }
+    }
+
+    matches.sort(function(a, b) {
+      var n = b.__resultScore - a.__resultScore;
+
+      if (n === 0) {
+        // lexicographical sort if scores are the same
+        n = (a.label < b.label) ? -1 : 1;
+      }
+
+      return n;
+    });
+  }
+
+  // Destructive but fast toUnique.
+  // http://stackoverflow.com/a/25082874
+  function toUnique(array) {
+    var c;
+    var b = array.length || 1;
+
+    while (c = --b) {
+      while (c--) {
+        if (array[b] === array[c]) {
+          array.splice(c, 1);
+        }
+      }
+    }
+    return array;
+  }
+
+  return search;
+})();
+
 (function($) {
   'use strict';
 
@@ -5165,7 +5281,7 @@
   ScrollButton.DEFAULTS_ = {
     duration: 300,
     easing: 'swing',
-    offset: 0,
+    offset: '.dac-header',
     scrollContainer: 'html, body'
   };
 
@@ -5181,11 +5297,26 @@
 
     event.preventDefault();
 
+    var position = this.getTargetPosition();
     $(this.options.scrollContainer).animate({
-      scrollTop: this.target.offset().top - this.options.offset
+      scrollTop: position - this.options.offset
     }, this.options);
   };
 
+  ScrollButton.prototype.getTargetPosition = function() {
+    if (this.options.scrollContainer === ScrollButton.DEFAULTS_.scrollContainer) {
+      return this.target.offset().top;
+    }
+    var scrollContainer = $(this.options.scrollContainer)[0];
+    var currentEl = this.target[0];
+    var pos = 0;
+    while (currentEl !== scrollContainer && currentEl !== null) {
+      pos += currentEl.offsetTop;
+      currentEl = currentEl.offsetParent;
+    }
+    return pos;
+  };
+
   /**
    * jQuery plugin
    * @param  {object} options - Override default options.
@@ -5206,6 +5337,605 @@
   });
 })(jQuery);
 
+/* global getLangPref */
+(function($) {
+  var LANG;
+
+  function getSearchLang() {
+    if (!LANG) {
+      LANG = getLangPref();
+
+      // Fix zh-cn to be zh-CN.
+      LANG = LANG.replace(/-\w+/, function(m) { return m.toUpperCase(); });
+    }
+    return LANG;
+  }
+
+  function customSearch(query, start) {
+    var searchParams = {
+      // current cse instance:
+      //cx: '001482626316274216503:zu90b7s047u',
+      // new cse instance:
+      cx: '000521750095050289010:zpcpi1ea4s8',
+      key: 'AIzaSyCFhbGnjW06dYwvRCU8h_zjdpS4PYYbEe8',
+      q: query,
+      start: start || 1,
+      num: 9,
+      hl: getSearchLang(),
+      fields: 'queries,items(pagemap,link,title,htmlSnippet,formattedUrl)'
+    };
+
+    return $.get('https://content.googleapis.com/customsearch/v1?' +  $.param(searchParams));
+  }
+
+  function renderResults(el, results, searchAppliance) {
+    var referenceResults = searchAppliance.getReferenceResults();
+    if (!results.items) {
+      el.append($('<div>').text('No results'));
+      return;
+    }
+
+    for (var i = 0; i < results.items.length; i++) {
+      var item = results.items[i];
+      var isDuplicate = false;
+      $(referenceResults.android).each(function(index, result) {
+        if (item.link.indexOf(result.link) > -1) {
+          isDuplicate = true;
+          return false;
+        }
+      });
+
+      if (!isDuplicate) {
+        var hasImage = item.pagemap && item.pagemap.cse_thumbnail;
+        var sectionMatch = item.link.match(/developer\.android\.com\/(\w*)/);
+        var section = (sectionMatch && sectionMatch[1]) || 'blog';
+
+        var entry = $('<div>').addClass('dac-custom-search-entry cols');
+
+        if (hasImage) {
+          var image = item.pagemap.cse_thumbnail[0];
+          entry.append($('<div>').addClass('dac-custom-search-image-wrapper')
+            .append($('<div>').addClass('dac-custom-search-image').css('background-image', 'url(' + image.src + ')')));
+        }
+
+        entry.append($('<div>').addClass('dac-custom-search-text-wrapper')
+          .append($('<p>').addClass('dac-custom-search-section').text(section))
+          .append(
+            $('<a>').text(item.title).attr('href', item.link).wrap('<h2>').parent().addClass('dac-custom-search-title')
+          )
+          .append($('<p>').addClass('dac-custom-search-snippet').html(item.htmlSnippet.replace(/<br>/g, '')))
+          .append($('<a>').addClass('dac-custom-search-link').text(item.formattedUrl).attr('href', item.link)));
+
+        el.append(entry);
+      }
+    }
+
+    if (results.queries.nextPage) {
+      var loadMoreButton = $('<button id="dac-custom-search-load-more">')
+        .addClass('dac-custom-search-load-more')
+        .text('Load more')
+        .click(function() {
+          loadMoreResults(el, results, searchAppliance);
+        });
+
+      el.append(loadMoreButton);
+    }
+  };
+
+  function loadMoreResults(el, results, searchAppliance) {
+    var query = results.queries.request[0].searchTerms;
+    var start = results.queries.nextPage[0].startIndex;
+    var loadMoreButton = el.find('#dac-custom-search-load-more');
+
+    loadMoreButton.text('Loading more...');
+
+    customSearch(query, start).then(function(results) {
+      loadMoreButton.remove();
+      renderResults(el, results, searchAppliance);
+    });
+  }
+
+  $.fn.customSearch = function(query, searchAppliance) {
+    var el = $(this);
+
+    customSearch(query).then(function(results) {
+      el.empty();
+      renderResults(el, results, searchAppliance);
+    });
+  };
+})(jQuery);
+
+/* global METADATA */
+
+(function($) {
+  $.fn.dacSearchRenderHero = function(resources, query) {
+    var el = $(this);
+    el.empty();
+
+    var resource = METADATA.searchHeroCollections[query];
+
+    if (resource) {
+      el.dacHero(resource, true);
+      el.show();
+
+      return true;
+    } else {
+      el.hide();
+    }
+  };
+})(jQuery);
+
+(function($) {
+  $.fn.dacSearchRenderReferences = function(results, query) {
+    var referenceCard = $('.suggest-card.reference');
+    referenceCard.data('searchreferences.dac', {results: results, query: query});
+    renderResults(referenceCard, results, query, false);
+  };
+
+  var ROW_COUNT_COLLAPSED = 20;
+  var ROW_COUNT_EXPANDED = 40;
+  var ROW_COUNT_GOOGLE_COLLAPSED = 1;
+  var ROW_COUNT_GOOGLE_EXPANDED = 8;
+
+  function onSuggestionClick(e) {
+    var normalClick = e.which === 1 && !e.ctrlKey && !e.shiftKey && !e.metaKey;
+    if (normalClick) {
+      e.preventDefault();
+    }
+
+    // When user clicks a suggested document, track it
+    var url = $(e.currentTarget).attr('href');
+    ga('send', 'event', 'Suggestion Click', 'clicked: ' + url,
+        'query: ' + $('#search_autocomplete').val().toLowerCase(),
+        {hitCallback: function() {
+          if (normalClick) {
+            document.location = url;
+          }
+        }});
+  }
+
+  function buildLink(match) {
+    var link = $('<a>').attr('href', window.toRoot + match.link);
+
+    var label = match.label;
+    var classNameStart = label.match(/[A-Z]/) ? label.search(/[A-Z]/) : label.lastIndexOf('.') + 1;
+    var newLink = '<span class="namespace">' +
+      label.substr(0, classNameStart) +
+      '</span>' +
+      label.substr(classNameStart, label.length);
+
+    link.html(newLink);
+    return link;
+  }
+
+  function buildSuggestion(match, query) {
+    var li = $('<li>').addClass('dac-search-results-reference-entry');
+
+    var link = buildLink(match);
+    link.highlightMatches(query);
+    li.append(link);
+    return li[0];
+  }
+
+  function buildResults(results, query) {
+    return results.map(function(match) {
+      return buildSuggestion(match, query);
+    });
+  }
+
+  function renderAndroidResults(list, gMatches, query) {
+    list.empty();
+
+    var header = $('<li class="dac-search-results-reference-header">android</li>');
+    list.append(header);
+
+    if (gMatches.length > 0) {
+      list.removeClass('no-results');
+
+      var resources = buildResults(gMatches, query);
+      list.append(resources);
+      return true;
+    } else {
+      list.append('<li class="dac-search-results-reference-entry-empty">No results</li>');
+    }
+  }
+
+  function renderGoogleDocsResults(list, gGoogleMatches, query) {
+    list = $('.suggest-card.reference ul');
+
+    if (gGoogleMatches.length > 0) {
+      list.append('<li class="dac-search-results-reference-header">in Google Services</li>');
+
+      var resources = buildResults(gGoogleMatches, query);
+      list.append(resources);
+
+      return true;
+    }
+  }
+
+  function renderResults(referenceCard, results, query, expanded) {
+    var list = referenceCard.find('ul');
+    list.toggleClass('is-expanded', !!expanded);
+
+    // Figure out how many results we can show in our fixed size box.
+    var total = expanded ? ROW_COUNT_EXPANDED : ROW_COUNT_COLLAPSED;
+    var googleCount = expanded ? ROW_COUNT_GOOGLE_EXPANDED : ROW_COUNT_GOOGLE_COLLAPSED;
+    googleCount = Math.max(googleCount, total - results.android.length);
+    googleCount = Math.min(googleCount, results.docs.length);
+
+    if (googleCount > 0) {
+      // If there are google results, reserve space for its header.
+      googleCount++;
+    }
+
+    var androidCount = Math.max(0, total - googleCount);
+    if (androidCount === 0) {
+      // Reserve space for "No reference results"
+      googleCount--;
+    }
+
+    renderAndroidResults(list, results.android.slice(0, androidCount), query);
+    renderGoogleDocsResults(list, results.docs.slice(0, googleCount - 1), query);
+
+    var totalResults = results.android.length + results.docs.length;
+    if (totalResults === 0) {
+      list.addClass('no-results');
+    }
+
+    // Tweak see more logic to account for references.
+    var hasMore = totalResults > ROW_COUNT_COLLAPSED && !util.matchesMedia('mobile');
+    if (hasMore) {
+      // We can't actually show all matches, only as many as the expanded list
+      // will fit, so we actually lie if the total results count is more
+      var moreCount = Math.min(totalResults, ROW_COUNT_EXPANDED + ROW_COUNT_GOOGLE_EXPANDED);
+      var $moreLink = $('<li class="dac-search-results-reference-entry-empty " data-toggle="show-more">see more matches</li>');
+      list.append($moreLink.on('click', onToggleMore));
+    }
+    var searchEl = $('#search-resources');
+    searchEl.toggleClass('dac-has-more', searchEl.hasClass('dac-has-more') || (hasMore && !expanded));
+    searchEl.toggleClass('dac-has-less', searchEl.hasClass('dac-has-less') || (hasMore && expanded));
+  }
+
+  function onToggleMore(e) {
+    var link = $(e.currentTarget);
+    var referenceCard = $('.suggest-card.reference');
+    var data = referenceCard.data('searchreferences.dac');
+
+    if (util.matchesMedia('mobile')) { return; }
+
+    renderResults(referenceCard, data.results, data.query, link.data('toggle') === 'show-more');
+  }
+
+  $(document).on('click', '.dac-search-results-resources [data-toggle="show-more"]', onToggleMore);
+  $(document).on('click', '.dac-search-results-resources [data-toggle="show-less"]', onToggleMore);
+  $(document).on('click', '.suggest-card.reference a', onSuggestionClick);
+})(jQuery);
+
+(function($) {
+  function highlightPage(query, page) {
+    page.find('.title').highlightMatches(query);
+  }
+
+  $.fn.dacSearchRenderResources = function(gDocsMatches, query) {
+    this.resourceWidget(gDocsMatches, {
+      itemsPerPage: 18,
+      initialResults: 6,
+      cardSizes: ['6x2'],
+      onRenderPage: highlightPage.bind(null, query)
+    });
+
+    return this;
+  };
+})(jQuery);
+
+/*global metadata */
+
+(function($, metadata) {
+  'use strict';
+
+  function Search() {
+    this.body = $('body');
+    this.lastQuery = null;
+    this.searchResults = $('#search-results');
+    this.searchClose = $('[data-search-close]');
+    this.searchClear = $('[data-search-clear]');
+    this.searchInput = $('#search_autocomplete');
+    this.searchResultsContent = $('#dac-search-results-content');
+    this.searchResultsFor = $('#search-results-for');
+    this.searchResultsHistory = $('#dac-search-results-history');
+    this.searchResultsResources = $('#search-resources');
+    this.searchResultsHero = $('#dac-search-results-hero');
+    this.searchResultsReference = $('#dac-search-results-reference');
+    this.searchHeader = $('[data-search]').data('search-input.dac');
+    this.currQueryReferenceResults = {};
+  }
+
+  Search.prototype.init = function() {
+    if (!devsite && this.checkRedirectToIndex()) { return; }
+
+    this.searchHistory = window.dacStore('search-history');
+
+    this.searchInput.focus(this.onSearchChanged.bind(this));
+    this.searchInput.keydown(this.handleKeyboardShortcut.bind(this));
+    this.searchInput.on('input', this.onSearchChanged.bind(this));
+    this.searchClear.click(this.clear.bind(this));
+    this.searchClose.click(this.close.bind(this));
+
+    this.customSearch = $.fn.debounce(function(query) {
+      $('#dac-custom-search-results').customSearch(query, this);
+    }.bind(this), 1000);
+    // Start search shortcut (/)
+    $('body').keyup(function(event) {
+      if (event.which === 191 && $(event.target).is(':not(:input)')) {
+        this.searchInput.focus();
+      }
+    }.bind(this));
+
+    $(window).on('popstate', this.onPopState.bind(this));
+    $(window).hashchange(this.onHashChange.bind(this));
+    this.onHashChange();
+  };
+
+  Search.prototype.checkRedirectToIndex = function() {
+    var query = this.getUrlQuery();
+    var target = window.getLangTarget();
+    var prefix = (target !== 'en') ? '/intl/' + target : '';
+    var pathname = location.pathname.slice(prefix.length);
+    if (query != null && pathname !== '/index.html') {
+      location.href = prefix + '/index.html' + location.hash;
+      return true;
+    }
+  };
+
+  Search.prototype.handleKeyboardShortcut = function(event) {
+    // Close (esc)
+    if (event.which === 27) {
+      this.searchClose.trigger('click');
+      event.preventDefault();
+    }
+
+    // Previous result (up arrow)
+    if (event.which === 38) {
+      this.previousResult();
+      event.preventDefault();
+    }
+
+    // Next result (down arrow)
+    if (event.which === 40) {
+      this.nextResult();
+      event.preventDefault();
+    }
+
+    // Navigate to result (enter)
+    if (event.which === 13) {
+      this.navigateToResult();
+      event.preventDefault();
+    }
+  };
+
+  Search.prototype.goToResult = function(relativeIndex) {
+    var links = this.searchResults.find('a').filter(':visible');
+    var selectedLink = this.searchResults.find('.dac-selected');
+
+    if (selectedLink.length) {
+      var found = $.inArray(selectedLink[0], links);
+
+      selectedLink.removeClass('dac-selected');
+      links.eq(found + relativeIndex).addClass('dac-selected');
+      return true;
+    } else {
+      if (relativeIndex > 0) {
+        links.first().addClass('dac-selected');
+      }
+    }
+  };
+
+  Search.prototype.previousResult = function() {
+    this.goToResult(-1);
+  };
+
+  Search.prototype.nextResult = function() {
+    this.goToResult(1);
+  };
+
+  Search.prototype.navigateToResult = function() {
+    var query = this.getQuery();
+    var selectedLink = this.searchResults.find('.dac-selected');
+
+    if (selectedLink.length) {
+      selectedLink[0].click();
+    } else {
+      this.searchHistory.push(query);
+      this.addQueryToUrl(query);
+
+      var isMobileOrTablet = typeof window.orientation !== 'undefined';
+
+      if (isMobileOrTablet) {
+        this.searchInput.blur();
+      }
+    }
+  };
+
+  Search.prototype.onHashChange = function() {
+    var query = this.getUrlQuery();
+    if (query != null && query !== this.getQuery()) {
+      this.searchInput.val(query);
+      this.onSearchChanged();
+    }
+  };
+
+  Search.prototype.clear = function() {
+    this.searchInput.val('');
+    window.location.hash = '';
+    this.onSearchChanged();
+    this.searchInput.focus();
+  };
+
+  Search.prototype.close = function() {
+    this.removeQueryFromUrl();
+    this.searchInput.blur();
+    this.hideOverlay();
+  };
+
+  Search.prototype.getUrlQuery = function() {
+    var queryMatch = location.hash.match(/q=(.*)&?/);
+    return queryMatch && queryMatch[1] && decodeURI(queryMatch[1]);
+  };
+
+  Search.prototype.getQuery = function() {
+    return this.searchInput.val().replace(/(^ +)|( +$)/g, '');
+  };
+
+  Search.prototype.getReferenceResults = function() {
+    return this.currQueryReferenceResults;
+  };
+
+  Search.prototype.onSearchChanged = function() {
+    var query = this.getQuery();
+
+    this.showOverlay();
+    this.render(query);
+  };
+
+  Search.prototype.render = function(query) {
+    if (this.lastQuery === query) { return; }
+
+    if (query.length < 2) {
+      query = '';
+    }
+
+    this.lastQuery = query;
+    this.searchResultsFor.text(query);
+
+    // CSE results lag behind the metadata/reference results. We need to empty
+    // the CSE results and add 'Loading' text so user's aren't looking at two
+    // different sets of search results at one time.
+    var $loadingEl =
+        $('<div class="loadingCustomSearchResults">Loading Results...</div>');
+    $('#dac-custom-search-results').empty().prepend($loadingEl);
+
+    this.customSearch(query);
+    var metadataResults = metadata.search(query);
+    this.searchResultsResources.dacSearchRenderResources(metadataResults.resources, query);
+    this.searchResultsReference.dacSearchRenderReferences(metadataResults, query);
+    this.currQueryReferenceResults = metadataResults;
+    var hasHero = this.searchResultsHero.dacSearchRenderHero(metadataResults.resources, query);
+    var hasQuery = !!query;
+
+    this.searchResultsReference.toggle(!hasHero);
+    this.searchResultsContent.toggle(hasQuery);
+    this.searchResultsHistory.toggle(!hasQuery);
+    this.addQueryToUrl(query);
+    this.pushState();
+  };
+
+  Search.prototype.addQueryToUrl = function(query) {
+    var hash = 'q=' + encodeURI(query);
+
+    if (query) {
+      if (window.history.replaceState) {
+        window.history.replaceState(null, '', '#' + hash);
+      } else {
+        window.location.hash = hash;
+      }
+    }
+  };
+
+  Search.prototype.onPopState = function() {
+    if (!this.getUrlQuery()) {
+      this.hideOverlay();
+      this.searchHeader.unsetActiveState();
+    }
+  };
+
+  Search.prototype.removeQueryFromUrl = function() {
+    window.location.hash = '';
+  };
+
+  Search.prototype.pushState = function() {
+    if (window.history.pushState && !this.lastQuery.length) {
+      window.history.pushState(null, '');
+    }
+  };
+
+  Search.prototype.showOverlay = function() {
+    this.body.addClass('dac-modal-open dac-search-open');
+  };
+
+  Search.prototype.hideOverlay = function() {
+    this.body.removeClass('dac-modal-open dac-search-open');
+  };
+
+  $(document).on('ready.aranja', function() {
+    var search = new Search();
+    search.init();
+  });
+})(jQuery, metadata);
+
+window.dacStore = (function(window) {
+  /**
+   * Creates a new persistent store.
+   * If localStorage is unavailable, the items are stored in memory.
+   *
+   * @constructor
+   * @param {string} name    The name of the store
+   * @param {number} maxSize The maximum number of items the store can hold.
+   */
+  var Store = function(name, maxSize) {
+    var content = [];
+
+    var hasLocalStorage = !!window.localStorage;
+
+    if (hasLocalStorage) {
+      try {
+        content = JSON.parse(window.localStorage.getItem(name) || []);
+      } catch (e) {
+        // Store contains invalid data
+        window.localStorage.removeItem(name);
+      }
+    }
+
+    function push(item) {
+      if (content[0] === item) {
+        return;
+      }
+
+      content.unshift(item);
+
+      if (maxSize) {
+        content.splice(maxSize, content.length);
+      }
+
+      if (hasLocalStorage) {
+        window.localStorage.setItem(name, JSON.stringify(content));
+      }
+    }
+
+    function all() {
+      // Return a copy
+      return content.slice();
+    }
+
+    return {
+      push: push,
+      all: all
+    };
+  };
+
+  var stores = {
+    'search-history': new Store('search-history', 3)
+  };
+
+  /**
+   * Get a named persistent store.
+   * @param  {string} name
+   * @return {Store}
+   */
+  return function getStore(name) {
+    return stores[name];
+  };
+})(window);
+
 (function($) {
   'use strict';
 
@@ -5221,10 +5951,12 @@
   function SwapContent(el, options) {
     this.el = $(el);
     this.options = $.extend({}, SwapContent.DEFAULTS_, options);
+    this.options.dynamic = this.options.dynamic === 'true';
     this.containers = this.el.find(this.options.container);
     this.initiallyActive = this.containers.children('.' + this.options.activeClass).eq(0);
     this.el.on('swap-content', this.swap.bind(this));
     this.el.on('swap-reset', this.reset.bind(this));
+    this.el.find(this.options.swapButton).on('click', this.swap.bind(this));
   }
 
   /**
@@ -5235,6 +5967,8 @@
   SwapContent.DEFAULTS_ = {
     activeClass: 'dac-active',
     container: '[data-swap-container]',
+    dynamic: 'true',
+    swapButton: '[data-swap-button]',
     transitionSpeed: 500
   };
 
@@ -5268,9 +6002,15 @@
    * Perform the swap of content.
    */
   SwapContent.prototype.swap = function() {
-    console.log(this.containers);
     this.containers.each(function(index, container) {
       container = $(container);
+
+      if (!this.options.dynamic) {
+        container.children().toggleClass(this.options.activeClass);
+        this.complete.bind(this);
+        return;
+      }
+
       container.height(this.currentHeight(container)).children().toggleClass(this.options.activeClass);
       container.animate({height: this.currentHeight(container)}, this.options.transitionSpeed,
         this.complete.bind(this));
@@ -5297,6 +6037,178 @@
   });
 })(jQuery);
 
+/* Tabs */
+(function($) {
+  'use strict';
+
+  /**
+   * @param {HTMLElement} el - The DOM element.
+   * @param {Object} options
+   * @constructor
+   */
+  function Tabs(el, options) {
+    this.el = $(el);
+    this.options = $.extend({}, Tabs.DEFAULTS_, options);
+    this.init();
+  }
+
+  Tabs.DEFAULTS_ = {
+    activeClass: 'dac-active',
+    viewDataAttr: 'tab-view',
+    itemDataAttr: 'tab-item'
+  };
+
+  Tabs.prototype.init = function() {
+    var itemDataAttribute = '[data-' + this.options.itemDataAttr + ']';
+    this.tabEl_ = this.el.find(itemDataAttribute);
+    this.tabViewEl_ = this.el.find('[data-' + this.options.viewDataAttr + ']');
+    this.el.on('click.dac-tabs', itemDataAttribute, this.changeTabs.bind(this));
+  };
+
+  Tabs.prototype.changeTabs = function(event) {
+    var current = $(event.currentTarget);
+    var index = current.index();
+
+    if (current.hasClass(this.options.activeClass)) {
+      current.add(this.tabViewEl_.eq(index)).removeClass(this.options.activeClass);
+    } else {
+      this.tabEl_.add(this.tabViewEl_).removeClass(this.options.activeClass);
+      current.add(this.tabViewEl_.eq(index)).addClass(this.options.activeClass);
+    }
+  };
+
+  /**
+   * jQuery plugin
+   */
+  $.fn.dacTabs = function() {
+    return this.each(function() {
+      var el = $(this);
+      new Tabs(el, el.data());
+    });
+  };
+
+  /**
+   * Data Attribute API
+   */
+  $(function() {
+    $('[data-tabs]').dacTabs();
+  });
+})(jQuery);
+
+/* Toast Component */
+(function($) {
+  'use strict';
+  /**
+   * @constant
+   * @type {String}
+   */
+  var LOCAL_STORAGE_KEY = 'toast-closed-index';
+
+  /**
+   * Dictionary from local storage.
+   */
+  var toastDictionary = localStorage.getItem(LOCAL_STORAGE_KEY);
+  toastDictionary = toastDictionary ? JSON.parse(toastDictionary) : {};
+
+  /**
+   * Variable used for caching the body.
+   */
+  var bodyCached;
+
+  /**
+   * @param {HTMLElement} el - The DOM element.
+   * @param {Object} options
+   * @constructor
+   */
+  function Toast(el, options) {
+    this.el = $(el);
+    this.options = $.extend({}, Toast.DEFAULTS_, options);
+    this.init();
+  }
+
+  Toast.DEFAULTS_ = {
+    closeBtnClass: 'dac-toast-close-btn',
+    closeDuration: 200,
+    visibleClass: 'dac-visible',
+    wrapClass: 'dac-toast-wrap'
+  };
+
+  /**
+   * Generate a close button.
+   * @returns {*|HTMLElement}
+   */
+  Toast.prototype.closeBtn = function() {
+    this.closeBtnEl = this.closeBtnEl || $('<button class="' + this.options.closeBtnClass + '">' +
+      '<i class="dac-sprite dac-close-black"></i>' +
+    '</button>');
+    return this.closeBtnEl;
+  };
+
+  /**
+   * Initialize a new toast element
+   */
+  Toast.prototype.init = function() {
+    this.hash = this.el.text().replace(/[\s\n\t]/g, '').split('').slice(0, 128).join('');
+
+    if (toastDictionary[this.hash]) {
+      return;
+    }
+
+    this.closeBtn().on('click', this.onClickHandler.bind(this));
+    this.el.find('.' + this.options.wrapClass).append(this.closeBtn());
+    this.el.addClass(this.options.visibleClass);
+    this.dynamicPadding(this.el.outerHeight());
+  };
+
+  /**
+   * Add padding to make sure all page is visible.
+   */
+  Toast.prototype.dynamicPadding = function(val) {
+    var currentPadding = parseInt(bodyCached.css('padding-bottom') || 0);
+    bodyCached.css('padding-bottom', val + currentPadding);
+  };
+
+  /**
+   * Remove a toast from the DOM
+   */
+  Toast.prototype.remove = function() {
+    this.dynamicPadding(-this.el.outerHeight());
+    this.el.remove();
+  };
+
+  /**
+   * Handle removal of the toast.
+   */
+  Toast.prototype.onClickHandler = function() {
+    // Only fadeout toasts from top of stack. Others are removed immediately.
+    var duration = this.el.index() === 0 ? this.options.closeDuration : 0;
+    this.el.fadeOut(duration, this.remove.bind(this));
+
+    // Save closed state.
+    toastDictionary[this.hash] = 1;
+    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(toastDictionary));
+  };
+
+  /**
+   * jQuery plugin
+   * @param  {object} options - Override default options.
+   */
+  $.fn.dacToast = function() {
+    return this.each(function() {
+      var el = $(this);
+      new Toast(el, el.data());
+    });
+  };
+
+  /**
+   * Data Attribute API
+   */
+  $(function() {
+    bodyCached = $('#body-content');
+    $('[data-toast]').dacToast();
+  });
+})(jQuery);
+
 (function($) {
   function Toggle(el) {
     $(el).on('click.dac.togglesection', this.toggle);
@@ -5341,8 +6253,12 @@
 
     // If we're hiding, first set the maxHeight we're transitioning from.
     if (!visible) {
-      $el.css('maxHeight', contentHeight + 'px')
-        .resolveStyles();
+      $el.css({
+          transitionDuration: '0s',
+          maxHeight: contentHeight + 'px'
+        })
+        .resolveStyles()
+        .css('transitionDuration', '');
     }
 
     // Transition to new state
@@ -5350,7 +6266,12 @@
 
     // Reset maxHeight to css value after transition.
     setTimeout(function() {
-      $el.css('maxHeight', '');
+      $el.css({
+          transitionDuration: '0s',
+          maxHeight: ''
+        })
+        .resolveStyles()
+        .css('transitionDuration', '');
     }, duration);
   }
 
@@ -5375,3 +6296,263 @@
   $(document)
     .on('click.toggle', '[data-toggle="section"]', Toggle.prototype.toggle);
 })(jQuery);
+
+(function(window) {
+  /**
+   * Media query breakpoints. Should match CSS.
+   */
+  var BREAKPOINTS = {
+    mobile: [0, 719],
+    tablet: [720, 959],
+    desktop: [960, 9999]
+  };
+
+  /**
+   * Fisher-Yates Shuffle (Knuth shuffle).
+   * @param {Array} input
+   * @returns {Array} shuffled array.
+   */
+  function shuffle(input) {
+    for (var i = input.length; i >= 0; i--) {
+      var randomIndex = Math.floor(Math.random() * (i + 1));
+      var randomItem = input[randomIndex];
+      input[randomIndex] = input[i];
+      input[i] = randomItem;
+    }
+
+    return input;
+  }
+
+  /**
+   * Matches media breakpoints like in CSS.
+   * @param {string} form of either mobile, tablet or desktop.
+   */
+  function matchesMedia(form) {
+    var breakpoint = BREAKPOINTS[form];
+    return window.innerWidth >= breakpoint[0] && window.innerWidth <= breakpoint[1];
+  }
+
+  window.util = {
+    shuffle: shuffle,
+    matchesMedia: matchesMedia
+  };
+})(window);
+
+(function($, window) {
+  'use strict';
+
+  var YouTubePlayer = (function() {
+    var player;
+
+    function VideoPlayer() {
+      this.mPlayerPaused = false;
+      this.doneSetup = false;
+    }
+
+    VideoPlayer.prototype.setup = function() {
+      // loads the IFrame Player API code asynchronously.
+      $.getScript('https://www.youtube.com/iframe_api');
+
+      // Add the shadowbox HTML to the body
+      $('body').prepend(
+'<div id="video-player" class="Video">' +
+  '<div id="video-overlay" class="Video-overlay" />' +
+  '<div class="Video-container">' +
+    '<div class="Video-frame">' +
+      '<span class="Video-loading">Loading&hellip;</span>' +
+      '<div id="youTubePlayer"></div>' +
+    '</div>' +
+    '<div class="Video-controls">' +
+      '<button id="picture-in-picture" class="Video-button Video-button--picture-in-picture">' +
+      '<button id="close-video" class="Video-button Video-button--close" />' +
+    '</div>' +
+  '</div>' +
+'</div>');
+
+      this.videoPlayer = $('#video-player');
+
+      var pictureInPictureButton = this.videoPlayer.find('#picture-in-picture');
+      pictureInPictureButton.on('click.aranja', this.toggleMinimizeVideo.bind(this));
+
+      var videoOverlay = this.videoPlayer.find('#video-overlay');
+      var closeButton = this.videoPlayer.find('#close-video');
+      var closeVideo = this.closeVideo.bind(this);
+      videoOverlay.on('click.aranja', closeVideo);
+      closeButton.on('click.aranja', closeVideo);
+
+      this.doneSetup = true;
+    };
+
+    VideoPlayer.prototype.startYouTubePlayer = function(videoId) {
+      this.videoPlayer.show();
+
+      if (!this.isLoaded) {
+        this.queueVideo = videoId;
+        return;
+      }
+
+      this.mPlayerPaused = false;
+      // check if we've already created this player
+      if (!this.youTubePlayer) {
+        // check if there's a start time specified
+        var idAndHash = videoId.split('#');
+        var startTime = 0;
+        if (idAndHash.length > 1) {
+          startTime = idAndHash[1].split('t=')[1] !== undefined ? idAndHash[1].split('t=')[1] : 0;
+        }
+        // enable localized player
+        var lang = getLangPref();
+        var captionsOn = lang === 'en' ? 0 : 1;
+
+        this.youTubePlayer = new YT.Player('youTubePlayer', {
+          height: 720,
+          width: 1280,
+          videoId: idAndHash[0],
+          // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
+          playerVars: {start: startTime, hl: lang, cc_load_policy: captionsOn},
+          // jscs:enable
+          events: {
+            'onReady': this.onPlayerReady.bind(this),
+            'onStateChange': this.onPlayerStateChange.bind(this)
+          }
+        });
+      } else {
+        // if a video different from the one already playing was requested, cue it up
+        if (videoId !== this.getVideoId()) {
+          this.youTubePlayer.cueVideoById(videoId);
+        }
+        this.youTubePlayer.playVideo();
+      }
+    };
+
+    VideoPlayer.prototype.onPlayerReady = function(event) {
+      if (!isMobile) {
+        event.target.playVideo();
+        this.mPlayerPaused = false;
+      }
+    };
+
+    VideoPlayer.prototype.toggleMinimizeVideo = function(event) {
+      event.stopPropagation();
+      this.videoPlayer.toggleClass('Video--picture-in-picture');
+    };
+
+    VideoPlayer.prototype.closeVideo = function() {
+      try {
+        this.youTubePlayer.pauseVideo();
+      } catch (e) {
+      }
+      this.videoPlayer.fadeOut(200, function() {
+        this.videoPlayer.removeClass('Video--picture-in-picture');
+      }.bind(this));
+    };
+
+    VideoPlayer.prototype.getVideoId = function() {
+      // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
+      return this.youTubePlayer && this.youTubePlayer.getVideoData().video_id;
+      // jscs:enable
+    };
+
+    /* Track youtube playback for analytics */
+    VideoPlayer.prototype.onPlayerStateChange = function(event) {
+      var videoId = this.getVideoId();
+      var currentTime = this.youTubePlayer && this.youTubePlayer.getCurrentTime();
+
+      // Video starts, send the video ID
+      if (event.data === YT.PlayerState.PLAYING) {
+        if (this.mPlayerPaused) {
+          ga('send', 'event', 'Videos', 'Resume', videoId);
+        } else {
+          // track the start playing event so we know from which page the video was selected
+          ga('send', 'event', 'Videos', 'Start: ' + videoId, 'on: ' + document.location.href);
+        }
+        this.mPlayerPaused = false;
+      }
+
+      // Video paused, send video ID and video elapsed time
+      if (event.data === YT.PlayerState.PAUSED) {
+        ga('send', 'event', 'Videos', 'Paused', videoId, currentTime);
+        this.mPlayerPaused = true;
+      }
+
+      // Video finished, send video ID and video elapsed time
+      if (event.data === YT.PlayerState.ENDED) {
+        ga('send', 'event', 'Videos', 'Finished', videoId, currentTime);
+        this.mPlayerPaused = true;
+      }
+    };
+
+    return {
+      getPlayer: function() {
+        if (!player) {
+          player = new VideoPlayer();
+        }
+
+        return player;
+      }
+    };
+  })();
+
+  var videoPlayer = YouTubePlayer.getPlayer();
+
+  window.onYouTubeIframeAPIReady = function() {
+    videoPlayer.isLoaded = true;
+
+    if (videoPlayer.queueVideo) {
+      videoPlayer.startYouTubePlayer(videoPlayer.queueVideo);
+    }
+  };
+
+  function wrapLinkInPlayer(e) {
+    e.preventDefault();
+
+    if (!videoPlayer.doneSetup) {
+      videoPlayer.setup();
+    }
+
+    var videoIdMatches = $(e.currentTarget).attr('href').match(/(?:youtu.be\/|v=)([^&]*)/);
+    var videoId = videoIdMatches && videoIdMatches[1];
+
+    if (videoId) {
+      videoPlayer.startYouTubePlayer(videoId);
+    }
+  }
+
+  $(document).on('click.video', 'a[href*="youtube.com/watch"], a[href*="youtu.be"]', wrapLinkInPlayer);
+})(jQuery, window);
+
+/**
+ * Wide table
+ *
+ * Wraps tables in a scrollable area so you can read them on mobile.
+ */
+(function($) {
+  function initWideTable() {
+    $('table.jd-sumtable').each(function(i, table) {
+      $(table).wrap('<div class="dac-expand wide-table">');
+    });
+  }
+
+  $(function() {
+    initWideTable();
+  });
+})(jQuery);
+
+/** Utilities */
+
+/* returns the given string with all HTML brackets converted to entities
+    TODO: move this to the site's JS library */
+function escapeHTML(string) {
+  return string.replace(/</g,"&lt;")
+                .replace(/>/g,"&gt;");
+};
+
+function getQueryVariable(variable) {
+  var query = window.location.search.substring(1);
+  var vars = query.split("&");
+  for (var i=0;i<vars.length;i++) {
+    var pair = vars[i].split("=");
+    if(pair[0] == variable){return pair[1];}
+  }
+  return(false);
+};
