Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.47
diff -u -r1.47 simpletest.module
--- modules/simpletest/simpletest.module	25 May 2009 05:20:16 -0000	1.47
+++ modules/simpletest/simpletest.module	26 May 2009 15:32:37 -0000
@@ -31,7 +31,8 @@
     'position' => 'right',
     'weight' => -7,
     'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
+    'access callback' => 'system_admin_menu_block_access',
+    'access arguments' => array('admin/content', 'access administration pages'),
   );
   $items['admin/development/testing'] = array(
     'title' => 'Testing',
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.993
diff -u -r1.993 user.module
--- modules/user/user.module	25 May 2009 13:42:56 -0000	1.993
+++ modules/user/user.module	26 May 2009 15:32:38 -0000
@@ -1335,7 +1335,8 @@
     'description' => "Manage your site's users, groups and access to site features.",
     'position' => 'left',
     'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
+    'access callback' => 'system_admin_menu_block_access',
+    'access arguments' => array('admin/user', 'access administration pages'),
   );
   $items['admin/user/user'] = array(
     'title' => 'Users',
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.700
diff -u -r1.700 system.module
--- modules/system/system.module	26 May 2009 09:12:29 -0000	1.700
+++ modules/system/system.module	26 May 2009 15:32:37 -0000
@@ -493,7 +493,8 @@
     'position' => 'left',
     'weight' => -10,
     'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
+    'access callback' => 'system_admin_menu_block_access',
+    'access arguments' => array('admin/content', 'access administration pages'),
   );
 
   // Menu items that are basically just menu blocks.
@@ -503,7 +504,8 @@
     'position' => 'right',
     'weight' => -5,
     'page callback' => 'system_settings_overview',
-    'access arguments' => array('access administration pages'),
+    'access callback' => 'system_admin_menu_block_access',
+    'access arguments' => array('admin/settings', 'access administration pages'),
   );
   $items['admin/build'] = array(
     'title' => 'Site building',
@@ -511,7 +513,8 @@
     'position' => 'right',
     'weight' => -10,
     'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
+    'access callback' => 'system_admin_menu_block_access',
+    'access arguments' => array('admin/build', 'access administration pages'),
   );
   // Themes.
   $items['admin/build/themes'] = array(
@@ -726,7 +729,8 @@
     'title' => 'Reports',
     'description' => 'View reports from system logs and other status information.',
     'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access site reports'),
+    'access callback' => 'system_admin_menu_block_access',
+    'access arguments' => array('admin/reports', 'access site reports'),
     'weight' => 5,
     'position' => 'left',
   );
@@ -779,6 +783,25 @@
 }
 
 /**
+ * Menu item access callback - hides empty system settings overview pages.
+ *
+ * @param $path
+ *   The path of the menu item to check for child menu entries.
+ * @param $string
+ *   The permission, such as "administer nodes", being checked for.
+ * @return
+ *   Boolean TRUE if the current user has the requested permission and the
+ *   current menu item has children.
+ */
+function system_admin_menu_block_access($path, $permission) {
+  if (!user_access($permission)) {
+    return FALSE;
+  }
+  $content = system_admin_menu_block(array('path' => $path));
+  return !empty($content);
+}
+
+/**
  * Implementation of hook_init().
  */
 function system_init() {
@@ -987,10 +1010,14 @@
  *   The menu item to be displayed.
  */
 function system_admin_menu_block($item) {
-  $content = array();
+  $cache = &drupal_static(__FUNCTION__, array());
   if (!isset($item['mlid'])) {
     $item += db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = :path AND module = 'system'", array(':path' => $item['path']))->fetchAssoc();
   }
+  else if (isset($cache[$item['mlid']])) {
+    return $cache[$item['mlid']];
+  }
+  $content = array();
   $result = db_query("
     SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, m.description, ml.*
     FROM {menu_links} ml
@@ -1011,6 +1038,7 @@
     $content[(50000 + $item['weight']) . ' ' . $item['title'] . ' ' . $item['mlid']] = $item;
   }
   ksort($content);
+  $cache[$item['mlid']] = $content;
   return $content;
 }
 
Index: modules/system/system.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.test,v
retrieving revision 1.44
diff -u -r1.44 system.test
--- modules/system/system.test	24 May 2009 17:39:34 -0000	1.44
+++ modules/system/system.test	26 May 2009 15:32:37 -0000
@@ -370,6 +370,10 @@
   }
 }
 
+
+/**
+ * Test administration pages and categories.
+ */
 class AdminOverviewTestCase extends DrupalWebTestCase {
   /**
    * Implementation of getInfo().
@@ -435,6 +439,26 @@
       $this->assertFalse($extra, t('No extra panels found.'));
     }
   }
+
+  /**
+   * Test administrative menu categories.
+   */
+  public function testHideEmptyCategories() {
+    $user = $this->drupalCreateUser(array('administer nodes', 'access administration pages'));
+    $this->drupalLogin($user);
+
+    $this->drupalGet('admin');
+
+    // Make sure menu items with children are displayed.
+    $this->assertLink(t('Administer'));
+    $this->assertLink(t('Content management'));
+
+    // Make sure menu items without children are hidden.
+    $this->assertNoLink(t('Site building'));
+    $this->assertNoLink(t('Site configuration'));
+    $this->assertNoLink(t('User management'));
+    $this->assertNoLink(t('Reports'));
+  }
 }
 
 class AdminMetaTagTestCase extends DrupalWebTestCase {
