diff --git a/build/tools/droiddoc/templates-cmsdk/assets/docs.js b/build/tools/droiddoc/templates-cmsdk/assets/docs.js
new file mode 100644
index 0000000..3ab4caf
--- /dev/null
+++ b/build/tools/droiddoc/templates-cmsdk/assets/docs.js
@@ -0,0 +1,4339 @@
+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
+
+// Ensure that all ajax getScript() requests allow caching
+$.ajaxSetup({
+  cache: true
+});
+
+/******  ON LOAD SET UP STUFF *********/
+
+$(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');
+
+  // setup keyboard listener for search shortcut
+  $('body').keyup(function(event) {
+    if (event.which == 191) {
+      $('#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
+  $('.scroll-pane').jScrollPane( {verticalGutter:0} );
+
+  // add HRs below all H2s (except for a few other h2 variants)
+  $('h2').not('#qv h2')
+         .not('#tb h2')
+         .not('.sidebox h2')
+         .not('#devdoc-nav h2')
+         .not('h2.norule').css({marginBottom:0})
+         .after('<hr/>');
+
+  // set up the search close button
+  $('.search .close').click(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 quicknav
+  var quicknav_open = false;
+  $("#btn-quicknav").click(function() {
+    if (quicknav_open) {
+      $(this).removeClass('active');
+      quicknav_open = false;
+      collapse();
+    } else {
+      $(this).addClass('active');
+      quicknav_open = true;
+      expand();
+    }
+  })
+
+  var expand = function() {
+   $('#header-wrap').addClass('quicknav');
+   $('#quicknav').stop().show().animate({opacity:'1'});
+  }
+
+  var collapse = function() {
+    $('#quicknav').stop().animate({opacity:'0'}, 100, function() {
+      $(this).hide();
+      $('#header-wrap').removeClass('quicknav');
+    });
+  }
+
+
+  //Set up search
+  $("#search_autocomplete").focus(function() {
+    $("#search-container").addClass('active');
+  })
+  $("#search-container").mouseover(function() {
+    $("#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;
+  // 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 /
+  }
+
+  if (pagePath.indexOf(SITE_ROOT) == 0) {
+    if (pagePath == '' || pagePath.charAt(pagePath.length - 1) == '/') {
+      pagePath += 'index.html';
+    }
+  }
+
+  // Need a copy of the pagePath before it gets changed in the next block;
+  // it's needed to perform proper tab highlighting in offline docs (see rootDir below)
+  var pagePathOriginal = pagePath;
+  if (SITE_ROOT.match(/\.\.\//) || SITE_ROOT == '') {
+    // If running locally, SITE_ROOT will be a relative path, so account for that by
+    // finding the relative URL to this page. This will allow us to find links on the page
+    // leading back to this page.
+    var pathParts = pagePath.split('/');
+    var relativePagePathParts = [];
+    var upDirs = (SITE_ROOT.match(/(\.\.\/)+/) || [''])[0].length / 3;
+    for (var i = 0; i < upDirs; i++) {
+      relativePagePathParts.push('..');
+    }
+    for (var i = 0; i < upDirs; i++) {
+      relativePagePathParts.push(pathParts[pathParts.length - (upDirs - i) - 1]);
+    }
+    relativePagePathParts.push(pathParts[pathParts.length - 1]);
+    pagePath = relativePagePathParts.join('/');
+  } else {
+    // Otherwise the page path is already an absolute URL
+  }
+
+  // Highlight the header tabs...
+  // highlight Design tab
+  if ($("body").hasClass("design")) {
+    $("#header li.design a").addClass("selected");
+    $("#sticky-header").addClass("design");
+
+  // highlight About tabs
+  } else if ($("body").hasClass("about")) {
+    var rootDir = pagePathOriginal.substring(1,pagePathOriginal.indexOf('/', 1));
+    if (rootDir == "about") {
+      $("#nav-x li.about a").addClass("selected");
+    } else if (rootDir == "wear") {
+      $("#nav-x li.wear a").addClass("selected");
+    } else if (rootDir == "tv") {
+      $("#nav-x li.tv a").addClass("selected");
+    } else if (rootDir == "auto") {
+      $("#nav-x li.auto a").addClass("selected");
+    }
+  // highlight Develop tab
+  } else if ($("body").hasClass("develop") || $("body").hasClass("google")) {
+    $("#header li.develop a").addClass("selected");
+    $("#sticky-header").addClass("develop");
+    // In Develop docs, also highlight appropriate sub-tab
+    var rootDir = pagePathOriginal.substring(1,pagePathOriginal.indexOf('/', 1));
+    if (rootDir == "training") {
+      $("#nav-x li.training a").addClass("selected");
+    } else if (rootDir == "guide") {
+      $("#nav-x li.guide a").addClass("selected");
+    } else if (rootDir == "reference") {
+      // If the root is reference, but page is also part of Google Services, select Google
+      if ($("body").hasClass("google")) {
+        $("#nav-x li.google a").addClass("selected");
+      } else {
+        $("#nav-x li.reference a").addClass("selected");
+      }
+    } else if ((rootDir == "tools") || (rootDir == "sdk")) {
+      $("#nav-x li.tools a").addClass("selected");
+    } else if ($("body").hasClass("google")) {
+      $("#nav-x li.google a").addClass("selected");
+    } else if ($("body").hasClass("samples")) {
+      $("#nav-x li.samples a").addClass("selected");
+    }
+
+  // highlight Distribute tab
+  } else if ($("body").hasClass("distribute")) {
+    $("#header li.distribute a").addClass("selected");
+    $("#sticky-header").addClass("distribute");
+
+    var baseFrag = pagePathOriginal.indexOf('/', 1) + 1;
+    var secondFrag = pagePathOriginal.substring(baseFrag, pagePathOriginal.indexOf('/', baseFrag));
+    if (secondFrag == "users") {
+      $("#nav-x li.users a").addClass("selected");
+    } else if (secondFrag == "engage") {
+      $("#nav-x li.engage a").addClass("selected");
+    } else if (secondFrag == "monetize") {
+      $("#nav-x li.monetize a").addClass("selected");
+    } else if (secondFrag == "analyze") {
+      $("#nav-x li.analyze a").addClass("selected");
+    } else if (secondFrag == "tools") {
+      $("#nav-x li.disttools a").addClass("selected");
+    } else if (secondFrag == "stories") {
+      $("#nav-x li.stories a").addClass("selected");
+    } else if (secondFrag == "essentials") {
+      $("#nav-x li.essentials a").addClass("selected");
+    } else if (secondFrag == "googleplay") {
+      $("#nav-x li.googleplay a").addClass("selected");
+    }
+  } else if ($("body").hasClass("about")) {
+    $("#sticky-header").addClass("about");
+  }
+
+  // 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 + '"]');
+  var $selListItem;
+  if ($selNavLink.length) {
+    $selListItem = $selNavLink.closest('li');
+
+    // set up prev links
+    var $prevLink = [];
+    var $prevListItem = $selListItem.prev('li');
+
+    var crossBoundaries = ($("body.design").length > 0) || ($("body.guide").length > 0) ? true :
+false; // navigate across topic boundaries only in design docs
+    if ($prevListItem.length) {
+      if ($prevListItem.hasClass('nav-section') || crossBoundaries) {
+        // jump to last topic of previous section
+        $prevLink = $prevListItem.find('a:last');
+      } else if (!$selListItem.hasClass('nav-section')) {
+        // jump to previous topic in this section
+        $prevLink = $prevListItem.find('a:eq(0)');
+      }
+    } else {
+      // jump to this section's index page (if it exists)
+      var $parentListItem = $selListItem.parents('li');
+      $prevLink = $selListItem.parents('li').find('a');
+
+      // 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')) {
+        $prevLink = [];
+      }
+    }
+
+    // set up next links
+    var $nextLink = [];
+    var startClass = false;
+    var isCrossingBoundary = false;
+
+    if ($selListItem.hasClass('nav-section') && $selListItem.children('div.empty').length == 0) {
+      // we're on an index page, jump to the first topic
+      $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) {
+        $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)
+        // then set the landing page "start link" text to be the first doc title
+        $('.topic-start-link').text($nextLink.text().toUpperCase());
+      }
+
+      // If the selected page has a description, then it's a class or article homepage
+      if ($selListItem.find('a[description]').length) {
+        // this means we're on a class landing page
+        startClass = true;
+      }
+    } else {
+      // jump to the next topic in this section (if it exists)
+      $nextLink = $selListItem.next('li').find('a:eq(0)');
+      if ($nextLink.length == 0) {
+        isCrossingBoundary = true;
+        // no more topics in this section, jump to the first topic in the next section
+        $nextLink = $selListItem.parents('li:eq(0)').next('li').find('a:eq(0)');
+        if (!$nextLink.length) {  // Go up another layer to look for next page (lesson > class > course)
+          $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")
+                                .click(function() { return false; });
+            // and completely hide the one in the footer
+            $('.content-footer .next-page-link').hide();
+          }
+        }
+      }
+    }
+
+    if (startClass) {
+      $('.start-class-link').attr('href', $nextLink.attr('href')).removeClass("hide");
+
+      // if there's no training bar (below the start button),
+      // then we need to add a bottom border to button
+      if (!$("#tb").length) {
+        $('.start-class-link').css({'border-bottom':'1px solid #DADADA'});
+      }
+    } else if (isCrossingBoundary && !$('body.design').length) {  // Design always crosses boundaries
+      $('.content-footer.next-class').show();
+      $('.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();
+      if ($nextLink.length) {
+        $('.next-class-link').attr('href',$nextLink.attr('href'))
+                             .removeClass("hide")
+                             .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());
+    }
+
+    if (!startClass && $prevLink.length) {
+      var prevHref = $prevLink.attr('href');
+      if (prevHref == SITE_ROOT + 'index.html') {
+        // Don't show Previous when it leads to the homepage
+      } else {
+        $('.prev-page-link').attr('href', $prevLink.attr('href')).removeClass("hide");
+      }
+    }
+
+  }
+
+
+
+  // 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');
+
+    // create an array for all the class descriptions
+    var $classDescriptions = new Array($classLinks.length);
+    var lang = getLangPref();
+    $classLinks.each(function(index) {
+      var langDescr = $(this).attr(lang + "-description");
+      if (typeof langDescr !== 'undefined' && langDescr !== false) {
+        // if there's a class description in the selected language, use that
+        $classDescriptions[index] = langDescr;
+      } else {
+        // otherwise, use the default english description
+        $classDescriptions[index] = $(this).attr("description");
+      }
+    });
+
+    var $olClasses  = $('<ol class="class-list"></ol>');
+    var $liClass;
+    var $imgIcon;
+    var $h2Title;
+    var $pSummary;
+    var $olLessons;
+    var $liLesson;
+    $classLinks.each(function(index) {
+      $liClass  = $('<li></li>');
+      $h2Title  = $('<a class="title" href="'+$(this).attr('href')+'"><h2>' + $(this).html()+'</h2><span></span></a>');
+      $pSummary = $('<p class="description">' + $classDescriptions[index] + '</p>');
+
+      $olLessons  = $('<ol class="lesson-list"></ol>');
+
+      $lessons = $(this).closest('li').find('ul li a');
+
+      if ($lessons.length) {
+        $imgIcon = $('<img src="'+toRoot+'assets/images/resource-tutorial.png" '
+            + ' width="64" height="64" alt=""/>');
+        $lessons.each(function(index) {
+          $olLessons.append('<li><a href="'+$(this).attr('href')+'">' + $(this).html()+'</a></li>');
+        });
+      } else {
+        $imgIcon = $('<img src="'+toRoot+'assets/images/resource-article.png" '
+            + ' width="64" height="64" alt=""/>');
+        $pSummary.addClass('article');
+      }
+
+      $liClass.append($h2Title).append($imgIcon).append($pSummary).append($olLessons);
+      $olClasses.append($liClass);
+    });
+    $('.jd-descr').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;
+    var stylesheet = $('link[rel="stylesheet"][class="fullscreen"]');
+    setNavBarLeftPos(); // 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
+    if (sticky) {
+      if ((stylesheet.attr("disabled") == "disabled") || stylesheet.length == 0) {
+        updateSideNavPosition();
+      } else {
+        updateSidenavFullscreenWidth();
+      }
+    }
+    resizeNav();
+  });
+
+
+  var navBarLeftPos;
+  if ($('#devdoc-nav').length) {
+    setNavBarLeftPos();
+  }
+
+
+  // Set up play-on-hover <video> tags.
+  $('video.play-on-hover').bind('click', function(){
+    $(this).get(0).load(); // in case the video isn't seekable
+    $(this).get(0).play();
+  });
+
+  // Set up tooltips
+  var TOOLTIP_MARGIN = 10;
+  $('acronym,.tooltip-link').each(function() {
+    var $target = $(this);
+    var $tooltip = $('<div>')
+        .addClass('tooltip-box')
+        .append($target.attr('title'))
+        .hide()
+        .appendTo('body');
+    $target.removeAttr('title');
+
+    $target.hover(function() {
+      // in
+      var targetRect = $target.offset();
+      targetRect.width = $target.width();
+      targetRect.height = $target.height();
+
+      $tooltip.css({
+        left: targetRect.left,
+        top: targetRect.top + targetRect.height + TOOLTIP_MARGIN
+      });
+      $tooltip.addClass('below');
+      $tooltip.show();
+    }, function() {
+      // out
+      $tooltip.hide();
+    });
+  });
+
+  // Set up <h2> deeplinks
+  $('h2').click(function() {
+    var id = $(this).attr('id');
+    if (id) {
+      document.location.hash = id;
+    }
+  });
+
+  //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);
+
+
+  // Revise the sidenav widths to make room for the scrollbar
+  // which avoids the visible width from changing each time the bar appears
+  var $sidenav = $("#side-nav");
+  var sidenav_width = parseInt($sidenav.innerWidth());
+
+  $("#devdoc-nav  #nav").css("width", sidenav_width - 4 + "px"); // 4px is scrollbar width
+
+
+  $(".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);
+      });
+    });
+  }
+});
+// 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 */
+      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 */
+      // 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();
+      });
+    }
+  });
+
+  // Stop expand/collapse behavior when clicking on nav section links
+  // (since we're navigating away from the page)
+  // This selector captures the first instance of <a>, but not those with "#" as the href.
+  $('.nav-section-header').find('a:eq(0)').not('a[href="#"]').click(function(evt) {
+    window.location.href = $(this).attr('href');
+    return false;
+  });
+}
+
+
+/** Create the list of breadcrumb links in the sticky header */
+function buildBreadcrumbs() {
+  var $breadcrumbUl =  $("#sticky-header ul.breadcrumb");
+  // Add the secondary horizontal nav item, if provided
+  var $selectedSecondNav = $("div#nav-x ul.nav-x a.selected").clone().removeClass("selected");
+  if ($selectedSecondNav.length) {
+    $breadcrumbUl.prepend($("<li>").append($selectedSecondNav))
+  }
+  // Add the primary horizontal nav
+  var $selectedFirstNav = $("div#header-wrap ul.nav-x a.selected").clone().removeClass("selected");
+  // If there's no header nav item, use the logo link and title from alt text
+  if ($selectedFirstNav.length < 1) {
+    $selectedFirstNav = $("<a>")
+        .attr('href', $("div#header .logo a").attr('href'))
+        .text($("div#header .logo img").attr('alt'));
+  }
+  $breadcrumbUl.prepend($("<li>").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)
+  if ($("ul#nav li.selected").length) {
+    unHighlightSidenav();
+  }
+  // look for URL in sidenav, including the hash
+  var $selNavLink = $('#nav').find('a[href="' + mPagePath + location.hash + '"]');
+
+  // If the selNavLink is still empty, look for it without the hash
+  if ($selNavLink.length == 0) {
+    $selNavLink = $('#nav').find('a[href="' + mPagePath + '"]');
+  }
+
+  var $selListItem;
+  if ($selNavLink.length) {
+    // Find this page's <li> in sidenav and set selected
+    $selListItem = $selNavLink.closest('li');
+    $selListItem.addClass('selected');
+
+    // Traverse up the tree and expand all parent nav-sections
+    $selNavLink.parents('li.nav-section').each(function() {
+      $(this).addClass('expanded');
+      $(this).children('ul').show();
+    });
+  }
+}
+
+function unHighlightSidenav() {
+  $("ul#nav li.selected").removeClass("selected");
+  $('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);
+  setNavBarLeftPos();
+  resizeNav(delay);
+  updateSideNavPosition();
+  setTimeout(initSidenavHeightResize,delay);
+}
+
+
+function setNavBarLeftPos() {
+  navBarLeftPos = $('#body-content').offset().left;
+}
+
+
+function updateSideNavPosition() {
+  var newLeft = $(window).scrollLeft() - navBarLeftPos;
+  $('#devdoc-nav').css({left: -newLeft});
+  $('#devdoc-nav .totop').css({left: -(newLeft - parseInt($('#side-nav').css('margin-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
+    (agent.indexOf("blackberry") != -1) ||
+    (agent.indexOf("webos") != -1) ||
+    (agent.indexOf("mini") != -1)) {        // opera mini browsers
+  isMobile = true;
+}
+
+
+$(document).ready(function() {
+  $("pre:not(.no-pretty-print)").addClass("prettyprint");
+  prettyPrint();
+});
+
+
+
+
+/* ######### RESIZE THE SIDENAV HEIGHT ########## */
+
+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('margin-top')) || parseInt($nav.css('top'))) + 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 ($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) { setTimeout(reInitScrollbars,300); 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) {
+  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;
+    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.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+"=";
+  if (document.cookie) {
+    var index = document.cookie.indexOf(myCookie);
+    if (index != -1) {
+      var valStart = index + myCookie.length;
+      var valEnd = document.cookie.indexOf(";", valStart);
+      if (valEnd == -1) {
+        valEnd = document.cookie.length;
+      }
+      var val = document.cookie.substring(valStart, valEnd);
+      return val;
+    }
+  }
+  return 0;
+}
+
+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=/";
+  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() - $('#sticky-header').outerHeight();
+}
+
+/*
+ * Displays sticky nav bar on pages when dac header scrolls out of view
+ */
+$(window).scroll(function(event) {
+
+  setStickyTop();
+  var hiding = false;
+  var $stickyEl = $('#sticky-header');
+  var $menuEl = $('.menu-container');
+  // Exit if there's no sidenav
+  if ($('#side-nav').length == 0) return;
+  // 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;
+  }
+
+  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;
+  }
+  // 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)) {
+    updateSideNavPosition();
+    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;
+    hiding = true;
+    // make the sidenav static again
+    $('#devdoc-nav')
+        .removeClass('fixed')
+        .css({'width':'auto','margin':''})
+        .prependTo('#side-nav');
+    // delay hide the sticky
+    $menuEl.removeClass('sticky-menu');
+    $stickyEl.fadeOut(250);
+    hiding = false;
+
+    // update the sidenaav position for side scrolling
+    updateSideNavPosition();
+  } else if (!sticky && shouldBeSticky) {
+    sticky = true;
+    $stickyEl.fadeIn(10);
+    $menuEl.addClass('sticky-menu');
+
+    // make the sidenav fixed
+    var width = $('#devdoc-nav').width();
+    $('#devdoc-nav')
+        .addClass('fixed')
+        .css({'width':width+'px'})
+        .prependTo('#body-content');
+
+    // update the sidenaav position for side scrolling
+    updateSideNavPosition();
+
+  } else if (hiding && top < 15) {
+    $menuEl.removeClass('sticky-menu');
+    $stickyEl.hide();
+    hiding = false;
+  }
+  resizeNav(250); // pass true in order to delay the scrollbar re-initialization for performance
+});
+
+/*
+ * Manages secion card states and nav resize to conclude loading
+ */
+(function() {
+  $(document).ready(function() {
+
+    // Stack hover states
+    $('.section-card-menu').each(function(index, el) {
+      var height = $(el).height();
+      $(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'});
+    });
+
+  });
+
+})();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*      MISC LIBRARY FUNCTIONS     */
+
+
+
+
+
+function toggle(obj, slide) {
+  var ul = $("ul:first", obj);
+  var li = ul.parent();
+  if (li.hasClass("closed")) {
+    if (slide) {
+      ul.slideDown("fast");
+    } else {
+      ul.show();
+    }
+    li.removeClass("closed");
+    li.addClass("open");
+    $(".toggle-img", li).attr("title", "hide pages");
+  } else {
+    ul.slideUp("fast");
+    li.removeClass("open");
+    li.addClass("closed");
+    $(".toggle-img", li).attr("title", "show pages");
+  }
+}
+
+
+function buildToggleLists() {
+  $(".toggle-list").each(
+    function(i) {
+      $("div:first", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
+      $(this).addClass("closed");
+    });
+}
+
+
+
+function hideNestedItems(list, toggle) {
+  $list = $(list);
+  // hide nested lists
+  if($list.hasClass('showing')) {
+    $("li ol", $list).hide('fast');
+    $list.removeClass('showing');
+  // show nested lists
+  } else {
+    $("li ol", $list).show('fast');
+    $list.addClass('showing');
+  }
+  $(".more,.less",$(toggle)).toggle();
+}
+
+
+/* Call this to add listeners to a <select> element for Studio/Eclipse/Other docs */
+function setupIdeDocToggle() {
+  $( "select.ide" ).change(function() {
+    var selected = $(this).find("option:selected").attr("value");
+    $(".select-ide").hide();
+    $(".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) {
+  var $links = $("#devdoc-nav,#header,#nav-x,.training-nav-top,.content-footer").find("a["+lang+"-lang]");
+  $links.each(function(i){ // for each link with a translation
+    var $link = $(this);
+    if (lang != "en") { // No need to worry about English, because a language change invokes new request
+      // 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);
+  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/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/triangle-closed.png");
+    });
+  }
+  return false;
+}
+
+
+/* New version of expandable content */
+function toggleExpandable(link,id) {
+  if($(id).is(':visible')) {
+    $(id).slideUp();
+    $(link).removeClass('expanded');
+  } else {
+    $(id).slideDown();
+    $(link).addClass('expanded');
+  }
+}
+
+function hideExpandable(ids) {
+  $(ids).slideUp();
+  $(ids).prev('h4').find('a.expandable').removeClass('expanded');
+}
+
+
+
+
+
+/*
+ *  Slideshow 1.0
+ *  Used on /index.html and /develop/index.html for carousel
+ *
+ *  Sample usage:
+ *  HTML -
+ *  <div class="slideshow-container">
+ *   <a href="" class="slideshow-prev">Prev</a>
+ *   <a href="" class="slideshow-next">Next</a>
+ *   <ul>
+ *       <li class="item"><img src="images/marquee1.jpg"></li>
+ *       <li class="item"><img src="images/marquee2.jpg"></li>
+ *       <li class="item"><img src="images/marquee3.jpg"></li>
+ *       <li class="item"><img src="images/marquee4.jpg"></li>
+ *   </ul>
+ *  </div>
+ *
+ *   <script type="text/javascript">
+ *   $('.slideshow-container').dacSlideshow({
+ *       auto: true,
+ *       btnPrev: '.slideshow-prev',
+ *       btnNext: '.slideshow-next'
+ *   });
+ *   </script>
+ *
+ *  Options:
+ *  btnPrev:    optional identifier for previous button
+ *  btnNext:    optional identifier for next button
+ *  btnPause:   optional identifier for pause button
+ *  auto:       whether or not to auto-proceed
+ *  speed:      animation speed
+ *  autoTime:   time between auto-rotation
+ *  easing:     easing function for transition
+ *  start:      item to select by default
+ *  scroll:     direction to scroll in
+ *  pagination: whether or not to include dotted pagination
+ *
+ */
+
+ (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
+
+     }, o || {});
+
+     //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 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"});
+
+         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));
+
+         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);
+             }
+         }
+
+         //Previous button
+         if(o.btnPrev)
+             $(o.btnPrev).click(function(e) {
+                 e.preventDefault();
+                 return go(curr-o.scroll);
+             });
+
+         //Next button
+         if(o.btnNext)
+             $(o.btnNext).click(function(e) {
+                 e.preventDefault();
+                 return go(curr+o.scroll);
+             });
+
+         //Pause button
+         if(o.btnPause)
+             $(o.btnPause).click(function(e) {
+                 e.preventDefault();
+                 if ($(this).hasClass('paused')) {
+                     startRotateTimer();
+                 } else {
+                     pauseRotateTimer();
+                 }
+             });
+
+         //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 pauseRotateTimer() {
+             clearInterval(timer);
+             $(o.btnPause).addClass('paused');
+         }
+
+         //Go to an item
+         function go(to) {
+             if(!running) {
+
+                 if(to<0) {
+                    to = itemLength-1;
+                 } else if (to>itemLength-1) {
+                    to = 0;
+                 }
+                 curr = to;
+
+                 running = true;
+
+                 ul.animate(
+                     animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
+                     function() {
+                         running = false;
+                     }
+                 );
+
+                 $(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');
+
+
+             }
+             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);
+
+
+/*
+ *  dacSlideshow 1.0
+ *  Used on develop/index.html for side-sliding tabs
+ *
+ *  Sample usage:
+ *  HTML -
+ *  <div class="slideshow-container">
+ *   <a href="" class="slideshow-prev">Prev</a>
+ *   <a href="" class="slideshow-next">Next</a>
+ *   <ul>
+ *       <li class="item"><img src="images/marquee1.jpg"></li>
+ *       <li class="item"><img src="images/marquee2.jpg"></li>
+ *       <li class="item"><img src="images/marquee3.jpg"></li>
+ *       <li class="item"><img src="images/marquee4.jpg"></li>
+ *   </ul>
+ *  </div>
+ *
+ *   <script type="text/javascript">
+ *   $('.slideshow-container').dacSlideshow({
+ *       auto: true,
+ *       btnPrev: '.slideshow-prev',
+ *       btnNext: '.slideshow-next'
+ *   });
+ *   </script>
+ *
+ *  Options:
+ *  btnPrev:    optional identifier for previous button
+ *  btnNext:    optional identifier for next button
+ *  auto:       whether or not to auto-proceed
+ *  speed:      animation speed
+ *  autoTime:   time between auto-rotation
+ *  easing:     easing function for transition
+ *  start:      item to select by default
+ *  scroll:     direction to scroll in
+ *  pagination: whether or not to include dotted pagination
+ *
+ */
+ (function($) {
+ $.fn.dacTabbedList = function(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() {
+
+         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) {
+           go($(nav_li).index($(this)));
+         })
+
+         //Go to an item
+         function go(to) {
+             if(!running) {
+                 curr = to;
+                 running = true;
+
+                 frame.animate({ 'margin-left' : -(curr*content_width) }, o.speed, o.easing,
+                     function() {
+                         running = false;
+                     }
+                 );
+
+
+                 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.dummy').show();
+      $('.suggest-card.reference').show();
+      var listIndex = 0; // list index position
+
+      // reset the lists
+      $(".search_filtered_wrapper.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();
+      $('.suggest-card.dummy').hide();
+    }
+
+    // ########### JD DOC RESULTS #############
+    if (gDocsMatches.length > 0) {
+        // reset the lists
+        $(".search_filtered_wrapper.docs 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 {
+      $('.search_filtered_wrapper.docs .suggest-card:not(.dummy)').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) {
+          // Regex to match only the beginning of a word
+          var textRegex = new RegExp("\\b" + text.toLowerCase(), "g");
+
+
+          // 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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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().match(textRegex)) {
+                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 = document.getElementById('search_autocomplete').value;
+  location.hash = 'q=' + query;
+  loadSearchResults();
+  $("#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.setSearchStartingCallback(this, function(control, searcher, query) {});
+
+  // forcefully regain key-up event control (previously jacked by search api)
+  $("#search_autocomplete").keyup(function(event) {
+    return search_changed(event, false, toRoot);
+  });
+
+  return false;
+}
+
+
+
+/* ########################################################## */
+/* ################  CUSTOM SEARCH ENGINE  ################## */
+/* ########################################################## */
+
+var searchControl;
+google.load('search', '1', {"callback" : function() {
+            searchControl = new google.search.SearchControl();
+          } });
+
+function loadSearchResults() {
+  document.getElementById("search_autocomplete").style.color = "#000";
+
+  searchControl = new google.search.SearchControl();
+
+  // use our existing search form and use tabs when multiple searchers are used
+  drawOptions = new google.search.DrawOptions();
+  drawOptions.setDrawMode(google.search.SearchControl.DRAW_MODE_TABBED);
+  drawOptions.setInput(document.getElementById("search_autocomplete"));
+
+  // configure search result options
+  searchOptions = new google.search.SearcherOptions();
+  searchOptions.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
+
+  // configure each of the searchers, for each tab
+  devSiteSearcher = new google.search.WebSearch();
+  devSiteSearcher.setUserDefinedLabel("All");
+  devSiteSearcher.setSiteRestriction("001482626316274216503:zu90b7s047u");
+
+  designSearcher = new google.search.WebSearch();
+  designSearcher.setUserDefinedLabel("Design");
+  designSearcher.setSiteRestriction("http://developer.android.com/design/");
+
+  trainingSearcher = new google.search.WebSearch();
+  trainingSearcher.setUserDefinedLabel("Training");
+  trainingSearcher.setSiteRestriction("http://developer.android.com/training/");
+
+  guidesSearcher = new google.search.WebSearch();
+  guidesSearcher.setUserDefinedLabel("Guides");
+  guidesSearcher.setSiteRestriction("http://developer.android.com/guide/");
+
+  referenceSearcher = new google.search.WebSearch();
+  referenceSearcher.setUserDefinedLabel("Reference");
+  referenceSearcher.setSiteRestriction("http://developer.android.com/reference/");
+
+  googleSearcher = new google.search.WebSearch();
+  googleSearcher.setUserDefinedLabel("Google Services");
+  googleSearcher.setSiteRestriction("http://developer.android.com/google/");
+
+  blogSearcher = new google.search.WebSearch();
+  blogSearcher.setUserDefinedLabel("Blog");
+  blogSearcher.setSiteRestriction("http://android-developers.blogspot.com");
+
+  // add each searcher to the search control
+  searchControl.addSearcher(devSiteSearcher, searchOptions);
+  searchControl.addSearcher(designSearcher, searchOptions);
+  searchControl.addSearcher(trainingSearcher, searchOptions);
+  searchControl.addSearcher(guidesSearcher, searchOptions);
+  searchControl.addSearcher(referenceSearcher, searchOptions);
+  searchControl.addSearcher(googleSearcher, searchOptions);
+  searchControl.addSearcher(blogSearcher, searchOptions);
+
+  // configure result options
+  searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
+  searchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
+  searchControl.setTimeoutInterval(google.search.SearchControl.TIMEOUT_SHORT);
+  searchControl.setNoResultsString(google.search.SearchControl.NO_RESULTS_DEFAULT_STRING);
+
+  // upon ajax search, refresh the url and search title
+  searchControl.setSearchStartingCallback(this, function(control, searcher, query) {
+    updateResultTitle(query);
+    var query = document.getElementById('search_autocomplete').value;
+    location.hash = 'q=' + query;
+  });
+
+  // once search results load, set up click listeners
+  searchControl.setSearchCompleteCallback(this, function(control, searcher, query) {
+    addResultClickListeners();
+  });
+
+  // draw the search results box
+  searchControl.draw(document.getElementById("leftSearchControl"), drawOptions);
+
+  // get query and execute the search
+  searchControl.execute(decodeURI(getQuery(location.hash)));
+
+  document.getElementById("search_autocomplete").focus();
+  addTabListeners();
+}
+// End of loadSearchResults
+
+
+google.setOnLoadCallback(function(){
+  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
+    $('#searchResults').slideDown('slow', setStickyTop);
+    $(".search .close").removeClass("hide");
+    loadSearchResults();
+  }
+}, 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) || (query == "undefined")) {
+    // If the results pane is open, close it.
+    if (!$("#searchResults").is(":hidden")) {
+      hideResults();
+    }
+    offsetScrollForSticky();
+    return;
+  }
+
+  // Otherwise, we have a search to do
+  var query = decodeURI(getQuery(location.hash));
+  searchControl.execute(query);
+  $('#searchResults').slideDown('slow', setStickyTop);
+  $("#search_autocomplete").focus();
+  $(".search .close").removeClass("hide");
+
+  updateResultTitle(query);
+});
+
+function updateResultTitle(query) {
+  $("#searchTitle").html("Results for <em>" + escapeHTML(query) + "</em>");
+}
+
+// forcefully regain key-up event control (previously jacked by search api)
+$("#search_autocomplete").keyup(function(event) {
+  return search_changed(event, false, toRoot);
+});
+
+// add event listeners to each tab so we can track the browser history
+function addTabListeners() {
+  var tabHeaders = $(".gsc-tabHeader");
+  for (var i = 0; i < tabHeaders.length; i++) {
+    $(tabHeaders[i]).attr("id",i).click(function() {
+    /*
+      // make a copy of the page numbers for the search left pane
+      setTimeout(function() {
+        // remove any residual page numbers
+        $('#searchResults .gsc-tabsArea .gsc-cursor-box.gs-bidi-start-align').remove();
+        // move the page numbers to the left position; make a clone,
+        // because the element is drawn to the DOM only once
+        // and because we're going to remove it (previous line),
+        // we need it to be available to move again as the user navigates
+        $('#searchResults .gsc-webResult .gsc-cursor-box.gs-bidi-start-align:visible')
+                        .clone().appendTo('#searchResults .gsc-tabsArea');
+        }, 200);
+      */
+    });
+  }
+  setTimeout(function(){$(tabHeaders[0]).click()},200);
+}
+
+// add analytics tracking events to each result link
+function addResultClickListeners() {
+  $("#searchResults a.gs-title").each(function(index, link) {
+    // When user clicks enter for Google search results, track it
+    $(link).click(function() {
+      ga('send', 'event', 'Google Click', 'clicked: ' + $(this).attr('href'),
+                'query: ' + $("#search_autocomplete").val().toLowerCase());
+    });
+  });
+}
+
+
+function getQuery(hash) {
+  var queryParts = hash.split('=');
+  return queryParts[1];
+}
+
+/* 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;");
+}
+
+
+
+
+
+
+
+/* ######################################################## */
+/* #################  JAVADOC REFERENCE ################### */
+/* ######################################################## */
+
+/* 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)) {
+    $(document).ready(function() {
+      // init available apis based on user pref
+      changeApiLevel();
+      initSidenavHeightResize()
+      });
+  }
+}
+
+var API_LEVEL_COOKIE = "api_level";
+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));
+  userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default
+
+  minLevel = parseInt($("#doc-api-level").attr("class"));
+  // Handle provisional api levels; the provisional level will always be the highest possible level
+  // Provisional api levels will also have a length; other stuff that's just missing a level won't,
+  // so leave those kinds of entities at the default level of 1 (for example, the R.styleable class)
+  if (isNaN(minLevel) && minLevel.length) {
+    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)
+    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);
+}
+
+function changeApiLevel() {
+  maxLevel = SINCE_DATA.length;
+  var selectedLevel = maxLevel;
+
+  selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
+  toggleVisisbleApis(selectedLevel, "body");
+
+  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>");
+  } else {
+    $("#naMessage").hide();
+  }
+}
+
+function toggleVisisbleApis(selectedLevel, context) {
+  var apis = $(".api",context);
+  apis.each(function(i) {
+    var obj = $(this);
+    var className = obj.attr("class");
+    var apiLevelIndex = className.lastIndexOf("-")+1;
+    var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
+    apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
+    var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
+    if (apiLevel.length == 0) { // for odd cases when the since data is actually missing, just bail
+      return;
+    }
+    apiLevel = parseInt(apiLevel);
+
+    // Handle provisional api levels; if this item's level is the provisional one, set it to the max
+    var selectedLevelNum = parseInt(selectedLevel)
+    var apiLevelNum = parseInt(apiLevel);
+    if (isNaN(apiLevelNum)) {
+        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");
+  });
+}
+
+
+
+
+/* #################  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)
+{
+  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_google_node(me, me.node);
+}
+
+function new_google_node(me, mom, text, link, children_data, api_level)
+{
+  var node = new Object();
+  var child;
+  node.children = Array();
+  node.children_data = children_data;
+  node.depth = mom.depth + 1;
+  node.get_children_ul = function() {
+      if (!node.children_ul) {
+        node.children_ul = document.createElement("ul");
+        node.children_ul.className = "tree-list-children";
+        node.li.appendChild(node.children_ul);
+      }
+      return node.children_ul;
+    };
+  node.li = document.createElement("li");
+
+  mom.get_children_ul().appendChild(node.li);
+
+
+  if(link) {
+    child = document.createElement("a");
+
+  }
+  else {
+    child = document.createElement("span");
+    child.className = "tree-list-subtitle";
+
+  }
+  if (children_data != null) {
+    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 {
+    node.li.appendChild(child);
+  }
+  if(link) {
+    child.href = me.toroot + link;
+  }
+  node.label = document.createTextNode(text);
+  child.appendChild(node.label);
+
+  node.children_ul = null;
+
+  return node;
+}
+
+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"){
+      linkText = linkText.substr(19, linkText.length);
+    }
+      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
+
+var NODE_NAME = 0;
+var NODE_HREF = 1;
+var NODE_GROUP = 2;
+var NODE_TAGS = 3;
+var NODE_CHILDREN = 4;
+
+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));
+  }
+
+  // Make all third-generation list items 'sticky' to prevent them from collapsing
+  $containerUl.find('li li li.nav-section').addClass('sticky');
+
+  initExpandableNavItems("#"+navtree_id);
+}
+
+function new_google_node2(node_data)
+{
+  var linkText = node_data[NODE_NAME];
+  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>');
+  } else {
+    $a = $('<a href="#" onclick="return false;" title="' + linkText + '" >'
+        + linkText + '/</a>');
+  }
+  var $childUl = $('<ul>');
+  if (node_data[NODE_CHILDREN] != null) {
+    $li.addClass("nav-section");
+    $a = $('<div class="nav-section-header">').append($a);
+    if (node_data[NODE_HREF] == null) $a.addClass('empty');
+
+    for (var i in node_data[NODE_CHILDREN]) {
+      var child_node_data = node_data[NODE_CHILDREN][i];
+      $childUl.append(new_google_node2(child_node_data));
+    }
+    $li.append($childUl);
+  }
+  $li.prepend($a);
+
+  return $li;
+}
+
+
+
+
+
+
+
+
+
+
+
+function showGoogleRefTree() {
+  init_default_google_navtree(toRoot);
+  init_default_gcm_navtree(toRoot);
+}
+
+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();
+      }
+  });
+}
+
+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();
+          }
+      }
+  });
+}
+
+/* TOGGLE INHERITED MEMBERS */
+
+/* Toggle an inherited class (arrow toggle)
+ * @param linkObj  The link that was clicked.
+ * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
+ *                '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/triangle-opened.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/triangle-closed.png";
+        a.removeClass("opened");
+        a.addClass("closed");
+    }
+    return false;
+}
+
+/* Toggle all inherited classes in a single table (e.g. all inherited methods)
+ * @param linkObj  The link that was clicked.
+ * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
+ *                'null' to simply toggle.
+ */
+function toggleAllInherited(linkObj, expand) {
+  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 ) {
+    expandos.each(function(i) {
+      toggleInherited(this, true);
+    });
+    a.text("[Collapse]");
+  } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
+    expandos.each(function(i) {
+      toggleInherited(this, false);
+    });
+    a.text("[Expand]");
+  }
+  return false;
+}
+
+/* Toggle all inherited members in the class (link in the class title)
+ */
+function toggleAllClassInherited() {
+  var a = $("#toggleAllClassInherited"); // get toggle link from class title
+  var toggles = $(".toggle-all", $("#body-content"));
+  if (a.text() == "[Expand All]") {
+    toggles.each(function(i) {
+      toggleAllInherited(this, true);
+    });
+    a.text("[Collapse All]");
+  } else {
+    toggles.each(function(i) {
+      toggleAllInherited(this, false);
+    });
+    a.text("[Expand All]");
+  }
+  return false;
+}
+
+/* Expand all inherited members in the class. Used when initiating page search */
+function ensureAllInheritedExpanded() {
+  var toggles = $(".toggle-all", $("#body-content"));
+  toggles.each(function(i) {
+    toggleAllInherited(this, true);
+  });
+  $("#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
+  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 */
+function initCodeLineNumbers() {
+  var numbers = $("#codesample-block a.number");
+  if (numbers.length) {
+    $("#codesample-line-numbers").removeClass("hidden").append(numbers);
+  }
+
+  $(document).ready(function() {
+    // select entire line when clicked
+    $("span.code-line").click(function() {
+      if (!shifted) {
+        selectText(this);
+      }
+    });
+    // invoke line link on double click
+    $(".code-line").dblclick(function() {
+      document.location.hash = $(this).attr('id');
+    });
+    // highlight the line when hovering on the number
+    $("#codesample-line-numbers a.number").mouseover(function() {
+      var id = $(this).attr('href');
+      $(id).css('background','#e7e7e7');
+    });
+    $("#codesample-line-numbers a.number").mouseout(function() {
+      var id = $(this).attr('href');
+      $(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;} );
+
+// 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);
+    }
+}
+
+
+
+
+/** Display links and other information about samples that match the
+    group specified by the URL */
+function showSamples() {
+  var group = $("#samples").attr('class');
+  $("#samples").html("<p>Here are some samples for <b>" + group + "</b> apps:</p>");
+
+  var $ul = $("<ul>");
+  $selectedLi = $("#nav li.selected");
+
+  $selectedLi.children("ul").children("li").each(function() {
+      var $li = $("<li>").append($(this).find("a").first().clone());
+      $ul.append($li);
+  });
+
+  $("#samples").append($ul);
+
+}
+
+
+
+/* ########################################################## */
+/* ###################  RESOURCE CARDS  ##################### */
+/* ########################################################## */
+
+/** Handle resource queries, collections, and grids (sections). Requires
+    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() {
+    $('.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 15px line height.
+    var lineHeight = 15;
+    $('.card-info .text').ellipsisfade(lineHeight);
+  });
+
+  /*
+    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');
+
+    // find size of widget by pulling out its class name
+    var sizeCols = 1;
+    var m = $widget.get(0).className.match(/\bcol-(\d+)\b/);
+    if (m) {
+      sizeCols = parseInt(m[1], 10);
+    }
+
+    var opts = {
+      cardSizes: ($widget.data('cardsizes') || '').split(','),
+      maxResults: parseInt($widget.data('maxresults') || '100', 10),
+      itemsPerPage: $widget.data('itemsperpage'),
+      sortOrder: $widget.data('sortorder'),
+      query: $widget.data('query'),
+      section: $widget.data('section'),
+      sizeCols: sizeCols,
+      /* Added by LFL 6/6/14 */
+      resourceStyle: $widget.data('resourcestyle') || 'card',
+      stackSort: $widget.data('stacksort') || 'true'
+    };
+
+    // run the search for the set of resources to show
+
+    var resources = buildResourceList(opts);
+
+    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*/);
+    }
+  }
+
+  /* Initializes a Resource Carousel Widget */
+  function drawResourcesCarouselWidget($widget, opts, resources) {
+    $widget.empty();
+    var plusone = true; //always show plusone on carousel
+
+    $widget.addClass('resource-card slideshow-container')
+      .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 $ul = $('<ul>');
+
+    for (var i = 0; i < resources.length; ++i) {
+      var $card = $('<a>')
+        .attr('href', cleanUrl(resources[i].url))
+        .decorateResourceCard(resources[i],plusone);
+
+      $('<li>').css(css)
+          .append($card)
+          .appendTo($ul);
+    }
+
+    $('<div>').addClass('frame')
+      .append($ul)
+      .appendTo($widget);
+
+    $widget.dacSlideshow({
+      auto: true,
+      btnPrev: '.slideshow-prev',
+      btnNext: '.slideshow-next'
+    });
+  };
+
+  /* Initializes a Resource Card Stack Widget (column-based layout)
+     Modified by LFL 6/6/14
+   */
+  function drawResourcesStackWidget($widget, opts, resources, sections) {
+    // Don't empty widget, grab all items inside since they will be the first
+    // items stacked, followed by the resource query
+    var plusone = true; //by default show plusone on section cards
+    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')
+          .appendTo($widget);
+    }
+
+    var sectionResources = [];
+
+    // Extract any subsections that are actually resource cards
+    if (sections) {
+      for (var 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]
+          );
+
+        } else {
+          cards.push(
+            $('<div>')
+              .addClass('resource-card section-card-menu')
+              .decorateResourceSection(sections[i],plusone)[0]
+          );
+        }
+      }
+    }
+
+    cards = cards.concat(sectionResources);
+
+    for (var i = 0; i < resources.length; ++i) {
+      var $card = createResourceElement(resources[i], opts);
+
+      if (opts.resourceStyle.indexOf('related') > -1) {
+        $card.addClass('related-card');
+      }
+
+      cards.push($card[0]);
+    }
+
+    if (opts.stackSort != 'false') {
+      for (var 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();
+        var minIndex = 0;
+
+        for (var j = 1; j < numStacks; ++j) {
+          var height = $stacks[j].height();
+          if (height < minHeight - 45) {
+            minHeight = height;
+            minIndex = j;
+          }
+        }
+
+        $stacks[minIndex].append($(cards[i]));
+      }
+    }
+
+  };
+
+  /*
+    Create a resource card using the given resource object and a list of html
+     configured options. Returns a jquery object containing the element.
+  */
+  function createResourceElement(resource, opts, plusone) {
+    var $el;
+
+    // The difference here is that generic cards are not entirely clickable
+    // 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') {
+      $el = $('<div>')
+        .addClass('resource')
+        .attr('href', cleanUrl(resource.url))
+        .decorateResource(resource, opts);
+    } else {
+      var cls = 'resource resource-card';
+
+      $el = $('<a>')
+        .addClass(cls)
+        .attr('href', cleanUrl(resource.url))
+        .decorateResourceCard(resource, plusone);
+    }
+
+    return $el;
+  }
+
+  /* Initializes a flow widget, see distribute.scss for generating accompanying css */
+  function drawResourcesFlowWidget($widget, opts, resources) {
+    $widget.empty();
+    var cardSizes = opts.cardSizes || ['6x6'];
+    var i = 0, j = 0;
+    var plusone = true; // by default show plusone on resource cards
+
+    while (i < resources.length) {
+      var cardSize = cardSizes[j++ % cardSizes.length];
+      cardSize = cardSize.replace(/^\s+|\s+$/,'');
+      // Some card sizes do not get a plusone button, such as where space is constrained
+      // or for cards commonly embedded in docs (to improve overall page speed).
+      plusone = !((cardSize == "6x2") || (cardSize == "6x3") ||
+                  (cardSize == "9x2") || (cardSize == "9x3") ||
+                  (cardSize == "12x2") || (cardSize == "12x3"));
+
+      // A stack has a third dimension which is the number of stacked items
+      var isStack = cardSize.match(/(\d+)x(\d+)x(\d+)/);
+      var stackCount = 0;
+      var $stackDiv = null;
+
+      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($widget);
+      }
+
+      // Build each stack item or just a single item
+      do {
+        var resource = resources[i];
+
+        var $card = createResourceElement(resources[i], opts, plusone);
+
+        $card.addClass('resource-card-' + cardSize +
+          ' resource-card-' + resource.type);
+
+        if (isStack) {
+          $card.addClass('resource-card-' + isStack[1] + 'x' + isStack[2]);
+          if (++stackCount == parseInt(isStack[3])) {
+            $card.addClass('resource-card-row-stack-last');
+            stackCount = 0;
+          }
+        } else {
+          stackCount = 0;
+        }
+
+        $card.appendTo($stackDiv || $widget);
+
+      } while (++i < resources.length && stackCount > 0);
+    }
+  }
+
+  /* Build a site map of resources using a section as a root. */
+  function buildSectionList(opts) {
+    if (opts.section && SECTION_BY_ID[opts.section]) {
+      return SECTION_BY_ID[opts.section].sections || [];
+    }
+    return [];
+  }
+
+  function buildResourceList(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++) {
+        // console.log(resources[j].title);
+        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 !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)
+  {
+    if (url && url.indexOf('//') === -1) {
+      url = toRoot + url;
+    }
+
+    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;
+  }
+})();
+
+(function($) {
+
+  /*
+    Utility method for creating dom for the description area of a card.
+    Used in decorateResourceCard and decorateResource.
+  */
+  function buildResourceCardDescription(resource, plusone) {
+    var $description = $('<div>').addClass('description ellipsis');
+
+    $description.append($('<div>').addClass('text').html(resource.summary));
+
+    if (resource.cta) {
+      $description.append($('<a>').addClass('cta').html(resource.cta));
+    }
+
+    if (plusone) {
+      var plusurl = resource.url.indexOf("//") > -1 ? resource.url :
+        "//developer.android.com/" + resource.url;
+
+      $description.append($('<div>').addClass('util')
+        .append($('<div>').addClass('g-plusone')
+          .attr('data-size', 'small')
+          .attr('data-align', 'right')
+          .attr('data-href', plusurl)));
+    }
+
+    return $description;
+  }
+
+
+  /* Simple jquery function to create dom for a standard resource card */
+  $.fn.decorateResourceCard = function(resource,plusone) {
+    var section = resource.group || resource.type;
+    var imgUrl = resource.image ||
+      'assets/images/resource-card-default-android.jpg';
+
+    if (imgUrl.indexOf('//') === -1) {
+      imgUrl = toRoot + imgUrl;
+    }
+
+    $('<div>').addClass('card-bg')
+      .css('background-image', 'url(' + (imgUrl || toRoot +
+        'assets/images/resource-card-default-android.jpg') + ')')
+      .appendTo(this);
+
+    $('<div>').addClass('card-info' + (!resource.summary ? ' empty-desc' : ''))
+      .append($('<div>').addClass('section').text(section))
+      .append($('<div>').addClass('title').html(resource.title))
+      .append(buildResourceCardDescription(resource, plusone))
+      .appendTo(this);
+
+    return this;
+  };
+
+  /* Simple jquery function to create dom for a resource section card (menu) */
+  $.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;
+    var $base = $('<a>')
+        .addClass('card-bg')
+        .attr('href', resource.url)
+        .append($('<div>').addClass('card-section-icon')
+          .append($('<div>').addClass('icon'))
+          .append($('<div>').addClass('section').html(resource.title)))
+      .appendTo(this);
+
+    var $cardInfo = $('<div>').addClass('card-info').appendTo(this);
+
+    if (section.sections && section.sections.length) {
+      // Recurse the section sub-tree to find a resource image.
+      var stack = [section];
+
+      while (stack.length) {
+        if (stack[0].resource.image) {
+          $base.css('background-image', 'url(' + urlPrefix + stack[0].resource.image + ')');
+          break;
+        }
+
+        if (stack[0].sections) {
+          stack = stack.concat(stack[0].sections);
+        }
+
+        stack.shift();
+      }
+
+      var $ul = $('<ul>')
+        .appendTo($cardInfo);
+
+      var max = section.sections.length > 3 ? 3 : section.sections.length;
+
+      for (var i = 0; i < max; ++i) {
+
+        var subResource = section.sections[i];
+        if (!plusone) {
+          $('<li>')
+            .append($('<a>').attr('href', subResource.url)
+              .append($('<div>').addClass('title').html(subResource.title))
+              .append($('<div>').addClass('description ellipsis')
+                .append($('<div>').addClass('text').html(subResource.summary))
+                .append($('<div>').addClass('util'))))
+          .appendTo($ul);
+        } else {
+          $('<li>')
+            .append($('<a>').attr('href', subResource.url)
+              .append($('<div>').addClass('title').html(subResource.title))
+              .append($('<div>').addClass('description ellipsis')
+                .append($('<div>').addClass('text').html(subResource.summary))
+                .append($('<div>').addClass('util')
+                  .append($('<div>').addClass('g-plusone')
+                    .attr('data-size', 'small')
+                    .attr('data-align', 'right')
+                    .attr('data-href', resource.url)))))
+          .appendTo($ul);
+        }
+      }
+
+      // Add a more row
+      if (max < section.sections.length) {
+        $('<li>')
+          .append($('<a>').attr('href', resource.url)
+            .append($('<div>')
+              .addClass('title')
+              .text('More')))
+        .appendTo($ul);
+      }
+    } else {
+      // No sub-resources, just render description?
+    }
+
+    return this;
+  };
+
+
+
+
+  /* Render other types of resource styles that are not cards. */
+  $.fn.decorateResource = function(resource, opts) {
+    var imgUrl = resource.image ||
+      'assets/images/resource-card-default-android.jpg';
+    var linkUrl = resource.url;
+
+    if (imgUrl.indexOf('//') === -1) {
+      imgUrl = toRoot + imgUrl;
+    }
+
+    if (linkUrl && linkUrl.indexOf('//') === -1) {
+      linkUrl = toRoot + linkUrl;
+    }
+
+    $(this).append(
+      $('<div>').addClass('image')
+        .css('background-image', 'url(' + imgUrl + ')'),
+      $('<div>').addClass('info').append(
+        $('<h4>').addClass('title').html(resource.title),
+        $('<p>').addClass('summary').html(resource.summary),
+        $('<a>').attr('href', linkUrl).addClass('cta').html('Learn More')
+      )
+    );
+
+    return this;
+  };
+})(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).height();
+                remainingHeight = remainingHeight - h;
+              }
+            });
+
+            adjustedRemainingHeight = ((remainingHeight)/lineHeight>>0)*lineHeight
+            $this.parent().css({'height': adjustedRemainingHeight});
+            $this.css({'height': "auto"});
+        });
+
+        return this;
+    };
+}) (jQuery);
+
+/*
+  Fullscreen Carousel
+
+  The following allows for an area at the top of the page that takes over the
+  entire browser height except for its top offset and an optional bottom
+  padding specified as a data attribute.
+
+  HTML:
+
+  <div class="fullscreen-carousel">
+    <div class="fullscreen-carousel-content">
+      <!-- content here -->
+    </div>
+    <div class="fullscreen-carousel-content">
+      <!-- content here -->
+    </div>
+
+    etc ...
+
+  </div>
+
+  Control over how the carousel takes over the screen can mostly be defined in
+  a css file. Setting min-height on the .fullscreen-carousel-content elements
+  will prevent them from shrinking to far vertically when the browser is very
+  short, and setting max-height on the .fullscreen-carousel itself will prevent
+  the area from becoming to long in the case that the browser is stretched very
+  tall.
+
+  There is limited functionality for having multiple sections since that request
+  was removed, but it is possible to add .next-arrow and .prev-arrow elements to
+  scroll between multiple content areas.
+*/
+
+(function() {
+  $(document).ready(function() {
+    $('.fullscreen-carousel').each(function() {
+      initWidget(this);
+    });
+  });
+
+  function initWidget(widget) {
+    var $widget = $(widget);
+
+    var topOffset = $widget.offset().top;
+    var padBottom = parseInt($widget.data('paddingbottom')) || 0;
+    var maxHeight = 0;
+    var minHeight = 0;
+    var $content = $widget.find('.fullscreen-carousel-content');
+    var $nextArrow = $widget.find('.next-arrow');
+    var $prevArrow = $widget.find('.prev-arrow');
+    var $curSection = $($content[0]);
+
+    if ($content.length <= 1) {
+      $nextArrow.hide();
+      $prevArrow.hide();
+    } else {
+      $nextArrow.click(function() {
+        var index = ($content.index($curSection) + 1);
+        $curSection.hide();
+        $curSection = $($content[index >= $content.length ? 0 : index]);
+        $curSection.show();
+      });
+
+      $prevArrow.click(function() {
+        var index = ($content.index($curSection) - 1);
+        $curSection.hide();
+        $curSection = $($content[index < 0 ? $content.length - 1 : 0]);
+        $curSection.show();
+      });
+    }
+
+    // Just hide all content sections except first.
+    $content.each(function(index) {
+      if ($(this).height() > minHeight) minHeight = $(this).height();
+      $(this).css({position: 'absolute',  display: index > 0 ? 'none' : ''});
+    });
+
+    // Register for changes to window size, and trigger.
+    $(window).resize(resizeWidget);
+    resizeWidget();
+
+    function resizeWidget() {
+      var height = $(window).height() - topOffset - padBottom;
+      $widget.width($(window).width());
+      $widget.height(height < minHeight ? minHeight :
+        (maxHeight && height > maxHeight ? maxHeight : height));
+    }
+  }
+})();
+
+
+
+
+
+/*
+  Tab Carousel
+
+  The following allows tab widgets to be installed via the html below. Each
+  tab content section should have a data-tab attribute matching one of the
+  nav items'. Also each tab content section should have a width matching the
+  tab carousel.
+
+  HTML:
+
+  <div class="tab-carousel">
+    <ul class="tab-nav">
+      <li><a href="#" data-tab="handsets">Handsets</a>
+      <li><a href="#" data-tab="wearable">Wearable</a>
+      <li><a href="#" data-tab="tv">TV</a>
+    </ul>
+
+    <div class="tab-carousel-content">
+      <div data-tab="handsets">
+        <!--Full width content here-->
+      </div>
+
+      <div data-tab="wearable">
+        <!--Full width content here-->
+      </div>
+
+      <div data-tab="tv">
+        <!--Full width content here-->
+      </div>
+    </div>
+  </div>
+
+*/
+(function() {
+  $(document).ready(function() {
+    $('.tab-carousel').each(function() {
+      initWidget(this);
+    });
+  });
+
+  function initWidget(widget) {
+    var $widget = $(widget);
+    var $nav = $widget.find('.tab-nav');
+    var $anchors = $nav.find('[data-tab]');
+    var $li = $nav.find('li');
+    var $contentContainer = $widget.find('.tab-carousel-content');
+    var $tabs = $contentContainer.find('[data-tab]');
+    var $curTab = $($tabs[0]); // Current tab is first tab.
+    var width = $widget.width();
+
+    // Setup nav interactivity.
+    $anchors.click(function(evt) {
+      evt.preventDefault();
+      var query = '[data-tab=' + $(this).data('tab') + ']';
+      transitionWidget($tabs.filter(query));
+    });
+
+    // Add highlight for navigation on first item.
+    var $highlight = $('<div>').addClass('highlight')
+      .css({left:$li.position().left + 'px', width:$li.outerWidth() + 'px'})
+      .appendTo($nav);
+
+    // Store height since we will change contents to absolute.
+    $contentContainer.height($contentContainer.height());
+
+    // Absolutely position tabs so they're ready for transition.
+    $tabs.each(function(index) {
+      $(this).css({position: 'absolute', left: index > 0 ? width + 'px' : '0'});
+    });
+
+    function transitionWidget($toTab) {
+      if (!$curTab.is($toTab)) {
+        var curIndex = $tabs.index($curTab[0]);
+        var toIndex = $tabs.index($toTab[0]);
+        var dir = toIndex > curIndex ? 1 : -1;
+
+        // Animate content sections.
+        $toTab.css({left:(width * dir) + 'px'});
+        $curTab.animate({left:(width * -dir) + 'px'});
+        $toTab.animate({left:'0'});
+
+        // Animate navigation highlight.
+        $highlight.animate({left:$($li[toIndex]).position().left + 'px',
+          width:$($li[toIndex]).outerWidth() + 'px'})
+
+        // Store new current section.
+        $curTab = $toTab;
+      }
+    }
+  }
+})();
