Index: database/database.mysql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.mysql,v
retrieving revision 1.191
diff -u -r1.191 database.mysql
--- database/database.mysql	29 Jul 2005 07:26:49 -0000	1.191
+++ database/database.mysql	31 Jul 2005 15:05:05 -0000
@@ -617,6 +617,7 @@
   status int(2) NOT NULL default '0',
   throttle tinyint(1) DEFAULT '0' NOT NULL,
   bootstrap int(2) NOT NULL default '0',
+  hooks varchar(255) NOT NULL default '',
   PRIMARY KEY (filename)
 ) TYPE=MyISAM;
 
Index: database/updates.inc
===================================================================
RCS file: /cvs/drupal/drupal/database/updates.inc,v
retrieving revision 1.122
diff -u -r1.122 updates.inc
--- database/updates.inc	29 Jul 2005 20:31:04 -0000	1.122
+++ database/updates.inc	31 Jul 2005 15:05:12 -0000
@@ -118,7 +118,8 @@
   "2005-05-11" => "update_139",
   "2005-05-12" => "update_140",
   "2005-05-22" => "update_141",
-  "2005-07-29" => "update_142"
+  "2005-07-29" => "update_142",
+  "2005-07-31" => "update_143"
 );
 
 function update_32() {
@@ -2518,6 +2519,12 @@
   return $ret;
 }
 
