diff --git a/admin_menu.css b/admin_menu.css
index 28c01cd..7757de6 100644
--- a/admin_menu.css
+++ b/admin_menu.css
@@ -34,7 +34,8 @@
   background: transparent url(images/icon_users.png) 90% center no-repeat;
   padding-right: 22px;
 }
-#admin-menu li.admin-menu-action {
+#admin-menu li.admin-menu-action,
+#admin-menu li.admin-menu-search {
   float: right;
 }
 #admin-menu li.admin-menu-action a {
@@ -106,7 +107,6 @@ body.admin-menu {
 #admin-menu li ul {
   background: none;
   display: none;
-  left: -999em;
   line-height: 1.2em;
   margin: 0;
   position: absolute;
@@ -115,19 +115,18 @@ body.admin-menu {
 
 /* Third-and-above-level lists */
 #admin-menu li li.expandable ul {
-  margin: -20px 0 0 160px;
+  margin: -19px 0 0 160px;
 }
 
 #admin-menu li:hover ul ul,
 #admin-menu li:hover ul ul ul,
 #admin-menu li:hover ul ul ul ul,
 #admin-menu li:hover ul ul ul ul ul,
-#admin-menu li.iehover ul ul,
-#admin-menu li.iehover ul ul ul,
-#admin-menu li.iehover ul ul ul ul,
-#admin-menu li.iehover ul ul ul ul ul {
+#admin-menu li.hover ul ul,
+#admin-menu li.hover ul ul ul,
+#admin-menu li.hover ul ul ul ul,
+#admin-menu li.hover ul ul ul ul ul {
   display: none;
-  left: -999em;
 }
 
 /* Lists nested under hovered list items */
@@ -136,13 +135,12 @@ body.admin-menu {
 #admin-menu li li li:hover ul,
 #admin-menu li li li li:hover ul,
 #admin-menu li li li li li:hover ul,
-#admin-menu li.iehover ul,
-#admin-menu li li.iehover ul,
-#admin-menu li li li.iehover ul,
-#admin-menu li li li li.iehover ul,
-#admin-menu li li li li li.iehover ul {
+#admin-menu li.hover ul,
+#admin-menu li li.hover ul,
+#admin-menu li li li.hover ul,
+#admin-menu li li li li.hover ul,
+#admin-menu li li li li li.hover ul {
   display: block;
-  left: auto;
 }
 #admin-menu li.admin-menu-action:hover ul {
   right: 0;
@@ -153,7 +151,7 @@ body.admin-menu {
   background: #45454A url(images/arrow.png) no-repeat 145px 6px;
 }
 #admin-menu li li:hover,
-#admin-menu li li.iehover {
+#admin-menu li li.hover {
   background-color: #111;
 }
 #admin-menu li li:hover a,
@@ -171,17 +169,44 @@ body.admin-menu {
   border-color: #323232;
 }
 #admin-menu li li:hover li a,
-#admin-menu li li.iehover li a,
-#admin-menu li li.iehover li.iehover li a {
+#admin-menu li li.hover li a,
+#admin-menu li li.hover li.hover li a {
   color: #EEE;
 }
-#admin-menu li li.iehover a,
-#admin-menu li li.iehover li.iehover a,
-#admin-menu li li.iehover li.iehover li.iehover a {
+#admin-menu li li.hover a,
+#admin-menu li li.hover li.hover a,
+#admin-menu li li.hover li.hover li.hover a {
   color: #FFF;
   width: 90%; /* IE */
 }
 
