Index: install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.113.2.6
diff -u -p -r1.113.2.6 install.php
--- install.php	17 Sep 2008 08:47:04 -0000	1.113.2.6
+++ install.php	26 Sep 2008 21:33:51 -0000
@@ -645,7 +645,7 @@ function install_tasks($profile, $task) 
   // Install profile modules.
   if ($task == 'profile-install') {
     $modules = variable_get('install_profile_modules', array());
-    $files = module_rebuild_cache();
+    $files = system_get_module_data();
     variable_del('install_profile_modules');
     $operations = array();
     foreach ($modules as $module) {
Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.252
diff -u -p -r1.252 update.php
--- update.php	3 Feb 2008 18:41:16 -0000	1.252
+++ update.php	26 Sep 2008 21:33:51 -0000
@@ -448,8 +448,8 @@ function update_check_incompatibility($n
 
   // Store values of expensive functions for future use.
   if (empty($themes) || empty($modules)) {
-    $themes = system_theme_data();
-    $modules = module_rebuild_cache();
+    $themes = system_get_theme_data();
+    $modules = system_get_module_data();
   }
 
   if ($type == 'module' && isset($modules[$name])) {
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.756.2.26
diff -u -p -r1.756.2.26 common.inc
--- includes/common.inc	23 Sep 2008 10:01:15 -0000	1.756.2.26
+++ includes/common.inc	2 Oct 2008 03:49:05 -0000
@@ -3537,7 +3537,7 @@ function drupal_flush_all_caches() {
 
   drupal_clear_css_cache();
   drupal_clear_js_cache();
-  system_theme_data();
+  system_get_theme_data();
   drupal_rebuild_theme_registry();
   menu_rebuild();
   node_types_rebuild();
Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.56.2.3
diff -u -p -r1.56.2.3 install.inc
--- includes/install.inc	14 Aug 2008 09:26:43 -0000	1.56.2.3
+++ includes/install.inc	26 Sep 2008 21:33:51 -0000
@@ -309,7 +309,7 @@ function drupal_verify_profile($profile,
  *   The modules to install.
  */
 function drupal_install_modules($module_list = array()) {
-  $files = module_rebuild_cache();
+  $files = system_get_module_data();
   $module_list = array_flip(array_values($module_list));
   do {
     $moved = FALSE;
@@ -363,7 +363,7 @@ function drupal_install_system() {
   db_query("INSERT INTO {system} (filename, name, type, owner, status, throttle, bootstrap, schema_version) VALUES('%s', '%s', '%s', '%s', %d, %d, %d, %d)", $system_path .'/system.module', 'system', 'module', '', 1, 0, 0, $system_version);
   // Now that we've installed things properly, bootstrap the full Drupal environment
   drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-  module_rebuild_cache();
+  system_get_module_data();
 }
 
 
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.115
diff -u -p -r1.115 module.inc
--- includes/module.inc	27 Dec 2007 12:31:05 -0000	1.115
+++ includes/module.inc	2 Oct 2008 04:33:42 -0000
@@ -94,61 +94,22 @@ function module_list($refresh = FALSE, $
  *   The array of filesystem objects used to rebuild the cache.
  */
 function module_rebuild_cache() {
-  // Get current list of modules
-  $files = drupal_system_listing('\.module$', 'modules', 'name', 0);
-
-  // Extract current files from database.
-  system_get_files_database($files, 'module');
-
-  ksort($files);
-
-  // Set defaults for module info
-  $defaults = array(
-    'dependencies' => array(),
-    'dependents' => array(),
-    'description' => '',
-    'version' => NULL,
-    'php' => DRUPAL_MINIMUM_PHP,
-  );
-
-  foreach ($files as $filename => $file) {
-    // Look for the info file.
-    $file->info = drupal_parse_info_file(dirname($file->filename) .'/'. $file->name .'.info');
-
-    // Skip modules that don't provide info.
-    if (empty($file->info)) {
-      unset($files[$filename]);
-      continue;
-    }
-    // Merge in defaults and save.
-    $files[$filename]->info = $file->info + $defaults;
-
-    // Invoke hook_system_info_alter() to give installed modules a chance to
-    // modify the data in the .info files if necessary.
-    drupal_alter('system_info', $files[$filename]->info, $files[$filename]);
-
-    // Log the critical hooks implemented by this module.
-    $bootstrap = 0;
-    foreach (bootstrap_hooks() as $hook) {
-      if (module_hook($file->name, $hook)) {
-        $bootstrap = 1;
-        break;
-      }
-    }
+  return system_get_module_data();
+}
 
-    // Update the contents of the system table:
-    if (isset($file->status) || (isset($file->old_filename) && $file->old_filename != $file->filename)) {
-      db_query("UPDATE {system} SET info = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", serialize($files[$filename]->info), $file->name, $file->filename, $bootstrap, $file->old_filename);
-    }
-    else {
-      // This is a new module.
-      $files[$filename]->status = 0;
-      $files[$filename]->throttle = 0;
-      db_query("INSERT INTO {system} (name, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0, 0, $bootstrap);
-    }
-  }
-  $files = _module_build_dependencies($files);
-  return $files;
+/**
+ * Collect data about all currently available modules.
+ *
+ * @return
+ *   Array of all available modules and their data.
+ */
+function system_get_module_data() {
+  $modules = _system_get_module_data();
+  ksort($modules);
+  system_get_files_database($modules, 'module');
+  system_update_files_database($modules, 'module');
+  $modules = _module_build_dependencies($modules);
+  return $modules;
 }
 
 /**
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.415.2.12
diff -u -p -r1.415.2.12 theme.inc
--- includes/theme.inc	17 Sep 2008 08:57:23 -0000	1.415.2.12
+++ includes/theme.inc	2 Oct 2008 03:50:38 -0000
@@ -436,7 +436,7 @@ function list_themes($refresh = FALSE) {
     }
     else {
       // Scan the installation when the database should not be read.
-      $themes = _system_theme_data();
+      $themes = _system_get_theme_data();
     }
 
     foreach ($themes as $theme) {
Index: includes/theme.maintenance.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.maintenance.inc,v
retrieving revision 1.10
diff -u -p -r1.10 theme.maintenance.inc
--- includes/theme.maintenance.inc	24 Jan 2008 09:42:50 -0000	1.10
+++ includes/theme.maintenance.inc	26 Sep 2008 21:33:51 -0000
@@ -210,7 +210,7 @@ function template_preprocess_maintenance
 
   global $theme;
   // Retrieve the theme data to list all available regions.
-  $theme_data = _system_theme_data();
+  $theme_data = _system_get_theme_data();
   $regions = $theme_data[$theme]->info['regions'];
 
   // Get all region content set with drupal_set_content().
Index: modules/help/help.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/help/help.admin.inc,v
retrieving revision 1.5
diff -u -p -r1.5 help.admin.inc
--- modules/help/help.admin.inc	25 Nov 2007 11:11:17 -0000	1.5
+++ modules/help/help.admin.inc	26 Sep 2008 21:33:51 -0000
@@ -47,7 +47,7 @@ function help_page($name) {
 
 function help_links_as_list() {
   $empty_arg = drupal_help_arg();
-  $module_info = module_rebuild_cache();
+  $module_info = system_get_module_data();
 
   $modules = array();
   foreach (module_implements('help', TRUE) as $module) {
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.63.2.3
diff -u -p -r1.63.2.3 system.admin.inc
--- modules/system/system.admin.inc	19 May 2008 07:27:35 -0000	1.63.2.3
+++ modules/system/system.admin.inc	26 Sep 2008 21:33:51 -0000
@@ -98,7 +98,7 @@ function system_admin_compact_page($mode
  */
 function system_admin_by_module() {
 
-  $modules = module_rebuild_cache();
+  $modules = system_get_module_data();
   $menu_items = array();
   $help_arg = module_exists('help') ? drupal_help_arg() : FALSE;
 
@@ -151,7 +151,7 @@ function system_settings_overview() {
  * @see system_settings_form()
  */
 function system_admin_theme_settings() {
-  $themes = system_theme_data();
+  $themes = system_get_theme_data();
 
   uasort($themes, 'system_sort_modules_by_info_name');
 
@@ -188,7 +188,7 @@ function system_admin_theme_settings() {
 function system_themes_form() {
 
   drupal_clear_css_cache();
-  $themes = system_theme_data();
+  $themes = system_get_theme_data();
 
   uasort($themes, 'system_sort_modules_by_info_name');
 
@@ -332,7 +332,7 @@ function system_theme_settings(&$form_st
   if ($key) {
     $settings = theme_get_settings($key);
     $var = str_replace('/', '_', 'theme_'. $key .'_settings');
-    $themes = system_theme_data();
+    $themes = system_get_theme_data();
     $features = $themes[$key]->info['features'];
   }
   else {
@@ -623,7 +623,7 @@ function system_modules($form_state = ar
   menu_rebuild();
   cache_clear_all('schema', 'cache');
   // Get current list of modules.
-  $files = module_rebuild_cache();
+  $files = system_get_module_data();
 
   uasort($files, 'system_sort_modules_by_info_name');
 
@@ -801,7 +801,7 @@ function system_modules_disable($form, $
  * Display confirmation form for dependencies.
  *
  * @param $modules
- *   Array of module file objects as returned from module_rebuild_cache().
+ *   Array of module file objects as returned from system_get_module_data().
  * @param $storage
  *   The contents of $form_state['storage']; an array with two
  *   elements: the list of dependencies and the list of status
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.238.2.5
diff -u -p -r1.238.2.5 system.install
--- modules/system/system.install	17 Sep 2008 05:33:36 -0000	1.238.2.5
+++ modules/system/system.install	26 Sep 2008 21:33:51 -0000
@@ -345,7 +345,7 @@ function system_install() {
   }
 
   // Load system theme data appropriately.
-  system_theme_data();
+  system_get_theme_data();
 
   // Inserting uid 0 here confuses MySQL -- the next user might be created as
   // uid 2 which is not what we want. So we insert the first user here, the
@@ -1278,8 +1278,8 @@ function system_update_6008() {
   db_drop_field($ret, 'system', 'description');
 
   // Rebuild system table contents.
-  module_rebuild_cache();
-  system_theme_data();
+  system_get_module_data();
+  system_get_theme_data();
 
   return $ret;
 }
@@ -1350,8 +1350,8 @@ function system_update_6012() {
  */
 function system_update_6013() {
   // Rebuild system table contents.
-  module_rebuild_cache();
-  system_theme_data();
+  system_get_module_data();
+  system_get_theme_data();
 
   return array(array('success' => TRUE, 'query' => 'Cache rebuilt.'));
 }
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.585.2.19
diff -u -p -r1.585.2.19 system.module
--- modules/system/system.module	5 Sep 2008 09:29:23 -0000	1.585.2.19
+++ modules/system/system.module	2 Oct 2008 04:34:02 -0000
@@ -814,23 +814,86 @@ function system_theme_default() {
  *   Array of all available themes and their data.
  */
 function system_theme_data() {
-  // Scan the installation theme .info files and their engines.
-  $themes = _system_theme_data();
+  return system_get_theme_data();
+}
 
-  // Extract current files from database.
+/**
+ * Collect data about all currently available themes.
+ *
+ * @return
+ *   Array of all available themes and their data.
+ */
+function system_get_theme_data() {
+  $themes = _system_get_theme_data();
+  ksort($themes);
   system_get_files_database($themes, 'theme');
+  system_update_files_database($themes, 'theme');
+  return $themes;
+}
 
-  db_query("DELETE FROM {system} WHERE type = 'theme'");
+/**
+ * Updates the records in the system table based on the files array.
+ *
+ * @param $files_updated
+ *   An array of files.
+ * @param $type
+ *   The type of the files.
+ */
+function system_update_files_database(&$files_updated, $type) {
+  // Need to make a safe, modifiable copy of the $files array since PHP
+  // automatically makes references to objects instead of copies.
+  $files = array();
+  foreach($files_updated as $key => $file) {
+    $files[$key] = clone $file;
+    $files[$key]->info = serialize($file->info);
+  }
 
-  foreach ($themes as $theme) {
-    if (!isset($theme->owner)) {
-      $theme->owner = '';
-    }
+  $result = db_query("SELECT * FROM {system} WHERE type = '%s'", $type);
+  while ($file = db_fetch_object($result)) {
+    if (isset($files[$file->name]) && is_object($files[$file->name])) {
+      // Keep the old filename from the database incase the file has moved
+      $file->old_filename = $file->filename;
+
+      // Find each updated field
+      $file->updated_fields = array();
+      $sql_sets = array();
+      $sql_args = array();
+      foreach ($file as $key => $value) {
+        if (isset($files[$file->name]->$key) && $files[$file->name]->$key != $value) {
+          $file->updated_fields[$key] = $files[$file->name]->$key;
+	  $sql_sets[] = "$key = '%s'";
+	  $sql_args[] = $files[$file->name]->$key;
+        }
+      }
+
+      // Update the record
+      if (count($file->updated_fields)) {
+	$sql_args[] = $file->old_filename;
+	db_query('UPDATE {system} SET ' . implode(',',$sql_sets) . ' WHERE filename=\'%s\'',$sql_args);
+      }
 
-    db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0);
+      // Remove the file so that we don't try to insert later
+      unset($files[$file->name]);
+    }
+    else {
+      // File not found in filesystem, so delete record from the system table
+      db_query('DELETE FROM {system} WHERE filename=\'' . $file->filename .'\'');
+    }
   }
 
-  return $themes;
+  // All remaining files are not in the system table, so we need to add them
+  foreach($files as $file) {
+    db_query("INSERT INTO {system} (filename,name,type,owner,bootstrap,info) VALUES ('%s','%s','%s','%s',%d,'%s')",
+        $file->filename,
+        $file->name,
+        $type,
+        isset($file->owner) ? $file->owner : '',
+        isset($file->bootstrap) ? $file->bootstrap : 0,
+        $file->info);
+    $files_updated[$file->name]->type = $type;
+    $files_updated[$file->name]->status = 0;
+    $files_updated[$file->name]->schema_version = -1;
+  }
 }
 
 /**
@@ -839,7 +902,7 @@ function system_theme_data() {
  * @return
  *   An associative array of themes information.
  */
-function _system_theme_data() {
+function _system_get_theme_data() {
   static $themes_info = array();
 
   if (empty($themes_info)) {
@@ -927,6 +990,56 @@ function _system_theme_data() {
 }
 
 /**
+ * Helper function to scan and collect module .info data.
+ *
+ * @return
+ *   An associative array of module information.
+ */
+function _system_get_module_data() {
+  // Find modules
+  $modules = drupal_system_listing('\.module$', 'modules', 'name', 0);
+
+  // Set defaults for module info
+  $defaults = array(
+    'dependencies' => array(),
+    'dependents' => array(),
+    'description' => '',
+    'version' => NULL,
+    'php' => DRUPAL_MINIMUM_PHP,
+  );
+
+  // Read info files for each theme
+  foreach ($modules as $key => $module) {
+    // Look for the info file.
+    $module->info = drupal_parse_info_file(dirname($module->filename) . '/' . $module->name . '.info');
+
+    // Skip modules that don't provide info.
+    if (empty($module->info)) {
+      unset($modules[$key]);
+      continue;
+    }
+
+    // Merge in defaults and save.
+    $modules[$key]->info = $module->info + $defaults;
+
+    // Invoke hook_system_info_alter() to give installed modules a chance to
+    // modify the data in the .info files if necessary.
+    drupal_alter('system_info', $modules[$key]->info, $modules[$key]);
+
+    // Log the critical hooks implemented by this module.
+    $modules[$key]->bootstrap = 0;
+    foreach (bootstrap_hooks() as $hook) {
+      if (module_hook($modules[$key]->name, $hook)) {
+        $modules[$key]->bootstrap = 1;
+        break;
+      }
+    }
+  }
+
+  return $modules;
+}
+
+/**
  * Recursive function to find the top level base theme. Themes can inherit
  * templates and function implementations from earlier themes.
  *
Index: modules/update/update.compare.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/update/update.compare.inc,v
retrieving revision 1.8.2.2
diff -u -p -r1.8.2.2 update.compare.inc
--- modules/update/update.compare.inc	28 Aug 2008 08:14:56 -0000	1.8.2.2
+++ modules/update/update.compare.inc	26 Sep 2008 21:33:51 -0000
@@ -27,8 +27,8 @@ function update_get_projects() {
     $projects = update_project_cache('update_project_projects');
     if (empty($projects)) {
       // Still empty, so we have to rebuild the cache.
-      _update_process_info_list($projects, module_rebuild_cache(), 'module');
-      _update_process_info_list($projects, system_theme_data(), 'theme');
+      _update_process_info_list($projects, system_get_module_data(), 'module');
+      _update_process_info_list($projects, system_get_theme_data(), 'theme');
       // Set the projects array into the cache table.
       cache_set('update_project_projects', $projects, 'cache_update', time() + 3600);
     }