+function update_143() {
+  $ret = array();
+  $ret[] = update_sql("ALTER TABLE {system} ADD COLUMN hooks varchar(255) NOT NULL default ''");
+  return $ret;
+}
+
 function update_sql($sql) {
   $edit = $_POST["edit"];
   $result = db_query($sql);
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.68
diff -u -r1.68 module.inc
--- includes/module.inc	29 Jul 2005 07:09:30 -0000	1.68
+++ includes/module.inc	31 Jul 2005 15:05:12 -0000
@@ -10,11 +10,11 @@
  * Initialize all modules.
  */
 function module_init() {
-  // Load all the modules that have been enabled in the system table.
-  foreach (module_list(TRUE, FALSE) as $module) {
-    drupal_load('module', $module);
-  }
+  // Preload all the modules that have been enabled in the system table.
+  module_list(TRUE, FALSE);
   module_invoke_all('init');
+  // Load locale if enabled
+  module_load('locale');
 }
 
 /**
@@ -49,11 +49,15 @@
 
   if (!$list) {
     $list = array('filter' => 'filter', 'system' => 'system', 'user' => 'user', 'watchdog' => 'watchdog');
+    // Load system modules
+    foreach($list as $name) {
+      module_load($name, TRUE);
+    }
     if ($bootstrap) {
-      $result = db_query("SELECT name, filename, throttle, bootstrap FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1");
+      $result = db_query("SELECT name, filename, throttle, bootstrap, hooks FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1");
     }
     else {
-      $result = db_query("SELECT name, filename, throttle, bootstrap FROM {system} WHERE type = 'module' AND status = 1");
+      $result = db_query("SELECT name, filename, throttle, bootstrap, hooks FROM {system} WHERE type = 'module' AND status = 1");
     }
     while ($module = db_fetch_object($result)) {
       if (file_exists($module->filename)) {
@@ -64,6 +68,8 @@
         if (!$throttle) {
           drupal_get_filename('module', $module->name, $module->filename);
           $list[$module->name] = $module->name;
+          $module->hooks = $module->hooks ? explode(';',$module->hooks) : array();
+          module_info($module->name, $module);
         }
       }
     }
@@ -73,6 +79,47 @@
 }
 
 /**
+ * This is the real module loader
+ * 
+ * @param $name
+ *   Name of the module to be loaded
+ * @param $system
+ *   Whether it is a system module, to be always loaded
+ * @return
+ *   TRUE if the module is successfully loaded. 
+ */
+function module_load($name, $system = FALSE){
+  static $loaded = array();
+
+  if(array_key_exists($name, $loaded)) {
+    return $loaded[$name];
+  } elseif($system || module_info($name)) {
+    return $loaded[$name] = drupal_load('module', $name);
+  } else {
+    // Module is not enabled nor a system module
+    return $loaded[$name] = FALSE;
+  }
+}
+
+/**
+ * Maintains info about enabled modules
+ * 
+ * @param $name
+ * 		Name of the module
+ * @param $data
+ *    An object containing module info to be set for that module
+ * @return
+ *    An object containing module info
+ */
+function module_info($name, $data = NULL){
+  static $info = array();
+  if($data){
+    return $info[$name] = $data;
+  } elseif(array_key_exists($name, $info)) {
+    return $info[$name];
+  }
+}
+/**
  * Determine whether a given module exists.
  *
  * @param $module
@@ -118,7 +165,11 @@
  *   implemented in that module.
  */
 function module_hook($module, $hook) {
-  return function_exists($module .'_'. $hook);
+  if($info = module_info($module)) {
+    return in_array($hook, $info->hooks);
+  } else {
+    return function_exists($module .'_'. $hook);
+  }
 }
 
 /**
@@ -162,9 +213,10 @@
   $module = array_shift($args);
   $hook = array_shift($args);
   $function = $module .'_'. $hook;
-  if (module_hook($module, $hook)) {
+  module_load($module);
+  if (function_exists($function)) {
     return call_user_func_array($function, $args);
-  }
+  } 
 }
 /**
  * Invoke a hook in all enabled modules that implement it.
@@ -182,6 +234,7 @@
   $hook = array_shift($args);
   $return = array();
   foreach (module_implements($hook) as $module) {
+    module_load($module);
     $function = $module .'_'. $hook;
     $result = call_user_func_array($function, $args);
     if (is_array($result)) {
@@ -196,6 +249,15 @@
 }
 
 /**
+ * Lists all hooks for modules
+ */
+
+function _module_list_hooks(){
+  return array('access', 'auth', 'block', 'comment', 'cron', 'db_rewrite_sql', 'delete', 'exit', 'filter', 'filter_tips', 'footer',
+  'form', 'help', 'info', 'init', 'insert', 'link', 'load', 'menu', 'nodeapi', 'node_grants', 'node_name', 'node_types',
+  'onload', 'perm', 'ping', 'search', 'search_item', 'search_preprocess', 'settings', 'taxonomy', 'textarea', 'update', 'update_index', 'user', 'validate', 'view', 'xmlrpc');
+}
+/**
  * @} End of "defgroup hooks".
  */
 
Index: modules/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system.module,v
retrieving revision 1.220
diff -u -r1.220 system.module
--- modules/system.module	26 Jul 2005 01:56:31 -0000	1.220
+++ modules/system.module	31 Jul 2005 15:05:15 -0000
@@ -477,10 +477,17 @@
         break;
       }
     }
+    // log remaining hooks
+    $hooks = array();
+    foreach (_module_list_hooks() as $hook){
+      if(function_exists($file->name.'_'.$hook)) {
+        $hooks[]= $hook;
+      }
+    }
 
     // Update the contents of the system table:
     db_query("DELETE FROM {system} WHERE name = '%s' AND type = '%s'", $file->name, 'module');
-    db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $file->description, 'module', $file->filename, $file->status, $file->throttle, $bootstrap);
+    db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap, hooks) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d, '%s')", $file->name, $file->description, 'module', $file->filename, $file->status, $file->throttle, $bootstrap, implode(';',$hooks));
 
     $row = array($file->name, $file->description, array('data' => (in_array($file->name, $required) ? form_hidden("status][$file->name", 1) . t('required') : form_checkbox('', "status][$file->name", 1, $file->status)), 'align' => 'center'));
     if (module_exist('throttle')) {
@@ -505,6 +512,8 @@
       // Make certain that the default theme is enabled to avoid user error
       if (($edit['type'] == 'theme') && ($edit['theme_default'] == $name)) {
         $status = 1;
+      } else {
+        
       }
 
       db_query("UPDATE {system} SET status = %d, throttle = %d WHERE type = '%s' AND name = '%s'", $status, $edit['throttle'][$name], $edit['type'], $name);
