Index: install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.228
diff -u -p -r1.228 install.php
--- install.php	7 Dec 2009 06:19:20 -0000	1.228
+++ install.php	23 Dec 2009 10:53:29 -0000
@@ -746,6 +746,7 @@ function install_verify_requirements(&$i
 function install_system_module(&$install_state) {
   // Install system.module.
   drupal_install_system();
+  registry_rebuild();
   // Save the list of other modules to install for the upcoming tasks.
   // variable_set() can be used now that system.module is installed and
   // Drupal is bootstrapped.
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.335
diff -u -p -r1.335 bootstrap.inc
--- includes/bootstrap.inc	22 Dec 2009 14:47:14 -0000	1.335
+++ includes/bootstrap.inc	23 Dec 2009 10:53:30 -0000
@@ -2097,6 +2097,92 @@ function registry_rebuild() {
 }
 
 /**
+ * Remove the files for the given disabled modules to the registry. 
+ * 
+ * @param array $modules 
+ *   List of disabled modules to remove from the registry.
+ */
+function registry_remove_modules(array $modules) {
+  require_once DRUPAL_ROOT . '/includes/registry.inc';
+  _registry_load_db();
+  $files = array();
+  foreach ($modules as $module_name) {
+    $dir = drupal_get_path('module', $module_name);
+    $info = drupal_parse_info_file("$dir/$module_name.info");
+    if (isset($info['files'])) {
+      foreach ($info['files'] as $file) {
+        $files[] = "$dir/$file";
+      }
+    }
+  }
+  registry_remove_files($files);
+  module_implements('', FALSE, TRUE);
+}
+
+/**
+ * Add the files for the given enabled modules to the registry. 
+ * 
+ * @param array $modules 
+ *   List of enabled modules to add to the registry.
+ */
+function registry_add_modules(array $modules) {
+  require_once DRUPAL_ROOT . '/includes/registry.inc';
+  _registry_load_db();
+  $files = array();
+  foreach ($modules as $module_name) {
+    $weight = db_query("SELECT weight FROM {system} WHERE name = ? AND type = 'module'", array($module_name))->fetchField();
+    $dir = drupal_get_path('module', $module_name);
+    $info = drupal_parse_info_file("$dir/$module_name.info");
+    if (isset($info['files'])) {
+      foreach ($info['files'] as $file) {
+        $files["$dir/$file"] = array(
+          'module' => $module_name,
+          'weight' => is_int($weight) ? $weight : 0,
+        );
+      }
+    }
+  }
+  registry_add_files($files);
+  module_implements('', FALSE, TRUE);
+}
+
+/**
+ * Add the given list of files to the registry.
+ * 
+ * @param array $files
+ */
+function registry_add_files(array $files) {
+  require_once DRUPAL_ROOT . '/includes/registry.inc';
+  _registry_load_db();
+
+  foreach (registry_get_parsed_files() as $filename => $file) {
+    if (isset($files[$filename])) {
+      $files[$filename]['filectime'] = $file['filectime'];
+      $files[$filename]['filemtime'] = $file['filemtime'];
+    }
+  }
+  _registry_parse_files($files);
+}
+
+/**
+ * Remove the given list of files from the registry.
+ * 
+ * @param array $files 
+ */
+function registry_remove_files(array $files) {
+  require_once DRUPAL_ROOT . '/includes/registry.inc';
+  _registry_load_db();
+  foreach ($files as $filename) {
+    db_delete('registry')
+      ->condition('filename', $filename)
+      ->execute();
+    db_delete('registry_file')
+      ->condition('filename', $filename)
+      ->execute();
+  }
+}
+
+/**
  * @} End of "ingroup registry".
  */
 
Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.117
diff -u -p -r1.117 install.inc
--- includes/install.inc	7 Dec 2009 06:19:20 -0000	1.117
+++ includes/install.inc	23 Dec 2009 10:53:31 -0000
@@ -550,10 +550,8 @@ function drupal_verify_profile($install_
  *
  * @param $module_list
  *   The modules to install.
- * @param $disable_modules_installed_hook
- *   Normally just testing wants to set this to TRUE.
  */
-function drupal_install_modules($module_list = array(), $disable_modules_installed_hook = FALSE) {
+function drupal_install_modules($module_list = array()) {
   $files = system_rebuild_module_data();
   $module_list = array_flip(array_values($module_list));
   do {
@@ -572,7 +570,7 @@ function drupal_install_modules($module_
   } while ($moved);
   asort($module_list);
   $module_list = array_keys($module_list);
-  module_enable($module_list, $disable_modules_installed_hook);
+  module_enable($module_list);
 }
 
 /**
@@ -633,6 +631,7 @@ function drupal_install_system() {
   require_once DRUPAL_ROOT . '/' . $system_path . '/system.install';
   drupal_install_initialize_database();
   module_invoke('system', 'install');
+  registry_add_modules(array('system'));
 
   $system_versions = drupal_get_schema_versions('system');
   $system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED;
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.176
diff -u -p -r1.176 module.inc
--- includes/module.inc	2 Dec 2009 00:17:49 -0000	1.176
+++ includes/module.inc	23 Dec 2009 10:53:31 -0000
@@ -287,10 +287,8 @@ function module_load_all_includes($type,
  *
  * @param $module_list
  *   An array of module names.
- * @param $disable_modules_installed_hook
- *   Normally just testing wants to set this to TRUE.
  */
-function module_enable($module_list, $disable_modules_installed_hook = FALSE) {
+function module_enable($module_list) {
   $invoke_modules = array();
 
   // Try to install the enabled modules and collect which were installed.
@@ -319,13 +317,13 @@ function module_enable($module_list, $di
     system_list_reset();
     module_list(TRUE);
     module_implements('', FALSE, TRUE);
-    // Force to regenerate the stored list of hook implementations.
-    registry_rebuild();
+    // Add the newly enabled modules to the registry.
+    registry_add_modules($invoke_modules);
     // Refresh the schema to include the new enabled module.
     drupal_get_schema(NULL, TRUE);
 
     // If any modules were newly installed, execute the hook for them.
-    if (!$disable_modules_installed_hook && !empty($modules_installed)) {
+    if (!empty($modules_installed)) {
       module_invoke_all('modules_installed', $modules_installed);
     }
   }
@@ -384,7 +382,7 @@ function module_disable($module_list) {
     // so we can still call module hooks to get information.
     module_invoke_all('modules_disabled', $invoke_modules);
     // Force to regenerate the stored list of hook implementations.
-    registry_rebuild();
+    registry_remove_modules($invoke_modules);
   }
 
   // If there remains no more node_access module, rebuilding will be
Index: includes/registry.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/registry.inc,v
retrieving revision 1.26
diff -u -p -r1.26 registry.inc
--- includes/registry.inc	10 Nov 2009 22:06:09 -0000	1.26
+++ includes/registry.inc	23 Dec 2009 10:53:31 -0000
@@ -20,19 +20,7 @@
  * @see registry_rebuild.
  */
 function _registry_rebuild() {
-
-  // The registry serves as a central autoloader for all classes, including
-  // the database query builders. However, the registry rebuild process
-  // requires write ability to the database, which means having access to the
-  // query builders that require the registry in order to be loaded. That
-  // causes a fatal race condition. Therefore we manually include the
-  // appropriate query builders for the currently active database before the
-  // registry rebuild process runs.
-  $connection_info = Database::getConnectionInfo();
-  $driver = $connection_info['default']['driver'];
-  require_once DRUPAL_ROOT . '/includes/database/query.inc';
-  require_once DRUPAL_ROOT . '/includes/database/select.inc';
-  require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
+  _registry_load_db();
 
   // Get current list of modules and their files.
   $modules = system_rebuild_module_data();
@@ -55,12 +43,6 @@ function _registry_rebuild() {
     $files["$filename"] = array('module' => '', 'weight' => 0);
   }
 
-  // Allow modules to manually modify the list of files before the registry
-  // parses them. The $modules array provides the .info file information, which
-  // includes the list of files registered to each module. Any files in the
-  // list can then be added to the list of files that the registry will parse,
-  // or modify attributes of a file.
-  drupal_alter('registry_files', $files, $modules);
   foreach (registry_get_parsed_files() as $filename => $file) {
     // Add the file creation and modification dates to those files we have
     // already parsed.
@@ -179,6 +161,25 @@ function _registry_parse_file($filename,
 }
 
 /**
+ * Load the database for the registry.
+ *
+ * The registry serves as a central autoloader for all classes, including
+ * the database query builders. However, the registry rebuild process
+ * requires write ability to the database, which means having access to the
+ * query builders that require the registry in order to be loaded. That
+ * causes a fatal race condition. Therefore we manually include the
+ * appropriate query builders for the currently active database before the
+ * registry rebuild process runs.
+ */
+function _registry_load_db() {
+  $connection_info = Database::getConnectionInfo();
+  $driver = $connection_info['default']['driver'];
+  require_once DRUPAL_ROOT . '/includes/database/query.inc';
+  require_once DRUPAL_ROOT . '/includes/database/select.inc';
+  require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
+}
+ 
+/**
  * @} End of "defgroup registry".
  */
 
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.182
diff -u -p -r1.182 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	15 Dec 2009 05:25:47 -0000	1.182
+++ modules/simpletest/drupal_web_test_case.php	23 Dec 2009 10:53:33 -0000
@@ -1096,8 +1096,7 @@ class DrupalWebTestCase extends DrupalTe
 
     include_once DRUPAL_ROOT . '/includes/install.inc';
     drupal_install_system();
-
-    $this->preloadRegistry();
+    $this->preloadIncludesRegistry();
 
     // Include the default profile
     variable_set('install_profile', 'default');
@@ -1105,16 +1104,10 @@ class DrupalWebTestCase extends DrupalTe
 
     // Add the specified modules to the list of modules in the default profile.
     // Install the modules specified by the default profile.
-    drupal_install_modules($profile_details['dependencies'], TRUE);
+    drupal_install_modules($profile_details['dependencies']);
 
     drupal_static_reset('_node_types_build');
-
-    // Install additional modules one at a time in order to make sure that the
-    // list of modules is updated between each module's installation.
-    $modules = func_get_args();
-    foreach ($modules as $module) {
-      drupal_install_modules(array($module), TRUE);
-    }
+    drupal_install_modules(array_diff(func_get_args(), $profile_details['dependencies']));
 
     // Because the schema is static cached, we need to flush
     // it between each run. If we don't, then it will contain
@@ -1124,7 +1117,7 @@ class DrupalWebTestCase extends DrupalTe
 
     // Run default profile tasks.
     $install_state = array();
-    drupal_install_modules(array('default'), TRUE);
+    drupal_install_modules(array('default'));
 
     // Rebuild caches.
     node_types_rebuild();
@@ -1159,12 +1152,12 @@ class DrupalWebTestCase extends DrupalTe
 
   /**
    * This method is called by DrupalWebTestCase::setUp, and preloads the
-   * registry from the testing site to cut down on the time it takes to
-   * setup a clean environment for the current test run.
+   * registry for files in the includes directory from the testing site to cut
+   * down on the time it takes to setup a clean environment for the current test run.
    */
-  protected function preloadRegistry() {
-    db_query('INSERT INTO {registry} SELECT * FROM ' . $this->originalPrefix . 'registry');
-    db_query('INSERT INTO {registry_file} SELECT * FROM ' . $this->originalPrefix . 'registry_file');
+  protected function preloadIncludesRegistry() {
+    db_query('INSERT INTO {registry} SELECT * FROM ' . $this->originalPrefix . "registry WHERE module = ''");
+    db_query('INSERT INTO {registry_file} SELECT * FROM ' . $this->originalPrefix . "registry_file WHERE filename LIKE 'includes/%'");
   }
 
   /**
Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.86
diff -u -p -r1.86 simpletest.module
--- modules/simpletest/simpletest.module	22 Dec 2009 14:47:14 -0000	1.86
+++ modules/simpletest/simpletest.module	23 Dec 2009 10:53:33 -0000
@@ -309,7 +309,8 @@ function simpletest_log_read($test_id, $
  * The list of test classes is loaded from the registry where it looks for
  * files ending in ".test". Once loaded the test list is cached and stored in
  * a static variable. In order to list tests provided by disabled modules
- * hook_registry_files_alter() is used to forcefully add them to the registry.
+ * we call simpletest_add_disabled_modules_test_files() which adds disabled 
+ * modules test files to the registry.
  *
  * @return
  *   An array of tests keyed with the groups specified in each of the tests
@@ -325,7 +326,7 @@ function simpletest_log_read($test_id, $
  *       ),
  *     );
  *   @endcode
- * @see simpletest_registry_files_alter()
+ * @see simpletest_add_disabled_modules_test_files()
  */
 function simpletest_test_get_all() {
   $groups = &drupal_static(__FUNCTION__);
@@ -337,6 +338,9 @@ function simpletest_test_get_all() {
       $groups = $cache->data;
     }
     else {
+      // Add test files for disabled modules to the registry.
+      simpletest_add_disabled_modules_test_files();
+
       // Select all clases in files ending with .test.
       $classes = db_query("SELECT name FROM {registry} WHERE type = :type AND filename LIKE :name", array(':type' => 'class', ':name' => '%.test'));
 
@@ -377,26 +381,26 @@ function simpletest_test_get_all() {
 }
 
 /**
- * Implements hook_registry_files_alter().
- *
  * Add the test files for disabled modules so that we get a list containing
- * all the avialable tests.
+ * all the available tests.
  */
-function simpletest_registry_files_alter(&$files, $modules) {
-  foreach ($modules as $module) {
-    // Only add test files for disabled modules, as enabled modules should
-    // already include any test files they provide.
-    if (!$module->status) {
-      $dir = $module->dir;
-      if (!empty($module->info['files'])) {
-        foreach ($module->info['files'] as $file) {
-          if (substr($file, -5) == '.test') {
-            $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
-          }
+function simpletest_add_disabled_modules_test_files() {
+  $disabled_modules = db_query("SELECT * FROM {system} WHERE type = 'module' AND status = 0")->fetchAll();
+  $files = array();
+  foreach ($disabled_modules as $module) {
+    $info = unserialize($module->info);
+    $dir = dirname($module->filename);
+    if (!empty($info['files'])) {
+      foreach ($info['files'] as $file) {
+        if (substr($file, -5) == '.test') {
+          $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
         }
       }
     }
   }
+  if ($files) {
+    registry_add_files($files);
+  }
 }
 
 /**
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.240
diff -u -p -r1.240 system.admin.inc
--- modules/system/system.admin.inc	18 Dec 2009 23:54:16 -0000	1.240
+++ modules/system/system.admin.inc	23 Dec 2009 10:53:35 -0000
@@ -1148,7 +1148,6 @@ function system_modules_submit($form, &$
   }
 
   // Clear all caches.
-  registry_rebuild();
   drupal_theme_rebuild();
   node_types_rebuild();
   menu_rebuild();
