=== modified file 'includes/common.inc'
--- includes/common.inc	2008-01-30 23:07:41 +0000
+++ includes/common.inc	2008-02-15 20:38:46 +0000
@@ -1463,6 +1463,8 @@ function drupal_page_footer() {
   if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED) {
     page_set_cache();
   }
+  // Store the used registry files.
+  _registry_mark_file(NULL, TRUE);
 
   module_invoke_all('exit');
 }
@@ -2451,6 +2453,9 @@ function _drupal_bootstrap_full() {
   unicode_check();
   // Undo magic quotes
   fix_gpc_magic();
+  // Register autoload functions so that we can acess classes and interfaces.
+  spl_autoload_register('registry_check_class');
+  spl_autoload_register('registry_check_interface');
   // Load all enabled modules
   module_load_all();
   // Let all modules take action before menu system handles the request
@@ -2708,7 +2713,7 @@ function drupal_render(&$elements) {
   // element is rendered into the final text.
   if (isset($elements['#pre_render'])) {
     foreach ($elements['#pre_render'] as $function) {
-      if (function_exists($function)) {
+      if (registry_check_function($function)) {
         $elements = $function($elements);
       }
     }
@@ -2770,7 +2775,7 @@ function drupal_render(&$elements) {
     // which allows the output'ed text to be filtered.
     if (isset($elements['#post_render'])) {
       foreach ($elements['#post_render'] as $function) {
-        if (function_exists($function)) {
+        if (registry_check_function($function)) {
           $content = $function($content, $elements);
         }
       }
@@ -3246,6 +3251,7 @@ function drupal_write_record($table, &$o
   }
 
   $schema = drupal_get_schema($table);
+
   if (empty($schema)) {
     return FALSE;
   }
@@ -3524,6 +3530,7 @@ function drupal_flush_all_caches() {
   // Change query-strings on css/js files to enforce reload for all users.
   _drupal_flush_css_js();
 
+  drupal_rebuild_code_registry();
   drupal_clear_css_cache();
   drupal_clear_js_cache();
   drupal_rebuild_theme_registry();
@@ -3531,7 +3538,7 @@ function drupal_flush_all_caches() {
   node_types_rebuild();
   // 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_block', 'cache_filter', 'cache_page');
+  $core = array('cache', 'cache_block', 'cache_filter', 'cache_registry', 'cache_page');
   $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
   foreach ($cache_tables as $table) {
     cache_clear_all('*', $table, TRUE);
@@ -3556,3 +3563,239 @@ function _drupal_flush_css_js() {
   }
   variable_set('css_js_query_string', $new_character . substr($string_history, 0, 19));
 }
+
+/**
+ * Rescan all installed modules and rebuild the registry.
+ */
+function drupal_rebuild_code_registry() {
+  // Flush the old registry.
+  db_query("DELETE FROM {registry}");
+  // We can't use module_invoke_all here because it depends on the registry
+  // which is being rebuilt right now.
+  $list = module_list(TRUE, FALSE, FALSE);
+  $patterns = array();
+  foreach ($list as $module) {
+    $function = $module .'_hooks';
+    if (function_exists($function)) {
+      $result = (array)$function();
+      foreach ($result as $pattern) {
+        // For example '__form_alter'
+        $patterns[] = '/'. str_replace('__', '.*_', $pattern) .'/';
+      }
+    }
+  }
+
+  foreach ($list as $module) {
+    _registry_parse_directory(drupal_get_path('module', $module), $patterns);
+  }
+
+  _registry_parse_directory('includes', $patterns);
+  $implementations = _registry_save_resource();
+  cache_set('hooks', array('patterns' => $patterns, 'implementations' => $implementations));
+}
+
+/**
+ * Parse all loadable files in a directory and save their function listings.
+ */
+function _registry_parse_directory($path, $patterns) {
+  static $map = array(T_FUNCTION => 'function', T_CLASS => 'class', T_INTERFACE => 'interface');
+  $files = file_scan_directory($path, '\.(inc|module|install)$');
+  foreach ($files as $filename => $file) {
+    $tokens = token_get_all(file_get_contents($filename));
+    while ($token = next($tokens)) {
+      if (is_array($token) && isset($map[$token[0]])) {
+        _registry_save_resource($token, $tokens, $map[$token[0]], $filename, $patterns);
+        // We skip the body because classes might contain functions.
+        _registry_skip_body($tokens);
+      }
+    }
+  }
+}
+
+/**
+ * Save a resource into the database.
+ *
+ * @param mixed $token
+ * @param ArrayIterator $tokens
+ * @param string $type
+ * @param string $module_path
+ * @param string $filename
+ */
+function _registry_save_resource($token = NULL, &$tokens = NULL, $type = NULL, $filename = NULL, $patterns = NULL) {
+  static $implementations, $resources, $dirs;
+  if (!isset($token)) {
+    return $implementations;
+  }
+  next($tokens); // Eat a space.
+  $token = next($tokens);
+  if ($token == '&') {
+    $token = next($tokens);
+  }
+  $resource_name = $token[1];
+  if (isset($resources[$type][$resource_name])) {
+    return;
+  }
+  $resources[$type][$resource_name] = TRUE;
+  $file_parts = explode('.', $filename);
+  $module = '';
+  $hook = '';
+  $count = count($file_parts);
+  if ($count == 2 && $file_parts[1] == 'inc') {
+    if (!isset($dirs[$filename])) {
+      $dir_parts = explode('/', $file_parts[0]);
+      array_pop($dir_parts);
+      $dirs[$filename] = array_pop($dir_parts);
+    }
+    $module = $dirs[$filename];
+  }
+  if (($count ==  2 && ($file_parts[1] == 'module' || $file_parts[1] == 'install')) || ($count == 3 && $file_parts[2] == 'inc')) {
+    $module = basename($file_parts[0]);
+  }
+  if ($module && strpos($resource_name, $module) === 0) {
+    $hook = substr($resource_name, strlen($module) + 1);
+    foreach ($patterns as $pattern) {
+      if (preg_match($pattern, $hook)) {
+        $implementations[$hook][] = $module;
+      }
+    }
+  }
+  db_query("INSERT INTO {registry} (name, type, module, hook, file) VALUES ('%s', '%s', '%s', '%s', '%s')", array($resource_name, $type, $module, $hook, "./$filename"));
+}
+
+/**
+ * Skip the body of a code block, as defined by { and }.
+ *
+ * This function assumes that the body starts at the next instance
+ * of { from the current position.
+ *
+ * @param ArrayIterator $tokens
+ */
+function _registry_skip_body(&$tokens) {
+  $num_braces = 1;
+
+  $token = '';
+  // Get to the first open brace.
+  while ($token != '{' && ($token = next($tokens)));
+
+  // Scan through the rest of the tokens until we reach the matching
+  // end brace.
+  while ($num_braces && ($token = next($tokens))) {
+    if ($token == '{') {
+      ++$num_braces;
+    }
+    elseif ($token == '}') {
+      --$num_braces;
+    }
+  }
+}
+
+/**
+ * Collect the files included so we can preload them on the next pageload.
+ *
+ * The function collects the files as the registry includes them and at the
+ * end of page request it stores them per router path.
+ *
+ * @param $file
+ *   A file or an array of files included.
+ * @param $store
+ *   If true, then store the collected array of files into the database as
+ *   necessary.
+ */
+function _registry_mark_file($file = NULL, $store = FALSE) {
+  static $used_files = array(), $original_files = array();
+
+if (isset($file)) {
+    if (is_array($file)) {
+      $used_files = array_merge($used_files, $file);
+    }
+    else {
+      $used_files[] = $file;
+    }
+  }
+  elseif ($store && $used_files != $original_files) {
+    // files we will likely need next time.
+    $files = array_unique($used_files);
+    $files = implode(';', $files);
+    $menu = menu_get_item();
+    cache_set($menu['path'], $files, 'cache_registry');
+  }
+}
+
+/**
+ * Confirm that a function is available.
+ *
+ * If the function is already available, this function does nothing.
+ * If it is not, it tries to load the file in which it lives.  If
+ * the file is not available, it simply returns false.  That way it
+ * can be used as a drop-in replacement for function_exists().
+ *
+ * @param string $function
+ * 	 The name of the function to check or load.
+ * @return
+ * 	 TRUE if the function is now available, FALSE otherwise.
+ */
+function registry_check_function($function) {
+  static $checked = array();
+  if (isset($checked[$function])) {
+    return $checked[$function];
+  }
+  if (!function_exists($function)) {
+    $file = db_result(db_query("SELECT file FROM {registry} WHERE name = '%s' AND type = 'function'", $function));
+    if (!$file) {
+      $checked[$function] = FALSE;
+      return FALSE;
+    }
+    //dsm(__FUNCTION__ . ": Including $file");
+    if ($file == './includes/theme.maintenance.inc') {
+      var_export(debug_backtrace());
+    }
+    require_once($file);
+    _registry_mark_file($file);
+  }
+  $checked[$function] = TRUE;
+  return TRUE;
+}
+
+/**
+ * Confirm that a class is available.
+ *
+ * This function parallel's registry_check_function(), but will rarely
+ * be called directly.  Instead, it will be registered as an spl_autoload()
+ * handler, and PHP will call it for us when necessary.
+ *
+ * @param string $class
+ * 	 The name of the class to check or load.
+ * @return
+ * 	 TRUE if the class is now available, FALSE otherwise.
+ */
+function registry_check_class($class) {
+  $file = db_result(db_query("SELECT file FROM {registry} WHERE name = '%s' AND type = 'class'", $class));
+  if (!$file) {
+    return FALSE;
+  }
+  require_once($file);
+  _registry_mark_file($file);
+  return TRUE;
+}
+
+/**
+ * Confirm that an interface is available.
+ *
+ * This function parallel's registry_check_function(), but will rarely
+ * be called directly.  Instead, it will be registered as an spl_autoload()
+ * handler, and PHP will call it for us when necessary.
+ *
+ * @param string $interface
+ * 	 The name of the interface to check or load.
+ * @return
+ * 	 TRUE if the interface is now available, FALSE otherwise.
+ */
+function registry_check_interface($interface) {
+  $file = db_result(db_query("SELECT file FROM {registry} WHERE name = '%s' AND type = 'interface'", $interface));
+  if (!$file) {
+    return FALSE;
+  }
+  require_once($file);
+  _registry_mark_file($file);
+  return TRUE;
+}

=== modified file 'includes/form.inc'
--- includes/form.inc	2008-02-12 13:52:32 +0000
+++ includes/form.inc	2008-02-15 04:05:38 +0000
@@ -326,7 +326,7 @@ function drupal_retrieve_form($form_id, 
 
   // We first check to see if there's a function named after the $form_id.
   // If there is, we simply pass the arguments on to it to get the form.
-  if (!function_exists($form_id)) {
+  if (!registry_check_function($form_id)) {
     // In cases where many form_ids need to share a central constructor function,
     // such as the node editing form, modules can implement hook_forms(). It
     // maps one or more form_ids to the correct constructor functions.
@@ -347,6 +347,7 @@ function drupal_retrieve_form($form_id, 
     }
     if (isset($form_definition['callback'])) {
       $callback = $form_definition['callback'];
+      registry_check_function($callback);
     }
   }
 
@@ -503,13 +504,13 @@ function drupal_prepare_form($form_id, &
   $form += _element_info('form');
 
   if (!isset($form['#validate'])) {
-    if (function_exists($form_id .'_validate')) {
+    if (registry_check_function($form_id .'_validate')) {
       $form['#validate'] = array($form_id .'_validate');
     }
   }
 
   if (!isset($form['#submit'])) {
-    if (function_exists($form_id .'_submit')) {
+    if (registry_check_function($form_id .'_submit')) {
       // We set submit here so that it can be altered.
       $form['#submit'] = array($form_id .'_submit');
     }
@@ -710,7 +711,7 @@ function _form_validate($elements, &$for
     // #value data.
     elseif (isset($elements['#element_validate'])) {
       foreach ($elements['#element_validate'] as $function) {
-        if (function_exists($function))  {
+        if (registry_check_function($function))  {
           $function($elements, $form_state, $complete_form);
         }
       }
@@ -747,7 +748,7 @@ function form_execute_handlers($type, &$
   }
 
   foreach ($handlers as $function) {
-    if (function_exists($function))  {
+    if (registry_check_function($function))  {
       if ($type == 'submit' && ($batch =& batch_get())) {
         // Some previous _submit handler has set a batch. We store the call
         // in a special 'control' batch set, for execution at the correct
@@ -1030,7 +1031,7 @@ function _form_builder_handle_input_elem
   // checkboxes and files.
   if (isset($form['#process']) && !$form['#processed']) {
     foreach ($form['#process'] as $process) {
-      if (function_exists($process)) {
+      if (registry_check_function($process)) {
         $form = $process($form, isset($edit) ? $edit : NULL, $form_state, $complete_form);
       }
     }

=== modified file 'includes/install.inc'
--- includes/install.inc	2008-02-12 13:45:16 +0000
+++ includes/install.inc	2008-02-15 02:40:11 +0000
@@ -687,8 +687,9 @@ function drupal_check_profile($profile) 
   $requirements = array();
   foreach ($installs as $install) {
     require_once $install->filename;
-    if (module_hook($install->name, 'requirements')) {
-      $requirements = array_merge($requirements, module_invoke($install->name, 'requirements', 'install'));
+    $function = $install->name. '_requirements';
+    if (function_exists($function)) {
+      $requirements = array_merge($requirements, $function('install'));
     }
   }
   return $requirements;

=== modified file 'includes/mail.inc'
--- includes/mail.inc	2008-02-06 19:38:26 +0000
+++ includes/mail.inc	2008-02-14 00:43:32 +0000
@@ -115,7 +115,7 @@ function drupal_mail($module, $key, $to,
   // Build the e-mail (get subject and body, allow additional headers) by
   // invoking hook_mail() on this module. We cannot use module_invoke() as
   // we need to have $message by reference in hook_mail().
-  if (function_exists($function = $module .'_mail')) {
+  if (registry_check_function($function = $module .'_mail')) {
     $function($key, $message, $params);
   }
 

=== modified file 'includes/menu.inc'
--- includes/menu.inc	2008-02-10 19:49:37 +0000
+++ includes/menu.inc	2008-02-15 01:11:27 +0000
@@ -340,11 +340,18 @@ function menu_execute_active_handler($pa
     menu_rebuild();
   }
   if ($router_item = menu_get_item($path)) {
+    $cache = cache_get($router_item['path'], 'cache_registry');
+    if (!empty($cache->data)) {
+      $files = explode(';', $cache->data);
+      foreach($files as $file) {
+        require_once($file);
+      }
+      _registry_mark_file($files);
+    }
     if ($router_item['access']) {
-      if ($router_item['file']) {
-        require_once($router_item['file']);
+      if (registry_check_function($router_item['page_callback'])) {
+        return call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
       }
-      return call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
     }
     else {
       return MENU_ACCESS_DENIED;
@@ -2169,12 +2176,12 @@ function _menu_router_build($callbacks) 
           $load_functions[$k] = NULL;
         }
         else {
-          if (function_exists($matches[1] .'_to_arg')) {
+          if (registry_check_function($matches[1] .'_to_arg')) {
             $to_arg_functions[$k] = $matches[1] .'_to_arg';
             $load_functions[$k] = NULL;
             $match = TRUE;
           }
-          if (function_exists($matches[1] .'_load')) {
+          if (registry_check_function($matches[1] .'_load')) {
             $function = $matches[1] .'_load';
             // Create an array of arguments that will be passed to the _load
             // function when this menu path is checked, if 'load arguments'
@@ -2260,12 +2267,6 @@ function _menu_router_build($callbacks) 
           if (!isset($item['page arguments']) && isset($parent['page arguments'])) {
             $item['page arguments'] = $parent['page arguments'];
           }
-          if (!isset($item['file']) && isset($parent['file'])) {
-            $item['file'] = $parent['file'];
-          }
-          if (!isset($item['file path']) && isset($parent['file path'])) {
-            $item['file path'] = $parent['file path'];
-          }
         }
       }
     }
@@ -2293,34 +2294,25 @@ function _menu_router_build($callbacks) 
       'tab_parent' => '',
       'tab_root' => $path,
       'path' => $path,
-      'file' => '',
-      'file path' => '',
-      'include file' => '',
     );
 
-    // Calculate out the file to be included for each callback, if any.
-    if ($item['file']) {
-      $file_path = $item['file path'] ? $item['file path'] : drupal_get_path('module', $item['module']);
-      $item['include file'] = $file_path .'/'. $item['file'];
-    }
-
     $title_arguments = $item['title arguments'] ? serialize($item['title arguments']) : '';
     db_query("INSERT INTO {menu_router}
       (path, load_functions, to_arg_functions, access_callback,
       access_arguments, page_callback, page_arguments, fit,
       number_parts, tab_parent, tab_root,
       title, title_callback, title_arguments,
-      type, block_callback, description, position, weight, file)
+      type, block_callback, description, position, weight)
       VALUES ('%s', '%s', '%s', '%s',
       '%s', '%s', '%s', %d,
       %d, '%s', '%s',
       '%s', '%s', '%s',
-      %d, '%s', '%s', '%s', %d, '%s')",
+      %d, '%s', '%s', '%s', %d)",
       $path, $item['load_functions'], $item['to_arg_functions'], $item['access callback'],
       serialize($item['access arguments']), $item['page callback'], serialize($item['page arguments']), $item['_fit'],
       $item['_number_parts'], $item['tab_parent'], $item['tab_root'],
       $item['title'], $item['title callback'], $title_arguments,
-      $item['type'], $item['block callback'], $item['description'], $item['position'], $item['weight'], $item['include file']);
+      $item['type'], $item['block callback'], $item['description'], $item['position'], $item['weight']);
   }
   // Sort the masks so they are in order of descending fit, and store them.
   $masks = array_keys($masks);

=== modified file 'includes/module.inc'
--- includes/module.inc	2007-12-27 12:31:05 +0000
+++ includes/module.inc	2008-02-16 00:02:24 +0000
@@ -228,7 +228,7 @@ function _module_build_dependencies($fil
  */
 function module_exists($module) {
   $list = module_list();
-  return array_key_exists($module, $list);
+  return isset($list[$module]);
 }
 
 /**
@@ -308,7 +308,7 @@ function module_enable($module_list) {
     // We check for the existence of node_access_needs_rebuild() since
     // at install time, module_enable() could be called while node.module
     // is not enabled yet.
-    if (function_exists('node_access_needs_rebuild') && !node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
+    if (registry_check_function('node_access_needs_rebuild') && !node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
       node_access_needs_rebuild(TRUE);
     }
   }
@@ -383,7 +383,9 @@ function module_disable($module_list) {
  *   implemented in that module.
  */
 function module_hook($module, $hook) {
-  return function_exists($module .'_'. $hook);
+  $function = $module .'_'. $hook;
+  // During bootstrap, registry_check_function might not exist.
+  return function_exists('registry_check_function') ? registry_check_function($function) : function_exists($function);
 }
 
 /**
@@ -402,30 +404,62 @@ function module_hook($module, $hook) {
  *   An array with the names of the modules which are implementing this hook.
  */
 function module_implements($hook, $sort = FALSE, $refresh = FALSE) {
-  static $implementations;
+  static $implementations, $patterns, $loaded;
 
   if ($refresh) {
     $implementations = array();
+    cache_clear_all('hooks', 'cache');
     return;
   }
-
-  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;
+  if (empty($implementations)) {
+    // During install we can not rely on the registry.
+    if (function_exists('install_verify_settings') && (!install_verify_settings() || !db_set_active() || !install_verify_drupal() || !function_exists('cache_get'))) {
+      $list = module_list();
+      $return = array();
+      foreach ($list as $module) {
+        $function = $module .'_'. $hook;
+        if (function_exists($function)) {
+          $return[] = $module;
+        }
       }
+      return $return;
+    }
+    $cache = cache_get('hooks');
+    if (!$cache) {
+      drupal_rebuild_code_registry();
+      $cache = cache_get('hooks');
     }
+    $implementations = $cache->data['implementations'];
+    $patterns = $cache->data['patterns'];
   }
-
-  // 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];
+  if (isset($implementations[$hook])) {
+    if (!isset($loaded[$hook])) {
+      $loaded[$hook] = TRUE;
+      array_walk($implementations[$hook], 'registry_check_function');
+    }
+    return (array)$implementations[$hook];
+  }
+  // We do not store empty arrays for every instance of dynamic hooks like
+  // hook_{$form_id}_form_alter. The actual implementations of dynamic
+  // hooks are cached by drupal_rebuild_code_registry so those are already
+  // returned. If the hook matches a pattern here then we know that there is
+  // no implementation.
+  foreach ($patterns as $pattern) {
+    if (preg_match($pattern, $hook)) {
+      return array();
+    }
+  }
+  // Other hooks are fetched from the registry and cached.
+  $implementations[$hook] = array();
+  $result = db_query("SELECT module, name, file FROM {registry} WHERE hook = '%s' AND type = 'function'", $hook);
+  while ($entry = db_fetch_array($result)) {
+    if (!function_exists($entry['name'])) {
+      require_once($entry['file']);
+    }
+    $implementations[$hook][] = $entry['module'];
+  }
+  cache_set('hooks', array('patterns' => $patterns, 'implementations' => $implementations));
+  return $implementations[$hook];
 }
 
 /**

=== modified file 'includes/theme.inc'
--- includes/theme.inc	2008-02-06 19:38:26 +0000
+++ includes/theme.inc	2008-02-15 03:29:26 +0000
@@ -628,7 +628,7 @@ function theme() {
       // call_user_func_array.
       $args = array(&$variables, $hook);
       foreach ($info['preprocess functions'] as $preprocess_function) {
-        if (function_exists($preprocess_function)) {
+        if (registry_check_function($preprocess_function)) {
           call_user_func_array($preprocess_function, $args);
         }
       }

=== modified file 'includes/xmlrpcs.inc'
--- includes/xmlrpcs.inc	2007-12-31 08:54:36 +0000
+++ includes/xmlrpcs.inc	2008-02-14 00:43:32 +0000
@@ -202,7 +202,7 @@ function xmlrpc_server_call($xmlrpc_serv
     }
   }
 
-  if (!function_exists($method)) {
+  if (!registry_check_function($method)) {
     return xmlrpc_error(-32601, t('Server error. Requested function %method does not exist.', array("%method" => $method)));
   }
   // Call the mapped function

=== modified file 'modules/system/system.install'
--- modules/system/system.install	2008-01-30 20:30:35 +0000
+++ modules/system/system.install	2008-02-15 03:43:32 +0000
@@ -551,6 +551,8 @@ function system_schema() {
   $schema['cache_page']['description'] = t('Cache table used to store compressed pages for anonymous users, if page caching is enabled.');
   $schema['cache_menu'] = $schema['cache'];
   $schema['cache_menu']['description'] = t('Cache table for the menu system to store router information as well as generated link trees for various menu/page/user combinations.');
+  $schema['cache_registry'] = $schema['cache'];
+  $schema['cache_registry']['description'] = t('Cache table for the code registry system to remember what code files need to be loaded on any given page.');
 
   $schema['files'] = array(
     'description' => t('Stores information for uploaded files.'),
@@ -773,10 +775,6 @@ function system_schema() {
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0),
-      'file' => array(
-        'description' => t('The file to include for this element, usually the page callback function lives in this file.'),
-        'type' => 'text',
-        'size' => 'medium')
       ),
     'indexes' => array(
       'fit' => array('fit'),
@@ -945,6 +943,48 @@ function system_schema() {
       ),
     'primary key' => array('mlid'),
     );
+  $schema['registry'] = array(
+    'description' => t("Each record is a function / class / interface name and the file it is in"),
+    'fields' => array(
+      'name'   => array(
+        'description' => t('The name of the function / class / interface.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'type'   => array(
+        'description' => t('Either function or class or interface'),
+        'type' => 'varchar',
+        'length' => 9,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'module' => array(
+        'description' => t('Name of the module this file belongs to.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'hook'   => array(
+        'description' => t('Name of the function minus the name of the module'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'file'   => array(
+        'description' => t('Path to the file'),
+        'type' => 'text',
+        'size' => 'medium',
+      ),
+    ),
+    'primary key' => array('name', 'type'),
+    'indexes' => array(
+      'module_implements' => array('type', 'hook'),
+    ),
+  );
 
   $schema['sessions'] = array(
     'description' => t("Drupal's session handlers read and write into the sessions table. Each record represents a user session, either anonymous or authenticated."),
@@ -2467,6 +2507,11 @@ function system_update_6047() {
   return $ret;
 }
 
+function system_update_7000() {
+  $ret = array();
+  db_drop_field($ret, 'menu_router', 'file');
+}
+
 /**
  * @} End of "defgroup updates-5.x-to-6.x"
  * The next series of updates should start at 7000.

=== modified file 'modules/system/system.module'
--- modules/system/system.module	2008-02-12 14:06:58 +0000
+++ modules/system/system.module	2008-02-15 02:20:06 +0000
@@ -1285,6 +1285,13 @@ function system_action_info() {
 }
 
 /**
+ * Implementation of hook_hooks().
+ */
+function system_hooks() {
+  return array('__form_alter');
+}
+
+/**
  * Menu callback. Display an overview of available and configured actions.
  */
 function system_actions_manage() {

=== modified file 'update.php'
--- update.php	2008-02-03 18:41:16 +0000
+++ update.php	2008-02-15 03:35:22 +0000
@@ -422,6 +422,41 @@ function update_create_batch_table() {
 }
 
 /**
+ * This is part of the Drupal 6.x to 7.x migration.
+ */
+function update_create_registry_tables() {
+  $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' => ''),
+      'module' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+      'hook'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+      'file'   => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),
+    ),
+    'primary key' => array('name', 'type'),
+    'indexes' => array(
+      'module_implements' => array('type', 'hook'),
+    ),
+  );
+  $schema['cache_registry'] = array(
+    'fields' => array(
+      'cid'        => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+      'data'       => array('type' => 'blob', 'not null' => FALSE, 'size' => 'big'),
+      'expire'     => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'created'    => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'headers'    => array('type' => 'text', 'not null' => FALSE),
+      'serialized' => array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0)
+    ),
+    'indexes' => array('expire' => array('expire')),
+    'primary key' => array('cid'),
+  );
+  $ret = array();
+  db_create_table($ret, 'cache_registry', $schema['cache_registry']);
+  db_create_table($ret, 'registry', $schema['registry']);
+  drupal_rebuild_code_registry();
+}
+
+/**
  * Disable anything in the {system} table that is not compatible with the
  * current version of Drupal core.
  */

