=== modified file 'includes/actions.inc'
--- includes/actions.inc	2008-06-29 12:07:15 +0000
+++ includes/actions.inc	2008-07-13 22:14:29 +0000
@@ -83,7 +83,10 @@ function actions_do($action_ids, $object
       }
       // Singleton action; $action_id is the function name.
       else {
-        $result[$action_id] = $action_id($object, $context, $a1, $a2);
+        $function = $action_id;
+      }
+      if (drupal_function_exists($function)) {
+        $result[$action_id] = $function($object, $context, $a1, $a2);
       }
     }
   }

=== modified file 'includes/batch.inc'
--- includes/batch.inc	2008-06-24 21:51:02 +0000
+++ includes/batch.inc	2008-07-13 22:14:10 +0000
@@ -190,7 +190,7 @@ function _batch_process() {
     // We assume a single pass operation and set the completion level
     // to 1 by default.
     $finished = 1;
-    if ((list($function, $args) = reset($current_set['operations'])) && function_exists($function)) {
+    if ((list($function, $args) = reset($current_set['operations'])) && drupal_function_exists($function)) {
       // Build the 'context' array, execute the function call,
       // and retrieve the user message.
       $batch_context = array('sandbox' => &$current_set['sandbox'], 'results' => &$current_set['results'], 'finished' => &$finished, 'message' => &$task_message);
@@ -282,7 +282,7 @@ function _batch_next_set() {
   if (isset($batch['sets'][$batch['current_set'] + 1])) {
     $batch['current_set']++;
     $current_set =& _batch_current_set();
-    if (isset($current_set['form_submit']) && ($function = $current_set['form_submit']) && function_exists($function)) {
+    if (isset($current_set['form_submit']) && ($function = $current_set['form_submit']) && drupal_function_exists($function)) {
       // We use our stored copies of $form and $form_state, to account for
       // possible alteration by the submit handlers.
       $function($batch['form'], $batch['form_state']);
@@ -306,7 +306,7 @@ function _batch_finished() {
       if (isset($batch_set['file']) && is_file($batch_set['file'])) {
         include_once($batch_set['file']);
       }
-      if (function_exists($batch_set['finished'])) {
+      if (drupal_function_exists($batch_set['finished'])) {
         $batch_set['finished']($batch_set['success'], $batch_set['results'], $batch_set['operations']);
       }
     }

=== modified file 'includes/bootstrap.inc'
--- includes/bootstrap.inc	2008-07-08 01:08:15 +0000
+++ includes/bootstrap.inc	2008-07-13 22:14:10 +0000
@@ -430,10 +430,11 @@ function drupal_get_filename($type, $nam
     // nothing
   }
   // Verify that we have an active database connection, before querying
-  // the database.  This is required because this function is called both
+  // the database. This is required because this function is called both
   // before we have a database connection (i.e. during installation) and
-  // when a database connection fails.
-  elseif (db_is_active() && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) {
+  // when a database connection fails. As this is called very, very early
+  // during the install process, even database.inc might not be loaded.
+  elseif (function_exists('db_is_active') && db_is_active() && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) {
     $files[$type][$name] = $file;
   }
   else {
@@ -507,17 +508,22 @@ function variable_get($name, $default) {
  * @param $value
  *   The value to set. This can be any PHP data type; these functions take care
  *   of serialization as necessary.
+ * @param $permanent
+ *   Whether to set the variable permanently or just for the time of this page
+ *   load.
  */
-function variable_set($name, $value) {
+function variable_set($name, $value, $permanent = TRUE) {
   global $conf;
 
-  $serialized_value = serialize($value);
-  db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name);
-  if (!db_affected_rows()) {
-    @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value);
-  }
+  if ($permanent) {
+    $serialized_value = serialize($value);
+    db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name);
+    if (!db_affected_rows()) {
+      @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value);
+    }
 
-  cache_clear_all('variables', 'cache');
+    cache_clear_all('variables', 'cache');
+  }
 
   $conf[$name] = $value;
 }
@@ -561,18 +567,6 @@ function page_get_cache() {
 }
 
 /**
- * Call all init or exit hooks without including all modules.
- *
- * @param $hook
- *   The name of the bootstrap hook we wish to invoke.
- */
-function bootstrap_invoke_all($hook) {
-  foreach (module_list(TRUE, TRUE) as $module) {
-    module_invoke($module, $hook);
-  }
-}
-
-/**
  * Includes a file with the provided type and name. This prevents
  * including a theme, engine, module, etc., more than once.
  *
@@ -677,13 +671,6 @@ function drupal_page_cache_header($cache
 }
 
 /**
- * Define the critical hooks that force modules to always be loaded.
- */
-function bootstrap_hooks() {
-  return array('boot', 'exit');
-}
-
-/**
  * Unserializes and appends elements from a serialized string.
  *
  * @param $obj
@@ -819,7 +806,7 @@ function watchdog($type, $message, $vari
     );
 
   // Call the logging hooks to log/process the message
-  foreach (module_implements('watchdog', TRUE) as $module) {
+  foreach (module_implements('watchdog') as $module) {
     module_invoke($module, 'watchdog', $log_message);
   }
 }
@@ -956,15 +943,23 @@ function drupal_anonymous_user($session 
  *     DRUPAL_BOOTSTRAP_LANGUAGE: identify the language used on the page.
  *     DRUPAL_BOOTSTRAP_PATH: set $_GET['q'] to Drupal path of request.
  *     DRUPAL_BOOTSTRAP_FULL: Drupal is fully loaded, validate and fix input data.
+ *
+ *  Optional. If left empty, then this function only returns the array of phases left.
+ *
+ * @return
+ *  Array of phases left.
  */
-function drupal_bootstrap($phase) {
+function drupal_bootstrap($phase = NULL) {
   static $phases = array(DRUPAL_BOOTSTRAP_CONFIGURATION, DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE, DRUPAL_BOOTSTRAP_DATABASE, DRUPAL_BOOTSTRAP_ACCESS, DRUPAL_BOOTSTRAP_SESSION, DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE, DRUPAL_BOOTSTRAP_LANGUAGE, DRUPAL_BOOTSTRAP_PATH, DRUPAL_BOOTSTRAP_FULL), $phase_index = 0;
 
-  while ($phase >= $phase_index && isset($phases[$phase_index])) {
-    $current_phase = $phases[$phase_index];
-    unset($phases[$phase_index++]);
-    _drupal_bootstrap($current_phase);
+  if (isset($phase)) {
+    while ($phase >= $phase_index && isset($phases[$phase_index])) {
+      $current_phase = $phases[$phase_index];
+      unset($phases[$phase_index++]);
+      _drupal_bootstrap($current_phase);
+    }
   }
+  return $phases;
 }
 
 function _drupal_bootstrap($phase) {
@@ -1027,14 +1022,14 @@ function _drupal_bootstrap($phase) {
       $cache = $cache_mode == CACHE_DISABLED ? '' : page_get_cache();
       // If the skipping of the bootstrap hooks is not enforced, call hook_boot.
       if ($cache_mode != CACHE_AGGRESSIVE) {
-        bootstrap_invoke_all('boot');
+        module_invoke_all('boot');
       }
       // If there is a cached page, display it.
       if ($cache) {
         drupal_page_cache_header($cache);
         // If the skipping of the bootstrap hooks is not enforced, call hook_exit.
         if ($cache_mode != CACHE_AGGRESSIVE) {
-          bootstrap_invoke_all('exit');
+          module_invoke_all('exit');
         }
         // We are done.
         exit;
@@ -1218,33 +1213,38 @@ function ip_address($reset = false) {
  * @return
  *   TRUE if the function is now available, FALSE otherwise.
  */
-function drupal_function_exists($function) {
-  static $checked = array();
+function drupal_function_exists($function, $file = '', $module = '') {
+  static $checked = array(), $modules = array();
 
-  if (defined('MAINTENANCE_MODE')) {
-    return function_exists($function);
-  }
-
-  if (isset($checked[$function])) {
-    return $checked[$function];
-  }
-  $checked[$function] = FALSE;
-
-  if (function_exists($function)) {
-    registry_mark_code('function', $function);
-    $checked[$function] = TRUE;
-    return TRUE;
-  }
-
-  $file = db_result(db_query("SELECT filename FROM {registry} WHERE name = '%s' AND type = '%s'", $function, 'function'));
-  if ($file) {
-    require_once($file);
+  // Is this the first time we see this function?
+  if (!isset($checked[$function])) {
     $checked[$function] = function_exists($function);
+    // It does not exist, let's try include files.
+    if (!$checked[$function]) {
+      // If we are not given a file but have the database loaded already,
+      // we try to look it up.
+      if (!$file && !defined('MAINTENANCE_MODE') && ($result = db_fetch_array(db_query("SELECT filename, module FROM {registry} WHERE name = '%s' AND type = 'function'", $function)))) {
+        $file = $result['filename'];
+        $module = $result['module'];
+      }
+      // Either a $file was passed to the function or one was found in the database.
+      if ($file) {
+        // Load it.
+        require_once($file);
+        // Does it exist now?
+        $checked[$function] = function_exists($function);
+        // Modules are files where we store common functionality so we need to
+        // make sure they are loaded along with the function itself.
+        if ($module && $file != $module && !isset($modules[$module])) {
+          $modules[$module] = TRUE;
+          require_once($module);
+        }
+      }
+    }
     if ($checked[$function]) {
       registry_mark_code('function', $function);
     }
   }
-
   return $checked[$function];
 }
 
@@ -1331,31 +1331,6 @@ function drupal_rebuild_code_registry() 
 }
 
 /**
- * Save hook implementations cache.
- *
- * @param $hook
- *   Array with the hook name and list of modules that implement it.
- * @param $write_to_persistent_cache
- *   Whether to write to the persistent cache.
- */
-function registry_cache_hook_implementations($hook, $write_to_persistent_cache = FALSE) {
-  static $implementations;
-
-  if ($hook) {
-    // Newer is always better, so overwrite anything that's come before.
-    $implementations[$hook['hook']] = $hook['modules'];
-  }
-
-  if ($write_to_persistent_cache === TRUE) {
-    // Only write this to cache if the implementations data we are going to cache
-    // is different to what we loaded earlier in the request.
-    if ($implementations != registry_get_hook_implementations_cache()) {
-      cache_set('hooks', $implementations, 'cache_registry');
-    }
-  }
-}
-
-/**
  * Save the files required by the registry for this path.
  */
 function registry_cache_path_files() {
@@ -1404,22 +1379,6 @@ function registry_load_path_files($retur
 }
 
 /**
- * registry_get_hook_implementations_cache
- */
-function registry_get_hook_implementations_cache() {
-  static $implementations;
-  if ($implementations === NULL) {
-    if ($cache = cache_get('hooks', 'cache_registry')) {
-      $implementations = $cache->data;
-    }
-    else {
-      $implementations = array();
-    }
-  }
-  return $implementations;
-}
-
-/**
  * @} End of "ingroup registry".
  */
 

=== modified file 'includes/common.inc'
--- includes/common.inc	2008-07-02 19:36:52 +0000
+++ includes/common.inc	2008-07-13 22:14:10 +0000
@@ -1482,7 +1482,8 @@ function drupal_page_footer() {
 
   module_invoke_all('exit');
 
-  registry_cache_hook_implementations(FALSE, TRUE);
+  // Write the implementation cache.
+  module_implements();
   registry_cache_path_files();
 }
 
@@ -2465,8 +2466,8 @@ function _drupal_bootstrap_full() {
   unicode_check();
   // Undo magic quotes
   fix_gpc_magic();
-  // Load all enabled modules
-  module_load_all();
+  // Load all essential modules.
+  module_load();
   // Let all modules take action before menu system handles the request
   // We do not want this while running update.php.
   if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
@@ -2494,7 +2495,7 @@ function page_set_cache() {
     // This will fail in some cases, see page_get_cache() for the explanation.
     if ($data = ob_get_contents()) {
       $cache = TRUE;
-      if (variable_get('page_compression', TRUE) && function_exists('gzencode')) {
+      if (variable_get('page_compression', TRUE) && drupal_function_exists('gzencode')) {
         // We do not store the data in case the zlib mode is deflate.
         // This should be rarely happening.
         if (zlib_get_coding_type() == 'deflate') {
@@ -3063,9 +3064,6 @@ function drupal_get_schema($table = NULL
     // Otherwise, rebuild the schema cache.
     else {
       $schema = array();
-      // Load the .install files to get hook_schema.
-      module_load_all_includes('install');
-
       // Invoke hook_schema for all modules.
       foreach (module_implements('schema') as $module) {
         $current = module_invoke($module, 'schema');

=== modified file 'includes/file.inc'
--- includes/file.inc	2008-07-05 18:34:29 +0000
+++ includes/file.inc	2008-07-13 22:14:10 +0000
@@ -585,6 +585,7 @@ function file_save_upload($source, $vali
     $errors = array();
     foreach ($validators as $function => $args) {
       array_unshift($args, $file);
+      drupal_function_exists($function);
       $errors = array_merge($errors, call_user_func_array($function, $args));
     }
 

=== modified file 'includes/menu.inc'
--- includes/menu.inc	2008-07-10 10:58:01 +0000
+++ includes/menu.inc	2008-07-13 22:14:10 +0000
@@ -454,9 +454,11 @@ function _menu_load_objects(&$item, &$ma
             }
           }
           array_unshift($args, $value);
-          $return = call_user_func_array($function, $args);
+          if (drupal_function_exists($function)) {
+            $return = call_user_func_array($function, $args);
+          }
         }
-        else {
+        elseif (drupal_function_exists($function)) {
           $return = $function($value);
         }
         // If callback returned an error or there is no callback, trigger 404.
@@ -498,7 +500,7 @@ function _menu_check_access(&$item, $map
     if ($callback == 'user_access') {
       $item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
     }
-    else {
+    elseif (drupal_function_exists($callback)) {
       $item['access'] = call_user_func_array($callback, $arguments);
     }
   }
@@ -545,7 +547,7 @@ function _menu_item_localize(&$item, $ma
         $item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map));
       }
     }
-    elseif ($callback) {
+    elseif ($callback && drupal_function_exists($callback)) {
       if (empty($item['title_arguments'])) {
         $item['title'] = $callback($item['title']);
       }
@@ -1726,7 +1728,7 @@ function menu_router_build($reset = FALS
       // We need to manually call each module so that we can know which module
       // a given item came from.
       $callbacks = array();
-      foreach (module_implements('menu', NULL, TRUE) as $module) {
+      foreach (module_implements('menu') as $module) {
         $router_items = call_user_func($module . '_menu');
         if (isset($router_items) && is_array($router_items)) {
           foreach (array_keys($router_items) as $path) {

=== modified file 'includes/module.inc'
--- includes/module.inc	2008-05-13 17:38:42 +0000
+++ includes/module.inc	2008-07-13 22:14:10 +0000
@@ -9,9 +9,9 @@
 /**
  * Load all the modules that have been enabled in the system table.
  */
-function module_load_all() {
-  foreach (module_list(TRUE, FALSE) as $module) {
-    drupal_load('module', $module);
+function module_load($modules = array('node', 'user', 'filter')) {
+  foreach ($modules as $module) {
+    drupal_load('module', $module, "./modules/$module/$module.module");
   }
 }
 
@@ -25,60 +25,15 @@ function module_iterate($function, $argu
 }
 
 /**
- * Collect a list of all loaded modules. During the bootstrap, return only
- * vital modules. See bootstrap.inc
+ * Collect a list of all loaded modules.
  *
- * @param $refresh
- *   Whether to force the module list to be regenerated (such as after the
- *   administrator has changed the system settings).
- * @param $bootstrap
- *   Whether to return the reduced set of modules loaded in "bootstrap mode"
- *   for cached pages. See bootstrap.inc.
- * @param $sort
- *   By default, modules are ordered by weight and filename, settings this option
- *   to TRUE, module list will be ordered by module name.
- * @param $fixed_list
- *   (Optional) Override the module list with the given modules. Stays until the
- *   next call with $refresh = TRUE.
  * @return
  *   An associative array whose keys and values are the names of all loaded
  *   modules.
  */
-function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE, $fixed_list = NULL) {
-  static $list, $sorted_list;
-
-  if ($refresh || $fixed_list) {
-    unset($sorted_list);
-    $list = array();
-    if ($fixed_list) {
-      foreach ($fixed_list as $name => $module) {
-        drupal_get_filename('module', $name, $module['filename']);
-        $list[$name] = $name;
-      }
-    }
-    else {
-      if ($bootstrap) {
-        $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1 ORDER BY weight ASC, filename ASC");
-      }
-      else {
-        $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, filename ASC");
-      }
-      while ($module = db_fetch_object($result)) {
-        if (file_exists($module->filename)) {
-          drupal_get_filename('module', $module->name, $module->filename);
-          $list[$module->name] = $module->name;
-        }
-      }
-    }
-  }
-  if ($sort) {
-    if (!isset($sorted_list)) {
-      $sorted_list = $list;
-      ksort($sorted_list);
-    }
-    return $sorted_list;
-  }
-  return $list;
+function module_list() {
+  static $stored_list, $sorted_list;
+  return variable_get('module_list', array());
 }
 
 /**
@@ -121,26 +76,21 @@ function module_rebuild_cache() {
     // 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;
-      }
-    }
-
     // 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);
+      db_query("UPDATE {system} SET info = '%s', name = '%s', filename = '%s' WHERE filename = '%s'", serialize($files[$filename]->info), $file->name, $file->filename, $file->old_filename);
+      if ($file->status) {
+        $module_list[$file->name] = $file->name;
+      }
     }
     else {
       // This is a new module.
       $files[$filename]->status = 0;
-      db_query("INSERT INTO {system} (name, info, type, filename, status, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0, $bootstrap);
+      db_query("INSERT INTO {system} (name, info, type, filename, status) VALUES ('%s', '%s', '%s', '%s', %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0);
     }
   }
   $files = _module_build_dependencies($files);
+  variable_set('module_list', $module_list);
   return $files;
 }
 
@@ -212,7 +162,7 @@ function _module_build_dependencies($fil
 }
 
 /**
- * Determine whether a given module exists.
+ * Determine whether a given module exists and load it if it does.
  *
  * @param $module
  *   The name of the module (without the .module extension).
@@ -221,7 +171,10 @@ function _module_build_dependencies($fil
  */
 function module_exists($module) {
   $list = module_list();
-  return isset($list[$module]);
+  if (isset($list[$module])) {
+    drupal_load('module', $module);
+    return TRUE;
+  }
 }
 
 /**
@@ -261,17 +214,6 @@ function module_load_include($type, $mod
 }
 
 /**
- * Load an include file for each of the modules that have been enabled in
- * the system table.
- */
-function module_load_all_includes($type, $name = NULL) {
-  $modules = module_list();
-  foreach ($modules as $module) {
-    module_load_include($type, $module, $name);
-  }
-}
-
-/**
  * Enable a given list of modules.
  *
  * @param $module_list
@@ -290,8 +232,6 @@ function module_enable($module_list) {
   }
 
   if (!empty($invoke_modules)) {
-    // Refresh the module list to include the new enabled module.
-    module_list(TRUE, FALSE);
     // Force to regenerate the stored list of hook implementations.
     drupal_rebuild_code_registry();
   }
@@ -377,13 +317,7 @@ function module_disable($module_list) {
  *   implemented in that module.
  */
 function module_hook($module, $hook) {
-  $function = $module . '_' . $hook;
-  if (defined('MAINTENANCE_MODE')) {
-    return function_exists($function);
-  }
-  else {
-    return drupal_function_exists($function);
-  }
+  return drupal_function_exists($module . '_' . $hook);
 }
 
 /**
@@ -391,9 +325,6 @@ function module_hook($module, $hook) {
  *
  * @param $hook
  *   The name of the hook (e.g. "help" or "menu").
- * @param $sort
- *   By default, modules are ordered by weight and filename, settings this option
- *   to TRUE, module list will be ordered by module name.
  * @param $refresh
  *   For internal use only: Whether to force the stored list of hook
  *   implementations to be regenerated (such as after enabling a new module,
@@ -401,25 +332,77 @@ function module_hook($module, $hook) {
  * @return
  *   An array with the names of the modules which are implementing this hook.
  */
-function module_implements($hook, $sort = FALSE, $refresh = FALSE) {
-  static $implementations = array();
+function module_implements($hook = '', $refresh = FALSE) {
+  static $implementations = array(), $loaded = array(), $cache;
 
+  // If we are in maintenance mode but managed to bootstrap fully then we can
+  // use the registry.
+  if (defined('MAINTENANCE_MODE') && drupal_bootstrap()) {
+    $implementations = array();
+    foreach (module_list() as $module) {
+      if (module_hook($module, $hook)) {
+        $implementations[] = $module;
+      }
+    }
+    return $implementations;
+  }
   if ($refresh) {
     $implementations = array();
+    $loaded = array();
+    cache_clear_all('hooks', 'cache_registry');
+    return;
   }
-  else if (!defined('MAINTENANCE_MODE') && empty($implementations)) {
-    $implementations = registry_get_hook_implementations_cache();
+  if (!$hook) {
+    // Only write this to cache if the implementations data we are going to cache
+    // is different to what we loaded earlier in the request.
+    if ($cache && $implementations != $cache->data) {
+      cache_set('hooks', $implementations, 'cache_registry');
+    }
+    return;
   }
 
-  if (!isset($implementations[$hook])) {
-    $implementations[$hook] = array();
-    foreach (module_list() as $module) {
-      if (module_hook($module, $hook)) {
-        $implementations[$hook][] = $module;
+  if (empty($implementations) && ($cache = cache_get('hooks', 'cache_registry'))) {
+    $implementations = $cache->data;
+  }
+
+  if (empty($loaded[$hook])) {
+    if (isset($implementations[$hook])) {
+      $cached = TRUE;
+      $candidate_list = $implementations[$hook];
+    }
+    else {
+      $cached = FALSE;
+      $candidate_list = module_list();
+      $implementations[$hook] = array();
+    }
+
+    $lookup = array();
+    $placeholders = array();
+    // $candidate_list holds the possible implementations.
+    foreach ($candidate_list as $module) {
+      $function = $module .'_'. $hook;
+      // If the implementations are already cached but the function can not
+      // be found then we need to look up the filename for this function and
+      // load the include file. No point in caching the filenames as they are
+      // cached by router path anyways.
+      if (!$cached || !function_exists($function)) {
+        $lookup[] = $function;
+        $functions[$function] = $module;
+        $placeholders[] = "'%s'";
+      }
+    }
+    if ($lookup) {
+      // If there are functions that needs to be looked up.
+      $result = db_query("SELECT name, filename, module FROM {registry} WHERE type = 'function' AND name IN (". implode(', ', $placeholders) .")", $lookup);
+      while ($function = db_fetch_object($result)) {
+        if (!$cached || !in_array($functions[$function->name], $implementations[$hook])) {
+          $implementations[$hook][] = $functions[$function->name];
+        }
+        drupal_function_exists($function->name, $function->filename, $function->module);
       }
     }
+    $loaded[$hook] = TRUE;
   }
-  registry_cache_hook_implementations(array('hook' => $hook, 'modules' => $implementations[$hook]));
 
   // The explicit cast forces a copy to be made. This is needed because
   // $implementations[$hook] is only a reference to an element of

=== modified file 'includes/registry.inc'
--- includes/registry.inc	2008-05-06 12:32:02 +0000
+++ includes/registry.inc	2008-07-13 22:14:10 +0000
@@ -23,6 +23,10 @@
  * @See drupal_rebuild_code_registry.
  */
 function _drupal_rebuild_code_registry() {
+  include_once './includes/module.inc';
+  include_once './includes/common.inc';
+  include_once './includes/file.inc';
+  drupal_load('module', 'system', 'modules/system/system.module');
   // Reset the resources cache.
   _registry_get_resource_name();
   // Get the list of files we are going to parse.
@@ -31,12 +35,12 @@ function _drupal_rebuild_code_registry()
     if ($module->status) {
       $dir = dirname($module->filename);
       foreach ($module->info['files'] as $file) {
-        $files["./$dir/$file"] = array();
+        $files["./$dir/$file"] = array('module' => "./$module->filename");
       }
     }
   }
   foreach (file_scan_directory('includes', '\.inc$') as $filename => $file) {
-    $files["./$filename"] = array();
+    $files["./$filename"] = array('module' => '');
   }
 
   foreach (registry_get_parsed_files() as $filename => $file) {
@@ -53,6 +57,7 @@ function _drupal_rebuild_code_registry()
   }
   _registry_parse_files($files);
 
+  module_implements('', TRUE);
   cache_clear_all('*', 'cache_registry');
 }
 
@@ -83,7 +88,7 @@ function _registry_parse_files($files) {
     if ($new_file || $md5 != $file['md5']) {
       // We update the md5 after we've saved the files resources rather than here, so if we
       // don't make it through this rebuild, the next run will reparse the file.
-      _registry_parse_file($filename, $contents);
+      _registry_parse_file($filename, $contents, $file['module']);
       $file['md5'] = $md5;
       if ($new_file) {
         db_query("INSERT INTO {registry_file} (md5, filename) VALUES ('%s', '%s')", $md5, $filename);
@@ -102,8 +107,10 @@ function _registry_parse_files($files) {
  *  Name of the file we are going to parse.
  * @param $contents
  *  Contents of the file we are going to parse as a string.
+ * @param $module
+ *  The name of the module this file belongs to.
  */
-function _registry_parse_file($filename, $contents) {
+function _registry_parse_file($filename, $contents, $module) {
   static $map = array(T_FUNCTION => 'function', T_CLASS => 'class', T_INTERFACE => 'interface');
   // Delete registry entries for this file, so we can insert the new resources.
   db_query("DELETE FROM {registry} WHERE filename = '%s'", $filename);
@@ -113,7 +120,7 @@ function _registry_parse_file($filename,
     if (is_array($token) && isset($map[$token[0]])) {
       $type = $map[$token[0]];
       if ($resource_name = _registry_get_resource_name($tokens, $type)) {
-        db_query("INSERT INTO {registry} (name, type, filename) VALUES ('%s', '%s', '%s')", $resource_name, $type, $filename);
+        db_query("INSERT INTO {registry} (name, type, filename, module) VALUES ('%s', '%s', '%s', '%s')", $resource_name, $type, $filename, $module);
         // We skip the body because classes may contain functions.
         _registry_skip_body($tokens);
       }

=== modified file 'includes/theme.inc'
--- includes/theme.inc	2008-07-11 02:23:08 +0000
+++ includes/theme.inc	2008-07-13 22:14:10 +0000
@@ -277,7 +277,7 @@ function drupal_rebuild_theme_registry()
  */
 function _theme_process_registry(&$cache, $name, $type, $theme, $path) {
   $function = $name . '_theme';
-  if (function_exists($function)) {
+  if (drupal_function_exists($function)) {
     $result = $function($cache, $type, $theme, $path);
 
     foreach ($result as $hook => $info) {
@@ -1596,7 +1596,7 @@ function theme_closure($main = 0) {
 function theme_blocks($region) {
   $output = '';
 
-  if ($list = block_list($region)) {
+  if ($list = module_invoke('block', 'list', $region)) {
     foreach ($list as $key => $block) {
       // $key == <i>module</i>_<i>delta</i>
       $output .= theme('block', $block);

=== modified file 'install.php'
--- install.php	2008-07-03 17:57:03 +0000
+++ install.php	2008-07-13 22:14:10 +0000
@@ -45,11 +45,9 @@ function install_main() {
 
   // Load module basics (needed for hook invokes).
   include_once './includes/module.inc';
-  $module_list['system']['filename'] = 'modules/system/system.module';
-  $module_list['filter']['filename'] = 'modules/filter/filter.module';
-  module_list(TRUE, FALSE, FALSE, $module_list);
-  drupal_load('module', 'system');
-  drupal_load('module', 'filter');
+  $modules = array('system', 'filter');
+  variable_set('module_list', $modules, FALSE);
+  module_load($modules);
 
   // Set up theme system for the maintenance page.
   drupal_maintenance_theme();
@@ -617,10 +615,11 @@ function install_already_done_error() {
  * Tasks performed after the database is initialized.
  */
 function install_tasks($profile, $task) {
-  global $base_url, $install_locale;
+  global $base_url, $install_locale, $module_list;
 
   // Bootstrap newly installed Drupal, while preserving existing messages.
   $messages = isset($_SESSION['messages']) ? $_SESSION['messages'] : '';
+  $module_list = array();
   drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
   $_SESSION['messages'] = $messages;
 

=== modified file 'modules/aggregator/aggregator.info'
--- modules/aggregator/aggregator.info	2008-05-15 21:27:32 +0000
+++ modules/aggregator/aggregator.info	2008-07-13 22:14:10 +0000
@@ -8,3 +8,4 @@ core = 7.x
 files[] = aggregator.module
 files[] = aggregator.admin.inc
 files[] = aggregator.pages.inc
+files[] = aggregator.install

=== modified file 'modules/block/block.info'
--- modules/block/block.info	2008-05-15 21:30:02 +0000
+++ modules/block/block.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ version = VERSION
 core = 7.x
 files[] = block.module
 files[] = block.admin.inc
+files[] = block.install

=== modified file 'modules/blogapi/blogapi.info'
--- modules/blogapi/blogapi.info	2008-05-13 18:13:43 +0000
+++ modules/blogapi/blogapi.info	2008-07-13 22:14:10 +0000
@@ -6,3 +6,4 @@ package = Core - optional
 version = VERSION
 core = 7.x
 files[] = blogapi.module
+files[] = blogapi.install

=== modified file 'modules/book/book.info'
--- modules/book/book.info	2008-05-15 21:19:24 +0000
+++ modules/book/book.info	2008-07-13 22:14:10 +0000
@@ -8,3 +8,4 @@ core = 7.x
 files[] = book.module
 files[] = book.admin.inc
 files[] = book.pages.inc
+files[] = book.install

=== modified file 'modules/color/color.info'
--- modules/color/color.info	2008-05-19 19:36:41 +0000
+++ modules/color/color.info	2008-07-13 22:14:10 +0000
@@ -6,3 +6,4 @@ package = Core - optional
 version = VERSION
 core = 7.x
 files[] = color.module
+files[] = color.install

=== modified file 'modules/dblog/dblog.info'
--- modules/dblog/dblog.info	2008-05-06 12:18:44 +0000
+++ modules/dblog/dblog.info	2008-07-13 22:14:10 +0000
@@ -6,3 +6,4 @@ version = VERSION
 core = 7.x
 files[] = dblog.module
 files[] = dblog.admin.inc
+files[] = dblog.install

=== modified file 'modules/filter/filter.info'
--- modules/filter/filter.info	2008-05-06 12:18:44 +0000
+++ modules/filter/filter.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ core = 7.x
 files[] = filter.module
 files[] = filter.admin.inc
 files[] = filter.pages.inc
+files[] = filter.install

=== modified file 'modules/forum/forum.info'
--- modules/forum/forum.info	2008-05-06 12:18:44 +0000
+++ modules/forum/forum.info	2008-07-13 22:14:10 +0000
@@ -9,3 +9,4 @@ core = 7.x
 files[] = forum.module
 files[] = forum.admin.inc
 files[] = forum.pages.inc
+files[] = forum.install

=== modified file 'modules/help/help.module'
--- modules/help/help.module	2008-05-06 12:18:44 +0000
+++ modules/help/help.module	2008-07-13 22:14:10 +0000
@@ -17,7 +17,7 @@ function help_menu() {
     'weight' => 9,
   );
 
-  foreach (module_implements('help', TRUE) as $module) {
+  foreach (module_implements('help') as $module) {
     $items['admin/help/' . $module] = array(
       'title' => $module,
       'page callback' => 'help_page',

=== modified file 'modules/locale/locale.info'
--- modules/locale/locale.info	2008-05-06 12:18:44 +0000
+++ modules/locale/locale.info	2008-07-13 22:14:10 +0000
@@ -5,3 +5,4 @@ package = Core - optional
 version = VERSION
 core = 7.x
 files[] = locale.module
+files[] = locale.install

=== modified file 'modules/menu/menu.info'
--- modules/menu/menu.info	2008-05-06 12:18:44 +0000
+++ modules/menu/menu.info	2008-07-13 22:14:10 +0000
@@ -6,3 +6,4 @@ version = VERSION
 core = 7.x
 files[] = menu.module
 files[] = menu.admin.inc
+files[] = menu.install

=== modified file 'modules/node/node.admin.inc'
--- modules/node/node.admin.inc	2008-04-14 17:48:33 +0000
+++ modules/node/node.admin.inc	2008-07-13 22:14:10 +0000
@@ -533,7 +533,7 @@ function node_admin_nodes_submit($form, 
   $operation = $operations[$form_state['values']['operation']];
   // Filter out unchecked nodes
   $nodes = array_filter($form_state['values']['nodes']);
-  if ($function = $operation['callback']) {
+  if (($function = $operation['callback']) && drupal_function_exists($function)) {
     // Add in callback arguments if present.
     if (isset($operation['callback arguments'])) {
       $args = array_merge(array($nodes), $operation['callback arguments']);

=== modified file 'modules/node/node.info'
--- modules/node/node.info	2008-05-06 12:18:44 +0000
+++ modules/node/node.info	2008-07-13 22:14:10 +0000
@@ -8,3 +8,4 @@ files[] = node.module
 files[] = content_types.inc
 files[] = node.admin.inc
 files[] = node.pages.inc
+files[] = node.install

=== modified file 'modules/openid/openid.info'
--- modules/openid/openid.info	2008-05-06 12:18:44 +0000
+++ modules/openid/openid.info	2008-07-13 22:14:10 +0000
@@ -8,3 +8,4 @@ files[] = openid.module
 files[] = openid.inc
 files[] = openid.pages.inc
 files[] = xrds.inc
+files[] = openid.install

=== modified file 'modules/php/php.info'
--- modules/php/php.info	2008-05-06 12:18:44 +0000
+++ modules/php/php.info	2008-07-13 22:14:10 +0000
@@ -5,3 +5,4 @@ package = Core - optional
 version = VERSION
 core = 7.x
 files[] = php.module
+files[] = php.install

=== modified file 'modules/poll/poll.info'
--- modules/poll/poll.info	2008-05-06 12:18:44 +0000
+++ modules/poll/poll.info	2008-07-13 22:14:10 +0000
@@ -6,3 +6,4 @@ version = VERSION
 core = 7.x
 files[] = poll.module
 files[] = poll.pages.inc
+files[] = poll.install

=== modified file 'modules/profile/profile.info'
--- modules/profile/profile.info	2008-05-06 12:18:44 +0000
+++ modules/profile/profile.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ core = 7.x
 files[] = profile.module
 files[] = profile.admin.inc
 files[] = profile.pages.inc
+files[] = profile.install

=== modified file 'modules/search/search.info'
--- modules/search/search.info	2008-05-06 12:18:44 +0000
+++ modules/search/search.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ core = 7.x
 files[] = search.module
 files[] = search.admin.inc
 files[] = search.pages.inc
+files[] = search.install

=== modified file 'modules/simpletest/simpletest.info'
--- modules/simpletest/simpletest.info	2008-05-06 12:18:44 +0000
+++ modules/simpletest/simpletest.info	2008-07-13 22:14:10 +0000
@@ -5,3 +5,4 @@ package = Core - optional
 version = VERSION
 core = 7.x
 files[] = simpletest.module
+files[] = simpletest.install

=== modified file 'modules/statistics/statistics.info'
--- modules/statistics/statistics.info	2008-05-06 12:18:44 +0000
+++ modules/statistics/statistics.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ core = 7.x
 files[] = statistics.module
 files[] = statistics.admin.inc
 files[] = statistics.pages.inc
+files[] = statistics.install

=== modified file 'modules/syslog/syslog.info'
--- modules/syslog/syslog.info	2008-05-06 12:18:44 +0000
+++ modules/syslog/syslog.info	2008-07-13 22:14:10 +0000
@@ -5,3 +5,4 @@ package = Core - optional
 version = VERSION
 core = 7.x
 files[] = syslog.module
+files[] = syslog.install

=== modified file 'modules/system/system.admin.inc'
--- modules/system/system.admin.inc	2008-07-01 20:36:39 +0000
+++ modules/system/system.admin.inc	2008-07-13 22:14:10 +0000
@@ -40,7 +40,7 @@ function system_main_admin_page($arg = N
       }
       $block = $item;
       $block['content'] = '';
-      if ($item['block_callback'] && function_exists($item['block_callback'])) {
+      if ($item['block_callback'] && drupal_function_exists($item['block_callback'])) {
         $function = $item['block_callback'];
         $block['content'] .= $function();
       }

=== modified file 'modules/system/system.install'
--- modules/system/system.install	2008-07-01 20:36:39 +0000
+++ modules/system/system.install	2008-07-13 22:14:10 +0000
@@ -1083,6 +1083,12 @@ function system_schema() {
         'length' => 255,
         'not null' => TRUE,
       ),
+      'module'   => array(
+        'description' => t('Name of the module this file belongs to.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
     ),
     'primary key' => array('name', 'type'),
   );
@@ -2919,16 +2925,17 @@ function system_update_7006() {
   db_drop_field($ret, 'menu_router', 'file');
   $schema['registry'] = array(
     'fields' => array(
-      'name'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
-      'type'   => array('type' => 'varchar', 'length' => 9, 'not null' => TRUE, 'default' => ''),
-      'filename'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+      'name'     => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+      'type'     => array('type' => 'varchar', 'length' => 9, 'not null' => TRUE, 'default' => ''),
+      'filename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+      'module' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
     ),
     'primary key' => array('name', 'type'),
   );
   $schema['registry_file'] = array(
     'fields' => array(
-      'filename'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
-      'md5'   => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+      'filename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+      'md5'      => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
     ),
     'primary key' => array('filename'),
   );

=== modified file 'modules/system/system.module'
--- modules/system/system.module	2008-07-08 01:08:15 +0000
+++ modules/system/system.module	2008-07-13 22:14:10 +0000
@@ -1654,7 +1654,7 @@ function system_actions_configure($form_
 function system_actions_configure_validate($form, $form_state) {
   $function = actions_function_lookup($form_state['values']['actions_action']) . '_validate';
   // Hand off validation to the action.
-  if (function_exists($function)) {
+  if (drupal_function_exists($function)) {
     $function($form, $form_state);
   }
 }

=== modified file 'modules/taxonomy/taxonomy.info'
--- modules/taxonomy/taxonomy.info	2008-05-06 12:18:44 +0000
+++ modules/taxonomy/taxonomy.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ core = 7.x
 files[] = taxonomy.module
 files[] = taxonomy.admin.inc
 files[] = taxonomy.pages.inc
+files[] = taxonomy.install

=== modified file 'modules/translation/translation.info'
--- modules/translation/translation.info	2008-05-06 12:18:44 +0000
+++ modules/translation/translation.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ version = VERSION
 core = 7.x
 files[] = translation.module
 files[] = translation.pages.inc
+files[] = translation.install

=== modified file 'modules/trigger/trigger.info'
--- modules/trigger/trigger.info	2008-05-06 12:18:44 +0000
+++ modules/trigger/trigger.info	2008-07-13 22:14:10 +0000
@@ -6,3 +6,4 @@ version = VERSION
 core = 7.x
 files[] = trigger.module
 files[] = trigger.admin.inc
+files[] = trigger.install

=== modified file 'modules/update/update.info'
--- modules/update/update.info	2008-05-06 12:18:44 +0000
+++ modules/update/update.info	2008-07-13 22:14:10 +0000
@@ -9,3 +9,4 @@ files[] = update.compare.inc
 files[] = update.fetch.inc
 files[] = update.report.inc
 files[] = update.settings.inc
+files[] = update.install

=== modified file 'modules/upload/upload.info'
--- modules/upload/upload.info	2008-05-06 12:18:44 +0000
+++ modules/upload/upload.info	2008-07-13 22:14:10 +0000
@@ -6,3 +6,4 @@ version = VERSION
 core = 7.x
 files[] = upload.module
 files[] = upload.admin.inc
+files[] = upload.install

=== modified file 'modules/user/user.admin.inc'
--- modules/user/user.admin.inc	2008-05-07 19:34:23 +0000
+++ modules/user/user.admin.inc	2008-07-13 22:14:10 +0000
@@ -201,7 +201,7 @@ function user_admin_account_submit($form
   $operation = $operations[$form_state['values']['operation']];
   // Filter out unchecked accounts.
   $accounts = array_filter($form_state['values']['accounts']);
-  if ($function = $operation['callback']) {
+  if (($function = $operation['callback']) && drupal_function_exists($function)) {
     // Add in callback arguments if present.
     if (isset($operation['callback arguments'])) {
       $args = array_merge(array($accounts), $operation['callback arguments']);

=== modified file 'modules/user/user.info'
--- modules/user/user.info	2008-05-06 12:18:44 +0000
+++ modules/user/user.info	2008-07-13 22:14:10 +0000
@@ -7,3 +7,4 @@ core = 7.x
 files[] = user.module
 files[] = user.admin.inc
 files[] = user.pages.inc
+files[] = user.install

=== modified file 'modules/user/user.module'
--- modules/user/user.module	2008-06-27 07:25:11 +0000
+++ modules/user/user.module	2008-07-13 22:14:10 +0000
@@ -23,11 +23,9 @@ define('EMAIL_MAX_LENGTH', 64);
  * be passed by reference.
  */
 function user_module_invoke($type, &$array, &$user, $category = NULL) {
-  foreach (module_list() as $module) {
+  foreach (module_implements('user') as $module) {
     $function = $module . '_user';
-    if (function_exists($function)) {
-      $function($type, $array, $user, $category);
-    }
+    $function($type, $array, $user, $category);
   }
 }
 

=== modified file 'profiles/default/default.profile'
--- profiles/default/default.profile	2008-06-24 21:26:48 +0000
+++ profiles/default/default.profile	2008-07-13 22:14:10 +0000
@@ -126,6 +126,7 @@ function default_profile_tasks(&$task, $
 
   // Default page to not be promoted and have comments disabled.
   variable_set('node_options_page', array('status'));
+  drupal_load('module', 'comment');
   variable_set('comment_page', COMMENT_NODE_DISABLED);
 
   // Don't display date and author information for page nodes by default.

