Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1210
diff -u -p -r1.1210 common.inc
--- includes/common.inc	22 Aug 2010 12:46:21 -0000	1.1210
+++ includes/common.inc	24 Aug 2010 12:40:41 -0000
@@ -6312,6 +6312,9 @@ function drupal_flush_all_caches() {
   menu_rebuild();
   node_types_rebuild();
 
+  // Synchronize to catch any actions that were added or removed.
+  actions_synchronize();
+
   // Don't clear cache_form - in-progress form submissions may break.
   // Ordered so clearing the page cache will always be the last action.
   $core = array('cache', 'cache_filter', 'cache_bootstrap', 'cache_page');
Index: includes/install.core.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.core.inc,v
retrieving revision 1.27
diff -u -p -r1.27 install.core.inc
--- includes/install.core.inc	22 Aug 2010 15:31:18 -0000	1.27
+++ includes/install.core.inc	24 Aug 2010 12:43:23 -0000
@@ -1494,9 +1494,6 @@ function install_finished(&$install_stat
   // registered by the install profile are registered correctly.
   drupal_flush_all_caches();
 
-  // Register actions declared by any modules.
-  actions_synchronize();
-
   // Remember the profile which was used.
   variable_set('install_profile', drupal_get_profile());
 
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.197
diff -u -p -r1.197 module.inc
--- includes/module.inc	28 Jul 2010 01:46:59 -0000	1.197
+++ includes/module.inc	24 Aug 2010 12:40:41 -0000
@@ -175,6 +175,7 @@ function system_list($type) {
  */
 function system_list_reset() {
   drupal_static_reset('system_list');
+  drupal_static_reset('system_region_list');
   drupal_static_reset('list_themes');
   cache_clear_all('bootstrap_modules', 'cache_bootstrap');
   cache_clear_all('system_list', 'cache_bootstrap');
@@ -386,39 +387,55 @@ function module_enable($module_list, $en
         ->condition('type', 'module')
         ->condition('name', $module)
         ->execute();
-      // Refresh the module list to include it.
-      system_list_reset();
-      module_list(TRUE);
-      module_implements('', FALSE, TRUE);
-      _system_update_bootstrap_status();
-      // Update the registry to include it.
-      registry_update();
-      // Refresh the schema to include it.
-      drupal_get_schema(NULL, TRUE);
-      // Clear entity cache.
-      entity_info_cache_clear();
 
       // Now install the module if necessary.
       if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
+        // Reset the module list in preparation for running hook_schema().
+        system_list_reset();
+        module_list(TRUE);
+        module_implements('', FALSE, TRUE);
+
         drupal_install_schema($module);
         $versions = drupal_get_schema_versions($module);
         drupal_set_installed_schema_version($module, $versions ? max($versions) : SCHEMA_INSTALLED);
-        // Allow the module to perform install tasks.
-        module_invoke($module, 'install');
         // Record the fact that it was installed.
         $modules_installed[] = $module;
-        watchdog('system', '%module module installed.', array('%module' => $module), WATCHDOG_INFO);
       }
 
-      // Enable the module.
-      module_invoke($module, 'enable');
-
       // Record the fact that it was enabled.
       $modules_enabled[] = $module;
-      watchdog('system', '%module module enabled.', array('%module' => $module), WATCHDOG_INFO);
     }
   }
 
+  if (!$modules_enabled) {
+    // Nothing to do. All modules already enabled.
+    return TRUE;
+  }
+
+  // Refresh the module list to include new modules.
+  system_list_reset();
+  module_list(TRUE);
+  module_implements('', FALSE, TRUE);
+  _system_update_bootstrap_status();
+  // Update the registry to include new modules.
+  registry_update();
+  // Refresh the schema to include new modules.
+  drupal_get_schema(NULL, TRUE);
+  // Clear entity cache.
+  entity_info_cache_clear();
+
+  foreach ($modules_installed as $module) {
+    // Allow the module to perform tasks when installed.
+    module_invoke($module, 'install');
+    watchdog('system', '%module module installed.', array('%module' => $module), WATCHDOG_INFO);
+  }
+
+  foreach ($modules_enabled as $module) {
+    // Allow the module to perform tasks when enabled.
+    module_invoke($module, 'enable');
+    watchdog('system', '%module module enabled.', array('%module' => $module), WATCHDOG_INFO);
+  }
+
   // If any modules were newly installed, invoke hook_modules_installed().
   if (!empty($modules_installed)) {
     module_invoke_all('modules_installed', $modules_installed);
Index: includes/update.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/update.inc,v
retrieving revision 1.64
diff -u -p -r1.64 update.inc
--- includes/update.inc	17 Jul 2010 19:44:06 -0000	1.64
+++ includes/update.inc	24 Aug 2010 12:40:41 -0000
@@ -637,6 +637,9 @@ function update_fix_d7_requirements() {
       db_change_field('languages', 'javascript', 'javascript', array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''));
     }
 
+    // Rename action description to label.
+    db_change_field('actions', 'description', 'label', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '0'));
+
     variable_set('update_d7_requirements', TRUE);
   }
 
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.226
diff -u -p -r1.226 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	22 Aug 2010 15:31:18 -0000	1.226
+++ modules/simpletest/drupal_web_test_case.php	24 Aug 2010 12:43:29 -0000
@@ -1204,6 +1204,10 @@ class DrupalWebTestCase extends DrupalTe
     variable_set('install_profile', $this->profile);
     $profile_details = install_profile_info($this->profile, 'en');
 
