diff --git a/includes/menu.inc b/includes/menu.inc
index 18a6e5aca254d994b17a435f5a19fd01c51f4ed5..9a5e21fd38e80f0badc3ca3269f69fe6b3121bb0 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -1,127 +1,120 @@
 <?php
 // $Id$
 
+/**
+ * Register a menu item to the menu system.
+ */
 function menu($path, $title, $callback = NULL, $help = NULL, $weight = 0, $hidden = 0) {
-  global $_gmenu;
+  global $_list;
 
-  if (empty($_gmenu[$path])) {
-    // add the menu to the flat list of menu items:
-    $_gmenu[$path] = array("title" => $title, "callback" => $callback, "help" => $help, "weight" => $weight, "hidden" => $hidden, "children" => array());
-
-    // find the best matching parent item:
-    $parent = substr($path, 0, strrpos($path, "/"));
-    while ($parent && !$_gmenu[$parent]) {
-      $parent = substr($parent, 0, strrpos($parent, "/"));
-    }
-
-    // check if any items need to be lowered:
-    if ($parent) {
-      foreach ($_gmenu[$parent]["children"] as $key => $item) {
-        if (strstr($item, $path)) {
-          // remove the item from its parent:
-          unset($_gmenu[$parent]["children"][$key]);
-
-          // add the item to its new parent:
-          $_gmenu[$path]["children"][] = $item;
-        }
-      }
-    }
-
-    // add the menu to the best matching parent:
-    $_gmenu[$parent]["children"][] = $path;
-  }
+  // add the menu to the flat list of menu items:
+  $_list[$path] = array("title" => $title, "callback" => $callback, "help" => $help, "weight" => $weight, "hidden" => $hidden);
 }
 
