diff --git a/admin_menu.js b/admin_menu.js
index be507ca..cdc120d 100644
--- a/admin_menu.js
+++ b/admin_menu.js
@@ -1,14 +1,5 @@
 (function($) {
 
-/**
- * Extends 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 || {};
@@ -261,59 +252,62 @@ Drupal.admin.behaviors.hover = function (context, settings, $adminMenu) {
   );
 };
 
+var cache;
 /**
  * Apply the search bar functionality.
  */
 Drupal.admin.behaviors.search = function (context, settings, $adminMenu) {
-  $('.admin-menu-search input', $adminMenu).each(function () {
-    var self = this, $self = $(this);
-
-    // Append the results container.
-    var $results = $('<ul class="dropdown admin-menu-search-results" />').insertAfter(self);
-
-    // Initialize the current search needle.
-    self.needle = $self.val();
-
-    $self.keyup(function (event) {
-      // Only proceed if the search needle has changed.
-      if (self.needle != event.target.value) {
-        // Update needle and remove previous results.
-        self.needle = event.target.value;
-        $results.empty();
-        $adminMenu.find('li').removeClass('highlight');
-
-        // Only search if the needle is longer than 3 characters.
-        if (event.target.value.length >= 3) {
-          // Select all links that match the search term and are not siblings
-          // of the actions menu.
-          // Separate selector and .filter() to leverage Sizzle cache.
-          $adminMenu.find('li:not(.admin-menu-action, .admin-menu-action li) > a').filter(':containsi("' + event.target.value + '")').each(function () {
-            var $match = $(this);
-            var $parent = $match.parent();
-            var result = $match.text();
+  // Having an ID and/or creating it with JS would help.
+  var $input = $('input.admin-menu-search', $adminMenu);
+  // Initialize the current search needle.
+  var needle = $input.val();
+  // Caches lowercase value of needle.
+  var needleMatch;
+  // Append the results container.
+  var $results = $('<div class="dropdown admin-menu-search-results" />').insertAfter($input);
+  // Build an array of all links we can look up.
+  var links = $adminMenu
+    .find('li:not(.admin-menu-action, .admin-menu-action li) > a')
+    .map(function () {
+      var text = (this.textContent || this.innerText);
+      return {
+        text: text,
+        textMatch: text.toLowerCase(),
+        element: this
+      };
+    });
 
-            // Add the top-level category to the result.
-            var $category = $adminMenu.find('#admin-menu-wrapper > ul > li').has(this);
-            if ($category.length) {
-              result = $category.children('a').text() + ': ' + result;
-            }
+  // The best after CSS hover.
+  $results.delegate('li', 'mouseover', function () {$(this).addClass('highlight');});
+  $results.delegate('li', 'mouseout', function () {$(this).removeClass('highlight');});
 
-            $('<li><a href="' + $match.attr('href') + '">' + result + '</a></li>')
-              .appendTo($results)
-              .hover(function () {
-                $parent.addClass('highlight');
-                $match.trigger('mouseenter');
-              }, function () {
-                $parent.removeClass('highlight');
-                $match.trigger('mouseleave');
-              });
-          });
-          // Show the search results.
-          // @todo Why do they appear without this?
-          //$self.trigger('mouseenter');
-        }
+  $input.keyup(function () {
+    var matches, $html, value = $(this).val();
+    // Only proceed if the search needle has changed.
+    if (value !== needle) {
+      needle = value;
+      $html = $('<ul />');
+      // Only search if the needle is longer than 3 characters.
+      if (needle.length >= 3) {
+        needleMatch = needle.toLowerCase();
+        // Select matching links from the cache.
+        matches = $.grep(links, function (link) {
+          return link.textMatch.indexOf(needleMatch) !== -1;
+        });
+        // Build the list in the detached DOM node.
+        $.each(matches, function () {
+          var result = this.text;
+          var $element = $(this.element);
+          var $category = $element.closest('#admin-menu-wrapper > ul > li');
+          if ($category.length) {
+            result = $category.find('> a').text() + ': ' + result;
+          }
+          $html.append('<li><a href="' + $element.attr('href') +'">' + result +'</a></li>');
+        });
+        // Display results.
+        $results.empty().append($html);
       }
-    });
+    }
   });
 };
 
