Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.200
diff -u -F^f -r1.200 update.php
--- update.php	18 Aug 2006 18:58:44 -0000	1.200
+++ update.php	22 Aug 2006 03:32:21 -0000
@@ -678,6 +678,24 @@ function update_convert_table_utf8($tabl
   return $ret;
 }
 
+function update_fix_hooks() {
+  $modules = module_list(TRUE, FALSE);
+  $hooks = system_define_hooks();
+
+  foreach ($modules as $module) {
+    // Register any hooks this module implements.
+    foreach ($hooks as $hook) {
+      if (module_hook($module, $hook)) {
+         $implements = variable_get("hook_$hook", array());
+         if (!in_array($module, $implements)) {
+           $implements[] = $module;
+           variable_set("hook_$hook", $implements);
+         }
+      }
+    }
+  }
+}
+
 // Some unavoidable errors happen because the database is not yet up-to-date.
 // Our custom error handler is not yet installed, so we just suppress them.
 ini_set('display_errors', FALSE);
@@ -706,6 +724,7 @@ function update_convert_table_utf8($tabl
   update_fix_watchdog_115();
   update_fix_watchdog();
   update_fix_sessions();
+  update_fix_hooks();
 
   $op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
   switch ($op) {
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.82
diff -u -F^f -r1.82 module.inc
--- includes/module.inc	20 Aug 2006 05:57:40 -0000	1.82
+++ includes/module.inc	22 Aug 2006 03:32:24 -0000
@@ -167,6 +167,18 @@ function module_enable($module) {
     db_query("UPDATE {system} SET status = 1, throttle = 0 WHERE type = 'module' AND name = '%s'", $module);
     drupal_load('module', $module);
     module_invoke($module, 'enable');
+
+    // Register any hooks this module implements.
+    $hooks = module_invoke_all('define_hooks');
+    foreach ($hooks as $hook) {
+      if (module_hook($module, $hook)) {
+        $implements = variable_get("hook_$hook", array());
+        if (!in_array($module, $implements)) {
+          $implements[] = $module;
+          variable_set("hook_$hook", $implements);
+        }
+      }
+    }
     return TRUE;
   }
   else {
@@ -185,6 +197,18 @@ function module_disable($module) {
     module_load_install($module);
     module_invoke($module, 'disable');
     db_query("UPDATE {system} SET status = 0, throttle = 0 WHERE type = 'module' AND name = '%s'", $module);
+
+    // Unregister any hooks this module implements.
+    $hooks = module_invoke_all('define_hooks');
+    foreach ($hooks as $hook) {
+      if (module_hook($module, $hook)) {
+        $implements = variable_get("hook_$hook", array());
+        if ($key = array_search($implements, $module) !== FALSE) {
+          unset($implements[$key]);
+          variable_set($implements);
+        }
+      }
+    }
     return TRUE;
   }
   else {
@@ -240,25 +264,12 @@ function module_hook($module, $hook) {
  *   An array with the names of the modules which are implementing this hook.
  */
 function module_implements($hook, $sort = FALSE) {
-  static $implementations;
-
-  if (!isset($implementations[$hook])) {
-    $implementations[$hook] = array();
-    $list = module_list(FALSE, TRUE, $sort);
-    foreach ($list as $module) {
-      if (module_hook($module, $hook)) {
-        $implementations[$hook][] = $module;
-      }
-    }
-  }
+   $modules = variable_get("hook_$hook", array());
+   if ($sort) {
+     sort($modules);
+   }  
 
-  // The explicit cast forces a copy to be made. This is needed because
-  // $implementations[$hook] is only a reference to an element of
-  // $implementations and if there are nested foreaches (due to nested node
-  // API calls, for example), they would both manipulate the same array's
-  // references, which causes some modules' hooks not to be called.
-  // See also http://www.zend.com/zend/art/ref-count.php.
-  return (array)$implementations[$hook];
+   return $modules;
 }
 
 /**
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.348
diff -u -F^f -r1.348 system.module
--- modules/system/system.module	20 Aug 2006 05:57:40 -0000	1.348
+++ modules/system/system.module	22 Aug 2006 03:32:30 -0000
@@ -9,6 +9,13 @@
 define('VERSION', '4.8.0 dev');
 
 /**
+ * Implementation of hook_define_hooks().
+ */
+function system_define_hooks() {
+  return array('access', 'auth', 'block', 'comment', 'cron', 'db_rewrite_sql', 'elements', 'disable', 'enable', 'exit', 'file_download', 'filter', 'filter_tips', 'footer', 'form_alter', 'forms', 'help', 'info', 'init', 'install', 'link', 'link_alter', 'mail_alter', 'menu', 'node_access_records', 'node_grants', 'node_info', 'node_operations', 'nodeapi', 'perm', 'ping', 'profile_alter', 'search', 'search_page', 'search_preprocess', 'settings', 'taxonomy', 'update_index', 'update_N', 'user', 'user_operations', 'xmlrpc');
+}
+
+/**
  * Implementation of hook_help().
  */
 function system_help($section) {
