diff --git a/core/modules/edit/edit.module b/core/modules/edit/edit.module
index a704221..584cace 100644
--- a/core/modules/edit/edit.module
+++ b/core/modules/edit/edit.module
@@ -47,26 +47,29 @@ function edit_toolbar() {
   }
 
   $tab['edit'] = array(
+    '#type' => 'toolbar_item',
     'tab' => array(
-      'title' => t('Edit'),
-      'href' => '',
-      'html' => FALSE,
-      'attributes' => array(
-        'class' => array('icon', 'icon-edit', 'edit-nothing-editable-hidden'),
+      '#type' => 'link',
+      '#title' => t('Edit'),
+      '#href' => '',
+      '#options' => array(
+        'html' => FALSE,
+        'attributes' => array(
+          'id' => 'toolbar-tab-edit',
+          'class' => array('icon', 'icon-edit', 'edit-nothing-editable-hidden'),
+        ),
       ),
     ),
-    'tray' => array(
-      '#attached' => array(
-        'library' => array(
-          array('edit', 'edit'),
-        ),
+    '#attached' => array(
+      'library' => array(
+        array('edit', 'edit'),
       ),
     ),
   );
 
   // Include the attachments and settings for all available editors.
   $attachments = drupal_container()->get('edit.editor.selector')->getAllEditorAttachments();
-  $tab['edit']['tray']['#attached'] = NestedArray::mergeDeep($tab['edit']['tray']['#attached'], $attachments);
+  $tab['edit']['#attached'] = NestedArray::mergeDeep($tab['edit']['#attached'], $attachments);
 
   return $tab;
 }
diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module
index b9c737d..237456a 100644
--- a/core/modules/shortcut/shortcut.module
+++ b/core/modules/shortcut/shortcut.module
@@ -608,13 +608,8 @@ function shortcut_preprocess_page(&$variables) {
  * Implements hook_toolbar().
  */
 function shortcut_toolbar() {
+  $items = array();
   $links = shortcut_renderable_links();
-  $links['#attached'] = array(
-    'css' => array(
-      drupal_get_path('module', 'shortcut') . '/shortcut.base.css',
-      drupal_get_path('module', 'shortcut') . '/shortcut.theme.css',
-    ),
-  );
   $shortcut_set = shortcut_current_displayed_set();
   $configure_link = NULL;
   if (shortcut_set_edit_access($shortcut_set)) {
@@ -625,26 +620,35 @@ function shortcut_toolbar() {
       '#options' => array('attributes' => array('class' => array('edit-shortcuts'))),
     );
   }
-
-  $links_tray = array(
-    '#heading' => t('User-defined shortcuts'),
-    'shortcuts' => $links,
-    'configure' => $configure_link,
-  );
-
-  $items['shortcuts'] = array(
-    'tab' => array(
-      'title' => t('Shortcuts'),
-      'href' => 'admin/config/user-interface/shortcut',
-      'html' => FALSE,
-      'attributes' => array(
-        'title' => t('Shortcuts'),
-        'class' => array('icon', 'icon-shortcut'),
+  if (!empty($links) || !empty($configure_link)) {
+    $items['shortcuts'] = array(
+      '#type' => 'toolbar_item',
+      'tab' => array(
+        '#type' => 'link',
+        '#title' => t('Shortcuts'),
+        '#href' => 'admin/config/user-interface/shortcut',
+        '#options' => array(
+          'attributes' => array(
+            'title' => t('Shortcuts'),
+            'class' => array('icon', 'icon-shortcut'),
+          ),
+        ),
       ),
-    ),
-    'tray' => $links_tray,
-    'weight' => -10,
-  );
+      'tray' => array(
+        '#heading' => t('User-defined shortcuts'),
+        'shortcuts' => $links,
+        'configure' => $configure_link,
+      ),
+      '#weight' => -10,
+      '#attached' => array(
+        'css' => array(
+          drupal_get_path('module', 'shortcut') . '/shortcut.base.css',
+          drupal_get_path('module', 'shortcut') . '/shortcut.theme.css',
+        ),
+      ),
+    );
+  }
+
   return $items;
 }
 
diff --git a/core/modules/toolbar/css/toolbar.base.css b/core/modules/toolbar/css/toolbar.base.css
index cbdf153..e6cf95a 100644
--- a/core/modules/toolbar/css/toolbar.base.css
+++ b/core/modules/toolbar/css/toolbar.base.css
@@ -39,12 +39,12 @@ html.js .toolbar {
 .toolbar .menu li {
   padding-top: 0;
 }
-.js .toolbar .bar li,
+.js .toolbar .bar .tab,
 .js .toolbar .menu li {
   display: block;
 }
-.js .toolbar .bar li,
-.js .toolbar .horizontal li  {
+.js .toolbar .bar .tab,
+.js .toolbar .horizontal .tab  {
   float: left; /* LTR */
 }
 .js .toolbar a {
@@ -62,13 +62,13 @@ html.js .toolbar {
   width: 100%;
 }
 @media only screen {
-  .js .toolbar .bar li,
+  .js .toolbar .bar .tab,
   .js .toolbar .tray li {
     float: none; /* LTR */
   }
 }
 @media only screen and (min-width: 16.5em) {
-  .js .toolbar .bar li,
+  .js .toolbar .bar .tab,
   .js .toolbar .horizontal li {
     float: left; /* LTR */
   }
diff --git a/core/modules/toolbar/css/toolbar.theme.css b/core/modules/toolbar/css/toolbar.theme.css
index 08a573c..c1317e5 100644
--- a/core/modules/toolbar/css/toolbar.theme.css
+++ b/core/modules/toolbar/css/toolbar.theme.css
@@ -31,19 +31,21 @@
   box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.3333);
   color: #dddddd;
 }
-.toolbar .bar a:hover {
+.toolbar .bar a {
+  color: #ffffff;
+}
+.toolbar .bar .tab > a {
+  font-weight: bold;
+}
+.toolbar .bar .tab > a:hover {
   background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.125) 20%, transparent 200%);
   background-image: linear-gradient(rgba(255, 255, 255, 0.125) 20%, transparent 200%);
   text-decoration: none;
 }
-.toolbar .bar a.active {
+.toolbar .bar .tab > a.active {
   background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.25) 20%, transparent 200%);
   background-image: linear-gradient(rgba(255, 255, 255, 0.25) 20%, transparent 200%);
 }
-.toolbar .bar a {
-  color: #ffffff;
-  font-weight: bold;
-}
 
 /**
  * Toolbar tray.
diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js
index 830684d..45e91ad 100644
--- a/core/modules/toolbar/js/toolbar.js
+++ b/core/modules/toolbar/js/toolbar.js
@@ -80,7 +80,7 @@ Drupal.behaviors.toolbar = {
       // query application decide the orientation.
       changeOrientation((locked) ? 'vertical' : ((mql.wide.matches) ? 'horizontal' : 'vertical'), locked);
       // Render the main menu as a nested, collapsible accordion.
-      $toolbar.find('.administration.tray .toolbar-menu > .menu').toolbarMenu();
+      $toolbar.find('.toolbar-menu-administration > .menu').toolbarMenu();
       // Call setHeight on screen resize. Wrap it in debounce to prevent
       // setHeight from being called too frequently.
       var setHeight = Drupal.debounce(Drupal.toolbar.setHeight, 200);
@@ -152,7 +152,7 @@ Drupal.toolbar.toggleTray = function (event) {
       localStorage.removeItem('Drupal.toolbar.activeTab');
     }
     // Disable non-selected tabs and trays.
-    $toolbar.find('.bar a')
+    $toolbar.find('.bar .trigger')
       .not($tab)
       .removeClass('active')
       // Set aria-pressed to false.
diff --git a/core/modules/toolbar/templates/toolbar.twig b/core/modules/toolbar/templates/toolbar.twig
deleted file mode 100644
index c2181df..0000000
--- a/core/modules/toolbar/templates/toolbar.twig
+++ /dev/null
@@ -1,39 +0,0 @@
-{#
-/**
- * @file
- * Default template for admin toolbar.
- *
- * Available variables:
- *
- * - tabs: Themed links for the top level tabs.
- * - trays: An array of trays. It contains:
- *   - content: The themed tray content.
- *   - attributes: HTML attributes for the surrounding element. It includes:
- *     - id: The unique id of the tray. This corresponds to the module name
- *       registered the tray.
- *     - class: A list of classes to target the trays for styling.
- * - attributes: HTML attributes for the surrounding element. It includes:
- *   - id: The unique id of the toolbar.
- *   - class: A list of classes to target the toolbar for styling.
- *
- * @see template_preprocess()
- * @see template_preprocess_toolbar()
- *
- * @ingroup themeable
- */
-#}
-
-<nav id="{{ attributes.id }}" class="{{ attributes.class }}"{{ attributes }}>
-  <!-- Tabs -->
-  {{ tabs }}
-
-  <!-- Trays -->
-  {% for tray in trays %}
-    <div id="{{ tray.attributes.id }}" class="{{ tray.attributes.class }}"{{ tray.attributes }}>
-      <div class="lining clearfix">
-        <h3 class="element-invisible">{{ tray.heading }}</h3>
-        {{ tray.content }}
-      </div>
-    </div>
-  {% endfor %}
-</nav>
diff --git a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module
index cadddc9..5bab7a9 100644
--- a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module
+++ b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module
@@ -6,34 +6,42 @@
  */
 
 /**
- * Um
+ * Implements hook_toolbar().
  */
 function toolbar_test_toolbar() {
-  $tray_items = array(
-    l('link 1', '<front>'),
-    l('link 2', '<front>'),
-    l('link 3', '<front>'),
-  );
-  $items['testing'] = array(
+
+    $items['testing'] = array(
+    '#type' => 'toolbar_item',
     'tab' => array(
-      'title' => t('Test tab'),
-      'href' => '',
-      'html' => FALSE,
-      'attributes' => array(
-        'title' => t('Test tab'),
+      '#type' => 'link',
+      '#title' => t('Test tab'),
+      '#href' => '',
+      '#options' => array(
+        'html' => FALSE,
+        'attributes' => array(
+          'id' => 'toolbar-tab-testing',
+          'title' => t('Test tab'),
+        ),
       ),
     ),
     'tray' => array(
-      '#heading' => t('Test tray'),
+      '#wrapper_attributes' => array(
+        'id' => 'toolbar-tray-testing',
+      ),
       'content' => array(
         '#theme' => 'item_list',
-        '#items' => $tray_items,
+        '#items' => array(
+          l(t('link 1'), '<front>'),
+          l(t('link 2'), '<front>'),
+          l(t('link 3'), '<front>'),
+        ),
+        '#prefix' => '<h2 class="element-invisible">' . t('Test tray') . '</h2>',
         '#attributes' => array(
           'class' => array('menu'),
         ),
       ),
     ),
-    'weight' => 50,
+    '#weight' => 50,
   );
 
   return $items;
diff --git a/core/modules/toolbar/toolbar.api.php b/core/modules/toolbar/toolbar.api.php
index 42ca3fe..3ff0999 100644
--- a/core/modules/toolbar/toolbar.api.php
+++ b/core/modules/toolbar/toolbar.api.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Hooks provided by the Toolbar module.
+ * Hooks provided by the toolbar module.
  */
 
 /**
@@ -11,82 +11,144 @@
  */
 
 /**
- * Add items to the Toolbar menu.
+ * Add items to the toolbar menu.
  *
- * The Toolbar has two parts. The tabs are menu links, rendered by
- * theme_links(), that are displayed if the module is enabled and the user has
- * the 'access toolbar' permission. The trays are render elements, usually lists
- * of links, and each tray corresponds to a tab. When a tab is activated, the
- * corresponding tray is displayed; only one tab can be activated at a time. If
- * a tab does not have a corresponding tray, or if javascript is disabled, then
- * the tab is simply a link.
+ * The toolbar is a container for adminstrative and site-global interactive
+ * components.
  *
- * This hook is invoked in toolbar_view().
+ * The toolbar provides a common styling for items denoted by the .tab class.
+ * The theme wrapper toolbar_tab_wrapper is provided to wrap a toolbar item
+ * with the appropriate markup to apply the styling.
+ *
+ * The toolbar provides a construct called a 'tray'. The tray is a container
+ * for content. The tray may be associated with a toggle in the adminstration
+ * bar. The toggle shows or hides the tray and is optimized for small and
+ * large screens. To create this association, hook_toolbar() returns one or
+ * more render elements of type 'toolbar_item', containing the toggle and tray
+ * elements in its 'tab' and 'tray' children.
+ *
+ * The following properties are available:
+ *   - '#weight': Optional. Integer weight used for sorting toolbar items in
+ *     adminstration bar area.
+ *
+ * This hook is invoked in toolbar_pre_render().
  *
  * @return
  *   An array of toolbar items, keyed by unique identifiers such as 'home' or
  *   'administration', or the short name of the module implementing the hook.
- *   The corresponding value is an associative array that may contain the
- *   following key-value pairs:
- *   - 'tab': Required, unless the item is adding links to an existing tab. An
- *   array with keys 'title', 'href', 'html', and 'attributes', as used by
- *   theme_links(). The 'href' value is ignored unless 'tray' (below) is
- *   omitted, or if javascript is disabled.
- *   - 'tray': Optional. A render element that is displayed when the tab is
- *     activated.
- *   - 'weight': Optional. Integer weight used for sorting tabs.
+ *   The corresponding value is a render element of type 'toolbar_item'.
  *
- * @see toolbar_view()
+ * @see toolbar_pre_render()
  * @ingroup toolbar_tabs
  */
 function hook_toolbar() {
   $items = array();
 
-  // The 'Home' tab is a simple link, with no corresponding tray.
+  // Add a search field to the toolbar. The search field employs no toolbar
+  // module theming functions.
+  $items['global_search'] = array(
+    '#type' => 'toolbar_item',
+    'tab' => array(
+      '#type' => 'search',
+      '#attributes' => array(
+        'placeholder' => t('Search the site'),
+        'class' => array('search-global'),
+      ),
+    ),
+    '#weight' => 200,
+    // Custom CSS, JS or a library can be associated with the toolbar item.
+    '#attached' => array(
+      'css' => array(
+        drupal_get_path('module', 'search') . '/css/search.base.css',
+      ),
+    ),
+  );
+
+  // The 'Home' tab is a simple link, which is wrapped in markup associated
+  // with a visual tab styling.
   $items['home'] = array(
+    '#type' => 'toolbar_item',
     'tab' => array(
-      'title' => t('Home'),
-      'href' => '<front>',
-      'html' => FALSE,
-      'attributes' => array(
-        'title' => t('Home page'),
+      '#type' => 'link',
+      '#title' => t('Home'),
+      '#href' => '<front>',
+      '#options' => array(
+        'attributes' => array(
+          'title' => t('Home page'),
+          'class' => array('icon', 'icon-home'),
+        ),
       ),
     ),
-    'weight' => -10,
+    '#weight' => -20,
   );
 
-  /**
-   * A tab may be associated with a tray.
-   *
-   * The tray should contain a renderable array. An option #heading property
-   * can be passed. The text is written to a heading tag in the tray as a
-   * landmark for accessibility. A default heading will be created if one is not
-   * passed.
-   */
+  // A tray may be associated with a tab.
+  //
+  // When the tab is activated, the tray will become visible, either in a
+  // horizontal or vertical orientation on the screen.
+  //
+  // The tray should contain a renderable array. An optional #heading property
+  // can be passed. This text is written to a heading tag in the tray as a
+  // landmark for accessibility.
   $items['commerce'] = array(
+    '#type' => 'toolbar_item',
     'tab' => array(
-      'title' => t('Shopping cart'),
-      'href' => '',
-      'html' => FALSE,
-      'attributes' => array(
-        'title' => t('Shopping cart'),
+      '#type' => 'link',
+      '#title' => t('Shopping cart'),
+      '#href' => '/cart',
+      '#options' => array(
+        'html' => FALSE,
+        'attributes' => array(
+          'title' => t('Shopping cart'),
+        ),
       ),
     ),
     'tray' => array(
       '#heading' => t('Shopping cart actions'),
-      'content' => array(
+      'shopping_cart' => array(
         '#theme' => 'item_list',
         '#items' => array( /* An item list renderable array */ ),
       ),
     ),
-    'weight' => 50,
+    '#weight' => 150,
+  );
+
+  // The 'tray' can be used to render arbritrary content.
+  //
+  // The 'tray' is rendered outside the administration bar but within the
+  // containing toolbar element.
+  //
+  // If the default behavior and styling of a toolbar tray is not desired, one
+  // can render content to the toolbar element and apply custom theming and
+  // behaviors.
+  $items['user_messages'] = array(
+    // Include the toolbar_tab_wrapper to style the link like a toolbar tab.
+    // Exclude the theme wrapper if custom styling is desired.
+    '#type' => 'toolbar_item',
+    'tab' => array(
+      '#type' => 'link',
+      '#theme' => 'user_message_toolbar_tab',
+      '#theme_wrappers' => array(),
+      '#title' => t('Messages'),
+      '#href' => '/user/messages',
+      '#options' => array(
+        'attributes' => array(
+          'title' => t('Messages'),
+        ),
+      ),
+    ),
+    'tray' => array(
+      '#heading' => t('User messages'),
+      'messages' => array(/* renderable content */),
+    ),
+    '#weight' => 125,
   );
 
   return $items;
 }
 
 /**
- * Alter the Toolbar menu after hook_toolbar() is invoked.
+ * Alter the toolbar menu after hook_toolbar() is invoked.
  *
  * This hook is invoked by toolbar_view() immediately after hook_toolbar(). The
  * toolbar definitions are passed in by reference. Each element of the $items
@@ -94,11 +156,11 @@ function hook_toolbar() {
  * may be added, or existing items altered.
  *
  * @param $items
- *   Associative array of Toolbar menu definitions returned from hook_toolbar().
+ *   Associative array of toolbar menu definitions returned from hook_toolbar().
  */
 function hook_toolbar_alter(&$items) {
   // Move the User tab to the right.
-  $items['commerce']['weight'] = 5;
+  $items['commerce']['#weight'] = 5;
 }
 
 /**
diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module
index e543326..a777a27 100644
--- a/core/modules/toolbar/toolbar.module
+++ b/core/modules/toolbar/toolbar.module
@@ -19,7 +19,7 @@ function toolbar_help($path, $arg) {
       $output .= '<h3>' . t('Uses') . '</h3>';
       $output .= '<dl>';
       $output .= '<dt>' . t('Displaying administrative links') . '</dt>';
-      $output .= '<dd>' . t('The Toolbar module displays a bar containing top-level administrative links across the top of the screen. Below that, the Toolbar module has a <em>drawer</em> section where it displays links provided by other modules, such as the core <a href="@shortcuts-help">Shortcut module</a>. The drawer can be hidden/shown by clicking on its corresponding tab.', array('@shortcuts-help' => url('admin/help/shortcut'))) . '</dd>';
+      $output .= '<dd>' . t('The Toolbar module displays a bar containing top-level administrative components across the top of the screen. Below that, the Toolbar module has a <em>drawer</em> section where it displays links provided by other modules, such as the core <a href="@shortcuts-help">Shortcut module</a>. The drawer can be hidden/shown by clicking on its corresponding tab.', array('@shortcuts-help' => url('admin/help/shortcut'))) . '</dd>';
       $output .= '</dl>';
       return $output;
   }
@@ -41,8 +41,19 @@ function toolbar_permission() {
  */
 function toolbar_theme($existing, $type, $theme, $path) {
   $items['toolbar'] = array(
-    'render element' => 'toolbar',
-    'template' => 'toolbar',
+    'render element' => 'element',
+  );
+  $items['toolbar_item'] = array(
+    'render element' => 'element',
+  );
+  $items['toolbar_tab_wrapper'] = array(
+    'render element' => 'element',
+  );
+  $items['toolbar_tray_wrapper'] = array(
+    'render element' => 'element',
+  );
+  $items['toolbar_tray_heading_wrapper'] = array(
+    'render element' => 'element',
   );
   return $items;
 }
@@ -62,6 +73,54 @@ function toolbar_menu() {
 }
 
 /**
+ * Implements hook_element_info().
+ */
+function toolbar_element_info() {
+  $elements = array();
+
+  $elements['toolbar'] = array(
+    // Do not build the toolbar if the user does not have access.
+    '#access' => user_access('access toolbar'),
+    '#pre_render' => array('toolbar_pre_render'),
+    '#theme' => 'toolbar',
+    '#attached' => array(
+      'library' => array(
+        array('toolbar', 'toolbar'),
+      ),
+    ),
+    // Metadata for the toolbar wrapping element.
+    '#attributes' => array(
+      // The id cannot be simply "toolbar" or it will clash with the simpletest
+      // tests listing which produces a checkbox with attribute id="toolbar"
+      'id' => 'toolbar-administration',
+      // The 'overlay-displace-top' class pushes the overlay down, so it appears
+      // below the toolbar.
+      'class' => array('toolbar', 'overlay-displace-top'),
+      'role' => 'navigation',
+    ),
+    // Metadata for the administration bar.
+    '#bar' => array(
+      '#heading' => t('Toolbar items'),
+      '#attributes' => array(
+        'id' => 'toolbar-bar',
+        'class' => array('bar', 'overlay-displace-top', 'clearfix'),
+      ),
+    ),
+  );
+
+  // A toolbar item is wrapped in markup for common styling.  The 'tray'
+  // property contains a renderable array. theme_toolbar_tab() is a light
+  // wrapper around the l() function. The contents of tray are rendered in
+  // theme_toolbar_tab().
+  $elements['toolbar_item'] = array(
+    '#pre_render' => array('toolbar_pre_render_item'),
+    '#theme' => 'toolbar_item',
+    '#theme_wrappers' => array('toolbar_tab_wrapper'),
+  );
+  return $elements;
+}
+
+/**
  * Access callback: Returns if the user has access to the rendered subtree requested by the hash.
  *
  * @see toolbar_menu().
@@ -130,60 +189,228 @@ function _toolbar_initialize_page_cache() {
  */
 function toolbar_page_build(&$page) {
   $page['page_top']['toolbar'] = array(
-    '#pre_render' => array('toolbar_pre_render'),
-    '#access' => user_access('access toolbar'),
+    '#type' => 'toolbar',
   );
 }
 
 /**
- * Provides pre_render function for the toolbar.
+ * Builds the Toolbar as a structured array ready for drupal_render().
  *
  * Since building the toolbar takes some time, it is done just prior to
  * rendering to ensure that it is built only if it will be displayed.
  *
+ * @param array $element
+ *  A renderable array.
+ *
+ * @return
+ *  A renderable array.
+ *
  * @see toolbar_page_build().
  */
-function toolbar_pre_render($toolbar) {
-  $toolbar = array_merge($toolbar, toolbar_view());
-  return $toolbar;
+function toolbar_pre_render($element) {
+
+  // Get the configured breakpoints to switch from vertical to horizontal
+  // toolbar presentation.
+  $breakpoints = entity_load('breakpoint_group', 'module.toolbar.toolbar');
+  if (!empty($breakpoints)) {
+    $media_queries = array();
+    $media_queries['toolbar']['breakpoints'] = array_map(
+      function ($object) {
+        return $object->mediaQuery;
+      },
+      $breakpoints->breakpoints
+    );
+
+    $element['#attached']['js'][] = array(
+      'data' => $media_queries,
+      'type' => 'setting',
+    );
+  }
+
+  // Get toolbar items from all modules that implement hook_toolbar().
+  $items = module_invoke_all('toolbar');
+  // Allow for altering of hook_toolbar().
+  drupal_alter('toolbar', $items);
+  // Sort the children.
+  uasort($items, 'element_sort');
+
+  // Merge in the original toolbar values.
+  $element = array_merge($element, $items);
+
+  // Render the children.
+  $element['#children'] = drupal_render_children($element);
+
+  return $element;
 }
 
 /**
- * Implements template_preprocess_HOOK().
+ * Returns HTML that wraps the administration toolbar.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties and children of
+ *     the tray. Properties used: #children, #attributes and #bar.
  */
-function template_preprocess_toolbar(&$variables) {
-  // Metadata for the toolbar wrapping element.
-  $variables['attributes'] = new Attribute(array(
-    // The id cannot be simply "toolbar" or it will clash with the simpletest
-    // tests listing which produces a checkbox with attribute id="toolbar"
-    'id' => 'toolbar-administration',
-    // The 'overlay-displace-top' class pushes the overlay down, so it appears
-    // below the toolbar.
-    'class' => array('toolbar', 'overlay-displace-top'),
-    'role' => 'navigation'
-  ));
-
-  // Provide a convenience variable for the themed tabs.
-  $variables['toolbar']['tabs']['#attributes']['class'][] = 'overlay-displace-top';
-  $variables['tabs'] = $variables['toolbar']['tabs'];
-
-  // Place the tabs in a top-level variable so that attribute information
-  // can be associated with each one.
-  foreach ($variables['toolbar']['trays'] as $key => $tray) {
-    // Create tray heading text. Prefer the provided heading text if it exists.
-    $heading = isset($tray['#heading']) ? $tray['#heading'] : t('@group actions', array('@group' => $key));
-
-    $variables['trays'][$key] = array(
-      'heading' => $heading,
-      'content' => $variables['toolbar']['trays'][$key],
-      'attributes' => new Attribute(array(
-          'id' => 'toolbar-tray-' . $key,
-          'class' => array('tray', 'overlay-displace-top', $key),
-          'data-toolbar-tray' => $key,
-          'aria-owned-by' => 'toolbar-tab-' . $key,
-        )
-      ),
+function theme_toolbar(&$variables) {
+  if (!empty($variables['element']['#children'])) {
+    $element = $variables['element'];
+    $trays = '';
+    foreach (element_children($element) as $key) {
+      $trays .= drupal_render($element[$key]['tray']);
+    }
+    return '<nav' . new Attribute($element['#attributes']) . '>'
+      . '<div' . new Attribute($element['#bar']['#attributes']) . '>'
+      . '<h2 class="element-invisible">' . $element['#bar']['#heading'] . '</h2>'
+      . $element['#children'] . '</div>' . $trays . '</nav>';
+  }
+}
+
+/**
+ * Provides markup for associating a tray trigger with a tray element.
+ *
+ * A tray is a responsive container that wraps renderable content. Trays present
+ * content well on small and large screens alike.
+ *
+ * @param array $element
+ *   A renderable array.
+ *
+ * @return
+ *   A renderable array.
+ */
+function toolbar_pre_render_item($element) {
+
+  // Attributes are nested in the #options property passed to l().
+  // To make the return structure of toolbar_pre_render_item() uniform,
+  // attributes will always be returned in the #attributes property. These
+  // properties will be included in the #options parameter passed to l() in
+  // theme_toolbar_tab().
+  $element['#attributes'] = $element['tab']['#options']['attributes'];
+
+  // If tray content is present, markup the tray and its associated trigger.
+  if (!empty($element['tray'])) {
+
+    // Trays are associated with their trigger by a unique ID.
+    $id = drupal_html_id('toolbar-tray');
+    $element['tab']['#tray_id'] = $id;
+
+    // Provide attributes for a tray trigger.
+    $attributes = array(
+      'id' => 'toolbar-tab-' . $id,
+      'data-toolbar-tray' => $id,
+      'aria-owns' => $id,
+      'role' => 'button',
+      'aria-pressed' => 'false',
+    );
+    // Merge in module-provided attributes.
+    $element['tab'] += array('#attributes' => array());
+    $element['tab']['#attributes'] += $attributes;
+    $element['tab']['#attributes']['class'][] = 'trigger';
+
+    // Provide attributes for the tray theme wrapper.
+    $attributes = array(
+      'id' => $id,
+      'data-toolbar-tray' => $id,
+      'aria-owned-by' => 'toolbar-tab-' . $id,
     );
+    // Merge in module-provided attributes.
+    if (!isset($element['tray']['#wrapper_attributes'])) {
+      $element['tray']['#wrapper_attributes'] = array();
+    }
+    $element['tray']['#wrapper_attributes'] += $attributes;
+    $element['tray']['#wrapper_attributes']['class'][] = 'tray';
+    $element['tray']['#wrapper_attributes']['class'][] = 'overlay-displace-top';
+
+    if (!isset($element['tray']['#theme_wrappers'])) {
+      $element['tray']['#theme_wrappers'] = array();
+    }
+    // Add the standard theme_wrapper for trays.
+    array_unshift($element['tray']['#theme_wrappers'], 'toolbar_tray_wrapper');
+    // If a #heading is provided for the tray, provided a #theme_wrapper
+    // function to append it.
+    if (!empty($element['tray']['#heading'])) {
+      array_unshift($element['tray']['#theme_wrappers'], 'toolbar_tray_heading_wrapper');
+    }
+  }
+
+  return $element;
+}
+
+/**
+ * Implements template_preprocess_HOOK().
+ */
+function template_preprocess_toolbar_tab_wrapper(&$variables) {
+  if (!isset($variables['element']['#wrapper_attributes'])) {
+    $variables['element']['#wrapper_attributes'] = array();
+  }
+  $variables['element']['#wrapper_attributes']['class'][] = 'tab';
+}
+
+/**
+ * Returns HTML for a toolbar item.
+ *
+ * This theme function only renders the tab portion of the toolbar item. The
+ * tray portion will be rendered later.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties and children of
+ *     the tray.
+ *
+ * @see toolbar_pre_render_item().
+ * @see theme_toolbar().
+ */
+function theme_toolbar_item(&$variables) {
+  return drupal_render($variables['element']['tab']);
+}
+
+/**
+ * Returns HTML for wrapping a toolbar tab.
+ *
+ * Toolbar tabs have a common styling and placement with the toolbar's bar area.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties and children of
+ *     the tray. Properties used: #children and #attributes.
+ */
+function theme_toolbar_tab_wrapper(&$variables) {
+  if (!empty($variables['element']['#children'])) {
+    $element = $variables['element'];
+    return '<div' . new Attribute($element['#wrapper_attributes']) . '>' . $element['#children'] . '</div>';
+  }
+}
+
+/**
+ * Returns HTML for wrapping a toolbar tray.
+ *
+ * Used in combination with theme_toolbar_tab() to create an
+ * association between a link tag in the administration bar and a tray.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties and children of
+ *     the tray. Properties used: #children, #toolbar_identifier and
+ *     #attributes.
+ */
+function theme_toolbar_tray_wrapper(&$variables) {
+  if (!empty($variables['element']['#children'])) {
+    $element = $variables['element'];
+    return '<div' . new Attribute($element['#wrapper_attributes']) . '><div class="lining clearfix">' . $element['#children'] . '</div></div>';
+  }
+}
+
+/**
+ * Returns HTML for prepending a heading to a toolbar tray.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties and children of
+ *     the tray. Properties used: #children and #heading.
+ */
+function theme_toolbar_tray_heading_wrapper(&$variables) {
+  if (!empty($variables['element']['#children'])) {
+    $element = $variables['element'];
+    return '<h3 class="element-invisible">' . $element['#heading'] . '</h3>' . $element['#children'];
   }
 }
 
@@ -211,16 +438,19 @@ function toolbar_toolbar() {
 
   // The 'Home' tab is a simple link, with no corresponding tray.
   $items['home'] = array(
+    '#type' => 'toolbar_item',
     'tab' => array(
-      'title' => t('Home'),
-      'href' => '<front>',
-      'html' => FALSE,
-      'attributes' => array(
-        'title' => t('Home page'),
-        'class' => array('icon', 'icon-home'),
+      '#type' => 'link',
+      '#title' => t('Home'),
+      '#href' => '<front>',
+      '#options' => array(
+        'attributes' => array(
+          'title' => t('Home page'),
+          'class' => array('icon', 'icon-home'),
+        ),
       ),
     ),
-    'weight' => -20,
+    '#weight' => -20,
   );
 
   // Retrieve the administration menu from the database.
@@ -230,14 +460,14 @@ function toolbar_toolbar() {
   toolbar_menu_navigation_links($tree);
 
   $menu = array(
+    '#heading' => t('Administration menu'),
     'toolbar_administration' => array(
       '#type' => 'container',
       '#attributes' => array(
-        'class' => array('toolbar-menu',),
+        'class' => array('toolbar-menu-administration'),
       ),
       'administration_menu' => menu_tree_output($tree),
     ),
-    '#heading' => t('Administration menu'),
   );
 
   // To conserve bandwidth, we only include the top-level links in the HTML.
@@ -247,110 +477,29 @@ function toolbar_toolbar() {
   // @see toolbar_subtrees_jsonp()
   $menu['toolbar_administration']['#attached']['js'][url('toolbar/subtrees/' . _toolbar_get_subtree_hash())] = array('type' => 'external');
 
+  // The administration element has a link that is themed to correspond to
+  // a toolbar tray. The tray contains the full administrative menu of the site.
   $items['administration'] = array(
+    '#type' => 'toolbar_item',
     'tab' => array(
-      'title' => t('Menu'),
-      'href' => 'admin',
-      'html' => FALSE,
-      'attributes' => array(
-        'title' => t('Admin menu'),
-        'class' => array('icon', 'icon-menu'),
+      '#type' => 'link',
+      '#title' => t('Menu'),
+      '#href' => 'admin',
+      '#options' => array(
+        'attributes' => array(
+          'title' => t('Admin menu'),
+          'class' => array('icon', 'icon-menu'),
+        ),
       ),
     ),
     'tray' => $menu,
-    'weight' => -15,
+    '#weight' => -15,
   );
 
   return $items;
 }
 
 /**
- * Builds the Toolbar as a structured array ready for drupal_render().
- *
- * @return
- *   A renderable arrray, with two children:
- *   - 'tabs': an array of links, rendered by theme('links').
- *   - 'trays': an array of render elements displayed when the corresponding tab
- *     is activated.
- */
-function toolbar_view() {
-
-  $build = array('#theme' => 'toolbar');
-  $build['#attached']['library'][] = array('toolbar', 'toolbar');
-
-  // Get the configured breakpoint to switch from vertical to horizontal
-  // toolbar presentation.
-  $breakpoints = entity_load('breakpoint_group', 'module.toolbar.toolbar');
-  if (!empty($breakpoints)) {
-    $media_queries = array();
-    $media_queries['toolbar']['breakpoints'] = array_map(
-      function($object) {return $object->mediaQuery;},
-      $breakpoints->breakpoints);
-
-    $build['#attached']['js'][] = array(
-      'data' => $media_queries,
-      'type' => 'setting',
-    );
-    // // Load the breakpoints for toolbar.
-    foreach ($breakpoints->breakpoints as $key => $breakpoint) {
-      $build['#attached']['js'][0]['data']['toolbar']['breakpoints'][$key] = $breakpoint->mediaQuery;
-    }
-  }
-
-  // Get toolbar items from all modules that implement hook_toolbar() or
-  // hook_toolbar_alter().
-  $toolbar_groups = module_invoke_all('toolbar');
-  drupal_alter('toolbar', $toolbar_groups);
-  uasort($toolbar_groups, 'drupal_sort_weight');
-
-  // Build the tabs and trays from the toolbar groups.
-  $build['trays'] = array();
-  $build['tabs'] = array(
-    '#theme' => 'links',
-    '#links' => array(),
-    '#attributes' => array(
-      'class' => array('bar', 'clearfix'),
-    ),
-    '#heading' => array('text' => t('Toolbar'), 'level' => 'h2', 'class' => 'element-invisible'),
-  );
-  $tab_defaults = array(
-    'title' => '',
-    'href' => '',
-    'html' => FALSE,
-    'attributes' => new Attribute(),
-  );
-
-  foreach ($toolbar_groups as $group => $items) {
-    if ($tab = $items['tab']) {
-      // Merge in the defaults.
-      $tab += $tab_defaults;
-    }
-    // Register a tray if one is associated with this tab.
-    if (!empty($items['tray'])) {
-      // Provide an id, a data attribute linking each tab to the corresponding
-      // tray and aria information.
-      $tab['attributes']['id'] = 'toolbar-tab-' . $group;
-      $tab['attributes']['data-toolbar-tray'] = $group;
-      $tab['attributes']['aria-owns'] = 'toolbar-tray-' . $group;
-      $tab['attributes']['role'] = 'button';
-      $tab['attributes']['aria-pressed'] = 'false';
-
-      if (array_key_exists($group, $build['trays'])) {
-        array_merge($build['trays'][$group], $items['tray']);
-      }
-      else {
-        // Assign the tray to the build.
-        $build['trays'][$group] = $items['tray'];
-      }
-    }
-    // Assign the tabs to the build.
-    $build['tabs']['#links'][$group] = $tab;
-  }
-
-  return $build;
-}
-
-/**
  * Gets only the top level items below the 'admin' path.
  *
  * @return
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 89bc6c1..1ca66b9 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -2715,29 +2715,30 @@ function user_toolbar() {
     );
   }
 
-  $user_tray = array(
-    '#heading' => t('User account actions'),
-    'content' => array(
-      '#theme' => 'links__toolbar_user',
-      '#links' => $links,
-      '#attributes' => array(
-        'class' => array('menu',),
-      ),
-    ),
-  );
-
   $items['user'] = array(
+    '#type' => 'toolbar_item',
     'tab' => array(
-      'title' => user_format_name($user),
-      'href' => 'user',
-      'html' => FALSE,
-      'attributes' => array(
-        'title' => t('My account'),
-        'class' => array('icon', 'icon-user'),
+      '#type' => 'link',
+      '#title' => user_format_name($user),
+      '#href' => 'user',
+      '#options' => array(
+        'attributes' => array(
+          'title' => t('My account'),
+          'class' => array('icon', 'icon-user'),
+        ),
+      ),
+    ),
+    'tray' => array(
+      '#heading' => t('User account actions'),
+      'user_links' => array(
+        '#theme' => 'links__toolbar_user',
+        '#links' => $links,
+        '#attributes' => array(
+          'class' => array('menu'),
+        ),
       ),
     ),
-    'tray' => $user_tray,
-    'weight' => 100,
+    '#weight' => 100,
   );
 
   return $items;
