From 5c7983c4deae55ad41b85ca99db54d3fce283fd9 Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Thu, 16 Sep 2004 07:17:56 +0000
Subject: [PATCH] - Patch #8179 by JonBob: reintroduced menu caching.

---
 includes/bootstrap.inc               |   2 +-
 includes/menu.inc                    | 209 +++++++++++++++++++--------
 modules/admin.module                 |  12 +-
 modules/aggregator.module            |  94 ++++++------
 modules/aggregator/aggregator.module |  94 ++++++------
 modules/archive.module               |  13 +-
 modules/archive/archive.module       |  13 +-
 modules/block.module                 |  41 +++---
 modules/block/block.module           |  41 +++---
 modules/blog.module                  |  33 +++--
 modules/blog/blog.module             |  33 +++--
 modules/blogapi.module               |   7 +-
 modules/blogapi/blogapi.module       |   7 +-
 modules/book.module                  |  48 +++---
 modules/book/book.module             |  48 +++---
 modules/comment.module               |  98 +++++++------
 modules/comment/comment.module       |  98 +++++++------
 modules/drupal.module                |  10 +-
 modules/drupal/drupal.module         |  10 +-
 modules/filter.module                |  74 +++++-----
 modules/filter/filter.module         |  74 +++++-----
 modules/forum.module                 |  16 +-
 modules/forum/forum.module           |  16 +-
 modules/help.module                  |  28 ++--
 modules/help/help.module             |  28 ++--
 modules/legacy.module                |  58 ++++----
 modules/legacy/legacy.module         |  58 ++++----
 modules/locale.module                |  81 ++++++-----
 modules/locale/locale.module         |  81 ++++++-----
 modules/menu.module                  |  75 +++++-----
 modules/menu/menu.module             |  75 +++++-----
 modules/node.module                  |  93 ++++++------
 modules/node/node.module             |  93 ++++++------
 modules/page.module                  |  10 +-
 modules/page/page.module             |  10 +-
 modules/path.module                  |  40 ++---
 modules/path/path.module             |  40 ++---
 modules/poll.module                  |  53 ++++---
 modules/poll/poll.module             |  53 ++++---
 modules/profile.module               |  46 +++---
 modules/profile/profile.module       |  46 +++---
 modules/queue.module                 |  14 +-
 modules/search.module                |  34 +++--
 modules/search/search.module         |  34 +++--
 modules/statistics.module            |  62 ++++----
 modules/statistics/statistics.module |  62 ++++----
 modules/story.module                 |  10 +-
 modules/story/story.module           |  10 +-
 modules/system.module                |  83 ++++++-----
 modules/system/system.module         |  83 ++++++-----
 modules/taxonomy.module              |  34 +++--
 modules/taxonomy/taxonomy.module     |  34 +++--
 modules/tracker.module               |  25 ++--
 modules/tracker/tracker.module       |  25 ++--
 modules/upload.module                |  42 +++---
 modules/upload/upload.module         |  42 +++---
 modules/user.module                  | 142 +++++++++---------
 modules/user/user.module             | 142 +++++++++---------
 modules/watchdog.module              |  16 +-
 modules/watchdog/watchdog.module     |  16 +-
 60 files changed, 1605 insertions(+), 1364 deletions(-)

diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index cf55dc17350d..7a0a37ac49ea 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -5,7 +5,7 @@
  * @file
  * Functions that need to be loaded on every Drupal request.
  */
- 
+
 define('CACHE_PERMANENT', 0);
 define('CACHE_TEMPORARY', -1);
 