-function menu_item($in_path) {
-  global $_gmenu;
-  /*
-  ** If you want to theme your links, or if you want to replace them
-  ** by an image, this would be the function to customize.
-  */
-  $trail = menu_trail();
-  if (end($trail) == $in_path) {
-    $css = " class=\"current\"";
-  }
-
-  return "<a href=\"". url($in_path) ."\"$css>". t($_gmenu[$in_path]["title"]) ."</a>";
-}
+/**
+ * Returns the path of the active menu item.
+ */
+function menu_get_active() {
+  global $_list;
+  static $path;
 
-function menu_title($in_path = null) {
-  global $_gmenu;
+  if (empty($path)) {
+    $path = $_GET["q"];
 
-  if ($in_path == null) {
-    $trail = menu_trail();
-    $in_path = array_pop($trail);
+    while ($path && !$_list[$path]) {
+      $path = substr($path, 0, strrpos($path, "/"));
+    }
   }
 
-  return ucfirst($_gmenu[$in_path]["title"]);
+  return $path;
 }
 
-function menu_trail() {
-  global $_gmenu;
+function menu_get_path($path) {
+  global $_list;
   static $trail; // cache
 
   if (empty($trail)) {
     $trail = array();
-    $path = $_GET["q"];
 
     while ($path) {
-      if ($_gmenu[$path]) {
-        $trail[] = $path;
+      if ($_list[$path]) {
+        array_unshift($trail, $path);
       }
 
       $path = substr($path, 0, strrpos($path, "/"));
     }
-
-    $trail = array_reverse($trail);
   }
 
   return $trail;
 }
 
-function menu_path() {
+function menu_get_active_title() {
+  global $_list;
 
-  $trail = menu_trail();
+  if ($path = menu_get_active()) {
+    return ucfirst($_list[$path]["title"]);
+  }
+}
 
-  $links[] = l(t("Home"), "");
+function menu_get_active_help() {
+  global $_list;
 
-  foreach ($trail as $item) {
-    $links[] = menu_item($item);
+  if ($path = menu_get_active()) {
+    return $_list[$path]["help"];
   }
+}
+
+function menu_is_active($path) {
 
-  return $links;
 }
 
-function menu_help() {
-  global $_gmenu;
-  $path = menu_trail();
-  if ($path) {
-    $item = array_pop($path);
-    $output = $_gmenu[$item]["help"];
+function menu_render_item($path) {
+  global $_list;
+
+  if ($path == $_GET["q"]) {
+    $css = " class=\"active\"";
   }
 
-  return @$output;
+  return "<a href=\"". url($path) ."\"$css>". t($_list[$path]["title"]) ."</a>";
+}
+
+function menu_active_breadcrumb() {
+
+  $links[] = l(t("Home"), "");
+
+  $trail = menu_get_path($_GET["q"]);
+  foreach ($trail as $item) {
+    $links[] = menu_render_item($item);
+  }
+
+  return $links;
 }
 
 function _menu_sort($a, $b) {
-  global $_gmenu;
-  $a = &$_gmenu[$a];
-  $b = &$_gmenu[$b];
+  global $_list;
+
+  $a = &$_list[$a];
+  $b = &$_list[$b];
+
   return $a["weight"] < $b["weight"] ? -1 : ($a["weight"] > $b["weight"] ? 1 : ($a["title"] < $b["title"] ? -1 : 1));
 }
 
 function menu_tree($parent = "") {
-  global $_gmenu;
+  global $_list;
+  static $trail;
 
-  if ($_gmenu[$parent]["children"]) {
+  if (empty($tail)) {
+    $trail = menu_get_path($_GET["q"]);
+  }
+
+  if ($_list[$parent]["children"]) {
     $output = "\n<ul>\n";
-    usort($_gmenu[$parent]["children"], "_menu_sort");
-    foreach ($_gmenu[$parent]["children"] as $item) {
-      if ($_gmenu[$item]["hidden"] == 0) {
-        $trail = menu_trail($item);
-        $style = ($_gmenu[$item]["children"] ? (in_array($item, $trail)  ? "expanded" : "collapsed") : "leaf");
+    usort($_list[$parent]["children"], "_menu_sort");
+    foreach ($_list[$parent]["children"] as $item) {
+      if ($_list[$item]["hidden"] == 0) {
+        $style = ($_list[$item]["children"] ? (in_array($item, $trail)  ? "expanded" : "collapsed") : "leaf");
         $output .= "<li class=\"$style\">";
-        $output .= menu_item($item);
+        $output .= menu_render_item($item);
         if (in_array($item, $trail)) {
           $output .= menu_tree($item);
         }
@@ -134,47 +127,52 @@ function menu_tree($parent = "") {
   return $output;
 }
 
-function menu_map($parent = "") {
-  global $_gmenu;
-
-  $output = "<ul>";
-  usort($_gmenu[$parent]["children"], "_menu_sort");
-  foreach ($_gmenu[$parent]["children"] as $item) {
-    if ($_gmenu[$item]["hidden"] == 0) {
-      $output .= "<li>";
-      $output .= menu_item($item);
-      $output .= menu_map($item);
-      $output .= "</li>";
-    }
-  }
-  $output .= "</ul>";
-
-  return $output;
-}
 
 function menu_execute_action() {
-  global $_gmenu;
-  $trail = menu_trail();
-  $selected_menu = array_pop($trail);
+  global $_list;
 
-  if ($_gmenu[$selected_menu]["callback"]) {
-    $arg = substr($_GET["q"], strlen($selected_menu) + 1);
+  $path = menu_get_active();
+
+  if ($_list[$path]["callback"]) {
+    $arg = substr($_GET["q"], strlen($path) + 1);
     if (empty($arg)) {
-      return call_user_func($_gmenu[$selected_menu]["callback"]);
+      return call_user_func($_list[$path]["callback"]);
     }
     else {
-      return call_user_func_array($_gmenu[$selected_menu]["callback"], explode("/", $arg));
+      return call_user_func_array($_list[$path]["callback"], explode("/", $arg));
     }
   }
 }
 
 function menu_build($type) {
+  /*
+  ** Build a sequential list of all menus items.
+  */
 
-  // Empty the existing menu tree (if any):
-  unset($GLOBALS["_gmenu"]);
-
-  // Build the menu tree:
   module_invoke_all("link", $type);
+
+  /*
+  ** Tree-ify the sequential list of menu items by adding each
+  ** menu item to the 'children' array of their direct parent.
+  */
+
+  global $_list;
+
+  foreach ($_list as $path => $data) {
+
+    /*
+    ** Find $path's direct parent:
+    */
+    $parent = $path;
+    do {
+      $parent = substr($parent, 0, strrpos($parent, "/"));
+    }
+    while ($parent && !$_list[$parent]);
+
+    if ($path) {
+      $_list[$parent]["children"][] = $path;
+    }
+  }
 }
 
 ?>
diff --git a/index.php b/index.php
index 416fa17a6b22c4c28928d4932067d4b298c95bea..198b23ed77a3da39c9ba5d755bf4b69028270203 100644
--- a/index.php
+++ b/index.php
@@ -16,12 +16,14 @@
 
 drupal_page_header();
 
+check_php_setting("magic_quotes_gpc", 0);
+
+menu_build("system");
+
 if (isset($mod) && module_hook($mod, "page")) {
   module_invoke($mod, "page");
 }
 else {
-  check_php_setting("magic_quotes_gpc", 0);
-
   if (module_hook(variable_get("site_frontpage", "node"), "page")) {
     module_invoke(variable_get("site_frontpage", "node"), "page");
   }
diff --git a/misc/drupal.css b/misc/drupal.css
index 8816572278f087e54fad5f3875456651968ba06f..93f4cac12e0ea8daf07a5c3ad21575e28651eee0 100644
--- a/misc/drupal.css
+++ b/misc/drupal.css
@@ -278,7 +278,7 @@ pre, code {
   width: 100%;
   text-decoration: none;
 }
-#menu li a.current {
+#menu li a.active {
   color: #000;
 }
 #menu li a:hover {
diff --git a/modules/admin.module b/modules/admin.module
index 5057c1f6044edb30cfd806b59e9c7b744d6b1ec8..3bba6845649dff0ad3a626f5bceb1578aac8e2bc 100644
--- a/modules/admin.module
+++ b/modules/admin.module
@@ -37,26 +37,13 @@ function admin_system($field){
 
 function admin_link($type) {
   if ($type == "system" && user_access("access administration pages")) {
-    menu("admin", t("administer %a", array("%a" => variable_get("site_name", "drupal"))) , NULL, NULL, 9);
-    menu("admin/overview", "sitemap", "overview_callback", admin_help("admin/overview"), 8);
+    menu("admin", t("administer"), NULL, NULL, 9);
   }
 }
 
-function overview_callback() {
-  return menu_map();
-}
-
-function admin_admin() {
-  return menu_map();
-}
-
-
 function admin_page() {
   if (user_access("access administration pages")) {
-    if (!isset($GLOBALS["_gmenu"])) {
-      menu_build("system");
-    }
-    if ($help = menu_help()) {
+    if ($help = menu_get_active_help()) {
       $contents = "<small>$help</small><hr />";
     }
     if (arg(1)) {
@@ -67,9 +54,9 @@ function admin_page() {
       $title = t("System messages");
     }
 
-    $breadcrumb = menu_path();
+    $breadcrumb = menu_active_breadcrumb();
     array_pop($breadcrumb);
-    $title = menu_title();
+    $title = menu_get_active_title();
 
     theme("header");
     theme("breadcrumb", $breadcrumb);
diff --git a/modules/book.module b/modules/book.module
index 5ac34dc6738700495106ec144d277e0b489510de..eb9fd971c7b47e0761d0df2bbb2b19604cac1f1a 100644
--- a/modules/book.module
+++ b/modules/book.module
@@ -79,10 +79,10 @@ function book_link($type, $node = 0, $main = 0) {
 
   if ($type == "system") {
     if (user_access("maintain books")) {
-      menu("node/add/book",t("book page"), NULL, NULL,0);
-      menu("admin/node/book", "books", NULL, NULL, 4);
-      menu("admin/node/book/orphan", "orphan pages", NULL, NULL, 8);
-      menu("admin/node/book/help", "help", NULL, NULL, 9);
+      menu("node/add/book", t("book page"), NULL, NULL,0);
+      menu("admin/node/book", t("books"), NULL, NULL, 4);
+      menu("admin/node/book/orphan", t("orphan pages"), NULL, NULL, 8);
+      menu("admin/node/book/help", t("help"), NULL, NULL, 9);
 
       $result = db_query("SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title");
       while ($book = db_fetch_object($result)) {
diff --git a/modules/book/book.module b/modules/book/book.module
index 5ac34dc6738700495106ec144d277e0b489510de..eb9fd971c7b47e0761d0df2bbb2b19604cac1f1a 100644
--- a/modules/book/book.module
+++ b/modules/book/book.module
@@ -79,10 +79,10 @@ function book_link($type, $node = 0, $main = 0) {
 
   if ($type == "system") {
     if (user_access("maintain books")) {
-      menu("node/add/book",t("book page"), NULL, NULL,0);
-      menu("admin/node/book", "books", NULL, NULL, 4);
-      menu("admin/node/book/orphan", "orphan pages", NULL, NULL, 8);
-      menu("admin/node/book/help", "help", NULL, NULL, 9);
+      menu("node/add/book", t("book page"), NULL, NULL,0);
+      menu("admin/node/book", t("books"), NULL, NULL, 4);
+      menu("admin/node/book/orphan", t("orphan pages"), NULL, NULL, 8);
+      menu("admin/node/book/help", t("help"), NULL, NULL, 9);
 
       $result = db_query("SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title");
       while ($book = db_fetch_object($result)) {
diff --git a/modules/user.module b/modules/user.module
index 6bead895d9dd7c8c5d1556bbfe37f355d4329a05..5808a128b14971c7da20bbbd56fb640f3c08bc05 100644
--- a/modules/user.module
+++ b/modules/user.module
@@ -427,7 +427,6 @@ function user_block($op = "list", $delta = 0) {
           $block["content"] = "<div class=\"user-login-link\">$output</div>";
         }
 
-        menu_build("system");
         $block["content"] .= "<div id=\"menu\">". menu_tree()."</div>";
         return $block;
         break;
@@ -467,22 +466,22 @@ function user_link($type) {
   if ($type == "system") {
     global $user;
     if ($user->uid) {
-      menu("user/edit", t("edit account"), NULL, NULL, 8);
-      menu("user/logout", t("logout"), NULL, NULL, 10);
+      menu("user/edit", t("edit my account"), NULL, NULL, 8);
+      menu("user/logout", t("log out"), NULL, NULL, 10);
     }
     if (user_access("administer users")) {
-      menu("admin/user", "user management", "user_admin", user_help("admin/user"), 2);
-      menu("admin/user/create", "create new account", "user_admin", user_help("admin/user/create"), 1);
-      menu("admin/user/account", "view user accounts", "user_admin", user_help("admin/user/account"), 2);
-      menu("admin/user/access", "access rules", NULL, user_help("admin/user/access"), 3);
-      menu("admin/user/access/mail", "e-mail rules", "user_admin", user_help("admin/user/access/mail"));
-      menu("admin/user/access/user", "username rules", "user_admin", user_help("admin/user/access/user"));
-      menu("admin/user/role", "user roles", "user_admin", user_help("admin/user/role"), 4);
-      menu("admin/user/permission", "user permissions", "user_admin", user_help("admin/user/permission"), 5);
-      menu("admin/user/search", "search accounts", "user_admin", user_help("admin/user/search"), 8);
-      menu("admin/user/help", "help", "user_help", NULL, 9);
-      menu("admin/user/edit", "edit user account", "user_admin", NULL, 0, 1); // hidden menu
-      menu("admin/user/account/1", "blocked users", "user_admin", user_help("admin/user/account/1"), 3);
+      menu("admin/user", "accounts", "user_admin", user_help("admin/user"), 2);
+      menu("admin/user/create", t("new user"), "user_admin", user_help("admin/user/create"), 1);
+      menu("admin/user/account", t("users"), "user_admin", user_help("admin/user/account"), 2);
+      menu("admin/user/access", t("access rules"), NULL, user_help("admin/user/access"), 3);
+      menu("admin/user/access/mail", t("by e-mail"), "user_admin", user_help("admin/user/access/mail"));
+      menu("admin/user/access/user", t("by name"), "user_admin", user_help("admin/user/access/user"));
+      menu("admin/user/role", t("roles"), "user_admin", user_help("admin/user/role"), 4);
+      menu("admin/user/permission", t("permissions"), "user_admin", user_help("admin/user/permission"), 5);
+      menu("admin/user/search", t("search"), "user_admin", user_help("admin/user/search"), 8);
+      menu("admin/user/help", t("help"), "user_help", NULL, 9);
+      menu("admin/user/edit", t("edit user account"), "user_admin", NULL, 0, 1); // hidden menu
+      menu("admin/user/account/1", t("blocked users"), "user_admin", user_help("admin/user/account/1"), 3);
 
       $i = 2;
       foreach (user_roles(1) as $key => $value) {
diff --git a/modules/user/user.module b/modules/user/user.module
index 6bead895d9dd7c8c5d1556bbfe37f355d4329a05..5808a128b14971c7da20bbbd56fb640f3c08bc05 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -427,7 +427,6 @@ function user_block($op = "list", $delta = 0) {
           $block["content"] = "<div class=\"user-login-link\">$output</div>";
         }
 
-        menu_build("system");
         $block["content"] .= "<div id=\"menu\">". menu_tree()."</div>";
         return $block;
         break;
@@ -467,22 +466,22 @@ function user_link($type) {
   if ($type == "system") {
     global $user;
     if ($user->uid) {
-      menu("user/edit", t("edit account"), NULL, NULL, 8);
-      menu("user/logout", t("logout"), NULL, NULL, 10);
+      menu("user/edit", t("edit my account"), NULL, NULL, 8);
+      menu("user/logout", t("log out"), NULL, NULL, 10);
     }
     if (user_access("administer users")) {
-      menu("admin/user", "user management", "user_admin", user_help("admin/user"), 2);
-      menu("admin/user/create", "create new account", "user_admin", user_help("admin/user/create"), 1);
-      menu("admin/user/account", "view user accounts", "user_admin", user_help("admin/user/account"), 2);
-      menu("admin/user/access", "access rules", NULL, user_help("admin/user/access"), 3);
-      menu("admin/user/access/mail", "e-mail rules", "user_admin", user_help("admin/user/access/mail"));
-      menu("admin/user/access/user", "username rules", "user_admin", user_help("admin/user/access/user"));
-      menu("admin/user/role", "user roles", "user_admin", user_help("admin/user/role"), 4);
-      menu("admin/user/permission", "user permissions", "user_admin", user_help("admin/user/permission"), 5);
-      menu("admin/user/search", "search accounts", "user_admin", user_help("admin/user/search"), 8);
-      menu("admin/user/help", "help", "user_help", NULL, 9);
-      menu("admin/user/edit", "edit user account", "user_admin", NULL, 0, 1); // hidden menu
-      menu("admin/user/account/1", "blocked users", "user_admin", user_help("admin/user/account/1"), 3);
+      menu("admin/user", "accounts", "user_admin", user_help("admin/user"), 2);
+      menu("admin/user/create", t("new user"), "user_admin", user_help("admin/user/create"), 1);
+      menu("admin/user/account", t("users"), "user_admin", user_help("admin/user/account"), 2);
+      menu("admin/user/access", t("access rules"), NULL, user_help("admin/user/access"), 3);
+      menu("admin/user/access/mail", t("by e-mail"), "user_admin", user_help("admin/user/access/mail"));
+      menu("admin/user/access/user", t("by name"), "user_admin", user_help("admin/user/access/user"));
+      menu("admin/user/role", t("roles"), "user_admin", user_help("admin/user/role"), 4);
+      menu("admin/user/permission", t("permissions"), "user_admin", user_help("admin/user/permission"), 5);
+      menu("admin/user/search", t("search"), "user_admin", user_help("admin/user/search"), 8);
+      menu("admin/user/help", t("help"), "user_help", NULL, 9);
+      menu("admin/user/edit", t("edit user account"), "user_admin", NULL, 0, 1); // hidden menu
+      menu("admin/user/account/1", t("blocked users"), "user_admin", user_help("admin/user/account/1"), 3);
 
       $i = 2;
       foreach (user_roles(1) as $key => $value) {