Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.443
diff -u -p -r1.443 bootstrap.inc
--- includes/bootstrap.inc	20 Nov 2010 05:45:48 -0000	1.443
+++ includes/bootstrap.inc	22 Nov 2010 02:06:49 -0000
@@ -902,7 +902,12 @@ function bootstrap_invoke_all($hook) {
   // only.
   foreach (module_list(FALSE, TRUE) as $module) {
     drupal_load('module', $module);
-    module_invoke($module, $hook);
+    // module_invoke() would prime the static cache of module_hook_info(), so
+    // bootstrap hook implementations need to be invoked manually.
+    $function = $module . '_' . $hook;
+    if (function_exists($function)) {
+      $function();
+    }
   }
 }
 
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.206
diff -u -p -r1.206 module.inc
--- includes/module.inc	21 Nov 2010 10:19:48 -0000	1.206
+++ includes/module.inc	22 Nov 2010 02:06:49 -0000
@@ -695,11 +695,12 @@ function module_implements($hook, $sort 
  * Retrieve a list of what hooks are explicitly declared.
  */
 function module_hook_info() {
-  $hook_info = &drupal_static(__FUNCTION__, array());
+  $hook_info = &drupal_static(__FUNCTION__);
 
-  if (empty($hook_info)) {
+  if (!isset($hook_info)) {
+    $hook_info = array();
     $cache = cache_get('hook_info', 'cache_bootstrap');
-    if ($cache === FALSE) {
+    if (!$cache) {
       // Rebuild the cache and save it.
       // We can't use module_invoke_all() here or it would cause an infinite
       // loop.
@@ -763,10 +764,23 @@ function module_invoke() {
   $module = $args[0];
   $hook = $args[1];
   unset($args[0], $args[1]);
-  if (module_hook($module, $hook)) {
-    return call_user_func_array($module . '_' . $hook, $args);
+  $function = $module . '_' . $hook;
+  $hook_exists = function_exists($function);
+  // If the hook implementation does not exist, check whether it may live in an
+  // optional include file registered via hook_hook_info().
+  if (!$hook_exists) {
+    $hook_info = module_hook_info();
+//    static $d; if (!isset($d) && $hook == 'field_settings_form') $d=1 && dsm($hook_info);
+    if (isset($hook_info[$hook]['group'])) {
+      module_load_include('inc', $module, $module . '.' . $hook_info[$hook]['group']);
+      $hook_exists = function_exists($function);
+    }
+  }
+  if ($hook_exists) {
+    return call_user_func_array($function, $args);
   }
 }
+
 /**
  * Invoke a hook in all enabled modules that implement it.
  *
@@ -783,6 +797,7 @@ function module_invoke_all() {
   $args = func_get_args();
   $hook = $args[0];
   unset($args[0]);
+
   $return = array();
   foreach (module_implements($hook) as $module) {
     $function = $module . '_' . $hook;
Index: modules/field/field.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.module,v
retrieving revision 1.90
diff -u -p -r1.90 field.module
--- modules/field/field.module	21 Nov 2010 19:09:18 -0000	1.90
+++ modules/field/field.module	22 Nov 2010 02:50:58 -0000
@@ -110,6 +110,98 @@ define('FIELD_LOAD_REVISION', 'FIELD_LOA
 class FieldUpdateForbiddenException extends FieldException {}
 
 /**
+ * Implements hook_hook_info().
+ */
+function field_hook_info() {
+  $field_hooks = array(
+    'field_access',
+    'field_attach_create_bundle',
+    'field_attach_delete',
+    'field_attach_delete_bundle',
+    'field_attach_delete_revision',
+    'field_attach_form',
+    'field_attach_insert',
+    'field_attach_load',
+    'field_attach_prepare_translation_alter',
+    'field_attach_preprocess_alter',
+    'field_attach_presave',
+    'field_attach_purge',
+    'field_attach_rename_bundle',
+    'field_attach_submit',
+    'field_attach_update',
+    'field_attach_validate',
+    'field_attach_view_alter',
+    'field_available_languages_alter',
+    'field_create_field',
+    'field_create_instance',
+    'field_delete',
+    'field_delete_field',
+    'field_delete_instance',
+    'field_delete_revision',
+    'field_display_alter',
+    // @todo http://drupal.org/node/968264
+    'field_display_ENTITY_TYPE_alter',
+    'field_extra_fields',
+    'field_extra_fields_alter',
+    'field_extra_fields_display_alter',
+    'field_formatter_info',
+    'field_formatter_info_alter',
+    'field_formatter_prepare_view',
+    'field_formatter_view',
+    'field_info',
+    'field_info_alter',
+    'field_info_max_weight',
+    'field_insert',
+    'field_is_empty',
+    'field_language_alter',
+    'field_load',
+    'field_prepare_translation',
+    'field_prepare_view',
+    'field_presave',
+    'field_purge_field',
+    'field_purge_field_instance',
+    'field_read_field',
+    'field_read_instance',
+    'field_settings_form',
+    'field_storage_create_field',
+    'field_storage_delete',
+    'field_storage_delete_field',
+    'field_storage_delete_instance',
+    'field_storage_delete_revision',
+    'field_storage_details',
+    'field_storage_details_alter',
+    'field_storage_info',
+    'field_storage_info_alter',
+    'field_storage_load',
+    'field_storage_pre_insert',
+    'field_storage_pre_load',
+    'field_storage_pre_update',
+    'field_storage_purge',
+    'field_storage_purge_field',
+    'field_storage_purge_field_instance',
+    'field_storage_query',
+    'field_storage_update_field',
+    'field_storage_write',
+    'field_update',
+    'field_update_field',
+    'field_update_forbid',
+    'field_update_instance',
+    'field_validate',
+    'field_widget_error',
+    'field_widget_form',
+    'field_widget_info',
+    'field_widget_info_alter',
+    'field_widget_properties_alter',
+    // @todo http://drupal.org/node/968264
+    'field_widget_properties_ENTITY_TYPE_alter',
+  );
+  $hooks = array_fill_keys($field_hooks, array(
+    'group' => 'field',
+  ));
+  return $hooks;
+}
+
+/**
  * Implements hook_flush_caches().
  */
 function field_flush_caches() {
Index: modules/file/file.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/file/file.field.inc,v
retrieving revision 1.40
diff -u -p -r1.40 file.field.inc
--- modules/file/file.field.inc	20 Nov 2010 19:57:01 -0000	1.40
+++ modules/file/file.field.inc	22 Nov 2010 02:40:35 -0000
@@ -42,15 +42,18 @@ function file_field_settings_form($field
 
   $form['display_field'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Enable <em>Display</em> field'),
+    '#title' => t('Allow users to choose if files should be shown when viewing content'),
     '#default_value' => $settings['display_field'],
-    '#description' => t('The display option allows users to choose if a file should be shown when viewing the content.'),
   );
   $form['display_default'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Files displayed by default'),
+    '#title' => t('Display files by default'),
     '#default_value' => $settings['display_default'],
-    '#description' => t('This setting only has an effect if the display option is enabled.'),
+    '#states' => array(
+      'visible' => array(
+        ':input[name*="display_field"]' => array('checked' => TRUE),
+      ),
+    ),
   );
 
   $scheme_options = array();
@@ -486,6 +489,12 @@ function file_field_widget_form(&$form, 
     // Allows this field to return an array instead of a single value.
     '#extended' => TRUE,
   );
+  // file_field_widget_process() is defined in this file, so ensure that it is
+  // loaded when the form is processed.
+  $form_state['build_info']['files']['file'] = array(
+    'module' => 'file',
+    'name' => 'file.field',
+  );
 
   if ($field['cardinality'] == 1) {
     // If there's only one field, return it as delta 0.
Index: modules/file/file.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/file/file.module,v
retrieving revision 1.46
diff -u -p -r1.46 file.module
--- modules/file/file.module	13 Nov 2010 14:04:08 -0000	1.46
+++ modules/file/file.module	22 Nov 2010 02:06:50 -0000
@@ -6,9 +6,6 @@
  * Defines a "managed_file" Form API field and a "file" field for Field module.
  */
 
-// Load all Field module hooks for File.
-require_once DRUPAL_ROOT . '/modules/file/file.field.inc';
-
 /**
  * Implements hook_help().
  */
Index: modules/image/image.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/image/image.field.inc,v
retrieving revision 1.34
diff -u -p -r1.34 image.field.inc
--- modules/image/image.field.inc	31 Oct 2010 12:12:00 -0000	1.34
+++ modules/image/image.field.inc	22 Nov 2010 02:45:52 -0000
@@ -71,7 +71,7 @@ function image_field_instance_settings_f
   $settings = $instance['settings'];
 
   // Use the file field instance settings form as a basis.
-  $form = file_field_instance_settings_form($field, $instance);
+  $form = module_invoke('file', 'field_instance_settings_form', $field, $instance);
 
   // Add maximum and minimum resolution settings.
   $max_resolution = explode('x', $settings['max_resolution']) + array('', '');
@@ -181,7 +181,7 @@ function _image_field_resolution_validat
  * Implements hook_field_load().
  */
 function image_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
-  file_field_load($entity_type, $entities, $field, $instances, $langcode, $items, $age);
+  module_invoke('file', 'field_load', $entity_type, $entities, $field, $instances, $langcode, $items, $age);
 }
 
 /**
@@ -206,42 +206,42 @@ function image_field_prepare_view($entit
  * Implements hook_field_presave().
  */
 function image_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  file_field_presave($entity_type, $entity, $field, $instance, $langcode, $items);
+  module_invoke('file', 'field_presave', $entity_type, $entity, $field, $instance, $langcode, $items);
 }
 
 /**
  * Implements hook_field_insert().
  */
 function image_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  file_field_insert($entity_type, $entity, $field, $instance, $langcode, $items);
+  module_invoke('file', 'field_insert', $entity_type, $entity, $field, $instance, $langcode, $items);
 }
 
 /**
  * Implements hook_field_update().
  */
 function image_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  file_field_update($entity_type, $entity, $field, $instance, $langcode, $items);
+  module_invoke('file', 'field_update', $entity_type, $entity, $field, $instance, $langcode, $items);
 }
 
 /**
  * Implements hook_field_delete().
  */
 function image_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  file_field_delete($entity_type, $entity, $field, $instance, $langcode, $items);
+  module_invoke('file', 'field_delete', $entity_type, $entity, $field, $instance, $langcode, $items);
 }
 
 /**
  * Implements hook_field_delete_revision().
  */
 function image_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  file_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, $items);
+  module_invoke('file', 'field_delete_revision', $entity_type, $entity, $field, $instance, $langcode, $items);
 }
 
 /**
  * Implements hook_field_is_empty().
  */
 function image_field_is_empty($item, $field) {
-  return file_field_is_empty($item, $field);
+  return module_invoke('file', 'field_is_empty', $item, $field);
 }
 
 /**
@@ -272,7 +272,7 @@ function image_field_widget_settings_for
   $settings = $widget['settings'];
 
   // Use the file widget settings form.
-  $form = file_field_widget_settings_form($field, $instance);
+  $form = module_invoke('file', 'field_widget_settings_form', $field, $instance);
 
   $form['preview_image_style'] = array(
     '#title' => t('Preview image style'),
@@ -295,7 +295,7 @@ function image_field_widget_form(&$form,
   // Add display_field setting to field because file_field_widget_form() assumes it is set.
   $field['settings']['display_field'] = 0;
 
-  $elements = file_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
+  $elements = module_invoke('file', 'field_widget_form', $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
   $settings = $instance['settings'];
 
   foreach (element_children($elements) as $delta) {
@@ -313,6 +313,12 @@ function image_field_widget_form(&$form,
     // Add all extra functionality provided by the image widget.
     $elements[$delta]['#process'][] = 'image_field_widget_process';
   }
+  // image_field_widget_process() is defined in this file, so ensure that it is
+  // loaded when the form is processed.
+  $form_state['build_info']['files']['image'] = array(
+    'module' => 'image',
+    'name' => 'image.field',
+  );
 
   if ($field['cardinality'] == 1) {
     // If there's only one field, return it as delta 0.
Index: modules/image/image.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/image/image.module,v
retrieving revision 1.54
diff -u -p -r1.54 image.module
--- modules/image/image.module	18 Nov 2010 05:36:27 -0000	1.54
+++ modules/image/image.module	22 Nov 2010 02:20:02 -0000
@@ -31,9 +31,6 @@ define('IMAGE_STORAGE_EDITABLE', IMAGE_S
  */
 define('IMAGE_STORAGE_MODULE', IMAGE_STORAGE_OVERRIDE | IMAGE_STORAGE_DEFAULT);
 
-// Load all Field module hooks for Image.
-require_once DRUPAL_ROOT . '/modules/image/image.field.inc';
-
 /**
  * Implement of hook_help().
  */
@@ -316,7 +313,7 @@ function image_file_download($uri) {
   if (count($files)) {
     $file = reset($files);
     if ($file->status) {
-      return file_file_download($uri, 'image');
+      return module_invoke('file', 'file_download', $uri, 'image');
     }
   }
 }
