diff --git a/admin_menu.css b/admin_menu.css
index f93784a..ff1719a 100644
--- a/admin_menu.css
+++ b/admin_menu.css
@@ -97,6 +97,9 @@ body.admin-menu { margin-top: 20px !important; }
 /* #210615: Mozilla on Mac fix */
 html.js fieldset.collapsible div.fieldset-wrapper { overflow: visible; }
 
+/* Keyboard navigation */
+div#admin-menu li.focused { background-color: #75757a; }
+
 @media print {
   #admin-menu { display: none; }
   body.admin-menu { margin-top: 0 !important; }
diff --git a/admin_menu.inc b/admin_menu.inc
index bfe1ee2..aca0146 100644
--- a/admin_menu.inc
+++ b/admin_menu.inc
@@ -314,14 +314,14 @@ function admin_menu_adjust_items(&$menu_links, &$sort) {
   $links[] = array(
     'title' => 'icon_users',
     'path' => 'user',
-    'weight' => -90,
+    'weight' => 999,
     'parent_path' => '<root>',
     'options' => array('extra class' => 'admin-menu-action admin-menu-icon admin-menu-users', 'html' => TRUE),
   );
   $links[] = array(
     'title' => 'Log out @username',
     'path' => 'logout',
-    'weight' => -100,
+    'weight' => 1000,
     'parent_path' => '<root>',
     // Note: @username is dynamically replaced by default, we just invoke
     // replacement by setting the 't' key here.
diff --git a/admin_menu.js b/admin_menu.js
index 2a24251..a511bf3 100644
--- a/admin_menu.js
+++ b/admin_menu.js
@@ -47,4 +47,313 @@ $(document).ready(function() {
       uls.css({left: '-999em', display: 'none'});
     }, 400);
   });
+  
+  
+  // Keyboard navigation.
+  var tree, active = false, current;
+  
+  /**
+  * Initialize function, caches the DOM tree in an JavaScript object.
+  */
+  
+  var createTree = function() {
+  
+    /**
+    * Cache menu's DOM as an JavaScript Object. This improves dramaticaly the 
+    * navigation performance, cause we are not required to travers the DOM while 
+    * each keypress instead we just travers the js object later.
+    * 
+    * @param HTMLListElement element
+    *   An HTMLListElement object containing the current LI Element
+    * @param integer index
+    *   An number inidicating serial index
+    * @return
+    *   This is the current structure of the return object
+    *   {
+    *     li: current li element
+    *     a:  current element's first A element
+    *     children: recursively collected array of current element's children
+    *     index: serial number of current element
+    *     uls: immediate descendant ul 
+    *   }
+    */
+  
+    var collectElements = function (element, index) {
+      // Cache creation of jQuery object
+      var _this = $(element);
+    
+      // Set default tree object
+      var tree = { li: _this, a: _this.find("> a"), index: index, alignment: _this.css("float") };
+
+      // Check whether this element has children
+      var children;
+      if ((children = _this.find("> ul > li")).length) {
+        // Yes, we have children, let us collect all children elements recursively
+        tree.children = $.map(children, collectElements);
+      }
+      return tree;
+    };
+  
+    tree = $.map($("#admin-menu > ul > li"), collectElements);
+  
+    /**
+    * Walks through the tree object and creates parents references on the fly.
+    * No return is required because we are working with object reference.
+    * 
+    * @param array array
+    *   Array with elements for looping through
+    * @param object parent
+    *   Refrence to the parent object
+    * @param interger parentIndex
+    *   Specifies the position of parent in array
+    * @param interger level
+    *   Current element depth
+    */
+    var setParents = function (array, parent, parentIndex, level) {
+      // fallback level on initialization
+      var level = level || 1;
+      
+      
+      for (var i = 0; i < array.length; i++) {
+        // Chache object.
+        var object = array[i];
+        
+        // Set current depth.
+        object.level = level;
+        
+        // Create reference to the parent object.
+        if (parent) object.parent = parent;
+
+        // Set parent's position in one's array.
+        object.parentIndex = parentIndex || i;
+
+        // Do we have children? If yes go lets apply the same on our children.
+        if (object.children) arguments.callee(object.children, object, i, level + 1);
+      }
+    };
+  
+    
+    // Trigger the setParents function
+    setParents(tree);
+    
+    // Toggle the order of right floated elements
+    var rightFloated = [], previousElement;
+    
+    for (var i = tree.length - 1; i >= 0; i--){
+      if(tree[i].alignment == "right") {
+        rightFloated.push(tree.pop());
+        
+        // Toggle index and parentIndex from current to previous element
+        if(previousElement) {
+          var index = rightFloated[rightFloated.length-1].index;
+          var cur = rightFloated[rightFloated.length-1];
+          var prev = rightFloated[rightFloated.length-2];
+          cur.index = cur.parentIndex = previousElement.index;
+          prev.index = prev.parentIndex = index;
+        }
+        previousElement = rightFloated[rightFloated.length-1];
+      }
+    };
+    // Append rightFloated elements back to the tree
+    tree = tree.concat(rightFloated);
+  };
+  
+  // We don't need delayed mouse out so copy and paste from above without timeout
+  var mouseLeave = function(element) {
+    element.find('> ul').css({left: '-999em', display: 'none'});
+  };
+  
+  // Allow while Keyboard navigation, mouse navigation too
+  $("#admin-menu a").bind("mouseenter", function(event){
+    current.a.unbind("blur", blur);
+  });
+    
+  var blur = function(event) {
+    // Find all active tabs and close them
+    mouseLeave($("#admin-menu li"));
+
+    // Color mark should be erased,
+    $("#admin-menu .focused").removeClass("focused");
+    
+    // Set current to undefined, so on next initialize 
+    // the current element would be picked again.
+    current = undefined;
+    
+    active = false;
+  };
+  
+    
+  // Attach the keydown trigger function on the document. 
+  // This is on place where we could pick off the keydown event in all browsers.
+  var keyevent = function (event) {    
+    // Cache keyCode
+    var key = event.keyCode || event.which;
+
+    // If not left, top, right, down or shift + space is pressed. Break here.
+    if (!(key == 37 || key == 38 || key == 39 || key == 40 || (key == 32 && event.shiftKey))) {
+      return true;
+    }
+
+    // Does somebody pressed shift + space?
+    if (key == 32 && event.shiftKey) {
+      
+      // Toggle the active state
+      active = !active;
+      
+      // If the keyboard navigation is not active anymore.
+      if (!active) {        
+        // Blur the current A element.
+        current.a.blur();
+        blur();
+        // Cancel event's propaganation.
+        return false;
+      }
+    }
+    
+    // If the menu is not active, break here.
+    if (!active) {
+      return false;
+    }
+    
+    // If the tree is not initializated, create.
+    if(!tree) {
+      createTree();
+    }
+    
+    // Reset first element on initialization.
+    if (!current) {
+      current = tree[1] || tree[0];
+    }
+
+    var next;
+    
+    switch (key) {
+      case 37: // Left
+        // Do we have first level here and can we go to the previous element?
+        if (current.level == 1 && tree[current.parentIndex - 1]) {
+          // Yes, our next selection is current's previous element.
+          next = tree[current.parentIndex - 1];
+        }
+        // Handle third and deeper levels.
+        else if (current.level > 2) {
+          // Our next element is our current parent.
+          next = current.parent;
+        }
+        // If somebody presed left in the second level.
+        else if(current.parent) {
+          // Go to the parents previous element.
+          next = tree[current.parent.parentIndex - 1];
+        }
+        break;
+
+      case 38: // Up
+        // We have first level.
+        if (current.level == 1 && current.children) {
+          // Next is our last child.
+          next = current.children[current.children.length - 1];
+        }
+        // We are at the second level and we are not on the top.
+        else if (!(current.level == 2 && current.index == 0)) {
+          if(current.index == 0) {
+            next = current.parent.children[current.parent.children.length-1];
+          } else if(current.parent){
+            // Select previous element.
+            next = current.parent.children[current.index - 1];
+          }
+        }
+        // Second level an we are at the top
+        else if (current.level == 2 && current.index == 0) {
+          // Select our parent, cause parent is visualy more at the top.
+          next = current.parent;
+        }
+        break;
+
+      case 39: // Right
+        // First level?
+        if (current.level == 1) {
+          // Next element is set?
+          if(tree[current.parentIndex + 1]) {
+            next = tree[current.parentIndex + 1];
+          }
+        }
+        // Handle third level and deeper. Do we have chidlren?
+        else if (current.children) {
+          // Select our first child.
+          next = current.children[0];
+        }
+        // Are we at the second level?
+        else if (current.level == 2) {
+          // Select visualy next element.
+          next = tree[current.parent.parentIndex + 1];
+        }
+        break;
+
+      case 40: // Down
+        // Do we are at the first level and have children?
+        if (current.level == 1 && tree[current.parentIndex].children) {
+          // Get first level element's first child.
+          next = tree[current.parentIndex].children[0];
+        }
+        // Last element?
+        else if (current.parent && current.index == current.parent.children.length-1) {
+          // Are we at the second level.
+          if(current.level == 2) {
+            // Our next element is our parent.
+            next = tree[current.parent.index];
+          } else {
+            next = current.parent.children[0];
+          }
+        } else if(current.parent) {
+          // Just select our previous element.
+          next = current.parent.children[current.index + 1];
+        }
+        break;
+    }
+    
+    // Fallback to current if next is not set.
+    if (!next) {
+      next = current;
+    }
+    
+    // Remove previous mark.
+    $("#admin-menu .focused").removeClass("focused");    
+    
+    // Do we go up or just have children and are at the same level?
+    if ((next.level < current.level) || (!next.children && next.level == current.level)) {
+      // Hid not required elements.
+      if (next.children == undefined && current.children == undefined && next.level == 1 && current.parent) {
+        mouseLeave(current.parent.li);
+      } else{      
+        mouseLeave(current.li);
+      }
+    }
+    
+    // Set current element mark.
+    next.li.parents("li").andSelf().addClass('focused');
+    
+    // Activate the enter key 
+    next.a.focus();
+    
+    // Allow while Keyboard navigation, mouse navigation too
+    current.a.trigger("mouseenter");
+    next.a.bind("blur", blur);
+    
+    // Show descendant ul
+    next.li.trigger('mouseenter');
+
+    // Save next object, so we could fall back on this next time
+    current = next;
+
+    // Cancel event propagation, in all browsers.
+    return false;
+  };
+  
+  // MSIE and Safari need to stop event propagation the keydown event
+  if(jQuery.browser.msie || jQuery.browser.safari) {
+    $(document).bind('keydown', keyevent);
+  }
+  // All other browsers are happy with the keypress event
+  else {
+    $(document).bind('keypress', keyevent);
+  }
 });
