Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.654
diff -u -p -r1.654 system.module
--- modules/system/system.module	28 Dec 2008 19:11:31 -0000	1.654
+++ modules/system/system.module	31 Dec 2008 00:36:28 -0000
@@ -425,7 +425,8 @@ function system_menu() {
     '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
@@ -435,7 +436,8 @@ function system_menu() {
     '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',
@@ -443,7 +445,8 @@ function system_menu() {
     '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'),
   );
   $items['admin/settings/admin'] = array(
     'title' => 'Administration theme',
@@ -667,7 +670,8 @@ function system_menu() {
     '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',
   );
@@ -727,6 +731,25 @@ function _system_themes_access($theme) {
 }
 
 /**
+ * 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() {
@@ -895,10 +918,14 @@ function system_block_view($delta = '') 
  *   The menu item to be displayed.
  */
 function system_admin_menu_block($item) {
-  $content = array();
+  static $cache;
   if (!isset($item['mlid'])) {
     $item += db_fetch_array(db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = '%s' AND module = 'system'", $item['path']));
   }
+  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
@@ -919,6 +946,7 @@ function system_admin_menu_block($item) 
     $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.33
diff -u -p -r1.33 system.test
--- modules/system/system.test	30 Dec 2008 16:43:19 -0000	1.33
+++ modules/system/system.test	31 Dec 2008 01:37:09 -0000
@@ -289,10 +289,10 @@ class CronRunTestCase extends DrupalWebT
   }
 }
 
+/**
+ * Test administration pages and categories.
+ */
 class AdminOverviewTestCase extends DrupalWebTestCase {
-  /**
-   * Implementation of getInfo().
-   */
   function getInfo() {
     return array(
       'name' => t('Admin overview'),
@@ -354,6 +354,26 @@ class AdminOverviewTestCase extends Drup
       $this->assertFalse($extra, t('No extra panels found.'));
     }
   }
+
+  /**
+   * Test administrative menu categories.
+   */
+  function testHideEmptyCategories() {
+    $user = $this->drupalCreateUser(array('administer nodes', 'access administration pages'));
+    $this->drupalLogin($user);
+
+    $this->drupalGet('admin');
+
+    // Assert that menu items with children are displayed.
+    $this->assertLink(t('Administer'));
+    $this->assertLink(t('Content management'));
+
+    // Assert that 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 {
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.951
diff -u -p -r1.951 user.module
--- modules/user/user.module	30 Dec 2008 16:43:20 -0000	1.951
+++ modules/user/user.module	31 Dec 2008 00:48:04 -0000
@@ -1015,7 +1015,8 @@ function user_menu() {
     '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',
