diff --git a/core/includes/common.inc b/core/includes/common.inc
index 353a9b5..d8985e7 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -7289,50 +7289,89 @@ function drupal_implode_tags($tags) {
 }
 
 /**
- * Flushes all cached data on the site.
- *
- * Empties cache tables, rebuilds the menu cache and theme registries, and
- * invokes a hook so that other modules' cache data can be cleared as well.
+ * Flushes and resets all caches, and rebuilds data structures.
+ *
+ * At times, it is necessary to "re-initialize" the entire system due to account
+ * for changed or new code. This function:
+ * - Clears all database caches (invoking hook_flush_caches())
+ * - Clears all static caches
+ * - Updates the system with latest extension information
+ * - Rebuilds and synchronizes data structures (invoking hook_rebuild())
+ * - Rebuilds the menu router
+ * - Clears page and asset/support file caches (last, in order to serve requests
+ *   from cache during re-initialization, if possible) @todo While a good idea,
+ *   this breaks the contract and doesn't work out, since cache_bootstrap would
+ *   also have to be retained in order to serve pages from cache. :(
+ *
+ * All modules need to ensure that all of their caches are flushed in
+ * hook_flush_caches() is invoked, so any previously known information no longer
+ * exists. This is important, since all of the following hook_rebuild()
+ * operations must be based on the current system data and must be able to rely
+ * on this contract.
+ *
+ * @see hook_flush_caches()
+ * @see hook_rebuild()
+ *
+ * @todo Rename hook_flush_caches() to enforce developers to re-implement it
+ *   according to this contract.
+ *
+ * @todo Make this obsolete:
+ * Note that after clearing all static caches also the theme is not initialized
+ * any more and any possible previously added Javascript or CSS is gone.
  */
 function drupal_flush_all_caches() {
-  // Change query-strings on css/js files to enforce reload for all users.
-  _drupal_flush_css_js();
+  // Flush all database caches.
+  // This is executed based on "previously" known information, which is
+  // sufficient, since new extensions cannot have any primed caches yet.
+  // Include all core cache tables; except 'cache_form': in-progress form
+  // submissions would break.
+  $core = array('bootstrap', 'cache', 'path');
+  $cache_bins = array_merge(module_invoke_all('flush_caches'), $core);
+  foreach ($cache_bins as $bin) {
+    cache($bin)->flush();
+  }
 
-  registry_rebuild();
-  drupal_clear_css_cache();
-  drupal_clear_js_cache();
+  // Reset all static caches.
+  drupal_static_reset();
+
+  // Clear all non-drupal_static() static caches.
+  // @todo Grep entire core for statics that need to be reset and can be reset,
+  //   and reset them here, or for modules, in hook_flush_caches().
 
-  // Rebuild the theme data. Note that the module data is rebuilt above, as
-  // part of registry_rebuild().
+
+  // Update and synchronize the class registry and extension information based
+  // on current/actual code.
+  // Module data is rebuilt as part of registry_rebuild().
+  registry_rebuild();
   system_rebuild_theme_data();
-  drupal_theme_rebuild();
 
-  entity_info_cache_clear();
+  // Update the list of bootstrap modules.
+  // Allows developers to get new hook_boot() implementations registered without
+  // having to write a hook_update_N() function.
+  _system_update_bootstrap_status();
 
-  // @todo D8: Split cache flushing from rebuilding.
-  // @see http://drupal.org/node/996236
-  if (module_exists('node')) {
-    node_types_rebuild();
-  }
-  // node_menu() defines menu items based on node types so it needs to come
-  // after node types are rebuilt.
-  menu_rebuild();
+  // Rebuild the schema and cache a fully-built schema based on new module data.
+  // This is necessary for any invocation of index.php, because setting cache
+  // table entries requires schema information and that occurs during bootstrap
+  // before any modules are loaded, so if there is no cached schema,
+  // drupal_get_schema() will try to generate one, but with no loaded modules,
+  // it will return nothing.
+  drupal_get_schema(NULL, TRUE);
+
+  // Rebuild all information based on new module data.
+  module_invoke_all('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', 'path', 'filter', 'bootstrap', 'page');
-  $cache_bins = array_merge(module_invoke_all('flush_caches'), $core);
-  foreach ($cache_bins as $bin) {
-    cache($bin)->flush();
-  }
+  // Lastly, rebuild the menu router based on all rebuilt data.
+  menu_rebuild();
 
-  // Rebuild the bootstrap module list. We do this here so that developers
-  // can get new hook_boot() implementations registered without having to
-  // write a hook_update_N() function.
-  _system_update_bootstrap_status();
+  // Now clear page, CSS and JS caches.
+  drupal_clear_css_cache();
+  drupal_clear_js_cache();
+  _drupal_flush_css_js();
+  cache('page')->flush();
 }
 
 /**
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 125852a..035467f 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1571,28 +1571,34 @@ function install_import_translations_remaining(&$install_state) {
  *   A message informing the user that the installation is complete.
  */
 function install_finished(&$install_state) {
-  drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_distribution_name())), PASS_THROUGH);
-  $messages = drupal_set_message();
-  $output = '<p>' . st('Congratulations, you installed @drupal!', array('@drupal' => drupal_install_profile_distribution_name())) . '</p>';
-  $output .= '<p>' . (isset($messages['error']) ? st('Review the messages above before visiting <a href="@url">your new site</a>.', array('@url' => url(''))) : st('<a href="@url">Visit your new site</a>.', array('@url' => url('')))) . '</p>';
-
-  // Flush all caches to ensure that any full bootstraps during the installer
-  // do not leave stale cached data, and that any content types or other items
-  // registered by the install profile are registered correctly.
-  drupal_flush_all_caches();
-
   // Remember the profile which was used.
   variable_set('install_profile', drupal_get_profile());
 
