=== modified file 'includes/menu.inc'
--- includes/menu.inc	2007-03-19 01:13:28 +0000
+++ includes/menu.inc	2007-03-25 22:54:36 +0000
@@ -414,7 +414,14 @@ function _menu_translate(&$item, $map, $
  */
 function menu_tree() {
   if ($item = menu_get_item()) {
-    list(, $menu) = _menu_tree(db_query('SELECT * FROM {menu} WHERE pid IN ('. $item->parents .') AND visible = 1 ORDER BY mleft'));
+    if (!$item->access) {
+      $trail = array_reverse($item->active_trail);
+      while ($trail && !$item->access) {
+        $item = array_pop($trail);
+      }
+    }
+    $parents = $item->access ? $item->parents : 0;
+    list(, $menu) = _menu_tree(db_query('SELECT * FROM {menu} WHERE pid IN ('. $parents .') AND visible = 1 ORDER BY mleft'));
     return $menu;
   }
 }
@@ -523,7 +530,7 @@ function menu_get_active_help() {
   $output = '';
   $item = menu_get_item();
 
-  if (!$item->access) {
+  if (!$item || !$item->access) {
     // Don't return help text for areas the user cannot access.
     return;
   }
@@ -691,11 +698,11 @@ function menu_rebuild() {
         // has this callback. When found, its callback argument will also be
         // copied but only if there is none in the current item.
 
-        // Because access is checked for each parent as well, we only inherit
-        // if arguments were given without a callback. Otherwise the inherited
-        // check would be identical to that of the parent.
+        // Because access is checked for each visible parent as well, we only
+        // inherit if arguments were given without a callback. Otherwise the
+        // inherited check would be identical to that of the parent.
         if (!isset($item['access callback']) && isset($parent['access callback']) && !isset($parent['access inherited'])) {
-          if (isset($item['access arguments'])) {
+          if (isset($item['access arguments']) || !$parent['_visible']) {
             $item['access callback'] = $parent['access callback'];
           }
           else {
@@ -830,6 +837,9 @@ function menu_local_tasks($level = 0) {
   static $tabs = array(), $parents = array(), $parents_done = array();
   if (empty($tabs)) {
     $router_item = menu_get_item();
+    if (!$router_item || !$router_item->access) {
+      return array();
+    }
     $map = arg(NULL);
     do {
       // Tabs are router items that have the same parent. If there is a new
@@ -902,8 +912,10 @@ function menu_set_location() {
 function menu_get_active_breadcrumb() {
   $breadcrumb = array(l(t('Home'), ''));
   $item = menu_get_item();
-  foreach ($item->active_trail as $parent) {
-    $breadcrumb[] = l($parent->title, $parent->link_path, (array)$parent);
+  if (!empty($item->active_trail)) {
+    foreach ($item->active_trail as $parent) {
+      $breadcrumb[] = l($parent->title, $parent->link_path, (array)$parent);
+    }
   }
   return $breadcrumb;
 }