+    // It's necessary to build the menu now for some modules to install
+    // correctly.
+    menu_rebuild();
+
     // Install the modules specified by the testing profile.
     module_enable($profile_details['dependencies'], FALSE);
 
@@ -1231,9 +1235,6 @@ class DrupalWebTestCase extends DrupalTe
     drupal_static_reset();
     drupal_flush_all_caches();
 
-    // Register actions declared by any modules.
-    actions_synchronize();
-
     // Reload global $conf array and permissions.
     $this->refreshVariables();
     $this->checkPermissions(array(), TRUE);
Index: modules/simpletest/tests/module_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/module_test.module,v
retrieving revision 1.6
diff -u -p -r1.6 module_test.module
--- modules/simpletest/tests/module_test.module	22 Apr 2010 18:56:31 -0000	1.6
+++ modules/simpletest/tests/module_test.module	24 Aug 2010 12:40:41 -0000
@@ -36,6 +36,9 @@ function module_test_system_info_alter(&
       $info['dependencies'][] = 'php';
     }
   }
+  if ($file->name == 'seven' && $type == 'theme') {
+    $info['regions']['test_region'] = t('Test region');
+  }
 }
 
 /**
Index: modules/simpletest/tests/upgrade/upgrade.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/upgrade/upgrade.test,v
retrieving revision 1.5
diff -u -p -r1.5 upgrade.test
--- modules/simpletest/tests/upgrade/upgrade.test	5 Aug 2010 23:53:38 -0000	1.5
+++ modules/simpletest/tests/upgrade/upgrade.test	24 Aug 2010 12:43:34 -0000
@@ -279,9 +279,6 @@ abstract class UpgradePathTestCase exten
     drupal_static_reset();
     drupal_flush_all_caches();
 
-    // Register actions declared by any modules.
-    actions_synchronize();
-
     // Reload global $conf array and permissions.
     $this->refreshVariables();
     $this->checkPermissions(array(), TRUE);
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.298
diff -u -p -r1.298 system.admin.inc
--- modules/system/system.admin.inc	22 Aug 2010 12:55:04 -0000	1.298
+++ modules/system/system.admin.inc	24 Aug 2010 12:42:56 -0000
@@ -1217,6 +1217,7 @@ function system_modules_submit($form, &$
     if ($module['enabled']) {
       if (drupal_get_installed_schema_version($name) == SCHEMA_UNINSTALLED) {
         $actions['install'][] = $name;
+        $actions['enable'][] = $name;
       }
       elseif (!module_exists($name)) {
         $actions['enable'][] = $name;
@@ -1233,32 +1234,22 @@ function system_modules_submit($form, &$
   unset($form_state['storage']);
 
   // Installs, enables, and disables modules.
-  module_enable($actions['enable']);
-  module_disable($actions['disable']);
-  module_enable($actions['install']);
+  module_enable($actions['enable'], FALSE);
+  module_disable($actions['disable'], FALSE);
 
   // Gets module list after install process, displays message if there are changes.
   $post_install_list = module_list(TRUE);
   if ($pre_install_list != $post_install_list) {
+    drupal_flush_all_caches();
     drupal_set_message(t('The configuration options have been saved.'));
   }
 
-  // Clear all caches. We need to invoke drupal_flush_all_caches() to ensure
-  // that also dependent caches are flushed, e.g. the filter cache and field
-  // cache, and also registered themes are rebuilt, since modules can also
-  // register themes.
-  drupal_flush_all_caches();
-  entity_info_cache_clear();
-
   $form_state['redirect'] = 'admin/modules';
 
   // Notify locale module about module changes, so translations can be
   // imported. This might start a batch, and only return to the redirect
   // path after that.
   module_invoke('locale', 'system_update', $actions['install']);
-
-  // Synchronize to catch any actions that were added or removed.
-  actions_synchronize();
 }
 
 /**
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.499
diff -u -p -r1.499 system.install
--- modules/system/system.install	23 Aug 2010 14:56:37 -0000	1.499
+++ modules/system/system.install	24 Aug 2010 12:40:41 -0000
@@ -2302,7 +2302,7 @@ function system_update_7036() {
  * Rename action description to label.
  */
 function system_update_7037() {
-  db_change_field('actions', 'description', 'label', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '0'));
+  // Moved to update_fix_d7_requirements().
 }
 
 /**
Index: modules/system/system.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.test,v
retrieving revision 1.140
diff -u -p -r1.140 system.test
--- modules/system/system.test	22 Aug 2010 14:55:29 -0000	1.140
+++ modules/system/system.test	24 Aug 2010 12:40:41 -0000
@@ -1665,6 +1665,73 @@ array_space[a b] = Value';
 }
 
 /**
+ * Tests the effectiveness of hook_system_info_alter().
+ */
+class SystemInfoAlterTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'System info alter',
+      'description' => 'Tests the effectiveness of hook_system_info_alter().',
+      'group' => 'System',
+    );
+  }
+
+  /**
+   * Tests that {system}.info is rebuilt after a module that implements
+   * hook_system_info_alter() is enabled. Also tests if core *_list() functions
+   * return freshly altered info.
+   */
+  function testSystemInfoAlter() {
+    // Enable our test module. Flush all caches, which we assert is the only
+    // thing necessary to use the rebuilt {system}.info.
+    module_enable(array('module_test'), FALSE);
+    drupal_flush_all_caches();
+    $this->assertTrue(module_exists('module_test'), t('Test module is enabled.'));
+
+    $info = $this->_getSystemInfo('seven', 'theme');
+    $this->assertTrue(isset($info['regions']['test_region']), t('Altered theme info was added to {system}.info.'));
+    $seven_regions = system_region_list('seven');
+    $this->assertTrue(isset($seven_regions['test_region']), t('Altered theme info was returned by system_region_list().'));
+    $system_list_themes = system_list('theme');
+    $info = $system_list_themes['seven']->info;
+    $this->assertTrue(isset($info['regions']['test_region']), t('Altered theme info was returned by system_list().'));
+    $list_themes = list_themes();
+    $this->assertTrue(isset($list_themes['seven']->info['regions']['test_region']), t('Altered theme info was returned by list_themes().'));
+
+    // Disable the module and verify that {system}.info is rebuilt without it.
+    module_disable(array('module_test'), FALSE);
+    drupal_flush_all_caches();
+    $this->assertFalse(module_exists('module_test'), t('Test module is disabled.'));
+
+    $info = $this->_getSystemInfo('seven', 'theme');
+    $this->assertFalse(isset($info['regions']['test_region']), t('Altered theme info was removed from {system}.info.'));
+    $seven_regions = system_region_list('seven');
+    $this->assertFalse(isset($seven_regions['test_region']), t('Altered theme info was not returned by system_region_list().'));
+    $system_list_themes = system_list('theme');
+    $info = $system_list_themes['seven']->info;
+    $this->assertFalse(isset($info['regions']['test_region']), t('Altered theme info was not returned by system_list().'));
+    $list_themes = list_themes();
+    $this->assertFalse(isset($list_themes['seven']->info['regions']['test_region']), t('Altered theme info was not returned by list_themes().'));
+  }
+
+  /**
+   * Support function. Returns the info array as it is stored in {system}.
+   *
+   * @param $name
+   *   The name of the record in {system}.
+   * @param $type
+   *   The type of record in {system}.
+   *
+   * @return
+   *   Array of info, or FALSE if the record is not found.
+   */
+  function _getSystemInfo($name, $type) {
+    $raw_info = db_query("SELECT info FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
+    return $raw_info ? unserialize($raw_info) : FALSE;
+  }
+}
+
+/**
  * Tests for the update system functionality.
  */
 class UpdateScriptFunctionalTest extends DrupalWebTestCase {
Index: modules/trigger/trigger.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/trigger/trigger.install,v
retrieving revision 1.17
diff -u -p -r1.17 trigger.install
--- modules/trigger/trigger.install	22 Aug 2010 13:55:53 -0000	1.17
+++ modules/trigger/trigger.install	24 Aug 2010 12:43:54 -0000
@@ -46,14 +46,6 @@ function trigger_schema() {
 }
 
 /**
- * Implements hook_install().
- */
-function trigger_install() {
-  // Do initial synchronization of actions in code and the database.
-  actions_synchronize();
-}
-
-/**
  * Adds operation names to the hook names and drops the "op" field.
  */
 function trigger_update_7000() {