-  // Install profiles are always loaded last
+  // Install profiles are always loaded last.
   db_update('system')
     ->fields(array('weight' => 1000))
     ->condition('type', 'module')
     ->condition('name', drupal_get_profile())
     ->execute();
 
-  // Cache a fully-built schema.
-  drupal_get_schema(NULL, TRUE);
+  // Flush all caches to ensure that any full bootstraps during the installer
+  // do not leave stale cached data, and that any content types or other items
+  // registered by the install profile are registered correctly.
+  drupal_flush_all_caches();
+
+  // Re-initialize the maintenance theme.
+  // @todo drupal_flush_all_caches() resets everything, and afterwards rebuilds
+  //   various data structures, among which menu_rebuild() invokes hook_menu()
+  //   implementations, which may trigger a theme initialization (e.g., Block
+  //   module defines separate menu items per theme).
+  unset($GLOBALS['theme']);
+  drupal_maintenance_theme();
+
+  drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_distribution_name())), PASS_THROUGH);
+
+  $messages = drupal_set_message();
+  $output = '<p>' . st('Congratulations, you installed @drupal!', array('@drupal' => drupal_install_profile_distribution_name())) . '</p>';
+  $output .= '<p>' . (isset($messages['error']) ? st('Review the messages above before visiting <a href="@url">your new site</a>.', array('@url' => url(''))) : st('<a href="@url">Visit your new site</a>.', array('@url' => url('')))) . '</p>';
 
   // Run cron to populate update status tables (if available) so that users
   // will be warned if they've installed an out of date Drupal version.
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 069e879..f689370 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -941,6 +941,13 @@ function _block_get_renderable_block($element) {
  * Implements hook_flush_caches().
  */
 function block_flush_caches() {
+  return array('block');
+}
+
+/**
+ * Implements hook_rebuild().
+ */
+function block_rebuild() {
   // Rehash blocks for active themes. We don't use list_themes() here,
   // because if MAINTENANCE_MODE is defined it skips reading the database,
   // and we can't tell which themes are active.
@@ -948,8 +955,6 @@ function block_flush_caches() {
   foreach ($themes as $theme) {
     _block_rehash($theme->name);
   }
-
-  return array('block');
 }
 
 /**
diff --git a/core/modules/comment/comment.test b/core/modules/comment/comment.test
index 1fc8297..cabca76 100644
--- a/core/modules/comment/comment.test
+++ b/core/modules/comment/comment.test
@@ -2086,7 +2086,6 @@ class CommentFieldsTest extends CommentHelperCase {
     $edit['modules[Core][book][enable]'] = 'book';
     $edit['modules[Core][poll][enable]'] = 'poll';
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->resetAll();
 
     // Now enable the comment module.
     $edit = array();
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 1e8b7bb..57c2eed 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -383,11 +383,16 @@ function field_system_info_alter(&$info, $file, $type) {
  * Implements hook_flush_caches().
  */
 function field_flush_caches() {
+  // Request a flush of our cache table.
+  return array('field');
+}
+
+/**
+ * Implements hook_rebuild().
+ */
+function field_rebuild() {
   // Refresh the 'active' status of fields.
   field_sync_field_status();
-
- // Request a flush of our cache table.
-  return array('field');
 }
 
 /**
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 45f5170..14ee3e9 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -6,6 +6,13 @@
  */
 
 /**
+ * Implements hook_flush_caches().
+ */
+function filter_flush_caches() {
+  return array('filter');
+}
+
+/**
  * Implements hook_help().
  */
 function filter_help($path, $arg) {
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 5e1c3b3..9e21bfa 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -77,6 +77,13 @@ const NODE_ACCESS_DENY = 'deny';
 const NODE_ACCESS_IGNORE = NULL;
 
 /**
+ * Implements hook_rebuild().
+ */
+function node_rebuild() {
+  node_types_rebuild();
+}
+
+/**
  * Implements hook_help().
  */
 function node_help($path, $arg) {
@@ -1890,9 +1897,6 @@ function node_menu() {
     'type' => MENU_CALLBACK,
   );
   // @todo Remove this loop when we have a 'description callback' property.
-  // Resets the internal static cache of _node_types_build() and forces a
-  // rebuild of the node type information.
-  node_type_cache_reset();
   foreach (node_type_get_types() as $type) {
     $type_url_str = str_replace('_', '-', $type->type);
     $items['node/add/' . $type_url_str] = array(
diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index 540dc0e..57e807d 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -1493,17 +1493,7 @@ class DrupalWebTestCase extends DrupalTestCase {
    * are enabled later.
    */
   protected function resetAll() {
-    // Reset all static variables.
-    drupal_static_reset();
-    // Reset the list of enabled modules.
-    module_list(TRUE);
-
-    // Reset cached schema for new database prefix. This must be done before
-    // drupal_flush_all_caches() so rebuilds can make use of the schema of
-    // modules enabled on the cURL side.
-    drupal_get_schema(NULL, TRUE);
-
-    // Perform rebuilds and flush remaining caches.
+    // Clear all database and static caches and rebuild data structures.
     drupal_flush_all_caches();
 
     // Reload global $conf array and permissions.
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index c6e1288..9d8c49a 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -2087,22 +2087,57 @@ function hook_mail($key, &$message, $params) {
 }
 
 /**
- * Add a list of cache tables to be cleared.
+ * Flush all database and static caches.
  *
- * This hook allows your module to add cache bins to the list of cache bins
- * that will be cleared by the Clear button on the Performance page or
- * whenever drupal_flush_all_caches is invoked.
+ * This hook asks your module to clear all of its database and static caches, in
+ * order to ensure a clean environment for subsequently invoked data rebuilds.
+ *
+ * Do NOT use this hook for rebuilding information. Only use it to flush caches
+ * and return cache bins to be flushed.
+ *
+ * Any static variables that are not using drupal_static() must be reset in this
+ * hook, too. However, static caches using drupal_static() do not need to be
+ * reset manually.
+ *
+ * This hook is invoked by drupal_flush_all_caches(). It runs before module data
+ * is updated and before hook_rebuild().
  *
  * @return
- *   An array of cache bins.
+ *   An array of cache bins to be flushed.
  *
  * @see drupal_flush_all_caches()
+ * @see hook_rebuild()
  */
 function hook_flush_caches() {
   return array('example');
 }
 
 /**
+ * Rebuild data based upon refreshed caches.
+ *
+ * This hook allows your module to rebuild its data based on the latest/current
+ * module data. It runs after hook_flush_caches() and after all module data has
+ * been updated.
+ *
+ * This hook is only invoked after the system has been completely
+ * "re-initialized"; i.e., all previously cached data is known to be gone and
+ * every API in the system is known to return current information, so your
+ * module can safely rely on all available data to rebuild its own.
+ *
+ * @see hook_flush_caches()
+ * @see drupal_flush_all_caches()
+ */
+function hook_rebuild() {
+  // Rehash blocks for active themes. We don't use list_themes() here,
+  // because if MAINTENANCE_MODE is defined it skips reading the database,
+  // and we can't tell which themes are active.
+  $themes = db_query("SELECT name FROM {system} WHERE type = 'theme' AND status = 1");
+  foreach ($themes as $theme) {
+    _block_rehash($theme->name);
+  }
+}
+
+/**
  * Perform necessary actions before modules are installed.
  *
  * This function allows all modules to react prior to a module being installed.
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index dfb8936..50ce242 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2531,6 +2531,7 @@ function _system_update_bootstrap_status() {
   }
   $query->execute();
   // Reset the cached list of bootstrap modules.
+  // @todo This the caller's job and not always necessary.
   system_list_reset();
 }
 
@@ -3091,13 +3092,11 @@ function system_cron() {
 }
 
 /**
- * Implements hook_flush_caches().
+ * Implements hook_rebuild().
  */
-function system_flush_caches() {
+function system_rebuild() {
   // Rebuild list of date formats.
   system_date_formats_rebuild();
-  // Reset the menu static caches.
-  menu_reset_static_cache();
 }
 
 /**