diff --git a/includes/menu.inc b/includes/menu.inc
index 9ac5a26474ac..889828d8e22f 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -196,11 +196,24 @@
  */
 function menu_get_menu() {
   global $_menu;
+  global $user;
 
   if (!isset($_menu['items'])) {
     // _menu_build() may indirectly call this function, so prevent infinite loops.
     $_menu['items'] = array();
-    _menu_build();
+
+    $cid = 'menu:'. $user->uid;
+    if ($cached = cache_get($cid)) {
+      $_menu = unserialize($cached->data);
+    }
+    else {
+      _menu_build();
+      // Cache the menu structure for this user, to expire after one day.
+      cache_set($cid, serialize($_menu), time() + (60 * 60 * 24));
+    }
+
+    // Make sure items that cannot be cached are added.
+    _menu_append_contextual_items();
   }
 
   return $_menu;
@@ -330,7 +343,7 @@ function menu_execute_active_handler() {
   }
 
   // We found one, and are allowed to execute it.
-  $arguments = $menu['items'][$mid]['callback arguments'];
+  $arguments = array_key_exists('callback arguments', $menu['items'][$mid]) ? $menu['items'][$mid]['callback arguments'] : array();
   $arg = substr($_GET['q'], strlen($menu['items'][$mid]['path']) + 1);
   if (strlen($arg)) {
     $arguments = array_merge($arguments, explode('/', $arg));
@@ -478,36 +491,41 @@ function menu_in_active_trail($mid) {
  * This need only be called at the start of pages that modify the menu.
  */
 function menu_rebuild() {
+  // Clear the page cache, so that changed menus are reflected for anonymous users.
   cache_clear_all();
-  _menu_build();
-  $menu = menu_get_menu();
+  // Also clear the menu cache.
+  cache_clear_all('menu:', TRUE);
 
-  $new_items = array();
-  foreach ($menu['items'] as $mid => $item) {
-    if ($mid < 0 && ($item['type'] & MENU_MODIFIABLE_BY_ADMIN)) {
-      $new_mid = db_next_id('{menu}_mid');
-      if (isset($new_items[$item['pid']])) {
-        $new_pid = $new_items[$item['pid']]['mid'];
-      }
-      else {
-        $new_pid = $item['pid'];
-      }
+  if (module_exist('menu')) {
+    $menu = menu_get_menu();
 
-      // Fix parent IDs for menu items already added.
-      if ($item['children']) {
-        foreach ($item['children'] as $child) {
-          if (isset($new_items[$child])) {
-            $new_items[$child]['pid'] = $new_mid;
+    $new_items = array();
+    foreach ($menu['items'] as $mid => $item) {
+      if ($mid < 0 && ($item['type'] & MENU_MODIFIABLE_BY_ADMIN)) {
+        $new_mid = db_next_id('{menu}_mid');
+        if (isset($new_items[$item['pid']])) {
+          $new_pid = $new_items[$item['pid']]['mid'];
+        }
+        else {
+          $new_pid = $item['pid'];
+        }
+
+        // Fix parent IDs for menu items already added.
+        if ($item['children']) {
+          foreach ($item['children'] as $child) {
+            if (isset($new_items[$child])) {
+              $new_items[$child]['pid'] = $new_mid;
+            }
           }
         }
-      }
 
-      $new_items[$mid] = array('mid' => $new_mid, 'pid' => $new_pid, 'path' => $item['path'], 'title' => $item['title'], 'description' => $item['description'], 'weight' => $item['weight'], 'type' => $item['type']);
+        $new_items[$mid] = array('mid' => $new_mid, 'pid' => $new_pid, 'path' => $item['path'], 'title' => $item['title'], 'description' => array_key_exists('description', $item) ? $item['description'] : '', 'weight' => $item['weight'], 'type' => $item['type']);
+      }
     }
-  }
 
-  foreach ($new_items as $item) {
-    db_query('INSERT INTO {menu} (mid, pid, path, title, description, weight, type) VALUES (%d, %d, \'%s\', \'%s\', \'%s\', %d, %d)', $item['mid'], $item['pid'], $item['path'], $item['title'], $item['description'], $item['weight'], $item['type']);
+    foreach ($new_items as $item) {
+      db_query('INSERT INTO {menu} (mid, pid, path, title, description, weight, type) VALUES (%d, %d, \'%s\', \'%s\', \'%s\', %d, %d)', $item['mid'], $item['pid'], $item['path'], $item['title'], $item['description'], $item['weight'], $item['type']);
+    }
   }
 
   // Rebuild the menu to account for any changes.
@@ -559,7 +577,7 @@ function theme_menu_item($mid) {
     $link_mid = $menu['items'][$link_mid]['pid'];
   }
 
-  return l($menu['items'][$mid]['title'], $menu['items'][$link_mid]['path'], $menu['items'][$mid]['description'] ? array("title" => $menu['items'][$mid]['description']) : array());
+  return l($menu['items'][$mid]['title'], $menu['items'][$link_mid]['path'], array_key_exists('description', $menu['items'][$mid]) ? array("title" => $menu['items'][$mid]['description']) : array());
 }
 
 /**
@@ -669,7 +687,7 @@ function _menu_build() {
     );
 
   // Build a sequential list of all menu items.
-  $menu_item_list = module_invoke_all('menu');
+  $menu_item_list = module_invoke_all('menu', TRUE);
 
   // Menu items not in the DB get temporary negative IDs.
   $temp_mid = -1;
@@ -681,15 +699,9 @@ function _menu_build() {
     if (!array_key_exists('type', $item)) {
       $item['type'] = MENU_NORMAL_ITEM;
     }
-    if (!array_key_exists('description', $item)) {
-      $item['description'] = '';
-    }
     if (!array_key_exists('weight', $item)) {
       $item['weight'] = 0;
     }
-    if (!array_key_exists('callback arguments', $item)) {
-      $item['callback arguments'] = array();
-    }
     $mid = $temp_mid;
     if (array_key_exists($item['path'], $_menu['path index'])) {
       // Newer menu items overwrite older ones.
@@ -717,7 +729,7 @@ function _menu_build() {
         else {
           // It has a permanent ID. Only replace with non-custom menu items.
           if ($item->type & MENU_CREATED_BY_ADMIN) {
-            $_menu['items'][$item->mid] = array('path' => $item->path, 'access' => TRUE, 'callback' => '', 'callback arguments' => array());
+            $_menu['items'][$item->mid] = array('path' => $item->path, 'access' => TRUE, 'callback' => '');
           }
           else {
             // Leave the old item around as a shortcut to this one.
@@ -729,7 +741,7 @@ function _menu_build() {
       else {
         // The path was not declared, so this is a custom item or an orphaned one.
         if ($item->type & MENU_CREATED_BY_ADMIN) {
-          $_menu['items'][$item->mid] = array('path' => $item->path, 'access' => TRUE, 'callback' => '', 'callback arguments' => array());
+          $_menu['items'][$item->mid] = array('path' => $item->path, 'access' => TRUE, 'callback' => '');
           if (!empty($item->path)) {
             $_menu['path index'][$item->path] = $item->mid;
           }
@@ -747,35 +759,8 @@ function _menu_build() {
     }
   }
 
-  // Establish parent-child relationships.
-  foreach ($_menu['items'] as $mid => $item) {
-    if (!isset($item['pid'])) {
-      // Parent's location has not been customized, so figure it out using the path.
-      $parent = $item['path'];
-      do {
-        $parent = substr($parent, 0, strrpos($parent, '/'));
-      }
-      while ($parent && !array_key_exists($parent, $_menu['path index']));
-
-      $pid = $parent ? $_menu['path index'][$parent] : 1;
-      $_menu['items'][$mid]['pid'] = $pid;
-    }
-    else {
-      $pid = $item['pid'];
-    }
-
-    // Don't make root a child of itself.
-    if ($mid) {
-      if (isset ($_menu['items'][$pid])) {
-        $_menu['items'][$pid]['children'][] = $mid;
-      }
-      else {
-        // If parent is missing, it is a menu item that used to be defined
-        // but is no longer. Default to a root-level "Navigation" menu item.
-        $_menu['items'][1]['children'][] = $mid;
-      }
-    }
-  }
+  // Associate parent and child menu items.
+  _menu_find_parents($_menu['items']);
 
   // Prepare to display trees to the user as required.
   _menu_build_visible_tree();
@@ -839,6 +824,104 @@ function _menu_build_visible_tree($pid = 0) {
   return array();
 }
 
+/**
+ * Account for menu items that are only defined at certain paths, so will not
+ * be cached.
+ *
+ * We don't support the full range of menu item options for these menu items. We
+ * don't support MENU_VISIBLE_IF_HAS_CHILDREN, and we require parent items to be
+ * declared before their children.
+ */
+function _menu_append_contextual_items() {
+  global $_menu;
+
+  // Build a sequential list of all menu items.
+  $menu_item_list = module_invoke_all('menu', FALSE);
+
+  // Menu items not in the DB get temporary negative IDs.
+  $temp_mid = min(array_keys($_menu['items'])) - 1;
+  $new_items = array();
+
+  foreach ($menu_item_list as $item) {
+    if (array_key_exists($item['path'], $_menu['path index'])) {
+      // The menu item already exists, so just add appropriate callback information.
+      $mid = $_menu['path index'][$item['path']];
+
+      $_menu['items'][$mid]['access'] = $item['access'];
+      $_menu['items'][$mid]['callback'] = $item['callback'];
+      $_menu['items'][$mid]['callback arguments'] = $item['callback arguments'];
+    }
+    else {
+      if (!array_key_exists('path', $item)) {
+        $item['path'] = '';
+      }
+      if (!array_key_exists('type', $item)) {
+        $item['type'] = MENU_NORMAL_ITEM;
+      }
+      if (!array_key_exists('weight', $item)) {
+        $item['weight'] = 0;
+      }
+      $_menu['items'][$temp_mid] = $item;
+      $_menu['path index'][$item['path']] = $temp_mid;
+      $new_items[$temp_mid] = $item;
+      $temp_mid--;
+    }
+  }
+
+  // Establish parent-child relationships.
+  _menu_find_parents($new_items);
+
+  // Add new items to the visible tree if necessary.
+  foreach ($new_items as $mid => $item) {
+    $item = $_menu['items'][$mid];
+    if (($item['type'] & MENU_VISIBLE_IN_TREE) && _menu_item_is_accessible($mid)) {
+      $pid = $item['pid'];
+      while ($pid && !array_key_exists($pid, $_menu['visible'])) {
+        $pid = $_menu['items'][$pid]['pid'];
+      }
+      $_menu['visible'][$mid] = array('title' => $item['title'], 'path' => $item['path'], 'pid' => $pid);
+      $_menu['visible'][$pid]['children'][] = $mid;
+      usort($_menu['visible'][$pid]['children'], '_menu_sort');
+    }
+  }
+}
+
+/**
+ * Establish parent-child relationships.
+ */
+function _menu_find_parents(&$items) {
+  global $_menu;
+
+  foreach ($items as $mid => $item) {
+    if (!isset($item['pid'])) {
+      // Parent's location has not been customized, so figure it out using the path.
+      $parent = $item['path'];
+      do {
+        $parent = substr($parent, 0, strrpos($parent, '/'));
+      }
+      while ($parent && !array_key_exists($parent, $_menu['path index']));
+
+      $pid = $parent ? $_menu['path index'][$parent] : 1;
+      $_menu['items'][$mid]['pid'] = $pid;
+    }
+    else {
+      $pid = $item['pid'];
+    }
+
+    // Don't make root a child of itself.
+    if ($mid) {
+      if (isset ($_menu['items'][$pid])) {
+        $_menu['items'][$pid]['children'][] = $mid;
+      }
+      else {
+        // If parent is missing, it is a menu item that used to be defined
+        // but is no longer. Default to a root-level "Navigation" menu item.
+        $_menu['items'][1]['children'][] = $mid;
+      }
+    }
+  }
+}
+
 /**
  * Find all the items in the current local task tree.
  *
diff --git a/modules/admin.module b/modules/admin.module
index d528c2d49c3f..98520fbc071a 100644
--- a/modules/admin.module
+++ b/modules/admin.module
@@ -21,12 +21,14 @@ function admin_help($section) {
 /**
  * Implementation of hook_menu().
  */
-function admin_menu() {
+function admin_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin', 'title' => t('administer'),
-    'access' => user_access('access administration pages'),
-    'callback' => 'admin_main_page',
-    'weight' => 9);
+  if ($may_cache) {
+    $items[] = array('path' => 'admin', 'title' => t('administer'),
+      'access' => user_access('access administration pages'),
+      'callback' => 'admin_main_page',
+      'weight' => 9);
+  }
   return $items;
 }
 
diff --git a/modules/aggregator.module b/modules/aggregator.module
index 7c16f06dc8c7..91c26b3962d8 100644
--- a/modules/aggregator.module
+++ b/modules/aggregator.module
@@ -119,53 +119,49 @@ function aggregator_link($type) {
 /**
  * Implementation of hook_menu().
  */
-function aggregator_menu() {
+function aggregator_menu($may_cache) {
   $items = array();
 
-  $edit = user_access('administer news feeds');
-  $view = user_access('access news feeds');
-
-  $items[] = array('path' => 'admin/aggregator', 'title' => t('aggregator'),
-    'callback' => 'aggregator_admin_overview', 'access' => $edit);
-  $items[] = array('path' => 'admin/aggregator/edit/feed', 'title' => t('edit feed'),
-    'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/aggregator/edit/category', 'title' => t('edit category'),
-    'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/aggregator/remove', 'title' => t('remove items'),
-    'callback' => 'aggregator_admin_remove_feed', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/aggregator/update', 'title' => t('update items'),
-    'callback' => 'aggregator_admin_refresh_feed', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'admin/aggregator/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/aggregator/add/feed', 'title' => t('add feed'),
-    'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/aggregator/add/category', 'title' => t('add category'),
-    'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/aggregator/configure', 'title' => t('configure'),
-    'callback' => 'aggregator_configure', 'access' => $edit,
-    'type' => MENU_LOCAL_TASK);
-
-  $items[] = array('path' => 'aggregator', 'title' => t('news aggregator'),
-    'callback' => 'aggregator_page_last', 'access' => $view,
-    'weight' => 5);
-  $items[] = array('path' => 'aggregator/sources', 'title' => t('sources'),
-    'callback' => 'aggregator_page_sources', 'access' => $view);
-  $items[] = array('path' => 'aggregator/categories', 'title' => t('categories'),
-    'callback' => 'aggregator_page_categories', 'access' => $view,
-    'type' => MENU_ITEM_GROUPING);
-
-  // To reduce the number of SQL queries, we don't query the database when
-  // not on an aggregator page.
-  // If caching of the menu is implemented, this check should be removed
-  // so that DHTML menu presentation can be used correctly.
-  if (arg(0) == 'aggregator') {
+  if ($may_cache) {
+    $edit = user_access('administer news feeds');
+    $view = user_access('access news feeds');
+
+    $items[] = array('path' => 'admin/aggregator', 'title' => t('aggregator'),
+      'callback' => 'aggregator_admin_overview', 'access' => $edit);
+    $items[] = array('path' => 'admin/aggregator/edit/feed', 'title' => t('edit feed'),
+      'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/aggregator/edit/category', 'title' => t('edit category'),
+      'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/aggregator/remove', 'title' => t('remove items'),
+      'callback' => 'aggregator_admin_remove_feed', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/aggregator/update', 'title' => t('update items'),
+      'callback' => 'aggregator_admin_refresh_feed', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'admin/aggregator/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/aggregator/add/feed', 'title' => t('add feed'),
+      'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/aggregator/add/category', 'title' => t('add category'),
+      'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/aggregator/configure', 'title' => t('configure'),
+      'callback' => 'aggregator_configure', 'access' => $edit,
+      'type' => MENU_LOCAL_TASK);
+
+    $items[] = array('path' => 'aggregator', 'title' => t('news aggregator'),
+      'callback' => 'aggregator_page_last', 'access' => $view,
+      'weight' => 5);
+    $items[] = array('path' => 'aggregator/sources', 'title' => t('sources'),
+      'callback' => 'aggregator_page_sources', 'access' => $view);
+    $items[] = array('path' => 'aggregator/categories', 'title' => t('categories'),
+      'callback' => 'aggregator_page_categories', 'access' => $view,
+      'type' => MENU_ITEM_GROUPING);
+
     // Sources:
     $result = db_query('SELECT title, fid FROM {aggregator_feed} ORDER BY title');
     while ($feed = db_fetch_object($result)) {
@@ -197,11 +193,11 @@ function aggregator_menu() {
         'type' => MENU_LOCAL_TASK,
         'weight' => 1);
     }
-  }
 
-  $items[] = array('path' => 'aggregator/opml', 'title' => t('opml'),
-    'callback' => 'aggregator_page_opml', 'access' => $view,
-    'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'aggregator/opml', 'title' => t('opml'),
+      'callback' => 'aggregator_page_opml', 'access' => $view,
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/aggregator/aggregator.module b/modules/aggregator/aggregator.module
index 7c16f06dc8c7..91c26b3962d8 100644
--- a/modules/aggregator/aggregator.module
+++ b/modules/aggregator/aggregator.module
@@ -119,53 +119,49 @@ function aggregator_link($type) {
 /**
  * Implementation of hook_menu().
  */
-function aggregator_menu() {
+function aggregator_menu($may_cache) {
   $items = array();
 
-  $edit = user_access('administer news feeds');
-  $view = user_access('access news feeds');
-
-  $items[] = array('path' => 'admin/aggregator', 'title' => t('aggregator'),
-    'callback' => 'aggregator_admin_overview', 'access' => $edit);
-  $items[] = array('path' => 'admin/aggregator/edit/feed', 'title' => t('edit feed'),
-    'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/aggregator/edit/category', 'title' => t('edit category'),
-    'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/aggregator/remove', 'title' => t('remove items'),
-    'callback' => 'aggregator_admin_remove_feed', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/aggregator/update', 'title' => t('update items'),
-    'callback' => 'aggregator_admin_refresh_feed', 'access' => $edit,
-    'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'admin/aggregator/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/aggregator/add/feed', 'title' => t('add feed'),
-    'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/aggregator/add/category', 'title' => t('add category'),
-    'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/aggregator/configure', 'title' => t('configure'),
-    'callback' => 'aggregator_configure', 'access' => $edit,
-    'type' => MENU_LOCAL_TASK);
-
-  $items[] = array('path' => 'aggregator', 'title' => t('news aggregator'),
-    'callback' => 'aggregator_page_last', 'access' => $view,
-    'weight' => 5);
-  $items[] = array('path' => 'aggregator/sources', 'title' => t('sources'),
-    'callback' => 'aggregator_page_sources', 'access' => $view);
-  $items[] = array('path' => 'aggregator/categories', 'title' => t('categories'),
-    'callback' => 'aggregator_page_categories', 'access' => $view,
-    'type' => MENU_ITEM_GROUPING);
-
-  // To reduce the number of SQL queries, we don't query the database when
-  // not on an aggregator page.
-  // If caching of the menu is implemented, this check should be removed
-  // so that DHTML menu presentation can be used correctly.
-  if (arg(0) == 'aggregator') {
+  if ($may_cache) {
+    $edit = user_access('administer news feeds');
+    $view = user_access('access news feeds');
+
+    $items[] = array('path' => 'admin/aggregator', 'title' => t('aggregator'),
+      'callback' => 'aggregator_admin_overview', 'access' => $edit);
+    $items[] = array('path' => 'admin/aggregator/edit/feed', 'title' => t('edit feed'),
+      'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/aggregator/edit/category', 'title' => t('edit category'),
+      'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/aggregator/remove', 'title' => t('remove items'),
+      'callback' => 'aggregator_admin_remove_feed', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/aggregator/update', 'title' => t('update items'),
+      'callback' => 'aggregator_admin_refresh_feed', 'access' => $edit,
+      'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'admin/aggregator/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/aggregator/add/feed', 'title' => t('add feed'),
+      'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/aggregator/add/category', 'title' => t('add category'),
+      'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/aggregator/configure', 'title' => t('configure'),
+      'callback' => 'aggregator_configure', 'access' => $edit,
+      'type' => MENU_LOCAL_TASK);
+
+    $items[] = array('path' => 'aggregator', 'title' => t('news aggregator'),
+      'callback' => 'aggregator_page_last', 'access' => $view,
+      'weight' => 5);
+    $items[] = array('path' => 'aggregator/sources', 'title' => t('sources'),
+      'callback' => 'aggregator_page_sources', 'access' => $view);
+    $items[] = array('path' => 'aggregator/categories', 'title' => t('categories'),
+      'callback' => 'aggregator_page_categories', 'access' => $view,
+      'type' => MENU_ITEM_GROUPING);
+
     // Sources:
     $result = db_query('SELECT title, fid FROM {aggregator_feed} ORDER BY title');
     while ($feed = db_fetch_object($result)) {
@@ -197,11 +193,11 @@ function aggregator_menu() {
         'type' => MENU_LOCAL_TASK,
         'weight' => 1);
     }
-  }
 
-  $items[] = array('path' => 'aggregator/opml', 'title' => t('opml'),
-    'callback' => 'aggregator_page_opml', 'access' => $view,
-    'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'aggregator/opml', 'title' => t('opml'),
+      'callback' => 'aggregator_page_opml', 'access' => $view,
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/archive.module b/modules/archive.module
index 21047dae7b53..d92e990f08b0 100644
--- a/modules/archive.module
+++ b/modules/archive.module
@@ -207,12 +207,15 @@ function archive_link($type) {
 /**
  * Implementation of hook_menu().
  */
-function archive_menu() {
+function archive_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'archive', 'title' => t('archives'),
-    'access' => user_access('access content'),
-    'callback' => 'archive_page',
-    'type' => MENU_SUGGESTED_ITEM);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'archive', 'title' => t('archives'),
+      'access' => user_access('access content'),
+      'callback' => 'archive_page',
+      'type' => MENU_SUGGESTED_ITEM);
+  }
   return $items;
 }
 
diff --git a/modules/archive/archive.module b/modules/archive/archive.module
index 21047dae7b53..d92e990f08b0 100644
--- a/modules/archive/archive.module
+++ b/modules/archive/archive.module
@@ -207,12 +207,15 @@ function archive_link($type) {
 /**
  * Implementation of hook_menu().
  */
-function archive_menu() {
+function archive_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'archive', 'title' => t('archives'),
-    'access' => user_access('access content'),
-    'callback' => 'archive_page',
-    'type' => MENU_SUGGESTED_ITEM);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'archive', 'title' => t('archives'),
+      'access' => user_access('access content'),
+      'callback' => 'archive_page',
+      'type' => MENU_SUGGESTED_ITEM);
+  }
   return $items;
 }
 
diff --git a/modules/block.module b/modules/block.module
index 9011c7984572..faa21eeb3687 100644
--- a/modules/block.module
+++ b/modules/block.module
@@ -48,26 +48,29 @@ function block_perm() {
 /**
  * Implementation of hook_menu().
  */
-function block_menu() {
+function block_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/block', 'title' => t('blocks'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_admin');
-  $items[] = array('path' => 'admin/block/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/block/edit', 'title' => t('edit block'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_box_edit',
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/block/delete', 'title' => t('delete block'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_box_delete',
-    'type' => MENU_CALLBACK);
-  // Tabs:
-  $items[] = array('path' => 'admin/block/add', 'title' => t('add'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_box_edit',
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/block', 'title' => t('blocks'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_admin');
+    $items[] = array('path' => 'admin/block/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/block/edit', 'title' => t('edit block'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_box_edit',
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/block/delete', 'title' => t('delete block'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_box_delete',
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/block/add', 'title' => t('add'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_box_edit',
+      'type' => MENU_LOCAL_TASK);
+  }
+
   return $items;
 }
 
diff --git a/modules/block/block.module b/modules/block/block.module
index 9011c7984572..faa21eeb3687 100644
--- a/modules/block/block.module
+++ b/modules/block/block.module
@@ -48,26 +48,29 @@ function block_perm() {
 /**
  * Implementation of hook_menu().
  */
-function block_menu() {
+function block_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/block', 'title' => t('blocks'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_admin');
-  $items[] = array('path' => 'admin/block/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/block/edit', 'title' => t('edit block'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_box_edit',
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/block/delete', 'title' => t('delete block'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_box_delete',
-    'type' => MENU_CALLBACK);
-  // Tabs:
-  $items[] = array('path' => 'admin/block/add', 'title' => t('add'),
-    'access' => user_access('administer blocks'),
-    'callback' => 'block_box_edit',
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/block', 'title' => t('blocks'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_admin');
+    $items[] = array('path' => 'admin/block/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/block/edit', 'title' => t('edit block'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_box_edit',
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/block/delete', 'title' => t('delete block'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_box_delete',
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/block/add', 'title' => t('add'),
+      'access' => user_access('administer blocks'),
+      'callback' => 'block_box_edit',
+      'type' => MENU_LOCAL_TASK);
+  }
+
   return $items;
 }
 
diff --git a/modules/blog.module b/modules/blog.module
index d1a97da32348..beec0eb5f0b4 100644
--- a/modules/blog.module
+++ b/modules/blog.module
@@ -259,23 +259,26 @@ function blog_link($type, $node = 0, $main) {
 /**
  * Implementation of hook_menu().
  */
-function blog_menu() {
+function blog_menu($may_cache) {
   global $user;
-
   $items = array();
-  $items[] = array('path' => 'node/add/blog', 'title' => t('blog entry'),
-    'access' => user_access('edit own blog'));
-  $items[] = array('path' => 'blog', 'title' => t('blogs'),
-    'callback' => 'blog_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'blog/'. $user->uid, 'title' => t('my blog'),
-    'access' => user_access('edit own blog'),
-    'type' => MENU_DYNAMIC_ITEM);
-  $items[] = array('path' => 'blog/feed', 'title' => t('RSS feed'),
-    'callback' => 'blog_feed',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/blog', 'title' => t('blog entry'),
+      'access' => user_access('edit own blog'));
+    $items[] = array('path' => 'blog', 'title' => t('blogs'),
+      'callback' => 'blog_page',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'blog/feed', 'title' => t('RSS feed'),
+      'callback' => 'blog_feed',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'blog/'. $user->uid, 'title' => t('my blog'),
+      'access' => user_access('edit own blog'),
+      'type' => MENU_DYNAMIC_ITEM);
+  }
+
   return $items;
 }
 
diff --git a/modules/blog/blog.module b/modules/blog/blog.module
index d1a97da32348..beec0eb5f0b4 100644
--- a/modules/blog/blog.module
+++ b/modules/blog/blog.module
@@ -259,23 +259,26 @@ function blog_link($type, $node = 0, $main) {
 /**
  * Implementation of hook_menu().
  */
-function blog_menu() {
+function blog_menu($may_cache) {
   global $user;
-
   $items = array();
-  $items[] = array('path' => 'node/add/blog', 'title' => t('blog entry'),
-    'access' => user_access('edit own blog'));
-  $items[] = array('path' => 'blog', 'title' => t('blogs'),
-    'callback' => 'blog_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'blog/'. $user->uid, 'title' => t('my blog'),
-    'access' => user_access('edit own blog'),
-    'type' => MENU_DYNAMIC_ITEM);
-  $items[] = array('path' => 'blog/feed', 'title' => t('RSS feed'),
-    'callback' => 'blog_feed',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/blog', 'title' => t('blog entry'),
+      'access' => user_access('edit own blog'));
+    $items[] = array('path' => 'blog', 'title' => t('blogs'),
+      'callback' => 'blog_page',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'blog/feed', 'title' => t('RSS feed'),
+      'callback' => 'blog_feed',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'blog/'. $user->uid, 'title' => t('my blog'),
+      'access' => user_access('edit own blog'),
+      'type' => MENU_DYNAMIC_ITEM);
+  }
+
   return $items;
 }
 
diff --git a/modules/blogapi.module b/modules/blogapi.module
index a603b2185cc8..534174660f9c 100644
--- a/modules/blogapi.module
+++ b/modules/blogapi.module
@@ -512,15 +512,16 @@ function blogapi_settings() {
   return $output;
 }
 
-function blogapi_menu() {
-  global $user;
+function blogapi_menu($may_cache) {
   $items = array();
 
   if ($_GET['q'] == variable_get('site_frontpage', 'node')) {
     drupal_set_html_head('<link rel="EditURI" type="application/rsd+xml" title="RSD" href="' . url('blogapi/rsd', NULL, NULL, TRUE) . '" />');
   }
 
-  $items[] = array('path' => 'blogapi', 'title' => t('RSD'), 'callback' => 'blogapi_blogapi', 'access' => user_access('access_content'), 'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $items[] = array('path' => 'blogapi', 'title' => t('RSD'), 'callback' => 'blogapi_blogapi', 'access' => user_access('access_content'), 'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/blogapi/blogapi.module b/modules/blogapi/blogapi.module
index a603b2185cc8..534174660f9c 100644
--- a/modules/blogapi/blogapi.module
+++ b/modules/blogapi/blogapi.module
@@ -512,15 +512,16 @@ function blogapi_settings() {
   return $output;
 }
 
-function blogapi_menu() {
-  global $user;
+function blogapi_menu($may_cache) {
   $items = array();
 
   if ($_GET['q'] == variable_get('site_frontpage', 'node')) {
     drupal_set_html_head('<link rel="EditURI" type="application/rsd+xml" title="RSD" href="' . url('blogapi/rsd', NULL, NULL, TRUE) . '" />');
   }
 
-  $items[] = array('path' => 'blogapi', 'title' => t('RSD'), 'callback' => 'blogapi_blogapi', 'access' => user_access('access_content'), 'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $items[] = array('path' => 'blogapi', 'title' => t('RSD'), 'callback' => 'blogapi_blogapi', 'access' => user_access('access_content'), 'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/book.module b/modules/book.module
index f4a847515456..f349991fd28c 100644
--- a/modules/book.module
+++ b/modules/book.module
@@ -76,31 +76,33 @@ function book_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function book_menu() {
+function book_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'node/add/book', 'title' => t('book page'),
-    'access' => user_access('maintain books'));
-  $items[] = array('path' => 'admin/node/book', 'title' => t('books'),
-    'callback' => 'book_admin',
-    'access' => user_access('administer nodes'),
-    'weight' => 4);
-  $items[] = array('path' => 'admin/node/book/orphan', 'title' => t('orphan pages'),
-    'callback' => 'book_admin_orphan',
-    'access' => user_access('administer nodes'),
-    'weight' => 8);
-  $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)) {
-    $items[] = array('path' => 'admin/node/book/'. $book->nid, 'title' => t('"%title" book', array('%title' => $book->title)));
-  }
-  $items[] = array('path' => 'book', 'title' => t('books'),
-    'callback' => 'book_render',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'book/print', 'title' => t('printer-friendly version'),
-    'callback' => 'book_print',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/book', 'title' => t('book page'),
+      'access' => user_access('maintain books'));
+    $items[] = array('path' => 'admin/node/book', 'title' => t('books'),
+      'callback' => 'book_admin',
+      'access' => user_access('administer nodes'),
+      'weight' => 4);
+    $items[] = array('path' => 'admin/node/book/orphan', 'title' => t('orphan pages'),
+      'callback' => 'book_admin_orphan',
+      'access' => user_access('administer nodes'),
+      'weight' => 8);
+    $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)) {
+      $items[] = array('path' => 'admin/node/book/'. $book->nid, 'title' => t('"%title" book', array('%title' => $book->title)));
+    }
+    $items[] = array('path' => 'book', 'title' => t('books'),
+      'callback' => 'book_render',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'book/print', 'title' => t('printer-friendly version'),
+      'callback' => 'book_print',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/book/book.module b/modules/book/book.module
index f4a847515456..f349991fd28c 100644
--- a/modules/book/book.module
+++ b/modules/book/book.module
@@ -76,31 +76,33 @@ function book_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function book_menu() {
+function book_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'node/add/book', 'title' => t('book page'),
-    'access' => user_access('maintain books'));
-  $items[] = array('path' => 'admin/node/book', 'title' => t('books'),
-    'callback' => 'book_admin',
-    'access' => user_access('administer nodes'),
-    'weight' => 4);
-  $items[] = array('path' => 'admin/node/book/orphan', 'title' => t('orphan pages'),
-    'callback' => 'book_admin_orphan',
-    'access' => user_access('administer nodes'),
-    'weight' => 8);
-  $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)) {
-    $items[] = array('path' => 'admin/node/book/'. $book->nid, 'title' => t('"%title" book', array('%title' => $book->title)));
-  }
-  $items[] = array('path' => 'book', 'title' => t('books'),
-    'callback' => 'book_render',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'book/print', 'title' => t('printer-friendly version'),
-    'callback' => 'book_print',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/book', 'title' => t('book page'),
+      'access' => user_access('maintain books'));
+    $items[] = array('path' => 'admin/node/book', 'title' => t('books'),
+      'callback' => 'book_admin',
+      'access' => user_access('administer nodes'),
+      'weight' => 4);
+    $items[] = array('path' => 'admin/node/book/orphan', 'title' => t('orphan pages'),
+      'callback' => 'book_admin_orphan',
+      'access' => user_access('administer nodes'),
+      'weight' => 8);
+    $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)) {
+      $items[] = array('path' => 'admin/node/book/'. $book->nid, 'title' => t('"%title" book', array('%title' => $book->title)));
+    }
+    $items[] = array('path' => 'book', 'title' => t('books'),
+      'callback' => 'book_render',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'book/print', 'title' => t('printer-friendly version'),
+      'callback' => 'book_print',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/comment.module b/modules/comment.module
index 9e746e3d3f61..af71c129a3cc 100644
--- a/modules/comment.module
+++ b/modules/comment.module
@@ -84,56 +84,58 @@ function comment_help($section = "admin/help#comment") {
 /**
  * Implementation of hook_menu().
  */
-function comment_menu() {
+function comment_menu($may_cache) {
   $items = array();
 
-  $access = user_access('administer comments');
-  $items[] = array('path' => 'admin/comment', 'title' => t('comments'),
-    'callback' => 'comment_admin_overview', 'access' => $access);
-  $items[] = array('path' => 'admin/comment/edit', 'title' => t('edit comment'),
-    'callback' => 'comment_admin_edit', 'access' => $access, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/comment/delete', 'title' => t('delete comment'),
-    'callback' => 'comment_delete', 'access' => $access, 'type' => MENU_CALLBACK);
-
-  // Tabs:
-  $items[] = array('path' => 'admin/comment/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/comment/configure', 'title' => t('configure'),
-    'callback' => 'comment_configure', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  if (module_exist('search')) {
-    $items[] = array('path' => 'admin/comment/search', 'title' => t('search'),
-      'callback' => 'comment_search', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  }
-
-  // Subtabs:
-  $items[] = array('path' => 'admin/comment/list/new', 'title' => t('new comments'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/comment/list/approval', 'title' => t('approval queue'),
-    'callback' => 'comment_admin_overview', 'access' => $access,
-    'callback arguments' => 'approval',
-    'type' => MENU_LOCAL_TASK);
-
-  $items[] = array('path' => 'admin/comment/configure/settings', 'title' => t('settings'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-
-  $access = user_access('administer comments') && user_access('administer moderation');
-  $items[] = array('path' => 'admin/comment/configure/matrix', 'title' => t('moderation matrix'),
-    'callback' => 'comment_matrix_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/comment/configure/thresholds', 'title' => t('moderation thresholds'),
-    'callback' => 'comment_threshold_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/comment/configure/roles', 'title' => t('moderation roles'),
-    'callback' => 'comment_role_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/comment/configure/votes', 'title' => t('moderation votes'),
-    'callback' => 'comment_vote_settings', 'access' => $access,'type' => MENU_LOCAL_TASK);
-
-  $access = user_access('post comments');
-  $items[] = array('path' => 'comment/reply', 'title' => t('reply to comment'),
-    'callback' => 'comment_reply', 'access' => $access, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'comment/edit', 'title' => t('edit your comment'),
-    'callback' => 'comment_edit', 'access' => $access, 'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'comment', 'title' => t('reply to comment'),
-    'callback' => 'comment_save_settings', 'access' => 1, 'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $access = user_access('administer comments');
+    $items[] = array('path' => 'admin/comment', 'title' => t('comments'),
+      'callback' => 'comment_admin_overview', 'access' => $access);
+    $items[] = array('path' => 'admin/comment/edit', 'title' => t('edit comment'),
+      'callback' => 'comment_admin_edit', 'access' => $access, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/comment/delete', 'title' => t('delete comment'),
+      'callback' => 'comment_delete', 'access' => $access, 'type' => MENU_CALLBACK);
+
+    // Tabs:
+    $items[] = array('path' => 'admin/comment/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/comment/configure', 'title' => t('configure'),
+      'callback' => 'comment_configure', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    if (module_exist('search')) {
+      $items[] = array('path' => 'admin/comment/search', 'title' => t('search'),
+        'callback' => 'comment_search', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    }
+
+    // Subtabs:
+    $items[] = array('path' => 'admin/comment/list/new', 'title' => t('new comments'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/comment/list/approval', 'title' => t('approval queue'),
+      'callback' => 'comment_admin_overview', 'access' => $access,
+      'callback arguments' => 'approval',
+      'type' => MENU_LOCAL_TASK);
+
+    $items[] = array('path' => 'admin/comment/configure/settings', 'title' => t('settings'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+
+    $access = user_access('administer comments') && user_access('administer moderation');
+    $items[] = array('path' => 'admin/comment/configure/matrix', 'title' => t('moderation matrix'),
+      'callback' => 'comment_matrix_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/comment/configure/thresholds', 'title' => t('moderation thresholds'),
+      'callback' => 'comment_threshold_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/comment/configure/roles', 'title' => t('moderation roles'),
+      'callback' => 'comment_role_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/comment/configure/votes', 'title' => t('moderation votes'),
+      'callback' => 'comment_vote_settings', 'access' => $access,'type' => MENU_LOCAL_TASK);
+
+    $access = user_access('post comments');
+    $items[] = array('path' => 'comment/reply', 'title' => t('reply to comment'),
+      'callback' => 'comment_reply', 'access' => $access, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'comment/edit', 'title' => t('edit your comment'),
+      'callback' => 'comment_edit', 'access' => $access, 'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'comment', 'title' => t('reply to comment'),
+      'callback' => 'comment_save_settings', 'access' => 1, 'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index 9e746e3d3f61..af71c129a3cc 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -84,56 +84,58 @@ function comment_help($section = "admin/help#comment") {
 /**
  * Implementation of hook_menu().
  */
-function comment_menu() {
+function comment_menu($may_cache) {
   $items = array();
 
-  $access = user_access('administer comments');
-  $items[] = array('path' => 'admin/comment', 'title' => t('comments'),
-    'callback' => 'comment_admin_overview', 'access' => $access);
-  $items[] = array('path' => 'admin/comment/edit', 'title' => t('edit comment'),
-    'callback' => 'comment_admin_edit', 'access' => $access, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/comment/delete', 'title' => t('delete comment'),
-    'callback' => 'comment_delete', 'access' => $access, 'type' => MENU_CALLBACK);
-
-  // Tabs:
-  $items[] = array('path' => 'admin/comment/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/comment/configure', 'title' => t('configure'),
-    'callback' => 'comment_configure', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  if (module_exist('search')) {
-    $items[] = array('path' => 'admin/comment/search', 'title' => t('search'),
-      'callback' => 'comment_search', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  }
-
-  // Subtabs:
-  $items[] = array('path' => 'admin/comment/list/new', 'title' => t('new comments'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/comment/list/approval', 'title' => t('approval queue'),
-    'callback' => 'comment_admin_overview', 'access' => $access,
-    'callback arguments' => 'approval',
-    'type' => MENU_LOCAL_TASK);
-
-  $items[] = array('path' => 'admin/comment/configure/settings', 'title' => t('settings'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-
-  $access = user_access('administer comments') && user_access('administer moderation');
-  $items[] = array('path' => 'admin/comment/configure/matrix', 'title' => t('moderation matrix'),
-    'callback' => 'comment_matrix_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/comment/configure/thresholds', 'title' => t('moderation thresholds'),
-    'callback' => 'comment_threshold_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/comment/configure/roles', 'title' => t('moderation roles'),
-    'callback' => 'comment_role_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/comment/configure/votes', 'title' => t('moderation votes'),
-    'callback' => 'comment_vote_settings', 'access' => $access,'type' => MENU_LOCAL_TASK);
-
-  $access = user_access('post comments');
-  $items[] = array('path' => 'comment/reply', 'title' => t('reply to comment'),
-    'callback' => 'comment_reply', 'access' => $access, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'comment/edit', 'title' => t('edit your comment'),
-    'callback' => 'comment_edit', 'access' => $access, 'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'comment', 'title' => t('reply to comment'),
-    'callback' => 'comment_save_settings', 'access' => 1, 'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $access = user_access('administer comments');
+    $items[] = array('path' => 'admin/comment', 'title' => t('comments'),
+      'callback' => 'comment_admin_overview', 'access' => $access);
+    $items[] = array('path' => 'admin/comment/edit', 'title' => t('edit comment'),
+      'callback' => 'comment_admin_edit', 'access' => $access, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/comment/delete', 'title' => t('delete comment'),
+      'callback' => 'comment_delete', 'access' => $access, 'type' => MENU_CALLBACK);
+
+    // Tabs:
+    $items[] = array('path' => 'admin/comment/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/comment/configure', 'title' => t('configure'),
+      'callback' => 'comment_configure', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    if (module_exist('search')) {
+      $items[] = array('path' => 'admin/comment/search', 'title' => t('search'),
+        'callback' => 'comment_search', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    }
+
+    // Subtabs:
+    $items[] = array('path' => 'admin/comment/list/new', 'title' => t('new comments'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/comment/list/approval', 'title' => t('approval queue'),
+      'callback' => 'comment_admin_overview', 'access' => $access,
+      'callback arguments' => 'approval',
+      'type' => MENU_LOCAL_TASK);
+
+    $items[] = array('path' => 'admin/comment/configure/settings', 'title' => t('settings'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+
+    $access = user_access('administer comments') && user_access('administer moderation');
+    $items[] = array('path' => 'admin/comment/configure/matrix', 'title' => t('moderation matrix'),
+      'callback' => 'comment_matrix_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/comment/configure/thresholds', 'title' => t('moderation thresholds'),
+      'callback' => 'comment_threshold_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/comment/configure/roles', 'title' => t('moderation roles'),
+      'callback' => 'comment_role_settings', 'access' => $access, 'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/comment/configure/votes', 'title' => t('moderation votes'),
+      'callback' => 'comment_vote_settings', 'access' => $access,'type' => MENU_LOCAL_TASK);
+
+    $access = user_access('post comments');
+    $items[] = array('path' => 'comment/reply', 'title' => t('reply to comment'),
+      'callback' => 'comment_reply', 'access' => $access, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'comment/edit', 'title' => t('edit your comment'),
+      'callback' => 'comment_edit', 'access' => $access, 'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'comment', 'title' => t('reply to comment'),
+      'callback' => 'comment_save_settings', 'access' => 1, 'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/drupal.module b/modules/drupal.module
index 388b8dac6fbd..a4da752087b3 100644
--- a/modules/drupal.module
+++ b/modules/drupal.module
@@ -185,11 +185,13 @@ function drupal_auth($username, $password, $server) {
 /**
  * Implementation of hook_menu().
  */
-function drupal_menu() {
+function drupal_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'drupal', 'title' => t('Drupal'),
-    'callback' => 'drupal_page_help', 'access' => TRUE,
-    'type' => MENU_SUGGESTED_ITEM);
+  if ($may_cache) {
+    $items[] = array('path' => 'drupal', 'title' => t('Drupal'),
+      'callback' => 'drupal_page_help', 'access' => TRUE,
+      'type' => MENU_SUGGESTED_ITEM);
+  }
   return $items;
 }
 
diff --git a/modules/drupal/drupal.module b/modules/drupal/drupal.module
index 388b8dac6fbd..a4da752087b3 100644
--- a/modules/drupal/drupal.module
+++ b/modules/drupal/drupal.module
@@ -185,11 +185,13 @@ function drupal_auth($username, $password, $server) {
 /**
  * Implementation of hook_menu().
  */
-function drupal_menu() {
+function drupal_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'drupal', 'title' => t('Drupal'),
-    'callback' => 'drupal_page_help', 'access' => TRUE,
-    'type' => MENU_SUGGESTED_ITEM);
+  if ($may_cache) {
+    $items[] = array('path' => 'drupal', 'title' => t('Drupal'),
+      'callback' => 'drupal_page_help', 'access' => TRUE,
+      'type' => MENU_SUGGESTED_ITEM);
+  }
   return $items;
 }
 
diff --git a/modules/filter.module b/modules/filter.module
index dece83b8ef84..26eeac6021b1 100644
--- a/modules/filter.module
+++ b/modules/filter.module
@@ -106,50 +106,54 @@ function filter_filter_tips($delta, $format, $long = false) {
 /**
  * Implementation of hook_menu().
  */
-function filter_menu() {
+function filter_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'admin/filters', 'title' => t('input formats'),
-    'callback' => 'filter_admin_overview',
-    'access' => user_access('administer filters'));
-
-  $items[] = array('path' => 'admin/filters/delete', 'title' => t('delete input format'),
-    'callback' => 'filter_admin_delete',
-    'type' => MENU_CALLBACK,
-    'access' => user_access('administer filters'));
-
-  if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) {
-    $formats = filter_formats();
-
-    if (isset($formats[arg(2)])) {
-      $items[] = array('path' => 'admin/filters/'. arg(2), 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)),
-      'callback' => 'filter_admin_filters',
-      'type' => MENU_CALLBACK,
-      'access' => user_access('administer filters'));
-
-      $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', 'title' => t('list filters'),
-      'callback' => 'filter_admin_filters',
-      'type' => MENU_DEFAULT_LOCAL_TASK,
-      'weight' => 0,
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/filters', 'title' => t('input formats'),
+      'callback' => 'filter_admin_overview',
       'access' => user_access('administer filters'));
 
-      $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', 'title' => t('configure filters'),
-      'callback' => 'filter_admin_configure',
-      'type' => MENU_LOCAL_TASK,
-      'weight' => 1,
+    $items[] = array('path' => 'admin/filters/delete', 'title' => t('delete input format'),
+      'callback' => 'filter_admin_delete',
+      'type' => MENU_CALLBACK,
       'access' => user_access('administer filters'));
 
-      $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', 'title' => t('rearrange filters'),
-      'callback' => 'filter_admin_order',
-      'type' => MENU_LOCAL_TASK,
-      'weight' => 2,
-      'access' => user_access('administer filters'));
+    $items[] = array('path' => 'filter/tips', 'title' => t('compose tips'),
+      'callback' => 'filter_tips_long', 'access' => TRUE,
+      'type' => MENU_SUGGESTED_ITEM);
+  }
+  else {
+    if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) {
+      $formats = filter_formats();
+
+      if (isset($formats[arg(2)])) {
+        $items[] = array('path' => 'admin/filters/'. arg(2), 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)),
+        'callback' => 'filter_admin_filters',
+        'type' => MENU_CALLBACK,
+        'access' => user_access('administer filters'));
+
+        $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', 'title' => t('list filters'),
+        'callback' => 'filter_admin_filters',
+        'type' => MENU_DEFAULT_LOCAL_TASK,
+        'weight' => 0,
+        'access' => user_access('administer filters'));
+
+        $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', 'title' => t('configure filters'),
+        'callback' => 'filter_admin_configure',
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 1,
+        'access' => user_access('administer filters'));
+
+        $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', 'title' => t('rearrange filters'),
+        'callback' => 'filter_admin_order',
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 2,
+        'access' => user_access('administer filters'));
+      }
     }
   }
 
-  $items[] = array('path' => 'filter/tips', 'title' => t('compose tips'),
-    'callback' => 'filter_tips_long', 'access' => TRUE,
-    'type' => MENU_SUGGESTED_ITEM);
   return $items;
 }
 
diff --git a/modules/filter/filter.module b/modules/filter/filter.module
index dece83b8ef84..26eeac6021b1 100644
--- a/modules/filter/filter.module
+++ b/modules/filter/filter.module
@@ -106,50 +106,54 @@ function filter_filter_tips($delta, $format, $long = false) {
 /**
  * Implementation of hook_menu().
  */
-function filter_menu() {
+function filter_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'admin/filters', 'title' => t('input formats'),
-    'callback' => 'filter_admin_overview',
-    'access' => user_access('administer filters'));
-
-  $items[] = array('path' => 'admin/filters/delete', 'title' => t('delete input format'),
-    'callback' => 'filter_admin_delete',
-    'type' => MENU_CALLBACK,
-    'access' => user_access('administer filters'));
-
-  if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) {
-    $formats = filter_formats();
-
-    if (isset($formats[arg(2)])) {
-      $items[] = array('path' => 'admin/filters/'. arg(2), 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)),
-      'callback' => 'filter_admin_filters',
-      'type' => MENU_CALLBACK,
-      'access' => user_access('administer filters'));
-
-      $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', 'title' => t('list filters'),
-      'callback' => 'filter_admin_filters',
-      'type' => MENU_DEFAULT_LOCAL_TASK,
-      'weight' => 0,
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/filters', 'title' => t('input formats'),
+      'callback' => 'filter_admin_overview',
       'access' => user_access('administer filters'));
 
-      $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', 'title' => t('configure filters'),
-      'callback' => 'filter_admin_configure',
-      'type' => MENU_LOCAL_TASK,
-      'weight' => 1,
+    $items[] = array('path' => 'admin/filters/delete', 'title' => t('delete input format'),
+      'callback' => 'filter_admin_delete',
+      'type' => MENU_CALLBACK,
       'access' => user_access('administer filters'));
 
-      $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', 'title' => t('rearrange filters'),
-      'callback' => 'filter_admin_order',
-      'type' => MENU_LOCAL_TASK,
-      'weight' => 2,
-      'access' => user_access('administer filters'));
+    $items[] = array('path' => 'filter/tips', 'title' => t('compose tips'),
+      'callback' => 'filter_tips_long', 'access' => TRUE,
+      'type' => MENU_SUGGESTED_ITEM);
+  }
+  else {
+    if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) {
+      $formats = filter_formats();
+
+      if (isset($formats[arg(2)])) {
+        $items[] = array('path' => 'admin/filters/'. arg(2), 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)),
+        'callback' => 'filter_admin_filters',
+        'type' => MENU_CALLBACK,
+        'access' => user_access('administer filters'));
+
+        $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', 'title' => t('list filters'),
+        'callback' => 'filter_admin_filters',
+        'type' => MENU_DEFAULT_LOCAL_TASK,
+        'weight' => 0,
+        'access' => user_access('administer filters'));
+
+        $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', 'title' => t('configure filters'),
+        'callback' => 'filter_admin_configure',
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 1,
+        'access' => user_access('administer filters'));
+
+        $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', 'title' => t('rearrange filters'),
+        'callback' => 'filter_admin_order',
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 2,
+        'access' => user_access('administer filters'));
+      }
     }
   }
 
-  $items[] = array('path' => 'filter/tips', 'title' => t('compose tips'),
-    'callback' => 'filter_tips_long', 'access' => TRUE,
-    'type' => MENU_SUGGESTED_ITEM);
   return $items;
 }
 
diff --git a/modules/forum.module b/modules/forum.module
index 4d7269400168..8c54405a7e7b 100644
--- a/modules/forum.module
+++ b/modules/forum.module
@@ -186,15 +186,17 @@ function forum_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function forum_menu() {
+function forum_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'node/add/forum', 'title' => t('forum topic'),
-    'access' => user_access('create forum topics'));
-  $items[] = array('path' => 'forum', 'title' => t('forums'),
-    'callback' => 'forum_page',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/forum', 'title' => t('forum topic'),
+      'access' => user_access('create forum topics'));
+    $items[] = array('path' => 'forum', 'title' => t('forums'),
+      'callback' => 'forum_page',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/forum/forum.module b/modules/forum/forum.module
index 4d7269400168..8c54405a7e7b 100644
--- a/modules/forum/forum.module
+++ b/modules/forum/forum.module
@@ -186,15 +186,17 @@ function forum_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function forum_menu() {
+function forum_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'node/add/forum', 'title' => t('forum topic'),
-    'access' => user_access('create forum topics'));
-  $items[] = array('path' => 'forum', 'title' => t('forums'),
-    'callback' => 'forum_page',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/forum', 'title' => t('forum topic'),
+      'access' => user_access('create forum topics'));
+    $items[] = array('path' => 'forum', 'title' => t('forums'),
+      'callback' => 'forum_page',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/help.module b/modules/help.module
index 1fb68e74337d..b3fe02ef4e7e 100644
--- a/modules/help.module
+++ b/modules/help.module
@@ -9,22 +9,26 @@
 /**
  * Implementation of hook_menu().
  */
-function help_menu() {
+function help_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/help', 'title' => t('help'),
-    'callback' => 'help_main',
-    'access' => user_access('access administration pages'),
-    'weight' => 9);
 
-  foreach (module_list() as $name) {
-    if (module_hook($name, 'help')) {
-      $items[] = array('path' => 'admin/help/' . $name,
-        'title' => t($name),
-        'callback' => 'help_page',
-  'type' => MENU_CALLBACK,
-        'access' => user_access('access administration pages'));
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/help', 'title' => t('help'),
+      'callback' => 'help_main',
+      'access' => user_access('access administration pages'),
+      'weight' => 9);
+
+    foreach (module_list() as $name) {
+      if (module_hook($name, 'help')) {
+        $items[] = array('path' => 'admin/help/' . $name,
+          'title' => t($name),
+          'callback' => 'help_page',
+    'type' => MENU_CALLBACK,
+          'access' => user_access('access administration pages'));
+      }
     }
   }
+
   return $items;
 }
 
diff --git a/modules/help/help.module b/modules/help/help.module
index 1fb68e74337d..b3fe02ef4e7e 100644
--- a/modules/help/help.module
+++ b/modules/help/help.module
@@ -9,22 +9,26 @@
 /**
  * Implementation of hook_menu().
  */
-function help_menu() {
+function help_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/help', 'title' => t('help'),
-    'callback' => 'help_main',
-    'access' => user_access('access administration pages'),
-    'weight' => 9);
 
-  foreach (module_list() as $name) {
-    if (module_hook($name, 'help')) {
-      $items[] = array('path' => 'admin/help/' . $name,
-        'title' => t($name),
-        'callback' => 'help_page',
-  'type' => MENU_CALLBACK,
-        'access' => user_access('access administration pages'));
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/help', 'title' => t('help'),
+      'callback' => 'help_main',
+      'access' => user_access('access administration pages'),
+      'weight' => 9);
+
+    foreach (module_list() as $name) {
+      if (module_hook($name, 'help')) {
+        $items[] = array('path' => 'admin/help/' . $name,
+          'title' => t($name),
+          'callback' => 'help_page',
+    'type' => MENU_CALLBACK,
+          'access' => user_access('access administration pages'));
+      }
     }
   }
+
   return $items;
 }
 
diff --git a/modules/legacy.module b/modules/legacy.module
index 662eaf81f61a..52348c61cfc6 100644
--- a/modules/legacy.module
+++ b/modules/legacy.module
@@ -21,36 +21,38 @@ function legacy_help($section) {
  *
  * Registers menu paths used in earlier Drupal versions.
  */
-function legacy_menu() {
+function legacy_menu($may_cache) {
   $items = array();
 
-  // Map "node/view/52" to "node/52".
-  $items[] = array('path' => 'node/view', 'title' => t('view'),
-    'callback' => 'drupal_goto',
-    'callback arguments' => array('node/'. arg(2), NULL, NULL),
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "book/view/52" to "node/52".
-  $items[] = array('path' => 'book/view', 'title' => t('view'),
-    'callback' => 'drupal_goto',
-    'callback arguments' => array('node/'. arg(2), NULL, NULL),
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "user/view/52" to "user/52".
-  $items[] = array('path' => 'user/view', 'title' => t('view'),
-    'callback' => 'drupal_goto',
-    'callback arguments' => array('user/'. arg(2), NULL, NULL),
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "taxonomy/page/or/52,97" to "taxonomy/term/52+97".
-  $items[] = array('path' => 'taxonomy/page', 'title' => t('taxonomy'),
-    'callback' => 'legacy_taxonomy_page',
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "taxonomy/feed/or/52,97" to "taxonomy/term/52+97/0/feed".
-  $items[] = array('path' => 'taxonomy/feed', 'title' => t('taxonomy'),
-    'callback' => 'legacy_taxonomy_feed',
-    'access' => TRUE, 'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    // Map "node/view/52" to "node/52".
+    $items[] = array('path' => 'node/view', 'title' => t('view'),
+      'callback' => 'drupal_goto',
+      'callback arguments' => array('node/'. arg(2), NULL, NULL),
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "book/view/52" to "node/52".
+    $items[] = array('path' => 'book/view', 'title' => t('view'),
+      'callback' => 'drupal_goto',
+      'callback arguments' => array('node/'. arg(2), NULL, NULL),
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "user/view/52" to "user/52".
+    $items[] = array('path' => 'user/view', 'title' => t('view'),
+      'callback' => 'drupal_goto',
+      'callback arguments' => array('user/'. arg(2), NULL, NULL),
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "taxonomy/page/or/52,97" to "taxonomy/term/52+97".
+    $items[] = array('path' => 'taxonomy/page', 'title' => t('taxonomy'),
+      'callback' => 'legacy_taxonomy_page',
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "taxonomy/feed/or/52,97" to "taxonomy/term/52+97/0/feed".
+    $items[] = array('path' => 'taxonomy/feed', 'title' => t('taxonomy'),
+      'callback' => 'legacy_taxonomy_feed',
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/legacy/legacy.module b/modules/legacy/legacy.module
index 662eaf81f61a..52348c61cfc6 100644
--- a/modules/legacy/legacy.module
+++ b/modules/legacy/legacy.module
@@ -21,36 +21,38 @@ function legacy_help($section) {
  *
  * Registers menu paths used in earlier Drupal versions.
  */
-function legacy_menu() {
+function legacy_menu($may_cache) {
   $items = array();
 
-  // Map "node/view/52" to "node/52".
-  $items[] = array('path' => 'node/view', 'title' => t('view'),
-    'callback' => 'drupal_goto',
-    'callback arguments' => array('node/'. arg(2), NULL, NULL),
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "book/view/52" to "node/52".
-  $items[] = array('path' => 'book/view', 'title' => t('view'),
-    'callback' => 'drupal_goto',
-    'callback arguments' => array('node/'. arg(2), NULL, NULL),
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "user/view/52" to "user/52".
-  $items[] = array('path' => 'user/view', 'title' => t('view'),
-    'callback' => 'drupal_goto',
-    'callback arguments' => array('user/'. arg(2), NULL, NULL),
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "taxonomy/page/or/52,97" to "taxonomy/term/52+97".
-  $items[] = array('path' => 'taxonomy/page', 'title' => t('taxonomy'),
-    'callback' => 'legacy_taxonomy_page',
-    'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  // Map "taxonomy/feed/or/52,97" to "taxonomy/term/52+97/0/feed".
-  $items[] = array('path' => 'taxonomy/feed', 'title' => t('taxonomy'),
-    'callback' => 'legacy_taxonomy_feed',
-    'access' => TRUE, 'type' => MENU_CALLBACK);
+  if ($may_cache) {
+    // Map "node/view/52" to "node/52".
+    $items[] = array('path' => 'node/view', 'title' => t('view'),
+      'callback' => 'drupal_goto',
+      'callback arguments' => array('node/'. arg(2), NULL, NULL),
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "book/view/52" to "node/52".
+    $items[] = array('path' => 'book/view', 'title' => t('view'),
+      'callback' => 'drupal_goto',
+      'callback arguments' => array('node/'. arg(2), NULL, NULL),
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "user/view/52" to "user/52".
+    $items[] = array('path' => 'user/view', 'title' => t('view'),
+      'callback' => 'drupal_goto',
+      'callback arguments' => array('user/'. arg(2), NULL, NULL),
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "taxonomy/page/or/52,97" to "taxonomy/term/52+97".
+    $items[] = array('path' => 'taxonomy/page', 'title' => t('taxonomy'),
+      'callback' => 'legacy_taxonomy_page',
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    // Map "taxonomy/feed/or/52,97" to "taxonomy/term/52+97/0/feed".
+    $items[] = array('path' => 'taxonomy/feed', 'title' => t('taxonomy'),
+      'callback' => 'legacy_taxonomy_feed',
+      'access' => TRUE, 'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/locale.module b/modules/locale.module
index 6669f1df0587..d7caf6d56832 100644
--- a/modules/locale.module
+++ b/modules/locale.module
@@ -62,46 +62,49 @@ function locale_help($section = "admin/help#locale") {
 /**
  * Implementation of hook_menu().
  */
-function locale_menu() {
-
+function locale_menu($may_cache) {
   $items = array();
-  $access = user_access('administer locales');
-
-  // Main admin menu item
-  $items[] = array('path' => 'admin/locale', 'title' => t('localization'),
-    'callback' => 'locale_admin_manage', 'access' => $access);
-
-  // Top level tabs
-  $items[] = array('path' => 'admin/locale/language', 'title' => t('manage languages'),
-    'access' => $access, 'weight' => -10, 'type' => MENU_DEFAULT_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/string/search', 'title' => t('manage strings'),
-    'callback' => 'locale_admin_string', 'access' => $access, 'weight' => 10,
-    'type' => MENU_LOCAL_TASK);
-
-  // Manage languages subtabs
-  $items[] = array('path' => 'admin/locale/language/overview', 'title' => t('list'),
-    'callback' => 'locale_admin_manage', 'access' => $access, "weight" => 0,
-    'type' => MENU_DEFAULT_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/language/add', 'title' => t('add language'),
-    'callback' => 'locale_admin_manage_add', 'access' => $access, "weight" => 5,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/language/import', 'title' => t('import'),
-    'callback' => 'locale_admin_import', 'access' => $access, 'weight' => 10,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/language/export', 'title' => t('export'),
-    'callback' => 'locale_admin_export', 'access' => $access, 'weight' => 20,
-    'type' => MENU_LOCAL_TASK);
-
-  // Language related callbacks
-  $items[] = array('path' => 'admin/locale/language/delete', 'title' => t('confirm'),
-    'callback' => 'locale_admin_manage_delete_screen', 'access' => $access,
-    'type' => MENU_CALLBACK);
-
-  // String related callbacks
-  $items[] = array('path' => 'admin/locale/string/edit', 'title' => t('edit'),
-    'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/locale/string/delete', 'title' => t('delete'),
-    'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $access = user_access('administer locales');
+
+    // Main admin menu item
+    $items[] = array('path' => 'admin/locale', 'title' => t('localization'),
+      'callback' => 'locale_admin_manage', 'access' => $access);
+
+    // Top level tabs
+    $items[] = array('path' => 'admin/locale/language', 'title' => t('manage languages'),
+      'access' => $access, 'weight' => -10, 'type' => MENU_DEFAULT_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/string/search', 'title' => t('manage strings'),
+      'callback' => 'locale_admin_string', 'access' => $access, 'weight' => 10,
+      'type' => MENU_LOCAL_TASK);
+
+    // Manage languages subtabs
+    $items[] = array('path' => 'admin/locale/language/overview', 'title' => t('list'),
+      'callback' => 'locale_admin_manage', 'access' => $access, "weight" => 0,
+      'type' => MENU_DEFAULT_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/language/add', 'title' => t('add language'),
+      'callback' => 'locale_admin_manage_add', 'access' => $access, "weight" => 5,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/language/import', 'title' => t('import'),
+      'callback' => 'locale_admin_import', 'access' => $access, 'weight' => 10,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/language/export', 'title' => t('export'),
+      'callback' => 'locale_admin_export', 'access' => $access, 'weight' => 20,
+      'type' => MENU_LOCAL_TASK);
+
+    // Language related callbacks
+    $items[] = array('path' => 'admin/locale/language/delete', 'title' => t('confirm'),
+      'callback' => 'locale_admin_manage_delete_screen', 'access' => $access,
+      'type' => MENU_CALLBACK);
+
+    // String related callbacks
+    $items[] = array('path' => 'admin/locale/string/edit', 'title' => t('edit'),
+      'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/locale/string/delete', 'title' => t('delete'),
+      'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
+  }
+
   return $items;
 }
 
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index 6669f1df0587..d7caf6d56832 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -62,46 +62,49 @@ function locale_help($section = "admin/help#locale") {
 /**
  * Implementation of hook_menu().
  */
-function locale_menu() {
-
+function locale_menu($may_cache) {
   $items = array();
-  $access = user_access('administer locales');
-
-  // Main admin menu item
-  $items[] = array('path' => 'admin/locale', 'title' => t('localization'),
-    'callback' => 'locale_admin_manage', 'access' => $access);
-
-  // Top level tabs
-  $items[] = array('path' => 'admin/locale/language', 'title' => t('manage languages'),
-    'access' => $access, 'weight' => -10, 'type' => MENU_DEFAULT_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/string/search', 'title' => t('manage strings'),
-    'callback' => 'locale_admin_string', 'access' => $access, 'weight' => 10,
-    'type' => MENU_LOCAL_TASK);
-
-  // Manage languages subtabs
-  $items[] = array('path' => 'admin/locale/language/overview', 'title' => t('list'),
-    'callback' => 'locale_admin_manage', 'access' => $access, "weight" => 0,
-    'type' => MENU_DEFAULT_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/language/add', 'title' => t('add language'),
-    'callback' => 'locale_admin_manage_add', 'access' => $access, "weight" => 5,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/language/import', 'title' => t('import'),
-    'callback' => 'locale_admin_import', 'access' => $access, 'weight' => 10,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/locale/language/export', 'title' => t('export'),
-    'callback' => 'locale_admin_export', 'access' => $access, 'weight' => 20,
-    'type' => MENU_LOCAL_TASK);
-
-  // Language related callbacks
-  $items[] = array('path' => 'admin/locale/language/delete', 'title' => t('confirm'),
-    'callback' => 'locale_admin_manage_delete_screen', 'access' => $access,
-    'type' => MENU_CALLBACK);
-
-  // String related callbacks
-  $items[] = array('path' => 'admin/locale/string/edit', 'title' => t('edit'),
-    'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/locale/string/delete', 'title' => t('delete'),
-    'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $access = user_access('administer locales');
+
+    // Main admin menu item
+    $items[] = array('path' => 'admin/locale', 'title' => t('localization'),
+      'callback' => 'locale_admin_manage', 'access' => $access);
+
+    // Top level tabs
+    $items[] = array('path' => 'admin/locale/language', 'title' => t('manage languages'),
+      'access' => $access, 'weight' => -10, 'type' => MENU_DEFAULT_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/string/search', 'title' => t('manage strings'),
+      'callback' => 'locale_admin_string', 'access' => $access, 'weight' => 10,
+      'type' => MENU_LOCAL_TASK);
+
+    // Manage languages subtabs
+    $items[] = array('path' => 'admin/locale/language/overview', 'title' => t('list'),
+      'callback' => 'locale_admin_manage', 'access' => $access, "weight" => 0,
+      'type' => MENU_DEFAULT_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/language/add', 'title' => t('add language'),
+      'callback' => 'locale_admin_manage_add', 'access' => $access, "weight" => 5,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/language/import', 'title' => t('import'),
+      'callback' => 'locale_admin_import', 'access' => $access, 'weight' => 10,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/locale/language/export', 'title' => t('export'),
+      'callback' => 'locale_admin_export', 'access' => $access, 'weight' => 20,
+      'type' => MENU_LOCAL_TASK);
+
+    // Language related callbacks
+    $items[] = array('path' => 'admin/locale/language/delete', 'title' => t('confirm'),
+      'callback' => 'locale_admin_manage_delete_screen', 'access' => $access,
+      'type' => MENU_CALLBACK);
+
+    // String related callbacks
+    $items[] = array('path' => 'admin/locale/string/edit', 'title' => t('edit'),
+      'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/locale/string/delete', 'title' => t('delete'),
+      'callback' => 'locale_admin_string', 'access' => $access, 'type' => MENU_CALLBACK);
+  }
+
   return $items;
 }
 
diff --git a/modules/menu.module b/modules/menu.module
index 916c31903695..fb3c042fbbf6 100644
--- a/modules/menu.module
+++ b/modules/menu.module
@@ -9,42 +9,45 @@
 /**
  * Implementation of hook_menu().
  */
-function menu_menu() {
+function menu_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/menu', 'title' => t('menus'),
-    'callback' => 'menu_overview',
-    'access' => user_access('administer menu'));
-  $items[] = array('path' => 'admin/menu/item/edit', 'title' => t('edit menu item'),
-    'callback' => 'menu_edit_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/menu/item/reset', 'title' => t('reset menu item'),
-    'callback' => 'menu_reset_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/menu/item/disable', 'title' => t('disable menu item'),
-    'callback' => 'menu_disable_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/menu/item/delete', 'title' => t('delete menu item'),
-    'callback' => 'menu_delete_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'admin/menu/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/menu/menu/add', 'title' => t('add menu'),
-    'callback' => 'menu_add_menu',
-    'access' => user_access('administer menu'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/menu/item/add', 'title' => t('add menu item'),
-    'callback' => 'menu_edit_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/menu/reset', 'title' => t('reset menus'),
-    'callback' => 'menu_reset',
-    'access' => user_access('administer menu'),
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/menu', 'title' => t('menus'),
+      'callback' => 'menu_overview',
+      'access' => user_access('administer menu'));
+    $items[] = array('path' => 'admin/menu/item/edit', 'title' => t('edit menu item'),
+      'callback' => 'menu_edit_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/menu/item/reset', 'title' => t('reset menu item'),
+      'callback' => 'menu_reset_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/menu/item/disable', 'title' => t('disable menu item'),
+      'callback' => 'menu_disable_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/menu/item/delete', 'title' => t('delete menu item'),
+      'callback' => 'menu_delete_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'admin/menu/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/menu/menu/add', 'title' => t('add menu'),
+      'callback' => 'menu_add_menu',
+      'access' => user_access('administer menu'),
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/menu/item/add', 'title' => t('add menu item'),
+      'callback' => 'menu_edit_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/menu/reset', 'title' => t('reset menus'),
+      'callback' => 'menu_reset',
+      'access' => user_access('administer menu'),
+      'type' => MENU_LOCAL_TASK);
+  }
 
   return $items;
 }
@@ -334,8 +337,6 @@ function menu_edit_item_save($edit) {
       drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l('<em>'. $old_item['title'] .'</em>', 'admin/menu/item/edit/'. $old_mid), '%path' => '<em>'. $edit['path'] .'</em>')));
     }
   }
-
-  menu_rebuild();
 }
 
 /**
diff --git a/modules/menu/menu.module b/modules/menu/menu.module
index 916c31903695..fb3c042fbbf6 100644
--- a/modules/menu/menu.module
+++ b/modules/menu/menu.module
@@ -9,42 +9,45 @@
 /**
  * Implementation of hook_menu().
  */
-function menu_menu() {
+function menu_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/menu', 'title' => t('menus'),
-    'callback' => 'menu_overview',
-    'access' => user_access('administer menu'));
-  $items[] = array('path' => 'admin/menu/item/edit', 'title' => t('edit menu item'),
-    'callback' => 'menu_edit_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/menu/item/reset', 'title' => t('reset menu item'),
-    'callback' => 'menu_reset_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/menu/item/disable', 'title' => t('disable menu item'),
-    'callback' => 'menu_disable_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/menu/item/delete', 'title' => t('delete menu item'),
-    'callback' => 'menu_delete_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'admin/menu/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/menu/menu/add', 'title' => t('add menu'),
-    'callback' => 'menu_add_menu',
-    'access' => user_access('administer menu'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/menu/item/add', 'title' => t('add menu item'),
-    'callback' => 'menu_edit_item',
-    'access' => user_access('administer menu'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/menu/reset', 'title' => t('reset menus'),
-    'callback' => 'menu_reset',
-    'access' => user_access('administer menu'),
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/menu', 'title' => t('menus'),
+      'callback' => 'menu_overview',
+      'access' => user_access('administer menu'));
+    $items[] = array('path' => 'admin/menu/item/edit', 'title' => t('edit menu item'),
+      'callback' => 'menu_edit_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/menu/item/reset', 'title' => t('reset menu item'),
+      'callback' => 'menu_reset_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/menu/item/disable', 'title' => t('disable menu item'),
+      'callback' => 'menu_disable_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/menu/item/delete', 'title' => t('delete menu item'),
+      'callback' => 'menu_delete_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'admin/menu/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/menu/menu/add', 'title' => t('add menu'),
+      'callback' => 'menu_add_menu',
+      'access' => user_access('administer menu'),
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/menu/item/add', 'title' => t('add menu item'),
+      'callback' => 'menu_edit_item',
+      'access' => user_access('administer menu'),
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/menu/reset', 'title' => t('reset menus'),
+      'callback' => 'menu_reset',
+      'access' => user_access('administer menu'),
+      'type' => MENU_LOCAL_TASK);
+  }
 
   return $items;
 }
@@ -334,8 +337,6 @@ function menu_edit_item_save($edit) {
       drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l('<em>'. $old_item['title'] .'</em>', 'admin/menu/item/edit/'. $old_mid), '%path' => '<em>'. $edit['path'] .'</em>')));
     }
   }
-
-  menu_rebuild();
 }
 
 /**
diff --git a/modules/node.module b/modules/node.module
index c7497a04cf0b..9c7156ba2e5f 100644
--- a/modules/node.module
+++ b/modules/node.module
@@ -626,62 +626,65 @@ function node_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function node_menu() {
+function node_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'admin/node', 'title' => t('content'),
-    'callback' => 'node_admin',
-    'access' => user_access('administer nodes'));
-  $items[] = array('path' => 'admin/node/overview', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/node/configure', 'title' => t('configure'),
-    'callback' => 'node_configure',
-    'access' => user_access('administer nodes'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/node/configure/settings', 'title' => t('settings'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/node/configure/defaults', 'title' => t('default workflow'),
-    'callback' => 'node_default_settings',
-    'access' => user_access('administer nodes'),
-    'type' => MENU_LOCAL_TASK);
-  if (module_exist('search')) {
-    $items[] = array('path' => 'admin/node/search', 'title' => t('search'),
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/node', 'title' => t('content'),
       'callback' => 'node_admin',
+      'access' => user_access('administer nodes'));
+    $items[] = array('path' => 'admin/node/overview', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/node/configure', 'title' => t('configure'),
+      'callback' => 'node_configure',
       'access' => user_access('administer nodes'),
       'type' => MENU_LOCAL_TASK);
-  }
-
-  $items[] = array('path' => 'node', 'title' => t('content'),
-    'callback' => 'node_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'node/add', 'title' => t('create content'),
-    'callback' => 'node_page',
-    'access' => user_access('access content'),
-    'type' => MENU_ITEM_GROUPING,
-    'weight' => 1);
-
-  if (arg(0) == 'node' && is_numeric(arg(1))) {
-    $node = node_load(array('nid' => arg(1)));
+    $items[] = array('path' => 'admin/node/configure/settings', 'title' => t('settings'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/node/configure/defaults', 'title' => t('default workflow'),
+      'callback' => 'node_default_settings',
+      'access' => user_access('administer nodes'),
+      'type' => MENU_LOCAL_TASK);
+    if (module_exist('search')) {
+      $items[] = array('path' => 'admin/node/search', 'title' => t('search'),
+        'callback' => 'node_admin',
+        'access' => user_access('administer nodes'),
+        'type' => MENU_LOCAL_TASK);
+    }
 
-    $items[] = array('path' => 'node/'. arg(1), 'title' => t('view'),
+    $items[] = array('path' => 'node', 'title' => t('content'),
       'callback' => 'node_page',
-      'access' => node_access('view', $node),
-      'type' => MENU_CALLBACK);
-    $items[] = array('path' => 'node/'. arg(1) .'/view', 'title' => t('view'),
-        'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-    $items[] = array('path' => 'node/'. arg(1) .'/edit', 'title' => t('edit'),
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'node/add', 'title' => t('create content'),
       'callback' => 'node_page',
-      'access' => node_access('update', $node),
-      'weight' => 1,
-      'type' => MENU_LOCAL_TASK);
+      'access' => user_access('access content'),
+      'type' => MENU_ITEM_GROUPING,
+      'weight' => 1);
+  }
+  else {
+    if (arg(0) == 'node' && is_numeric(arg(1))) {
+      $node = node_load(array('nid' => arg(1)));
 
-    if ($node->revisions) {
-      $items[] = array('path' => 'node/'. arg(1) .'/revisions', 'title' => t('revisions'),
+      $items[] = array('path' => 'node/'. arg(1), 'title' => t('view'),
         'callback' => 'node_page',
-        'access' => user_access('administer nodes'),
-        'weight' => 2,
+        'access' => node_access('view', $node),
+        'type' => MENU_CALLBACK);
+      $items[] = array('path' => 'node/'. arg(1) .'/view', 'title' => t('view'),
+          'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+      $items[] = array('path' => 'node/'. arg(1) .'/edit', 'title' => t('edit'),
+        'callback' => 'node_page',
+        'access' => node_access('update', $node),
+        'weight' => 1,
         'type' => MENU_LOCAL_TASK);
+
+      if ($node->revisions) {
+        $items[] = array('path' => 'node/'. arg(1) .'/revisions', 'title' => t('revisions'),
+          'callback' => 'node_page',
+          'access' => user_access('administer nodes'),
+          'weight' => 2,
+          'type' => MENU_LOCAL_TASK);
+      }
     }
   }
 
diff --git a/modules/node/node.module b/modules/node/node.module
index c7497a04cf0b..9c7156ba2e5f 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -626,62 +626,65 @@ function node_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function node_menu() {
+function node_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'admin/node', 'title' => t('content'),
-    'callback' => 'node_admin',
-    'access' => user_access('administer nodes'));
-  $items[] = array('path' => 'admin/node/overview', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/node/configure', 'title' => t('configure'),
-    'callback' => 'node_configure',
-    'access' => user_access('administer nodes'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/node/configure/settings', 'title' => t('settings'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/node/configure/defaults', 'title' => t('default workflow'),
-    'callback' => 'node_default_settings',
-    'access' => user_access('administer nodes'),
-    'type' => MENU_LOCAL_TASK);
-  if (module_exist('search')) {
-    $items[] = array('path' => 'admin/node/search', 'title' => t('search'),
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/node', 'title' => t('content'),
       'callback' => 'node_admin',
+      'access' => user_access('administer nodes'));
+    $items[] = array('path' => 'admin/node/overview', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/node/configure', 'title' => t('configure'),
+      'callback' => 'node_configure',
       'access' => user_access('administer nodes'),
       'type' => MENU_LOCAL_TASK);
-  }
-
-  $items[] = array('path' => 'node', 'title' => t('content'),
-    'callback' => 'node_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'node/add', 'title' => t('create content'),
-    'callback' => 'node_page',
-    'access' => user_access('access content'),
-    'type' => MENU_ITEM_GROUPING,
-    'weight' => 1);
-
-  if (arg(0) == 'node' && is_numeric(arg(1))) {
-    $node = node_load(array('nid' => arg(1)));
+    $items[] = array('path' => 'admin/node/configure/settings', 'title' => t('settings'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/node/configure/defaults', 'title' => t('default workflow'),
+      'callback' => 'node_default_settings',
+      'access' => user_access('administer nodes'),
+      'type' => MENU_LOCAL_TASK);
+    if (module_exist('search')) {
+      $items[] = array('path' => 'admin/node/search', 'title' => t('search'),
+        'callback' => 'node_admin',
+        'access' => user_access('administer nodes'),
+        'type' => MENU_LOCAL_TASK);
+    }
 
-    $items[] = array('path' => 'node/'. arg(1), 'title' => t('view'),
+    $items[] = array('path' => 'node', 'title' => t('content'),
       'callback' => 'node_page',
-      'access' => node_access('view', $node),
-      'type' => MENU_CALLBACK);
-    $items[] = array('path' => 'node/'. arg(1) .'/view', 'title' => t('view'),
-        'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-    $items[] = array('path' => 'node/'. arg(1) .'/edit', 'title' => t('edit'),
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'node/add', 'title' => t('create content'),
       'callback' => 'node_page',
-      'access' => node_access('update', $node),
-      'weight' => 1,
-      'type' => MENU_LOCAL_TASK);
+      'access' => user_access('access content'),
+      'type' => MENU_ITEM_GROUPING,
+      'weight' => 1);
+  }
+  else {
+    if (arg(0) == 'node' && is_numeric(arg(1))) {
+      $node = node_load(array('nid' => arg(1)));
 
-    if ($node->revisions) {
-      $items[] = array('path' => 'node/'. arg(1) .'/revisions', 'title' => t('revisions'),
+      $items[] = array('path' => 'node/'. arg(1), 'title' => t('view'),
         'callback' => 'node_page',
-        'access' => user_access('administer nodes'),
-        'weight' => 2,
+        'access' => node_access('view', $node),
+        'type' => MENU_CALLBACK);
+      $items[] = array('path' => 'node/'. arg(1) .'/view', 'title' => t('view'),
+          'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+      $items[] = array('path' => 'node/'. arg(1) .'/edit', 'title' => t('edit'),
+        'callback' => 'node_page',
+        'access' => node_access('update', $node),
+        'weight' => 1,
         'type' => MENU_LOCAL_TASK);
+
+      if ($node->revisions) {
+        $items[] = array('path' => 'node/'. arg(1) .'/revisions', 'title' => t('revisions'),
+          'callback' => 'node_page',
+          'access' => user_access('administer nodes'),
+          'weight' => 2,
+          'type' => MENU_LOCAL_TASK);
+      }
     }
   }
 
diff --git a/modules/page.module b/modules/page.module
index 6dc7c2441640..a73da4679fd8 100644
--- a/modules/page.module
+++ b/modules/page.module
@@ -87,10 +87,14 @@ function page_load($node) {
 /**
  * Implementation of hook_menu().
  */
-function page_menu() {
+function page_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'node/add/page', 'title' => t('page'),
-    'access' => page_access('create', NULL));
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/page', 'title' => t('page'),
+      'access' => page_access('create', NULL));
+  }
+
   return $items;
 }
 
diff --git a/modules/page/page.module b/modules/page/page.module
index 6dc7c2441640..a73da4679fd8 100644
--- a/modules/page/page.module
+++ b/modules/page/page.module
@@ -87,10 +87,14 @@ function page_load($node) {
 /**
  * Implementation of hook_menu().
  */
-function page_menu() {
+function page_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'node/add/page', 'title' => t('page'),
-    'access' => page_access('create', NULL));
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/page', 'title' => t('page'),
+      'access' => page_access('create', NULL));
+  }
+
   return $items;
 }
 
diff --git a/modules/path.module b/modules/path.module
index daa53bf589e8..20348d592944 100644
--- a/modules/path.module
+++ b/modules/path.module
@@ -65,25 +65,29 @@ function conf_url_rewrite(\$path, \$mode = 'incoming') {
 /**
  * Implementation of hook_menu().
  */
-function path_menu() {
+function path_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/path', 'title' => t('url aliases'),
-    'callback' => 'path_admin',
-    'access' => user_access('administer url aliases'));
-  $items[] = array('path' => 'admin/path/edit', 'title' => t('edit alias'),
-    'callback' => 'path_admin_edit',
-    'access' => user_access('administer url aliases'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/path/delete', 'title' => t('delete alias'),
-    'callback' => 'path_admin_delete',
-    'access' => user_access('administer url aliases'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/path/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/path/add', 'title' => t('add'),
-    'callback' => 'path_admin_edit',
-    'access' => user_access('administer url aliases'),
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/path', 'title' => t('url aliases'),
+      'callback' => 'path_admin',
+      'access' => user_access('administer url aliases'));
+    $items[] = array('path' => 'admin/path/edit', 'title' => t('edit alias'),
+      'callback' => 'path_admin_edit',
+      'access' => user_access('administer url aliases'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/path/delete', 'title' => t('delete alias'),
+      'callback' => 'path_admin_delete',
+      'access' => user_access('administer url aliases'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/path/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/path/add', 'title' => t('add'),
+      'callback' => 'path_admin_edit',
+      'access' => user_access('administer url aliases'),
+      'type' => MENU_LOCAL_TASK);
+  }
+
   return $items;
 }
 
diff --git a/modules/path/path.module b/modules/path/path.module
index daa53bf589e8..20348d592944 100644
--- a/modules/path/path.module
+++ b/modules/path/path.module
@@ -65,25 +65,29 @@ function conf_url_rewrite(\$path, \$mode = 'incoming') {
 /**
  * Implementation of hook_menu().
  */
-function path_menu() {
+function path_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/path', 'title' => t('url aliases'),
-    'callback' => 'path_admin',
-    'access' => user_access('administer url aliases'));
-  $items[] = array('path' => 'admin/path/edit', 'title' => t('edit alias'),
-    'callback' => 'path_admin_edit',
-    'access' => user_access('administer url aliases'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/path/delete', 'title' => t('delete alias'),
-    'callback' => 'path_admin_delete',
-    'access' => user_access('administer url aliases'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/path/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/path/add', 'title' => t('add'),
-    'callback' => 'path_admin_edit',
-    'access' => user_access('administer url aliases'),
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/path', 'title' => t('url aliases'),
+      'callback' => 'path_admin',
+      'access' => user_access('administer url aliases'));
+    $items[] = array('path' => 'admin/path/edit', 'title' => t('edit alias'),
+      'callback' => 'path_admin_edit',
+      'access' => user_access('administer url aliases'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/path/delete', 'title' => t('delete alias'),
+      'callback' => 'path_admin_delete',
+      'access' => user_access('administer url aliases'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/path/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/path/add', 'title' => t('add'),
+      'callback' => 'path_admin_edit',
+      'access' => user_access('administer url aliases'),
+      'type' => MENU_LOCAL_TASK);
+  }
+
   return $items;
 }
 
diff --git a/modules/poll.module b/modules/poll.module
index e3973501143d..2fe6207b8511 100644
--- a/modules/poll.module
+++ b/modules/poll.module
@@ -195,33 +195,38 @@ function poll_link($type, $node = 0, $main) {
 /**
  * Implementation of hook_menu().
  */
-function poll_menu() {
+function poll_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'node/add/poll', 'title' => t('poll'),
-    'access' => user_access('create polls'));
-  $items[] = array('path' => 'poll', 'title' => t('polls'),
-    'callback' => 'poll_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-
-  $items[] = array('path' => 'poll/vote',
-    'title' => t('vote'),
-    'callback' => 'poll_vote',
-    'access' => user_access('vote on polls'),
-    'type' => MENU_CALLBACK);
-
-  if (arg(0) == 'node' && is_numeric(arg(1))) {
-    $node = node_load(array('nid' => arg(1)));
-
-    if ($node->type == 'poll' && $node->allowvotes) {
-      $items[] = array('path' => 'node/'. arg(1) .'/results',
-        'title' => t('results'),
-        'callback' => 'poll_results',
-        'access' => user_access('access content'),
-        'weight' => 3,
-        'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/poll', 'title' => t('poll'),
+      'access' => user_access('create polls'));
+    $items[] = array('path' => 'poll', 'title' => t('polls'),
+      'callback' => 'poll_page',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+
+    $items[] = array('path' => 'poll/vote',
+      'title' => t('vote'),
+      'callback' => 'poll_vote',
+      'access' => user_access('vote on polls'),
+      'type' => MENU_CALLBACK);
+  }
+  else {
+    if (arg(0) == 'node' && is_numeric(arg(1))) {
+      $node = node_load(array('nid' => arg(1)));
+
+      if ($node->type == 'poll' && $node->allowvotes) {
+        $items[] = array('path' => 'node/'. arg(1) .'/results',
+          'title' => t('results'),
+          'callback' => 'poll_results',
+          'access' => user_access('access content'),
+          'weight' => 3,
+          'type' => MENU_LOCAL_TASK);
+      }
     }
   }
+
   return $items;
 }
 
diff --git a/modules/poll/poll.module b/modules/poll/poll.module
index e3973501143d..2fe6207b8511 100644
--- a/modules/poll/poll.module
+++ b/modules/poll/poll.module
@@ -195,33 +195,38 @@ function poll_link($type, $node = 0, $main) {
 /**
  * Implementation of hook_menu().
  */
-function poll_menu() {
+function poll_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'node/add/poll', 'title' => t('poll'),
-    'access' => user_access('create polls'));
-  $items[] = array('path' => 'poll', 'title' => t('polls'),
-    'callback' => 'poll_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-
-  $items[] = array('path' => 'poll/vote',
-    'title' => t('vote'),
-    'callback' => 'poll_vote',
-    'access' => user_access('vote on polls'),
-    'type' => MENU_CALLBACK);
-
-  if (arg(0) == 'node' && is_numeric(arg(1))) {
-    $node = node_load(array('nid' => arg(1)));
-
-    if ($node->type == 'poll' && $node->allowvotes) {
-      $items[] = array('path' => 'node/'. arg(1) .'/results',
-        'title' => t('results'),
-        'callback' => 'poll_results',
-        'access' => user_access('access content'),
-        'weight' => 3,
-        'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/poll', 'title' => t('poll'),
+      'access' => user_access('create polls'));
+    $items[] = array('path' => 'poll', 'title' => t('polls'),
+      'callback' => 'poll_page',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+
+    $items[] = array('path' => 'poll/vote',
+      'title' => t('vote'),
+      'callback' => 'poll_vote',
+      'access' => user_access('vote on polls'),
+      'type' => MENU_CALLBACK);
+  }
+  else {
+    if (arg(0) == 'node' && is_numeric(arg(1))) {
+      $node = node_load(array('nid' => arg(1)));
+
+      if ($node->type == 'poll' && $node->allowvotes) {
+        $items[] = array('path' => 'node/'. arg(1) .'/results',
+          'title' => t('results'),
+          'callback' => 'poll_results',
+          'access' => user_access('access content'),
+          'weight' => 3,
+          'type' => MENU_LOCAL_TASK);
+      }
     }
   }
+
   return $items;
 }
 
diff --git a/modules/profile.module b/modules/profile.module
index e379d75db3d0..2aef8aa030a2 100644
--- a/modules/profile.module
+++ b/modules/profile.module
@@ -26,30 +26,32 @@ function profile_help($section) {
 /**
  * Implementation of hook_menu().
  */
-function profile_menu() {
+function profile_menu($may_cache) {
   global $user;
-
   $items = array();
-  $items[] = array('path' => 'profile', 'title' => t('user list'),
-    'callback' => 'profile_browse',
-    'access' => TRUE,
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'admin/user/configure/profile', 'title' => t('profiles'),
-    'callback' => 'profile_admin_overview',
-    'access' => user_access('administer users'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/profile/add', 'title' => t('add field'),
-    'callback' => 'profile_admin_add',
-    'access' => user_access('administer users'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/user/configure/profile/edit', 'title' => t('edit field'),
-    'callback' => 'profile_admin_edit',
-    'access' => user_access('administer users'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/user/configure/profile/delete', 'title' => t('delete field'),
-    'callback' => 'profile_admin_delete',
-    'access' => user_access('administer users'),
-    'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'profile', 'title' => t('user list'),
+      'callback' => 'profile_browse',
+      'access' => TRUE,
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'admin/user/configure/profile', 'title' => t('profiles'),
+      'callback' => 'profile_admin_overview',
+      'access' => user_access('administer users'),
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/profile/add', 'title' => t('add field'),
+      'callback' => 'profile_admin_add',
+      'access' => user_access('administer users'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/user/configure/profile/edit', 'title' => t('edit field'),
+      'callback' => 'profile_admin_edit',
+      'access' => user_access('administer users'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/user/configure/profile/delete', 'title' => t('delete field'),
+      'callback' => 'profile_admin_delete',
+      'access' => user_access('administer users'),
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/profile/profile.module b/modules/profile/profile.module
index e379d75db3d0..2aef8aa030a2 100644
--- a/modules/profile/profile.module
+++ b/modules/profile/profile.module
@@ -26,30 +26,32 @@ function profile_help($section) {
 /**
  * Implementation of hook_menu().
  */
-function profile_menu() {
+function profile_menu($may_cache) {
   global $user;
-
   $items = array();
-  $items[] = array('path' => 'profile', 'title' => t('user list'),
-    'callback' => 'profile_browse',
-    'access' => TRUE,
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'admin/user/configure/profile', 'title' => t('profiles'),
-    'callback' => 'profile_admin_overview',
-    'access' => user_access('administer users'),
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/profile/add', 'title' => t('add field'),
-    'callback' => 'profile_admin_add',
-    'access' => user_access('administer users'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/user/configure/profile/edit', 'title' => t('edit field'),
-    'callback' => 'profile_admin_edit',
-    'access' => user_access('administer users'),
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'admin/user/configure/profile/delete', 'title' => t('delete field'),
-    'callback' => 'profile_admin_delete',
-    'access' => user_access('administer users'),
-    'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'profile', 'title' => t('user list'),
+      'callback' => 'profile_browse',
+      'access' => TRUE,
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'admin/user/configure/profile', 'title' => t('profiles'),
+      'callback' => 'profile_admin_overview',
+      'access' => user_access('administer users'),
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/profile/add', 'title' => t('add field'),
+      'callback' => 'profile_admin_add',
+      'access' => user_access('administer users'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/user/configure/profile/edit', 'title' => t('edit field'),
+      'callback' => 'profile_admin_edit',
+      'access' => user_access('administer users'),
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/user/configure/profile/delete', 'title' => t('delete field'),
+      'callback' => 'profile_admin_delete',
+      'access' => user_access('administer users'),
+      'type' => MENU_CALLBACK);
+  }
 
   return $items;
 }
diff --git a/modules/queue.module b/modules/queue.module
index a0f9923b6b01..5176ef971710 100644
--- a/modules/queue.module
+++ b/modules/queue.module
@@ -40,12 +40,16 @@ function queue_perm() {
 /**
  * Implementation of hook_menu().
  */
-function queue_menu($type) {
+function queue_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'queue', 'title' => t('submission queue'),
-    'callback' => 'queue_page',
-    'access' => user_access('access submission queue'),
-    'weight' => 1);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'queue', 'title' => t('submission queue'),
+      'callback' => 'queue_page',
+      'access' => user_access('access submission queue'),
+      'weight' => 1);
+  }
+
   return $items;
 }
 
diff --git a/modules/search.module b/modules/search.module
index f42c1e2bad08..c7422ac81c25 100644
--- a/modules/search.module
+++ b/modules/search.module
@@ -47,22 +47,26 @@ function search_link($type) {
 /**
  * Implementation of hook_menu().
  */
-function search_menu() {
+function search_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'search', 'title' => t('search'),
-    'callback' => 'search_view',
-    'access' => user_access('search content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'search/help', 'title' => t('search help'),
-    'callback' => 'search_help_page',
-    'access' => user_access('search content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'search/search', 'title' => t('search'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'search/configure', 'title' => t('configure'),
-    'callback' => 'search_configure',
-    'access' => user_access('administer site configuration'),
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'search', 'title' => t('search'),
+      'callback' => 'search_view',
+      'access' => user_access('search content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'search/help', 'title' => t('search help'),
+      'callback' => 'search_help_page',
+      'access' => user_access('search content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'search/search', 'title' => t('search'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'search/configure', 'title' => t('configure'),
+      'callback' => 'search_configure',
+      'access' => user_access('administer site configuration'),
+      'type' => MENU_LOCAL_TASK);
+  }
+
   return $items;
 }
 
diff --git a/modules/search/search.module b/modules/search/search.module
index f42c1e2bad08..c7422ac81c25 100644
--- a/modules/search/search.module
+++ b/modules/search/search.module
@@ -47,22 +47,26 @@ function search_link($type) {
 /**
  * Implementation of hook_menu().
  */
-function search_menu() {
+function search_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'search', 'title' => t('search'),
-    'callback' => 'search_view',
-    'access' => user_access('search content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'search/help', 'title' => t('search help'),
-    'callback' => 'search_help_page',
-    'access' => user_access('search content'),
-    'type' => MENU_SUGGESTED_ITEM);
-  $items[] = array('path' => 'search/search', 'title' => t('search'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'search/configure', 'title' => t('configure'),
-    'callback' => 'search_configure',
-    'access' => user_access('administer site configuration'),
-    'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'search', 'title' => t('search'),
+      'callback' => 'search_view',
+      'access' => user_access('search content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'search/help', 'title' => t('search help'),
+      'callback' => 'search_help_page',
+      'access' => user_access('search content'),
+      'type' => MENU_SUGGESTED_ITEM);
+    $items[] = array('path' => 'search/search', 'title' => t('search'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'search/configure', 'title' => t('configure'),
+      'callback' => 'search_configure',
+      'access' => user_access('administer site configuration'),
+      'type' => MENU_LOCAL_TASK);
+  }
+
   return $items;
 }
 
diff --git a/modules/statistics.module b/modules/statistics.module
index 10029d9d309f..4df088ed27cb 100644
--- a/modules/statistics.module
+++ b/modules/statistics.module
@@ -153,36 +153,40 @@ function statistics_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function statistics_menu() {
+function statistics_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'statistics', 'title' => t('most popular content'),
-    'callback' => 'statistics_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-
-  $access = user_access('administer statistics module') || user_access('administer statistics');
-  $items[] = array('path' => 'admin/logs/hits', 'title' => t('hits'),
-    'callback' => 'statistics_admin_displaylog', 'access' => $access,
-    'weight' => 3);
-  $items[] = array('path' => 'admin/logs/hits/posts', 'title' => t('posts'),
-    'callback' => 'statistics_admin_content', 'access' => $access,
-    'weight' => 1);
-  $items[] = array('path' => 'admin/logs/hits/pages', 'title' => t('pages'),
-    'callback' => 'statistics_top_titles', 'access' => $access,
-    'weight' => 1);
-  $items[] = array('path' => 'admin/logs/hits/users', 'title' => t('users'),
-    'callback' => 'statistics_top_users', 'access' => $access,
-    'weight' => 2);
-  $items[] = array('path' => 'admin/logs/hits/hostnames',
-    'title' => t('hostnames'), 'callback' => 'statistics_top_hostnames',
-    'access' => $access, 'weight' => 3);
-  $items[] = array('path' => 'admin/logs/referrers',
-    'title' => t('referrers'), 'callback' => 'statistics_top_referrers',
-    'access' => $access, 'weight' => 4);
-  $items[] = array('path' => 'admin/logs/referrers/internal',
-    'title' => t('internal'), 'access' => $access);
-  $items[] = array('path' => 'admin/logs/referrers/external',
-    'title' => t('external'), 'access' => $access);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'statistics', 'title' => t('most popular content'),
+      'callback' => 'statistics_page',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+
+    $access = user_access('administer statistics module') || user_access('administer statistics');
+    $items[] = array('path' => 'admin/logs/hits', 'title' => t('hits'),
+      'callback' => 'statistics_admin_displaylog', 'access' => $access,
+      'weight' => 3);
+    $items[] = array('path' => 'admin/logs/hits/posts', 'title' => t('posts'),
+      'callback' => 'statistics_admin_content', 'access' => $access,
+      'weight' => 1);
+    $items[] = array('path' => 'admin/logs/hits/pages', 'title' => t('pages'),
+      'callback' => 'statistics_top_titles', 'access' => $access,
+      'weight' => 1);
+    $items[] = array('path' => 'admin/logs/hits/users', 'title' => t('users'),
+      'callback' => 'statistics_top_users', 'access' => $access,
+      'weight' => 2);
+    $items[] = array('path' => 'admin/logs/hits/hostnames',
+      'title' => t('hostnames'), 'callback' => 'statistics_top_hostnames',
+      'access' => $access, 'weight' => 3);
+    $items[] = array('path' => 'admin/logs/referrers',
+      'title' => t('referrers'), 'callback' => 'statistics_top_referrers',
+      'access' => $access, 'weight' => 4);
+    $items[] = array('path' => 'admin/logs/referrers/internal',
+      'title' => t('internal'), 'access' => $access);
+    $items[] = array('path' => 'admin/logs/referrers/external',
+      'title' => t('external'), 'access' => $access);
+  }
+
   return $items;
 }
 
diff --git a/modules/statistics/statistics.module b/modules/statistics/statistics.module
index 10029d9d309f..4df088ed27cb 100644
--- a/modules/statistics/statistics.module
+++ b/modules/statistics/statistics.module
@@ -153,36 +153,40 @@ function statistics_link($type, $node = 0, $main = 0) {
 /**
  * Implementation of hook_menu().
  */
-function statistics_menu() {
+function statistics_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'statistics', 'title' => t('most popular content'),
-    'callback' => 'statistics_page',
-    'access' => user_access('access content'),
-    'type' => MENU_SUGGESTED_ITEM);
-
-  $access = user_access('administer statistics module') || user_access('administer statistics');
-  $items[] = array('path' => 'admin/logs/hits', 'title' => t('hits'),
-    'callback' => 'statistics_admin_displaylog', 'access' => $access,
-    'weight' => 3);
-  $items[] = array('path' => 'admin/logs/hits/posts', 'title' => t('posts'),
-    'callback' => 'statistics_admin_content', 'access' => $access,
-    'weight' => 1);
-  $items[] = array('path' => 'admin/logs/hits/pages', 'title' => t('pages'),
-    'callback' => 'statistics_top_titles', 'access' => $access,
-    'weight' => 1);
-  $items[] = array('path' => 'admin/logs/hits/users', 'title' => t('users'),
-    'callback' => 'statistics_top_users', 'access' => $access,
-    'weight' => 2);
-  $items[] = array('path' => 'admin/logs/hits/hostnames',
-    'title' => t('hostnames'), 'callback' => 'statistics_top_hostnames',
-    'access' => $access, 'weight' => 3);
-  $items[] = array('path' => 'admin/logs/referrers',
-    'title' => t('referrers'), 'callback' => 'statistics_top_referrers',
-    'access' => $access, 'weight' => 4);
-  $items[] = array('path' => 'admin/logs/referrers/internal',
-    'title' => t('internal'), 'access' => $access);
-  $items[] = array('path' => 'admin/logs/referrers/external',
-    'title' => t('external'), 'access' => $access);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'statistics', 'title' => t('most popular content'),
+      'callback' => 'statistics_page',
+      'access' => user_access('access content'),
+      'type' => MENU_SUGGESTED_ITEM);
+
+    $access = user_access('administer statistics module') || user_access('administer statistics');
+    $items[] = array('path' => 'admin/logs/hits', 'title' => t('hits'),
+      'callback' => 'statistics_admin_displaylog', 'access' => $access,
+      'weight' => 3);
+    $items[] = array('path' => 'admin/logs/hits/posts', 'title' => t('posts'),
+      'callback' => 'statistics_admin_content', 'access' => $access,
+      'weight' => 1);
+    $items[] = array('path' => 'admin/logs/hits/pages', 'title' => t('pages'),
+      'callback' => 'statistics_top_titles', 'access' => $access,
+      'weight' => 1);
+    $items[] = array('path' => 'admin/logs/hits/users', 'title' => t('users'),
+      'callback' => 'statistics_top_users', 'access' => $access,
+      'weight' => 2);
+    $items[] = array('path' => 'admin/logs/hits/hostnames',
+      'title' => t('hostnames'), 'callback' => 'statistics_top_hostnames',
+      'access' => $access, 'weight' => 3);
+    $items[] = array('path' => 'admin/logs/referrers',
+      'title' => t('referrers'), 'callback' => 'statistics_top_referrers',
+      'access' => $access, 'weight' => 4);
+    $items[] = array('path' => 'admin/logs/referrers/internal',
+      'title' => t('internal'), 'access' => $access);
+    $items[] = array('path' => 'admin/logs/referrers/external',
+      'title' => t('external'), 'access' => $access);
+  }
+
   return $items;
 }
 
diff --git a/modules/story.module b/modules/story.module
index f7b06782a54a..90214812aeb8 100644
--- a/modules/story.module
+++ b/modules/story.module
@@ -90,10 +90,14 @@ function story_link($type, $node = 0, $main) {
 /**
  * Implementation of hook_menu().
  */
-function story_menu() {
+function story_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'node/add/story', 'title' => t('story'),
-    'access' => story_access('create', NULL));
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/story', 'title' => t('story'),
+      'access' => story_access('create', NULL));
+  }
+
   return $items;
 }
 
diff --git a/modules/story/story.module b/modules/story/story.module
index f7b06782a54a..90214812aeb8 100644
--- a/modules/story/story.module
+++ b/modules/story/story.module
@@ -90,10 +90,14 @@ function story_link($type, $node = 0, $main) {
 /**
  * Implementation of hook_menu().
  */
-function story_menu() {
+function story_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'node/add/story', 'title' => t('story'),
-    'access' => story_access('create', NULL));
+
+  if ($may_cache) {
+    $items[] = array('path' => 'node/add/story', 'title' => t('story'),
+      'access' => story_access('create', NULL));
+  }
+
   return $items;
 }
 
diff --git a/modules/system.module b/modules/system.module
index 4a1af86e1415..00ace7e1c003 100644
--- a/modules/system.module
+++ b/modules/system.module
@@ -59,49 +59,52 @@ function system_perm() {
 /**
  * Implementation of hook_menu().
  */
-function system_menu() {
+function system_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'system/files', 'title' => t('file download'),
-    'callback' => 'file_download',
-    'access' => TRUE,
-    'type' => MENU_CALLBACK);
-
-  $access = user_access('administer site configuration');
-
-  // Themes:
-  $items[] = array('path' => 'admin/themes', 'title' => t('themes'),
-    'callback' => 'system_themes', 'access' => $access);
-
-  $items[] = array('path' => 'admin/themes/select', 'title' => t('select'),
-    'callback' => 'system_themes', 'access' => $access,
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
-
-  $items[] = array('path' => 'admin/themes/settings', 'title' => t('configure'),
-    'callback' => 'system_theme_settings', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-
-  // Theme configuration subtabs
-  $items[] = array('path' => 'admin/themes/settings/global', 'title' => t('global settings'),
-    'callback' => 'system_theme_settings', 'access' => $access,
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
-
-  foreach (list_themes() as $theme) {
-     $path = str_replace('/', '.', $theme->name);
-     $items[] = array('path' => 'admin/themes/settings/'. $path, 'title' => basename($theme->name),
-     'callback' => 'system_theme_settings', 'access' => $access,
-     'type' => MENU_LOCAL_TASK);
-  }
 
-  // Modules:
-  $items[] = array('path' => 'admin/settings', 'title' => t('settings'),
-    'callback' => 'system_site_settings', 'access' => $access);
-  foreach (module_list() as $name) {
-    if (module_hook($name, 'settings')) {
-      $items[] = array('path' => 'admin/settings/'. $name, 'title' => t($name));
+  if ($may_cache) {
+    $items[] = array('path' => 'system/files', 'title' => t('file download'),
+      'callback' => 'file_download',
+      'access' => TRUE,
+      'type' => MENU_CALLBACK);
+
+    $access = user_access('administer site configuration');
+
+    // Themes:
+    $items[] = array('path' => 'admin/themes', 'title' => t('themes'),
+      'callback' => 'system_themes', 'access' => $access);
+
+    $items[] = array('path' => 'admin/themes/select', 'title' => t('select'),
+      'callback' => 'system_themes', 'access' => $access,
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
+
+    $items[] = array('path' => 'admin/themes/settings', 'title' => t('configure'),
+      'callback' => 'system_theme_settings', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+
+    // Theme configuration subtabs
+    $items[] = array('path' => 'admin/themes/settings/global', 'title' => t('global settings'),
+      'callback' => 'system_theme_settings', 'access' => $access,
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
+
+    foreach (list_themes() as $theme) {
+       $theme_path = str_replace('/', '.', $theme->name);
+       $items[] = array('path' => 'admin/themes/settings/'. $theme_path, 'title' => basename($theme->name),
+       'callback' => 'system_theme_settings', 'access' => $access,
+       'type' => MENU_LOCAL_TASK);
+    }
+
+    // Modules:
+    $items[] = array('path' => 'admin/settings', 'title' => t('settings'),
+      'callback' => 'system_site_settings', 'access' => $access);
+    foreach (module_list() as $name) {
+      if (module_hook($name, 'settings')) {
+        $items[] = array('path' => 'admin/settings/'. $name, 'title' => t($name));
+      }
     }
+    $items[] = array('path' => 'admin/modules', 'title' => t('modules'),
+      'callback' => 'system_modules', 'access' => $access);
   }
-  $items[] = array('path' => 'admin/modules', 'title' => t('modules'),
-    'callback' => 'system_modules', 'access' => $access);
 
   return $items;
 }
@@ -502,6 +505,7 @@ function system_listing_save($edit = array()) {
     }
 
     cache_clear_all();
+    menu_rebuild();
 
     drupal_set_message(t('The configuration options have been saved.'));
     drupal_goto($_GET['q']);
@@ -536,6 +540,7 @@ function system_settings_save() {
   }
 
   cache_clear_all();
+  menu_rebuild();
   drupal_goto($_GET['q']);
 }
 
diff --git a/modules/system/system.module b/modules/system/system.module
index 4a1af86e1415..00ace7e1c003 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -59,49 +59,52 @@ function system_perm() {
 /**
  * Implementation of hook_menu().
  */
-function system_menu() {
+function system_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'system/files', 'title' => t('file download'),
-    'callback' => 'file_download',
-    'access' => TRUE,
-    'type' => MENU_CALLBACK);
-
-  $access = user_access('administer site configuration');
-
-  // Themes:
-  $items[] = array('path' => 'admin/themes', 'title' => t('themes'),
-    'callback' => 'system_themes', 'access' => $access);
-
-  $items[] = array('path' => 'admin/themes/select', 'title' => t('select'),
-    'callback' => 'system_themes', 'access' => $access,
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
-
-  $items[] = array('path' => 'admin/themes/settings', 'title' => t('configure'),
-    'callback' => 'system_theme_settings', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-
-  // Theme configuration subtabs
-  $items[] = array('path' => 'admin/themes/settings/global', 'title' => t('global settings'),
-    'callback' => 'system_theme_settings', 'access' => $access,
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
-
-  foreach (list_themes() as $theme) {
-     $path = str_replace('/', '.', $theme->name);
-     $items[] = array('path' => 'admin/themes/settings/'. $path, 'title' => basename($theme->name),
-     'callback' => 'system_theme_settings', 'access' => $access,
-     'type' => MENU_LOCAL_TASK);
-  }
 
-  // Modules:
-  $items[] = array('path' => 'admin/settings', 'title' => t('settings'),
-    'callback' => 'system_site_settings', 'access' => $access);
-  foreach (module_list() as $name) {
-    if (module_hook($name, 'settings')) {
-      $items[] = array('path' => 'admin/settings/'. $name, 'title' => t($name));
+  if ($may_cache) {
+    $items[] = array('path' => 'system/files', 'title' => t('file download'),
+      'callback' => 'file_download',
+      'access' => TRUE,
+      'type' => MENU_CALLBACK);
+
+    $access = user_access('administer site configuration');
+
+    // Themes:
+    $items[] = array('path' => 'admin/themes', 'title' => t('themes'),
+      'callback' => 'system_themes', 'access' => $access);
+
+    $items[] = array('path' => 'admin/themes/select', 'title' => t('select'),
+      'callback' => 'system_themes', 'access' => $access,
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
+
+    $items[] = array('path' => 'admin/themes/settings', 'title' => t('configure'),
+      'callback' => 'system_theme_settings', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+
+    // Theme configuration subtabs
+    $items[] = array('path' => 'admin/themes/settings/global', 'title' => t('global settings'),
+      'callback' => 'system_theme_settings', 'access' => $access,
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1);
+
+    foreach (list_themes() as $theme) {
+       $theme_path = str_replace('/', '.', $theme->name);
+       $items[] = array('path' => 'admin/themes/settings/'. $theme_path, 'title' => basename($theme->name),
+       'callback' => 'system_theme_settings', 'access' => $access,
+       'type' => MENU_LOCAL_TASK);
+    }
+
+    // Modules:
+    $items[] = array('path' => 'admin/settings', 'title' => t('settings'),
+      'callback' => 'system_site_settings', 'access' => $access);
+    foreach (module_list() as $name) {
+      if (module_hook($name, 'settings')) {
+        $items[] = array('path' => 'admin/settings/'. $name, 'title' => t($name));
+      }
     }
+    $items[] = array('path' => 'admin/modules', 'title' => t('modules'),
+      'callback' => 'system_modules', 'access' => $access);
   }
-  $items[] = array('path' => 'admin/modules', 'title' => t('modules'),
-    'callback' => 'system_modules', 'access' => $access);
 
   return $items;
 }
@@ -502,6 +505,7 @@ function system_listing_save($edit = array()) {
     }
 
     cache_clear_all();
+    menu_rebuild();
 
     drupal_set_message(t('The configuration options have been saved.'));
     drupal_goto($_GET['q']);
@@ -536,6 +540,7 @@ function system_settings_save() {
   }
 
   cache_clear_all();
+  menu_rebuild();
   drupal_goto($_GET['q']);
 }
 
diff --git a/modules/taxonomy.module b/modules/taxonomy.module
index 8754d5da3717..819194da4d0f 100644
--- a/modules/taxonomy.module
+++ b/modules/taxonomy.module
@@ -47,22 +47,26 @@ function taxonomy_link($type, $node = NULL) {
 /**
  * Implementation of hook_menu().
  */
-function taxonomy_menu() {
+function taxonomy_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/taxonomy', 'title' => t('categories'),
-    'callback' => 'taxonomy_admin',
-    'access' => user_access('administer taxonomy'));
-  $items[] = array('path' => 'admin/taxonomy/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/taxonomy/add/vocabulary', 'title' => t('add vocabulary'),
-    'callback' => 'taxonomy_admin',
-    'access' => user_access('administer taxonomy'),
-    'type' => MENU_LOCAL_TASK);
-
-  $items[] = array('path' => 'taxonomy/term', 'title' => t('taxonomy term'),
-    'callback' => 'taxonomy_term_page',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/taxonomy', 'title' => t('categories'),
+      'callback' => 'taxonomy_admin',
+      'access' => user_access('administer taxonomy'));
+    $items[] = array('path' => 'admin/taxonomy/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/taxonomy/add/vocabulary', 'title' => t('add vocabulary'),
+      'callback' => 'taxonomy_admin',
+      'access' => user_access('administer taxonomy'),
+      'type' => MENU_LOCAL_TASK);
+
+    $items[] = array('path' => 'taxonomy/term', 'title' => t('taxonomy term'),
+      'callback' => 'taxonomy_term_page',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+  }
+
   return $items;
 }
 
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index 8754d5da3717..819194da4d0f 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -47,22 +47,26 @@ function taxonomy_link($type, $node = NULL) {
 /**
  * Implementation of hook_menu().
  */
-function taxonomy_menu() {
+function taxonomy_menu($may_cache) {
   $items = array();
-  $items[] = array('path' => 'admin/taxonomy', 'title' => t('categories'),
-    'callback' => 'taxonomy_admin',
-    'access' => user_access('administer taxonomy'));
-  $items[] = array('path' => 'admin/taxonomy/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/taxonomy/add/vocabulary', 'title' => t('add vocabulary'),
-    'callback' => 'taxonomy_admin',
-    'access' => user_access('administer taxonomy'),
-    'type' => MENU_LOCAL_TASK);
-
-  $items[] = array('path' => 'taxonomy/term', 'title' => t('taxonomy term'),
-    'callback' => 'taxonomy_term_page',
-    'access' => user_access('access content'),
-    'type' => MENU_CALLBACK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/taxonomy', 'title' => t('categories'),
+      'callback' => 'taxonomy_admin',
+      'access' => user_access('administer taxonomy'));
+    $items[] = array('path' => 'admin/taxonomy/list', 'title' => t('list'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/taxonomy/add/vocabulary', 'title' => t('add vocabulary'),
+      'callback' => 'taxonomy_admin',
+      'access' => user_access('administer taxonomy'),
+      'type' => MENU_LOCAL_TASK);
+
+    $items[] = array('path' => 'taxonomy/term', 'title' => t('taxonomy term'),
+      'callback' => 'taxonomy_term_page',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+  }
+
   return $items;
 }
 
diff --git a/modules/tracker.module b/modules/tracker.module
index ef406194fbb7..24951d50e7de 100644
--- a/modules/tracker.module
+++ b/modules/tracker.module
@@ -21,20 +21,21 @@ function tracker_help($section) {
 /**
  * Implementation of hook_menu().
  */
-function tracker_menu() {
+function tracker_menu($may_cache) {
   global $user;
-
   $items = array();
-  $items[] = array('path' => 'tracker', 'title' => t('recent posts'),
-    'callback' => 'tracker_page', 'access' => user_access('access content'),
-    'weight' => 1);
-
-  // Tabs:
-  if ($user->uid) {
-    $items[] = array('path' => 'tracker/all', 'title' => t('all recent posts'),
-      'type' => MENU_DEFAULT_LOCAL_TASK);
-    $items[] = array('path' => "tracker/$user->uid", 'title' => t('my recent posts'),
-      'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'tracker', 'title' => t('recent posts'),
+      'callback' => 'tracker_page', 'access' => user_access('access content'),
+      'weight' => 1);
+
+    if ($user->uid) {
+      $items[] = array('path' => 'tracker/all', 'title' => t('all recent posts'),
+        'type' => MENU_DEFAULT_LOCAL_TASK);
+      $items[] = array('path' => 'tracker/'. $user->uid, 'title' => t('my recent posts'),
+        'type' => MENU_LOCAL_TASK);
+    }
   }
 
   return $items;
diff --git a/modules/tracker/tracker.module b/modules/tracker/tracker.module
index ef406194fbb7..24951d50e7de 100644
--- a/modules/tracker/tracker.module
+++ b/modules/tracker/tracker.module
@@ -21,20 +21,21 @@ function tracker_help($section) {
 /**
  * Implementation of hook_menu().
  */
-function tracker_menu() {
+function tracker_menu($may_cache) {
   global $user;
-
   $items = array();
-  $items[] = array('path' => 'tracker', 'title' => t('recent posts'),
-    'callback' => 'tracker_page', 'access' => user_access('access content'),
-    'weight' => 1);
-
-  // Tabs:
-  if ($user->uid) {
-    $items[] = array('path' => 'tracker/all', 'title' => t('all recent posts'),
-      'type' => MENU_DEFAULT_LOCAL_TASK);
-    $items[] = array('path' => "tracker/$user->uid", 'title' => t('my recent posts'),
-      'type' => MENU_LOCAL_TASK);
+
+  if ($may_cache) {
+    $items[] = array('path' => 'tracker', 'title' => t('recent posts'),
+      'callback' => 'tracker_page', 'access' => user_access('access content'),
+      'weight' => 1);
+
+    if ($user->uid) {
+      $items[] = array('path' => 'tracker/all', 'title' => t('all recent posts'),
+        'type' => MENU_DEFAULT_LOCAL_TASK);
+      $items[] = array('path' => 'tracker/'. $user->uid, 'title' => t('my recent posts'),
+        'type' => MENU_LOCAL_TASK);
+    }
   }
 
   return $items;
diff --git a/modules/upload.module b/modules/upload.module
index e9cd1e8c937e..0d1092ba6a4b 100644
--- a/modules/upload.module
+++ b/modules/upload.module
@@ -21,27 +21,31 @@ function upload_perm() {
   return array('upload files');
 }
 
-function upload_menu() {
-  // Add handlers for previewing new uploads.
-  if ($_SESSION['file_uploads']) {
-    $items = array();
-    foreach ($_SESSION['file_uploads'] as $key => $file) {
-      $filename = file_create_filename($file->filename, file_create_path());
-      $items[] = array(
-        'path' => $filename, 'title' => t('file download'),
-        'callback' => 'upload_download',
-        'access' => true,
-        'type' => MENU_DYNAMIC_ITEM & MENU_HIDDEN
-      );
-      $_SESSION['file_uploads'][$key]->_filename = $filename;
+function upload_menu($may_cache) {
+  $items = array();
+
+  if ($may_cache) {
+    // Add handlers for previewing new uploads.
+    if ($_SESSION['file_uploads']) {
+      foreach ($_SESSION['file_uploads'] as $key => $file) {
+        $filename = file_create_filename($file->filename, file_create_path());
+        $items[] = array(
+          'path' => $filename, 'title' => t('file download'),
+          'callback' => 'upload_download',
+          'access' => true,
+          'type' => MENU_DYNAMIC_ITEM & MENU_HIDDEN
+        );
+        $_SESSION['file_uploads'][$key]->_filename = $filename;
+      }
     }
+    $items[] = array(
+      'path' => 'admin/upload', 'title' => t('uploads'),
+      'callback' => 'upload_admin',
+      'access' => user_access('access administration pages'),
+      'type' => MENU_NORMAL_ITEM
+    );
   }
-  $items[] = array(
-    'path' => 'admin/upload', 'title' => t('uploads'),
-    'callback' => 'upload_admin',
-    'access' => user_access('access administration pages'),
-    'type' => MENU_NORMAL_ITEM
-  );
+
   return $items;
 }
 
diff --git a/modules/upload/upload.module b/modules/upload/upload.module
index e9cd1e8c937e..0d1092ba6a4b 100644
--- a/modules/upload/upload.module
+++ b/modules/upload/upload.module
@@ -21,27 +21,31 @@ function upload_perm() {
   return array('upload files');
 }
 
-function upload_menu() {
-  // Add handlers for previewing new uploads.
-  if ($_SESSION['file_uploads']) {
-    $items = array();
-    foreach ($_SESSION['file_uploads'] as $key => $file) {
-      $filename = file_create_filename($file->filename, file_create_path());
-      $items[] = array(
-        'path' => $filename, 'title' => t('file download'),
-        'callback' => 'upload_download',
-        'access' => true,
-        'type' => MENU_DYNAMIC_ITEM & MENU_HIDDEN
-      );
-      $_SESSION['file_uploads'][$key]->_filename = $filename;
+function upload_menu($may_cache) {
+  $items = array();
+
+  if ($may_cache) {
+    // Add handlers for previewing new uploads.
+    if ($_SESSION['file_uploads']) {
+      foreach ($_SESSION['file_uploads'] as $key => $file) {
+        $filename = file_create_filename($file->filename, file_create_path());
+        $items[] = array(
+          'path' => $filename, 'title' => t('file download'),
+          'callback' => 'upload_download',
+          'access' => true,
+          'type' => MENU_DYNAMIC_ITEM & MENU_HIDDEN
+        );
+        $_SESSION['file_uploads'][$key]->_filename = $filename;
+      }
     }
+    $items[] = array(
+      'path' => 'admin/upload', 'title' => t('uploads'),
+      'callback' => 'upload_admin',
+      'access' => user_access('access administration pages'),
+      'type' => MENU_NORMAL_ITEM
+    );
   }
-  $items[] = array(
-    'path' => 'admin/upload', 'title' => t('uploads'),
-    'callback' => 'upload_admin',
-    'access' => user_access('access administration pages'),
-    'type' => MENU_NORMAL_ITEM
-  );
+
   return $items;
 }
 
diff --git a/modules/user.module b/modules/user.module
index a2fd76ca8c87..f919cb0b8c36 100644
--- a/modules/user.module
+++ b/modules/user.module
@@ -585,88 +585,91 @@ function theme_user_list($items, $title = NULL) {
 /**
  * Implementation of hook_menu().
  */
-function user_menu() {
+function user_menu($may_cache) {
   global $user;
 
   $items = array();
 
   $access = user_access('administer users');
 
-  if (arg(0) == 'user' && is_numeric(arg(1))) {
-    $items[] = array('path' => 'user/'. arg(1), 'title' => t('user'),
-      'type' => MENU_CALLBACK, 'callback' => 'user_page', 'access' => TRUE);
-    $items[] = array('path' => 'user/'. arg(1) .'/view', 'title' => t('view'),
+  if ($may_cache) {
+    $items[] = array('path' => 'user', 'title' => t('user'),
+      'callback' => 'user_page', 'access' => TRUE,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'user/login', 'title' => t('log in'),
+      'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'user/register', 'title' => t('register'),
+      'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'user/password', 'title' => t('request new password'),
+      'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'admin/user', 'title' => t('users'),
+      'callback' => 'user_admin', 'access' => $access);
+    $items[] = array('path' => 'admin/user/list', 'title' => t('list'),
       'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-    $items[] = array('path' => 'user/'. arg(1) .'/edit', 'title' => t('edit'),
-      'callback' => 'user_edit', 'access' => $access || $user->uid == arg(1),
+    $items[] = array('path' => 'admin/user/create', 'title' => t('add'),
+      'callback' => 'user_admin', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure', 'title' => t('configure'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/settings', 'title' => t('settings'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/user/configure/access', 'title' => t('access rules'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/access/mail', 'title' => t('e-mail rules'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/access/user', 'title' => t('name rules'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/role', 'title' => t('roles'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/permission', 'title' => t('permissions'),
+      'callback' => 'user_configure', 'access' => $access,
       'type' => MENU_LOCAL_TASK);
 
-    if (arg(2) == 'edit') {
-      if (($categories = _user_categories()) && (count($categories) > 1)) {
-        foreach ($categories as $key => $category) {
-          $items[] = array('path' => 'user/'. arg(1) .'/edit/'. $category['name'], 'title' => $category['title'],
-            'type' => $category['name'] == 'account' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
-            'weight' => $category['weight']);
-        }
-      }
+    if (module_exist('search')) {
+      $items[] = array('path' => 'admin/user/search', 'title' => t('search'),
+        'callback' => 'user_admin', 'access' => $access,
+        'type' => MENU_LOCAL_TASK);
     }
-  }
 
-  if ($user->uid) {
-    $items[] = array('path' => "user/$user->uid", 'title' => t('my account'),
-      'callback' => 'user_page', 'access' => TRUE);
-    $items[] = array('path' => 'logout', 'title' => t('log out'),
-      'access' => TRUE,
-      'callback' => 'user_logout',
-      'weight' => 10);
+    if ($user->uid) {
+      $items[] = array('path' => 'user/'. $user->uid, 'title' => t('my account'),
+        'callback' => 'user_page', 'access' => TRUE);
+      $items[] = array('path' => 'logout', 'title' => t('log out'),
+        'access' => TRUE,
+        'callback' => 'user_logout',
+        'weight' => 10);
+    }
+    else {
+      $items[] = array('path' => 'logout', 'title' => t('log out'),
+        'callback' => 'user_logout', 'access' => FALSE);
+    }
   }
   else {
-    $items[] = array('path' => 'logout', 'title' => t('log out'),
-      'callback' => 'user_logout', 'access' => FALSE);
-  }
-
-  $items[] = array('path' => 'user', 'title' => t('user'),
-    'callback' => 'user_page', 'access' => TRUE,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'user/login', 'title' => t('log in'),
-    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'user/register', 'title' => t('register'),
-    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'user/password', 'title' => t('request new password'),
-    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'admin/user', 'title' => t('users'),
-    'callback' => 'user_admin', 'access' => $access);
-  $items[] = array('path' => 'admin/user/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/user/create', 'title' => t('add'),
-    'callback' => 'user_admin', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure', 'title' => t('configure'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/settings', 'title' => t('settings'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/user/configure/access', 'title' => t('access rules'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/access/mail', 'title' => t('e-mail rules'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/access/user', 'title' => t('name rules'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/role', 'title' => t('roles'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/permission', 'title' => t('permissions'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-
-  if (module_exist('search')) {
-    $items[] = array('path' => 'admin/user/search', 'title' => t('search'),
-      'callback' => 'user_admin', 'access' => $access,
-      'type' => MENU_LOCAL_TASK);
+    if (arg(0) == 'user' && is_numeric(arg(1))) {
+      $items[] = array('path' => 'user/'. arg(1), 'title' => t('user'),
+        'type' => MENU_CALLBACK, 'callback' => 'user_page', 'access' => TRUE);
+      $items[] = array('path' => 'user/'. arg(1) .'/view', 'title' => t('view'),
+        'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+      $items[] = array('path' => 'user/'. arg(1) .'/edit', 'title' => t('edit'),
+        'callback' => 'user_edit', 'access' => $access || $user->uid == arg(1),
+        'type' => MENU_LOCAL_TASK);
+
+      if (arg(2) == 'edit') {
+        if (($categories = _user_categories()) && (count($categories) > 1)) {
+          foreach ($categories as $key => $category) {
+            $items[] = array('path' => 'user/'. arg(1) .'/edit/'. $category['name'], 'title' => $category['title'],
+              'type' => $category['name'] == 'account' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+              'weight' => $category['weight']);
+          }
+        }
+      }
+    }
   }
 
   return $items;
@@ -1385,6 +1388,7 @@ function user_admin_perm($edit = array()) {
     // Clear the cache, as we might have changed the anonymous user's
     // permissions.
     cache_clear_all();
+    menu_rebuild();
   }
 
   // Compile permission array:
diff --git a/modules/user/user.module b/modules/user/user.module
index a2fd76ca8c87..f919cb0b8c36 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -585,88 +585,91 @@ function theme_user_list($items, $title = NULL) {
 /**
  * Implementation of hook_menu().
  */
-function user_menu() {
+function user_menu($may_cache) {
   global $user;
 
   $items = array();
 
   $access = user_access('administer users');
 
-  if (arg(0) == 'user' && is_numeric(arg(1))) {
-    $items[] = array('path' => 'user/'. arg(1), 'title' => t('user'),
-      'type' => MENU_CALLBACK, 'callback' => 'user_page', 'access' => TRUE);
-    $items[] = array('path' => 'user/'. arg(1) .'/view', 'title' => t('view'),
+  if ($may_cache) {
+    $items[] = array('path' => 'user', 'title' => t('user'),
+      'callback' => 'user_page', 'access' => TRUE,
+      'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'user/login', 'title' => t('log in'),
+      'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'user/register', 'title' => t('register'),
+      'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'user/password', 'title' => t('request new password'),
+      'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+
+    $items[] = array('path' => 'admin/user', 'title' => t('users'),
+      'callback' => 'user_admin', 'access' => $access);
+    $items[] = array('path' => 'admin/user/list', 'title' => t('list'),
       'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-    $items[] = array('path' => 'user/'. arg(1) .'/edit', 'title' => t('edit'),
-      'callback' => 'user_edit', 'access' => $access || $user->uid == arg(1),
+    $items[] = array('path' => 'admin/user/create', 'title' => t('add'),
+      'callback' => 'user_admin', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure', 'title' => t('configure'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/settings', 'title' => t('settings'),
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/user/configure/access', 'title' => t('access rules'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/access/mail', 'title' => t('e-mail rules'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/access/user', 'title' => t('name rules'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/role', 'title' => t('roles'),
+      'callback' => 'user_configure', 'access' => $access,
+      'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/user/configure/permission', 'title' => t('permissions'),
+      'callback' => 'user_configure', 'access' => $access,
       'type' => MENU_LOCAL_TASK);
 
-    if (arg(2) == 'edit') {
-      if (($categories = _user_categories()) && (count($categories) > 1)) {
-        foreach ($categories as $key => $category) {
-          $items[] = array('path' => 'user/'. arg(1) .'/edit/'. $category['name'], 'title' => $category['title'],
-            'type' => $category['name'] == 'account' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
-            'weight' => $category['weight']);
-        }
-      }
+    if (module_exist('search')) {
+      $items[] = array('path' => 'admin/user/search', 'title' => t('search'),
+        'callback' => 'user_admin', 'access' => $access,
+        'type' => MENU_LOCAL_TASK);
     }
-  }
 
-  if ($user->uid) {
-    $items[] = array('path' => "user/$user->uid", 'title' => t('my account'),
-      'callback' => 'user_page', 'access' => TRUE);
-    $items[] = array('path' => 'logout', 'title' => t('log out'),
-      'access' => TRUE,
-      'callback' => 'user_logout',
-      'weight' => 10);
+    if ($user->uid) {
+      $items[] = array('path' => 'user/'. $user->uid, 'title' => t('my account'),
+        'callback' => 'user_page', 'access' => TRUE);
+      $items[] = array('path' => 'logout', 'title' => t('log out'),
+        'access' => TRUE,
+        'callback' => 'user_logout',
+        'weight' => 10);
+    }
+    else {
+      $items[] = array('path' => 'logout', 'title' => t('log out'),
+        'callback' => 'user_logout', 'access' => FALSE);
+    }
   }
   else {
-    $items[] = array('path' => 'logout', 'title' => t('log out'),
-      'callback' => 'user_logout', 'access' => FALSE);
-  }
-
-  $items[] = array('path' => 'user', 'title' => t('user'),
-    'callback' => 'user_page', 'access' => TRUE,
-    'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'user/login', 'title' => t('log in'),
-    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'user/register', 'title' => t('register'),
-    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
-  $items[] = array('path' => 'user/password', 'title' => t('request new password'),
-    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
-
-  $items[] = array('path' => 'admin/user', 'title' => t('users'),
-    'callback' => 'user_admin', 'access' => $access);
-  $items[] = array('path' => 'admin/user/list', 'title' => t('list'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/user/create', 'title' => t('add'),
-    'callback' => 'user_admin', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure', 'title' => t('configure'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/settings', 'title' => t('settings'),
-    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
-  $items[] = array('path' => 'admin/user/configure/access', 'title' => t('access rules'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/access/mail', 'title' => t('e-mail rules'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/access/user', 'title' => t('name rules'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/role', 'title' => t('roles'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-  $items[] = array('path' => 'admin/user/configure/permission', 'title' => t('permissions'),
-    'callback' => 'user_configure', 'access' => $access,
-    'type' => MENU_LOCAL_TASK);
-
-  if (module_exist('search')) {
-    $items[] = array('path' => 'admin/user/search', 'title' => t('search'),
-      'callback' => 'user_admin', 'access' => $access,
-      'type' => MENU_LOCAL_TASK);
+    if (arg(0) == 'user' && is_numeric(arg(1))) {
+      $items[] = array('path' => 'user/'. arg(1), 'title' => t('user'),
+        'type' => MENU_CALLBACK, 'callback' => 'user_page', 'access' => TRUE);
+      $items[] = array('path' => 'user/'. arg(1) .'/view', 'title' => t('view'),
+        'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+      $items[] = array('path' => 'user/'. arg(1) .'/edit', 'title' => t('edit'),
+        'callback' => 'user_edit', 'access' => $access || $user->uid == arg(1),
+        'type' => MENU_LOCAL_TASK);
+
+      if (arg(2) == 'edit') {
+        if (($categories = _user_categories()) && (count($categories) > 1)) {
+          foreach ($categories as $key => $category) {
+            $items[] = array('path' => 'user/'. arg(1) .'/edit/'. $category['name'], 'title' => $category['title'],
+              'type' => $category['name'] == 'account' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+              'weight' => $category['weight']);
+          }
+        }
+      }
+    }
   }
 
   return $items;
@@ -1385,6 +1388,7 @@ function user_admin_perm($edit = array()) {
     // Clear the cache, as we might have changed the anonymous user's
     // permissions.
     cache_clear_all();
+    menu_rebuild();
   }
 
   // Compile permission array:
diff --git a/modules/watchdog.module b/modules/watchdog.module
index 9be7a45f72e5..31e305242880 100644
--- a/modules/watchdog.module
+++ b/modules/watchdog.module
@@ -43,17 +43,17 @@ function watchdog_help($section = 'admin/help#watchdog') {
 /**
  * Implementation of hook_menu().
  */
-function watchdog_menu() {
+function watchdog_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'admin/logs', 'title' => t('logs'),
-    'callback' => 'watchdog_overview', 'access' => user_access('administer watchdog'));
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/logs', 'title' => t('logs'),
+      'callback' => 'watchdog_overview', 'access' => user_access('administer watchdog'));
 
-  $items[] = array('path' => 'admin/logs/view', 'title' => t('view details'),
-    'callback' => 'watchdog_view', 'access' => user_access('administer watchdog'),
-    'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/logs/view', 'title' => t('view details'),
+      'callback' => 'watchdog_view', 'access' => user_access('administer watchdog'),
+      'type' => MENU_CALLBACK);
 
-  if (arg(1) == 'logs') {
     foreach (_watchdog_get_message_types() as $type) {
       $items[] = array('path' => 'admin/logs/'. $type, 'title' => t($type), 'type' => MENU_DYNAMIC_ITEM);
     }
@@ -105,7 +105,7 @@ function watchdog_overview($type = '') {
         l(t('details'), "admin/logs/view/$watchdog->wid")
       ),
       // Attributes for tr
-      'class' => "watchdog-$watchdog->type"      
+      'class' => "watchdog-$watchdog->type"
     );
   }
 
diff --git a/modules/watchdog/watchdog.module b/modules/watchdog/watchdog.module
index 9be7a45f72e5..31e305242880 100644
--- a/modules/watchdog/watchdog.module
+++ b/modules/watchdog/watchdog.module
@@ -43,17 +43,17 @@ function watchdog_help($section = 'admin/help#watchdog') {
 /**
  * Implementation of hook_menu().
  */
-function watchdog_menu() {
+function watchdog_menu($may_cache) {
   $items = array();
 
-  $items[] = array('path' => 'admin/logs', 'title' => t('logs'),
-    'callback' => 'watchdog_overview', 'access' => user_access('administer watchdog'));
+  if ($may_cache) {
+    $items[] = array('path' => 'admin/logs', 'title' => t('logs'),
+      'callback' => 'watchdog_overview', 'access' => user_access('administer watchdog'));
 
-  $items[] = array('path' => 'admin/logs/view', 'title' => t('view details'),
-    'callback' => 'watchdog_view', 'access' => user_access('administer watchdog'),
-    'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'admin/logs/view', 'title' => t('view details'),
+      'callback' => 'watchdog_view', 'access' => user_access('administer watchdog'),
+      'type' => MENU_CALLBACK);
 
-  if (arg(1) == 'logs') {
     foreach (_watchdog_get_message_types() as $type) {
       $items[] = array('path' => 'admin/logs/'. $type, 'title' => t($type), 'type' => MENU_DYNAMIC_ITEM);
     }
@@ -105,7 +105,7 @@ function watchdog_overview($type = '') {
         l(t('details'), "admin/logs/view/$watchdog->wid")
       ),
       // Attributes for tr
-      'class' => "watchdog-$watchdog->type"      
+      'class' => "watchdog-$watchdog->type"
     );
   }
 
-- 
GitLab