+/* Search form */
+#admin-menu .admin-menu-search .form-item {
+  margin: 0;
+}
+
+#admin-menu .admin-menu-search input {
+  outline: none;
+  width: 180px;
+  padding: 2px;
+  margin: 1px;
+  font-size: 10px;
+  border: none;
+}
+
+#admin-menu .admin-menu-search-results {
+  display: block !important;
+}
+
+#admin-menu .admin-menu-search-results,
+#admin-menu .admin-menu-search-results li {
+  width: 186px
+}
+
+#admin-menu li.highlight > a {
+  color: #ff0000 !important;
+}
+
 /* #210615: Mozilla on Mac fix */
 html.js fieldset.collapsible div.fieldset-wrapper {
   overflow: visible;
diff --git a/admin_menu.js b/admin_menu.js
index f8c730a..eb3ef55 100644
--- a/admin_menu.js
+++ b/admin_menu.js
@@ -1,5 +1,12 @@
 (function($) {
 
+// Extend jQuery with a case-insensitive *:containsi selector.
+$.extend($.expr[':'], {
+  'containsi': function(elem, i, match, array) {
+    return (elem.textContent || elem.innerText || '').toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
+  }
+});
+
 Drupal.admin = Drupal.admin || {};
 Drupal.admin.behaviors = Drupal.admin.behaviors || {};
 Drupal.admin.hashes = Drupal.admin.hashes || {};
@@ -192,37 +199,91 @@ Drupal.admin.behaviors.destination = function (context, settings, $adminMenu) {
  *   it will not run last.
  */
 Drupal.admin.behaviors.hover = function (context, settings, $adminMenu) {
-  // Hover emulation for IE 6.
-  if ($.browser.msie && parseInt(jQuery.browser.version) == 6) {
-    $('li', $adminMenu).hover(
-      function () {
-        $(this).addClass('iehover');
-      },
-      function () {
-        $(this).removeClass('iehover');
-      }
-    );
-  }
+  // Hover emulation for IE 6 and delayed mouseout for all browsers.
+  $('li', $adminMenu).hover(function () {
+    clearTimeout(this.hoverTimer);
+    // Hide all siblings immediately.
+    $(this).addClass('hover').siblings().removeClass('hover');
+  }, function () {
+    var $this = $(this);
+    this.hoverTimer = setTimeout(function () {
+      $this.removeClass('hover');
+    }, 400);
+  });
+};
 
-  // Delayed mouseout.
-  $('li.expandable', $adminMenu).hover(
-    function () {
-      // Stop the timer.
-      clearTimeout(this.sfTimer);
-      // Display child lists.
-      $('> ul', this)
-        .css({left: 'auto', display: 'block'})
-        // Immediately hide nephew lists.
-        .parent().siblings('li').children('ul').css({left: '-999em', display: 'none'});
-    },
-    function () {
-      // Start the timer.
-      var uls = $('> ul', this);
-      this.sfTimer = setTimeout(function () {
-        uls.css({left: '-999em', display: 'none'});
-      }, 400);
+/**
+ * Apply up and down arrow navigation functionality to the search bar.
+ */
+Drupal.admin.behaviors.searchNavigation = function(context, settings, $adminMenu) {
+  $('.admin-menu-search').keydown(function (e) {
+    // Only continue if the down or up arrow was pressed.
+    if (e.which == 40 || e.which == 38) {
+      // Prevent the browser from scrolling.
+      e.preventDefault();
+      var $results = $('.admin-menu-search-results li', this);
+      // Check if we got a focused element in our results already and find the
+      // next or previous sibling ...
+      var $next = $('a:focus', $results).parent()[e.which == 40 ? 'next' : 'prev']();
+      if (!$next.length) {
+        // ... Otherwise select the first or last element in the list ...
+        $next = $results[e.which == 40 ? 'first' : 'last']();
+      }
+      // ... And give it the focus.
+      $next.find('a').focus();
     }
-  );
+  });
+}
+
+/**
+ * Apply the search bar functionality.
+ */
+Drupal.admin.behaviors.search = function(context, settings, $adminMenu) {
+  // Add the container for the search results.
+  $('.admin-menu-search input', $adminMenu).each(function () {
+    // Append the results container.
+    var $results = $('<ul class="admin-menu-search-results"/>').insertAfter($(this));
+    // Initialize the current value property on the input element.
+    $(this).data('current', $(this).val());
+    $(this).keyup(function (e) {
+      // Only proceed if the string in the search box has changed.
+      if ($(this).data('current') != $(this).val()) {
+        $(this).data('current', $(this).val());
+        // Nuke all previous results from the results container.
+        $results.empty();
+        $('li', $adminMenu).removeClass('hover');
+        $('li a', $adminMenu).removeClass('highlight');
+        // Only search for matches if we have a search string that is at least
+        // three characters long.
+        if (e.target.value.length >= 3) {
+          // Select all links that match the search term and are not siblings
+          // of the actions menu.
+          $('li:not(.admin-menu-action, .admin-menu-action li) > a:containsi("' + e.target.value + '")', $adminMenu).each(function () {
+            var $match = $(this);
+            var $parent = $match.parent();
+            var $trail = $parent.parentsUntil('#admin-menu-wrapper', 'li');
+            var $text = $match.text();
+            // Check which category this menu item belongs to and add that
+            // information to the result.
+            var $category = $parent.parents('#admin-menu-wrapper > ul > li:not(.admin-menu-icon)').children('a').text();
+            if ($category) {
+              $text = $text + ' (' + $category + ')';
+            }
+            // .toggleClass() might cause problems here since we got the delayed
+            // blur behavior on in the rest of the navigation.
+            $('<li><a href="' + $match.attr('href') + '">' + $text +'</a></li>').appendTo($results).hover(function () {
+              $parent.addClass('highlight');
+              $trail.addClass('hover');
+            }, function () {
+              $parent.removeClass('highlight');
+              $trail.removeClass('hover');
+            });
+          });
+        }
+      }
+
+    });
+  });
 };
 
 /**
diff --git a/admin_menu.module b/admin_menu.module
index 6fa85f2..8b49410 100644
--- a/admin_menu.module
+++ b/admin_menu.module
@@ -419,6 +419,18 @@ function admin_menu_output() {
     $content['icon'] = admin_menu_links_icon();
     $content['user'] = admin_menu_links_user();
 
+    $content['search'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Search'),
+      '#title_display' => 'invisible',
+      '#attributes' => array(
+        'placeholder' => t('Search'),
+      ),
+      '#prefix' => '<li class="admin-menu-search">',
+      '#suffix' => '</li>',
+      '#weight' => 200,
+    );
+
     // Allow modules to alter the output.
     drupal_alter('admin_menu_output', $content);
     $content = drupal_render($content);
