diff --git a/core/includes/common.inc b/core/includes/common.inc
index c9913a2..82b8228 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6539,6 +6539,9 @@ function drupal_common_theme() {
     'links' => array(
       'variables' => array('links' => array(), 'attributes' => array('class' => array('links')), 'heading' => array()),
     ),
+    'dropbutton' => array(
+      'variables' => array('title' => NULL, 'links' => NULL, 'attributes' => array()),
+    ),
     'image' => array(
       // HTML 4 and XHTML 1.0 always require an alt attribute. The HTML 5 draft
       // allows the alt attribute to be omitted in some cases. Therefore,
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 2d1d375..15ffcd9 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1691,6 +1691,99 @@ function theme_links($variables) {
 }
 
 /**
+ * Builds a render array for theme_dropbutton().
+ */
+function template_preprocess_dropbutton(&$variables) {
+  // Remove the 'inline' and 'links' classes.
+  if (!empty($variables['attributes']['class'])) {
+    foreach ($variables['attributes']['class'] as $key => $class) {
+      if ($class === 'inline' || $class === 'links') {
+        unset($variables['attributes']['class'][$key]);
+      }
+    }
+  }
+
+  // Give each button a unique ID.
+  static $id = 0;
+
+  $variables['element'] = array(
+    '#type' => 'container',
+    '#attached' => array(
+      'library' => array(
+        array('system', 'drupal.dropbutton'),
+      ),
+    ),
+    '#attributes' => array(
+      'class' => array(
+        'dropbutton-no-js',
+        'dropbutton',
+      ),
+      'id' => 'dropbutton-' . ++$id,
+    ),
+  );
+  if (count($variables['links']) > 1) {
+    $title = isset($variables['title']) ? check_plain($variables['title']) : t('Open dropbutton');
+    $variables['element']['#attributes']['class'][] = 'dropbutton-multiple';
+    $variables['element']['wrapper'] = array(
+      '#type' => 'container',
+      '#attributes' => array(
+        'class' => array(
+          'dropbutton-link',
+        ),
+      ),
+      'link' => array(
+        '#type' => 'link',
+        '#href' => '',
+        '#title' => '<span class="element-invisible">' . $title .  '</span>',
+        '#options' => array(
+          'fragment' => 'noname',
+          'html' => TRUE,
+        ),
+        '#attributes' => array(
+          'class' => array(
+            'dropbutton-arrow',
+          ),
+        ),
+      ),
+    );
+  }
+  $variables['element']['content'] = array(
+    '#type' => 'container',
+    '#attributes' => array(
+      'class' => array(
+        'dropbutton-content',
+      ),
+    ),
+    'links' => array(
+      '#theme' => 'links',
+      '#links' => $variables['links'],
+      '#attributes' => $variables['attributes'],
+    ),
+  );
+}
+
+/**
+ * Create a dropbutton menu.
+ *
+ * @param $title
+ *   The text to place in the clickable area to activate the dropbutton. This
+ *   text is indented to -9999px by default.
+ * @param $links
+ *   A list of links to provide within the dropbutton, suitable for use
+ *   in via Drupal's theme('links').
+ * @param $image
+ *   If true, the dropbutton link is an image and will not get extra decorations
+ *   that a text dropbutton link will.
+ * @param $class
+ *   An optional class to add to the dropbutton's container div to allow you
+ *   to style a single dropbutton however you like without interfering with
+ *   other dropbuttons.
+ */
+function theme_dropbutton($variables) {
+  return render($variables['element']);
+}
+
+/**
  * Returns HTML for an image.
  *
  * @param $variables
diff --git a/core/misc/dropbutton.base.css b/core/misc/dropbutton.base.css
new file mode 100644
index 0000000..a73e02c
--- /dev/null
+++ b/core/misc/dropbutton.base.css
@@ -0,0 +1,68 @@
+.dropbutton .dropbutton-content ul {
+  list-style-image: none;
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+}
+.dropbutton .dropbutton-content ul li {
+  line-height: 1.333;
+}
+.dropbutton .dropbutton-content ul.actions {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+}
+
+/**
+ * This creates the dropbutton arrow and inherits the link color.
+ */
+.dropbutton-link {
+  bottom: 0;
+  overflow: hidden;
+  position: absolute;
+  right: 0;
+  text-indent: 110%;
+  top: 0;
+  white-space: nowrap;
+  width: 17px;
+}
+.dropbutton-arrow {
+  border-bottom-color: transparent;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  border-style: solid;
+  border-width: 4px 4px 0;
+  display: none;
+  line-height: 0;
+  position: absolute;
+  right: 6px;
+  top: 0.667em;
+}
+
+.js .dropbutton-arrow {
+  display: inline-block;
+}
+.js .dropbutton {
+  display: inline-block;
+}
+.js .dropbutton-multiple {
+  padding-right: 18px;
+  position: relative;
+}
+.js .dropbutton-multiple .dropbutton-content ul {
+  margin: 0;
+  overflow: hidden;
+  padding: 0;
+}
+.js .dropbutton-multiple .dropbutton-content li,
+.js .dropbutton-multiple .dropbutton-content a {
+  display: block;
+}
+.js .dropbutton-multiple.open {
+  z-index: 100;
+}
+.js .dropbutton-multiple.open .dropbutton-arrow {
+  border-bottom: 4px solid;
+  border-top-color: transparent;
+  top: 0.333em;
+}
diff --git a/core/misc/dropbutton.js b/core/misc/dropbutton.js
new file mode 100644
index 0000000..fbc0f30
--- /dev/null
+++ b/core/misc/dropbutton.js
@@ -0,0 +1,99 @@
+/**
+ * @file
+ * Implement a simple, clickable dropbutton menu.
+ *
+ * See dropbutton.theme.inc for primary documentation.
+ *
+ * The javascript relies on four classes:
+ * - The dropbutton must be fully contained in a div with the class
+ *   dropbutton. It must also contain the class dropbutton-no-js
+ *   which will be immediately removed by the javascript; this allows for
+ *   graceful degradation.
+ * - The trigger that opens the dropbutton must be an a tag wit hthe class
+ *   dropbutton-link. The href should just be '#' as this will never
+ *   be allowed to complete.
+ * - The part of the dropbutton that will appear when the link is clicked must
+ *   be a div with class dropbutton-container.
+ * - Finally, dropbutton-hover will be placed on any link that is being
+ *   hovered over, so that the browser can restyle the links.
+ *
+ * This tool isn't meant to replace click-tips or anything, it is specifically
+ * meant to work well presenting menus.
+ */
+
+(function ($) {
+
+"use strict";
+
+Drupal.behaviors.dropbutton = {
+  attach: function (context) {
+    var $context = $(context);
+    // Process buttons. All dropbuttons are buttons.
+    $context.find('.dropbutton')
+      .once('dropbutton')
+      .removeClass('dropbutton-no-js');
+
+    // Process dropbuttons. Not all buttons are dropbuttons.
+    $context.find('.dropbutton-multiple').once('dropbutton-multiple', function () {
+      var $dropbutton = $(this);
+      var $button = $dropbutton.find('.dropbutton-content');
+      var $secondaryActions = $button.find('li').not(':first');
+      var $arrow = $dropbutton.find(".dropbutton-link");
+      var open = false;
+      var hovering = false;
+      var timerID = 0;
+
+      var toggle = function (close) {
+        // if it's open or we're told to close it, close it.
+        if (open || close) {
+          // If we're just toggling it, close it immediately.
+          if (!close) {
+            open = false;
+            $secondaryActions.slideUp(100);
+            $dropbutton.removeClass('open');
+          }
+          else {
+            // If we were told to close it, wait half a second to make
+            // sure that's what the user wanted.
+            // Clear any previous timer we were using.
+            if (timerID) {
+              clearTimeout(timerID);
+            }
+            timerID = setTimeout(function () {
+              if (!hovering) {
+                open = false;
+                $secondaryActions.slideUp(100);
+                $dropbutton.removeClass('open');
+              }}, 500);
+          }
+        }
+        else {
+          // open it.
+          open = true;
+          $secondaryActions.animate({height: "show", opacity: "show"}, 100);
+          $dropbutton.addClass('open');
+        }
+      };
+      // Hide the secondary actions initially.
+      $secondaryActions.hide();
+
+      $arrow.click(function () {
+          toggle();
+          return false;
+        });
+
+      $dropbutton.hover(
+        function () {
+          hovering = true;
+        }, // hover in
+        function () { // hover out
+          hovering = false;
+          toggle(true);
+          return false;
+        }
+      );
+    });
+  }
+};
+
+})(jQuery);
diff --git a/core/misc/dropbutton.theme.css b/core/misc/dropbutton.theme.css
new file mode 100644
index 0000000..ba8f95d
--- /dev/null
+++ b/core/misc/dropbutton.theme.css
@@ -0,0 +1,77 @@
+/**
+ * Make dropbuttons pretty.
+ */
+.dropbutton-content {
+  padding-bottom: 0;
+  padding-top: 0;
+}
+
+.dropbutton-arrow:focus {
+  outline: medium none;
+}
+
+.js .dropbutton {
+  background-image: -moz-linear-gradient(-90deg, white 0, #f9f9f9 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, white), color-stop(1, #f9f9f9));
+  background-image: -webkit-linear-gradient(-90deg, white 0, #f9f9f9 100%);
+  background-image: linear-gradient(-90deg, #ffffff 0%, #f9f9f9 100%);
+  border: #cccccc solid 1px;
+  border-radius: 5px;
+  cursor: pointer;
+  font-size: 11px;
+  padding-bottom: 1px;
+  padding-top: 1px;
+}
+.js .dropbutton:hover {
+  background-image: -moz-linear-gradient(-90deg, white 0, #f1f1f1 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, white), color-stop(1, #f1f1f1));
+  background-image: -webkit-linear-gradient(-90deg, white 0, #f1f1f1 100%);
+  background-image: linear-gradient(-90deg, #ffffff 0%, #f1f1f1 100%);
+  border-color: #b8b8b8;
+}
+.js .dropbutton:active {
+  border-color: #a0a0a0;
+}
+.js .dropbutton li a {
+  padding-left: 9px;
+  padding-right: 9px;
+}
+.js .dropbutton .dropbutton-content a {
+  background-image: none;
+  border: medium none;
+}
+.js .dropbutton-multiple {
+  background-color: inherit;
+  position: absolute;
+}
+.js .dropbutton-multiple .dropbutton-content {
+  border-right: 1px solid #e8e8e8;
+}
+.js .dropbutton-multiple.open {
+  -moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
+  -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
+  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
+}
+.js .dropbutton-multiple.open:hover {
+  background-image: -moz-linear-gradient(-90deg, white 0, #f9f9f9 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, white), color-stop(1, #f9f9f9));
+  background-image: -webkit-linear-gradient(-90deg, white 0, #f9f9f9 100%);
+  background-image: linear-gradient(-90deg, #ffffff 0%, #f9f9f9 100%);
+  border-color: #d0d0d0;
+}
+.js .dropbutton-multiple.open .dropbutton-link {
+  border-left: 1px solid white;
+}
+.js .dropbutton-multiple.open .dropbutton-content {
+  padding-bottom: 4px;
+}
+.js .dropbutton-multiple.open li a,
+.js .dropbutton-multiple.open li input {
+  padding-right: 9px;
+}
+.js .dropbutton-multiple.open li + li {
+  border-top: 1px solid #efefef;
+  margin-top: 4px;
+  padding-bottom: 0;
+  padding-top: 4px;
+}
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 922b8a7..0fc0727 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1392,6 +1392,25 @@ function system_library_info() {
     ),
   );
 
+  // Dropbutton.
+  $libraries['drupal.dropbutton'] = array(
+    'title' => 'Dropbutton',
+    'website' => 'http://drupal.org/node/1608878',
+    'version' => '1.0',
+    'js' => array(
+      'core/misc/dropbutton.js' => array(),
+    ),
+    'css' => array(
+      'core/misc/dropbutton.base.css' => array(),
+      'core/misc/dropbutton.theme.css' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'jquery.once'),
+      array('system', 'drupal'),
+    ),
+  );
+
   // Vertical Tabs.
   $libraries['drupal.vertical-tabs'] = array(
     'title' => 'Vertical Tabs',
