? .DS_Store
? clear_cache_00.patch
? clear_cache_01.patch
? clear_cache_02.patch
? clear_cache_03.patch
? installation_server_settings_00.patch
? performance_settings_06.patch
? modules/.DS_Store
? modules/field/.DS_Store
? modules/field/modules/.DS_Store
? sites/.DS_Store
? sites/default/files
? sites/default/settings.php
Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.289
diff -u -p -r1.289 update.php
--- update.php	9 Jun 2009 11:20:16 -0000	1.289
+++ update.php	21 Jun 2009 01:43:33 -0000
@@ -410,11 +410,10 @@ function update_results_page() {
 }
 
 function update_info_page() {
-  // Change query-strings on css/js files to enforce reload for all users.
-  _drupal_flush_css_js();
-  // Flush the cache of all data for the update status module.
+  cache_clear_css_js();
+  // Clear the cache of all data for the update status module.
   if (db_table_exists('cache_update')) {
-    cache_clear_all('*', 'cache_update', TRUE);
+    cache_clear('update_status');
   }
 
   update_task_list('info');
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.287
diff -u -p -r1.287 bootstrap.inc
--- includes/bootstrap.inc	10 Jun 2009 20:00:10 -0000	1.287
+++ includes/bootstrap.inc	21 Jun 2009 01:43:34 -0000
@@ -8,7 +8,7 @@
 
 /**
  * Indicates that the item should never be removed unless explicitly told to
- * using cache_clear_all() with a cache ID.
+ * using cache_clear_item() with a cache ID.
  */
 define('CACHE_PERMANENT', 0);
 
@@ -650,7 +650,7 @@ function variable_set($name, $value) {
 
   db_merge('variable')->key(array('name' => $name))->fields(array('value' => serialize($value)))->execute();
 
-  cache_clear_all('variables', 'cache');
+  cache_clear_item('variables', 'general');
 
   $conf[$name] = $value;
 }
@@ -667,7 +667,7 @@ function variable_del($name) {
   db_delete('variable')
     ->condition('name', $name)
     ->execute();
-  cache_clear_all('variables', 'cache');
+  cache_clear_item('variables', 'general');
 
   unset($conf[$name]);
 }
Index: includes/cache-install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/cache-install.inc,v
retrieving revision 1.2
diff -u -p -r1.2 cache-install.inc
--- includes/cache-install.inc	7 Aug 2007 08:39:35 -0000	1.2
+++ includes/cache-install.inc	21 Jun 2009 01:43:34 -0000
@@ -11,14 +11,14 @@
  * on performance.
  */
 
-function cache_get($key, $table = 'cache') {
+function cache_get($key, $bin = 'cache') {
   return FALSE;
 }
 
-function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
+function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
   return;
 }
 
-function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
+function cache_clear_item($cid, $cache, $wildcard = FALSE) {
   return;
 }
Index: includes/cache.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/cache.inc,v
retrieving revision 1.35
diff -u -p -r1.35 cache.inc
--- includes/cache.inc	19 Jun 2009 08:46:44 -0000	1.35
+++ includes/cache.inc	21 Jun 2009 01:43:34 -0000
@@ -108,7 +108,7 @@ function cache_get($cid, $bin = 'cache')
  * @param $expire
  *   One of the following values:
  *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
- *     explicitly told to using cache_clear_all() with a cache ID.
+ *     explicitly told to using cache_clear_item() with a cache ID.
  *   - CACHE_TEMPORARY: Indicates that the item should be removed at the next
  *     general cache wipe.
  *   - A Unix timestamp: Indicates that the item should be kept at least until
@@ -121,35 +121,65 @@ function cache_set($cid, $data, $bin = '
 }
 
 /**
- * Expire data from the cache.
+ * Load all cache information.
  *
- * If called without arguments, expirable entries will be cleared from the
- * cache_page and cache_block bins.
- *
- * @param $cid
- *   If set, the cache ID to delete. Otherwise, all cache entries that can
- *   expire are deleted.
+ * @return
+ *   An array containing information about all caches defined through
+ *   hook_cache_info().
+ */
+function cache_info() {
+  $cache_info = &drupal_static(__FUNCTION__, NULL);
+
+  if (!$cache_info) {
+    $cache_info = module_invoke_all('cache_info');
+  }
+
+  return $cache_info;
+}
+
+/**
+ * Clear a cache.
  *
- * @param $bin
- *   If set, the bin $bin to delete from. Mandatory
- *   argument if $cid is set.
+ * @param $cache
+ *   The name of the cache to clear.
+ */
+function cache_clear($cache) {
+  $cache_info = cache_info();
+
+  if (isset($cache_info[$cache]['callback']) && drupal_function_exists($cache_info[$cache]['callback'])) {
+    call_user_func($cache_info[$cache]['callback']);
+  }
+
+  if (isset($cache_info[$cache]['bin'])) {
+    _cache_get_object($cache_info[$cache]['bin'])->clear(NULL, TRUE);
+  }
+}
+
+/**
+ * Clear all caches.
+ */
+function cache_clear_all() {
+  $cache_info = cache_info();
+  foreach ($cache_info as $cache) {
+    cache_clear($cache);
+  }
+}
+
+/**
+ * Clear a specific item from a cache.
  *
+ * @param $cid
+ *   The cache item ID to delete. '*' may be used as a wildcard.
+ * @param $cache
+ *   The cache to delete the item from.
  * @param $wildcard
- *   If $wildcard is TRUE, cache IDs starting with $cid are deleted in
- *   addition to the exact cache ID specified by $cid.  If $wildcard is
- *   TRUE and $cid is '*' then the entire table $table is emptied. 
+ *   When is TRUE, cache IDs starting with $cid are deleted in addition to the
+ *   exact cache ID specified by $cid. If you want to clear an entire cache, use
+ *   cache_clear() instead of $wildcard = TRUE and $cid = '*'.
  */
-function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
-  if (!isset($cid) && !isset($bin)) {
-    // Clear the block cache first, so stale data will
-    // not end up in the page cache.
-    if (module_exists('block')) {
-      cache_clear_all(NULL, 'cache_block');
-    }
-    cache_clear_all(NULL, 'cache_page');
-    return;
-  }
-  return _cache_get_object($bin)->clear($cid, $wildcard);
+function cache_clear_item($cid, $cache, $wildcard = FALSE) {
+  $cache_info = cache_info();
+  _cache_get_object($cache_info[$cache]['bin'])->clear($cid, $wildcard);
 }
 
 /**
@@ -209,7 +239,7 @@ interface DrupalCacheInterface {
    * @param $expire
    *   One of the following values:
    *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
-   *     explicitly told to using cache_clear_all() with a cache ID.
+   *     explicitly told to using cache_clear_item() with a cache ID.
    *   - CACHE_TEMPORARY: Indicates that the item should be removed at the next
    *     general cache wipe.
    *   - A Unix timestamp: Indicates that the item should be kept at least until
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.925
diff -u -p -r1.925 common.inc
--- includes/common.inc	18 Jun 2009 21:19:01 -0000	1.925
+++ includes/common.inc	21 Jun 2009 01:43:36 -0000
@@ -2645,13 +2645,6 @@ function _drupal_load_stylesheet($matche
 }
 
 /**
- * Delete all cached CSS files.
- */
-function drupal_clear_css_cache() {
-  file_scan_directory(file_create_path('css'), '/.*/', array('callback' => 'file_unmanaged_delete'));
-}
-
-/**
  * Add a JavaScript file, setting or inline code to the page.
  *
  * The behavior of this function depends on the parameters it is called with.
@@ -3118,14 +3111,6 @@ function drupal_build_js_cache($files, $
 }
 
 /**
- * Delete all cached JS files.
- */
-function drupal_clear_js_cache() {
-  file_scan_directory(file_create_path('js'), '/.*/', array('callback' => 'file_unmanaged_delete'));
-  variable_set('javascript_parsed', array());
-}
-
-/**
  * Converts a PHP variable into its Javascript equivalent.
  *
  * We use HTML-safe strings, i.e. with <, > and & escaped.
@@ -4600,50 +4585,21 @@ function drupal_implode_tags($tags) {
 }
 
 /**
- * Flush all cached data on the site.
+ * Clear CSS and JS files cached by Drupal and browsers.
  *
- * Empties cache tables, rebuilds the menu cache and theme registries, and
- * invokes a hook so that other modules' cache data can be cleared as well.
+ * Don't call directly, but through cache_clear('system_css_js');.
  */
-function drupal_flush_all_caches() {
-  // Change query-strings on css/js files to enforce reload for all users.
-  _drupal_flush_css_js();
-
-  registry_rebuild();
-  drupal_clear_css_cache();
-  drupal_clear_js_cache();
-
-  // If invoked from update.php, we must not update the theme information in the
-  // database, or this will result in all themes being disabled.
-  if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
-    _system_get_theme_data();
-  }
-  else {
-    system_get_theme_data();
-  }
-
-  drupal_theme_rebuild();
-  // Rebuild content types, menu will be rebuilt as well.
-  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_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);
-  }
-}
+function _cache_clear_css_js() {
+  // Delete cached CSS and JavaScript files.
+  file_scan_directory(file_create_path('css'), '/.*/', array('callback' => 'file_unmanaged_delete'));
+  file_scan_directory(file_create_path('js'), '/.*/', array('callback' => 'file_unmanaged_delete'));
+  variable_set('javascript_parsed', array());
 
-/**
- * Helper function to change query-strings on css/js files.
- *
- * Changes the character added to all css/js files as dummy query-string,
- * so that all browsers are forced to reload fresh files. We keep
- * 20 characters history (FIFO) to avoid repeats, but only the first
- * (newest) character is actually used on urls, to keep them short.
- * This is also called from update.php.
- */
-function _drupal_flush_css_js() {
+  // Change the character added to all CSS and JS files as dummy query-string,
+  // so that all browsers are forced to reload fresh files. We keep 20
+  // characters history (FIFO) to avoid repeats, but only the first (newest)
+  // character is actually used on urls, to keep them short. This is also called
+  // from update.php.
   $string_history = variable_get('css_js_query_string', '00000000000000000000');
   $new_character = $string_history[0];
   // Not including 'q' to allow certain JavaScripts to re-use query string.
@@ -4652,4 +4608,4 @@ function _drupal_flush_css_js() {
     $new_character = $characters[mt_rand(0, strlen($characters) - 1)];
   }
   variable_set('css_js_query_string', $new_character . substr($string_history, 0, 19));
-}
+}
\ No newline at end of file
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.342
diff -u -p -r1.342 form.inc
--- includes/form.inc	18 Jun 2009 15:48:13 -0000	1.342
+++ includes/form.inc	21 Jun 2009 01:43:37 -0000
@@ -500,8 +500,8 @@ function drupal_process_form($form_id, &
       // here, as we've finished with them. The in-memory copies are still
       // here, though.
       if (variable_get('cache', CACHE_DISABLED) == CACHE_DISABLED && !empty($form_state['values']['form_build_id'])) {
-        cache_clear_all('form_' . $form_state['values']['form_build_id'], 'cache_form');
-        cache_clear_all('storage_' . $form_state['values']['form_build_id'], 'cache_form');
+        cache_clear_item('form_' . $form_state['values']['form_build_id'], 'cache_form');
+        cache_clear_item('storage_' . $form_state['values']['form_build_id'], 'cache_form');
       }
 
       // If batches were set in the submit handlers, we process them now,
Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.219
diff -u -p -r1.219 locale.inc
--- includes/locale.inc	8 Jun 2009 05:00:11 -0000	1.219
+++ includes/locale.inc	21 Jun 2009 01:43:38 -0000
@@ -140,7 +140,7 @@ function locale_languages_overview_form_
   variable_set('language_count', $enabled_count);
 
   // Changing the language settings impacts the interface.
-  cache_clear_all('*', 'cache_page', TRUE);
+  cache_clear('system_page');
 
   $form_state['redirect'] = 'admin/international/language';
   return;
@@ -441,7 +441,7 @@ function locale_languages_delete_form_su
     db_delete('locales_target')
       ->condition('language', $form_state['values']['langcode'])
       ->execute();
-    cache_clear_all('locale:' . $form_state['values']['langcode'], 'cache');
+    cache_clear_item('locale:' . $form_state['values']['langcode'], 'general');
     // With no translations, this removes existing JavaScript translations file.
     _locale_rebuild_js($form_state['values']['langcode']);
     // Remove the language.
@@ -458,7 +458,7 @@ function locale_languages_delete_form_su
   }
 
   // Changing the language settings impacts the interface:
-  cache_clear_all('*', 'cache_page', TRUE);
+  cache_clear('system_page');
 
   $form_state['redirect'] = 'admin/international/language';
   return;
@@ -1022,7 +1022,7 @@ function locale_translate_edit_form_subm
 
   // Clear locale cache.
   _locale_invalidate_js();
-  cache_clear_all('locale:', 'cache', TRUE);
+  cache_clear_item('locale:', 'general', TRUE);
 
   $form_state['redirect'] = 'admin/international/translate/translate';
   return;
@@ -1068,7 +1068,7 @@ function locale_translate_delete_form_su
     ->execute();
   // Force JavaScript translation file recreation for all languages.
   _locale_invalidate_js();
-  cache_clear_all('locale:', 'cache', TRUE);
+  cache_clear_item('locale:', 'general', TRUE);
   drupal_set_message(t('The string has been removed.'));
   $form_state['redirect'] = 'admin/international/translate/translate';
 }
@@ -1194,7 +1194,7 @@ function _locale_import_po($file, $langc
 
   // Clear cache and force refresh of JavaScript translations.
   _locale_invalidate_js($langcode);
-  cache_clear_all('locale:', 'cache', TRUE);
+  cache_clear_item('locale:', 'general', TRUE);
 
   // Rebuild the menu, strings may have changed.
   menu_rebuild();
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.328
diff -u -p -r1.328 menu.inc
--- includes/menu.inc	10 Jun 2009 21:52:36 -0000	1.328
+++ includes/menu.inc	21 Jun 2009 01:43:39 -0000
@@ -1811,7 +1811,7 @@ function menu_cache_clear($menu_name = '
   $cache_cleared = &drupal_static(__FUNCTION__, array());
 
   if (empty($cache_cleared[$menu_name])) {
-    cache_clear_all('links:' . $menu_name . ':', 'cache_menu', TRUE);
+    cache_clear_item('links:' . $menu_name . ':', 'cache_menu', TRUE);
     $cache_cleared[$menu_name] = 1;
   }
   elseif ($cache_cleared[$menu_name] == 1) {
@@ -1821,14 +1821,6 @@ function menu_cache_clear($menu_name = '
 }
 
 /**
- * Clears all cached menu data. This should be called any time broad changes
- * might have been made to the router items or menu links.
- */
-function menu_cache_clear_all() {
-  cache_clear_all('*', 'cache_menu', TRUE);
-}
-
-/**
  * (Re)populate the database tables used by various menu functions.
  *
  * This function will clear and populate the {menu_router} table, add entries
@@ -1843,7 +1835,7 @@ function menu_rebuild() {
   list($menu, $masks) = menu_router_build();
   _menu_router_save($menu, $masks);
   _menu_navigation_links_rebuild($menu);
-  menu_cache_clear_all();
+  cache_clear('menu');
   // Clear the page and block caches.
   _menu_clear_page_cache();
   if (defined('MAINTENANCE_MODE')) {
Index: includes/registry.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/registry.inc,v
retrieving revision 1.18
diff -u -p -r1.18 registry.inc
--- includes/registry.inc	10 Jun 2009 16:14:49 -0000	1.18
+++ includes/registry.inc	21 Jun 2009 01:43:39 -0000
@@ -103,7 +103,7 @@ function _registry_rebuild() {
   _registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
 
   module_implements(MODULE_IMPLEMENTS_CLEAR_CACHE);
-  cache_clear_all('*', 'cache_registry', TRUE);
+  cache_clear('system_registry');
 
   // We have some unchanged resources, warm up the cache - no need to pay
   // for looking them up again.
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.496
diff -u -p -r1.496 theme.inc
--- includes/theme.inc	18 Jun 2009 21:19:02 -0000	1.496
+++ includes/theme.inc	21 Jun 2009 01:43:40 -0000
@@ -258,7 +258,16 @@ function _theme_save_registry($theme, $r
  * to add more theme hooks.
  */
 function drupal_theme_rebuild() {
-  cache_clear_all('theme_registry', 'cache', TRUE);
+  // If invoked from update.php, we must not update the theme information in the
+  // database, or this will result in all themes being disabled.
+  if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
+    _system_get_theme_data();
+  }
+  else {
+    system_get_theme_data();
+  }
+
+  cache_clear('system_theme_registry');
 }
 
 /**
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.345
diff -u -p -r1.345 block.module
--- modules/block/block.module	12 Jun 2009 09:02:55 -0000	1.345
+++ modules/block/block.module	21 Jun 2009 01:43:41 -0000
@@ -173,6 +173,18 @@ function block_menu() {
 }
 
 /**
+ * Implement hook_cache_info().
+ */
+function block_cache_info() {
+  $caches['block'] = array(
+    'title' => t('Blocks'),
+    'bin' => 'cache_block',
+  );
+
+  return $caches;
+}
+
+/**
  * Menu item access callback - only admin or enabled themes can be accessed.
  */
 function _block_themes_access($theme) {
@@ -803,13 +815,6 @@ function _block_get_cache_id($block) {
 }
 
 /**
- * Implement hook_flush_caches().
- */
-function block_flush_caches() {
-  return array('cache_block');
-}
-
-/**
  * Process variables for block.tpl.php
  *
  * Prepare the values passed to the theme_block function to be passed
Index: modules/field/field.attach.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.attach.inc,v
retrieving revision 1.22
diff -u -p -r1.22 field.attach.inc
--- modules/field/field.attach.inc	7 Jun 2009 00:00:57 -0000	1.22
+++ modules/field/field.attach.inc	21 Jun 2009 01:43:41 -0000
@@ -944,8 +944,7 @@ function field_attach_prepare_translatio
 function field_attach_create_bundle($bundle) {
   module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_create_bundle', $bundle);
 
-  // Clear the cache.
-  field_cache_clear();
+  cache_clear('field');
 
   foreach (module_implements('field_attach_create_bundle') as $module) {
     $function = $module . '_field_attach_create_bundle';
@@ -968,8 +967,7 @@ function field_attach_rename_bundle($bun
     ->condition('bundle', $bundle_old)
     ->execute();
 
-  // Clear the cache.
-  field_cache_clear();
+  cache_clear('field');
 
   foreach (module_implements('field_attach_rename_bundle') as $module) {
     $function = $module . '_field_attach_rename_bundle';
Index: modules/field/field.crud.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.crud.inc,v
retrieving revision 1.15
diff -u -p -r1.15 field.crud.inc
--- modules/field/field.crud.inc	12 Jun 2009 08:39:36 -0000	1.15
+++ modules/field/field.crud.inc	21 Jun 2009 01:43:41 -0000
@@ -273,7 +273,8 @@ function field_create_field($field) {
   module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_create_field', $field);
 
   // Clear caches
-  field_cache_clear(TRUE);
+  cache_clear('field');
+  drupal_get_schema(NULL, TRUE);
 
   return $field;
 }
@@ -380,7 +381,8 @@ function field_delete_field($field_name)
     ->execute();
 
   // Clear the cache.
-  field_cache_clear(TRUE);
+  cache_clear('field');
+  drupal_get_schema(NULL, TRUE);
 }
 
 /**
@@ -444,8 +446,7 @@ function field_create_instance($instance
 
   _field_write_instance($instance);
 
-  // Clear caches
-  field_cache_clear();
+  cache_clear('field');
 
   // Invoke external hooks after the cache is cleared for API consistency.
   module_invoke_all('field_create_instance', $instance);
@@ -487,8 +488,7 @@ function field_update_instance($instance
 
   _field_write_instance($instance, TRUE);
 
-  // Clear caches.
-  field_cache_clear();
+  cache_clear('field');
 }
 
 /**
@@ -682,8 +682,8 @@ function field_delete_instance($field_na
 
   // Mark all data associated with the field for deletion.
   module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_delete_instance', $field_name, $bundle);
-  // Clear the cache.
-  field_cache_clear();
+
+  cache_clear('field');
 }
 
 /**
Index: modules/field/field.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.module,v
retrieving revision 1.13
diff -u -p -r1.13 field.module
--- modules/field/field.module	6 Jun 2009 16:17:30 -0000	1.13
+++ modules/field/field.module	21 Jun 2009 01:43:42 -0000
@@ -186,7 +186,7 @@ function field_theme() {
  * Implement hook_modules_installed().
  */
 function field_modules_installed($modules) {
-  field_cache_clear();
+  cache_clear('field');
 }
 
 /**
@@ -207,7 +207,7 @@ function field_modules_enabled($modules)
   foreach ($modules as $module) {
     field_associate_fields($module);
   }
-  field_cache_clear();
+  cache_clear('field');
 }
 
 /**
@@ -223,11 +223,36 @@ function field_modules_disabled($modules
       ->fields(array('widget_active' => 0))
       ->condition('widget_module', $module)
       ->execute();
-    field_cache_clear(TRUE);
+    cache_clear('field');
+    drupal_get_schema(NULL, TRUE);
   }
 }
 
 /**
+ * Implement hook_cache_info().
+ */
+function field_cache_info() {
+  $caches['field'] = array(
+    'title' => t('Fields'),
+    'bin' => 'cache_field',
+    'callback' => '_field_cache_clear',
+  );
+
+  return $caches;
+}
+
+/**
+ * Clear cached field information.
+ *
+ * Don't call directly, but through cache_clear('field');.
+ */
+function _field_cache_clear() {
+  module_load_include('inc', 'field', 'field.info');
+  _field_info_collate_types(TRUE);
+  _field_info_collate_fields(TRUE);
+}
+
+/**
  * Allows a module to update the database for fields and columns it controls.
  *
  * @param string $module
@@ -341,25 +366,6 @@ function field_build_modes($obj_type) {
 }
 
 /**
- * Clear the cached information; called in several places when field
- * information is changed.
- */
-function field_cache_clear($rebuild_schema = FALSE) {
-  cache_clear_all('*', 'cache_field', TRUE);
-
-  module_load_include('inc', 'field', 'field.info');
-  _field_info_collate_types(TRUE);
-  _field_info_collate_fields(TRUE);
-
-  // Refresh the schema to pick up new information.
-  // TODO : if db storage gets abstracted out, we'll need to revisit how and when
-  // we refresh the schema...
-  if ($rebuild_schema) {
-    $schema = drupal_get_schema(NULL, TRUE);
-  }
-}
-
-/**
  * Like filter_xss_admin(), but with a shorter list of allowed tags.
  *
  * Used for items entered by administrators, like field descriptions,
Index: modules/field/field.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.test,v
retrieving revision 1.27
diff -u -p -r1.27 field.test
--- modules/field/field.test	16 Jun 2009 08:40:18 -0000	1.27
+++ modules/field/field.test	21 Jun 2009 01:43:43 -0000
@@ -190,7 +190,7 @@ class FieldAttachTestCase extends Drupal
     $this->assertTrue(empty($entity->{$this->field_name}), t('Insert: missing field results in no value saved'));
 
     // Insert: Field is NULL.
-    field_cache_clear();
+    cache_clear('field');
     $entity = clone($entity_init);
     $entity->{$this->field_name} = NULL;
     field_attach_insert($entity_type, $entity);
@@ -200,7 +200,7 @@ class FieldAttachTestCase extends Drupal
     $this->assertTrue(empty($entity->{$this->field_name}), t('Insert: NULL field results in no value saved'));
 
     // Add some real data.
-    field_cache_clear();
+    cache_clear('field');
     $entity = clone($entity_init);
     $values = $this->_generateTestFieldValues(1);
     $entity->{$this->field_name} = $values;
@@ -211,7 +211,7 @@ class FieldAttachTestCase extends Drupal
     $this->assertEqual($entity->{$this->field_name}, $values, t('Field data saved'));
 
     // Update: Field is missing. Data should survive.
-    field_cache_clear();
+    cache_clear('field');
     $entity = clone($entity_init);
     field_attach_update($entity_type, $entity);
 
@@ -220,7 +220,7 @@ class FieldAttachTestCase extends Drupal
     $this->assertEqual($entity->{$this->field_name}, $values, t('Update: missing field leaves existing values in place'));
 
     // Update: Field is NULL. Data should be wiped.
-    field_cache_clear();
+    cache_clear('field');
     $entity = clone($entity_init);
     $entity->{$this->field_name} = NULL;
     field_attach_update($entity_type, $entity);
@@ -251,7 +251,7 @@ class FieldAttachTestCase extends Drupal
     $this->assertTrue(empty($entity->{$this->field_name}), t('Insert: NULL field results in no value saved'));
 
     // Insert: Field is missing.
-    field_cache_clear();
+    cache_clear('field');
     $entity = clone($entity_init);
     field_attach_insert($entity_type, $entity);
 
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.261
diff -u -p -r1.261 filter.module
--- modules/filter/filter.module	13 Jun 2009 19:37:27 -0000	1.261
+++ modules/filter/filter.module	21 Jun 2009 01:43:43 -0000
@@ -286,6 +286,18 @@ function filter_filter_tips($delta, $for
 }
 
 /**
+ * Implement hook_cache_info().
+ */
+function filter_cache_info() {
+  $caches['filter'] = array(
+    'title' => t('Filter cache'),
+    'bin' => 'cache_filter',
+  );
+
+  return $caches;
+}
+
+/**
  * Retrieve a list of text formats.
  */
 function filter_formats($index = NULL) {
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.117
diff -u -p -r1.117 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	16 Jun 2009 04:43:47 -0000	1.117
+++ modules/simpletest/drupal_web_test_case.php	21 Jun 2009 01:43:45 -0000
@@ -1117,7 +1117,7 @@ class DrupalWebTestCase extends DrupalTe
       module_implements(MODULE_IMPLEMENTS_CLEAR_CACHE);
 
       // Reset the Field API.
-      field_cache_clear();
+      cache_clear('field');
 
       // Rebuild caches.
       $this->refreshVariables();
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.157
diff -u -p -r1.157 system.admin.inc
--- modules/system/system.admin.inc	16 Jun 2009 08:28:40 -0000	1.157
+++ modules/system/system.admin.inc	21 Jun 2009 01:43:46 -0000
@@ -7,6 +7,28 @@
  */
 
 /**
+ * Implement hook_modules_enabled().
+ */
+function system_modules_enabled($modules) {
+  // Clear all caches.
+  registry_rebuild();
+  drupal_theme_rebuild();
+  node_types_rebuild();
+  cache_clear_item('schema', 'cache');
+}
+
+/**
+ * Implement hook_modules_disabled().
+ */
+function system_modules_disabled($modules) {
+  // Clear all caches.
+  registry_rebuild();
+  drupal_theme_rebuild();
+  node_types_rebuild();
+  cache_clear_item('schema', 'cache');
+}
+
+/**
  * Menu callback; Provide the administration overview page.
  */
 function system_main_admin_page($arg = NULL) {
@@ -524,7 +546,7 @@ function system_theme_settings_submit($f
     drupal_set_message(t('The configuration options have been saved.'));
   }
 
-  cache_clear_all();
+  cache_clear('system_theme_registry');
 }
 
 /**
@@ -574,11 +596,6 @@ function _system_is_incompatible(&$incom
  *   The form array.
  */
 function system_modules($form_state = array()) {
-  // Clear all caches.
-  registry_rebuild();
-  drupal_theme_rebuild();
-  node_types_rebuild();
-  cache_clear_all('schema', 'cache');
   // Get current list of modules.
   $files = system_get_module_data();
 
@@ -1363,22 +1380,65 @@ function system_performance_settings() {
     '#description' => t('This option can interfere with module development and should only be enabled in a production environment.'),
   );
 
-  $form['clear_cache'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clear cached data'),
-    '#description' => t('Caching data improves performance, but may cause problems while troubleshooting new modules, themes, or translations, if outdated information has been cached. To refresh all cached data on your site, click the button below. <em>Warning: high-traffic sites will experience performance slowdowns while cached data is rebuilt.</em>'),
-  );
+  $form['#submit'][] = 'drupal_clear_css_cache';
+  $form['#submit'][] = 'drupal_clear_js_cache';
+
+  return system_settings_form($form, FALSE);
+}
+
+/**
+ * Form builder; Clear caches for a selection of modules.
+ *
+ * @ingroup forms
+ */
+function system_clear_caches() {
+  foreach (cache_info() as $cache => $cache_info) {
+    $form[$cache] = array(
+      '#type' => 'checkbox',
+      '#title' => $cache_info['title'],
+      '#description' => isset($cache_info['description']) ? $cache_info['description'] : NULL,
+      '#default_value' => TRUE,
+    );
+  }
 
-  $form['clear_cache']['clear'] = array(
+  $form['submit'] = array(
     '#type' => 'submit',
-    '#value' => t('Clear cached data'),
-    '#submit' => array('system_clear_cache_submit'),
+    '#value' => t('Clear selected caches'),
   );
 
-  $form['#submit'][] = 'drupal_clear_css_cache';
-  $form['#submit'][] = 'drupal_clear_js_cache';
+  return $form;
+}
 
-  return system_settings_form($form, FALSE);
+function theme_system_clear_caches($form) {
+  $rows = array();
+  foreach (array_keys(cache_info()) as $cache) {
+    $row = array();
+    $name = $form[$cache]['#title'];
+    unset($form[$cache]['#title']);
+    $description = $form[$cache]['#description'];
+    unset($form[$cache]['#description']);
+    $row[] = array(
+      'class' => 'checkbox',
+      'data' => drupal_render($form[$cache]),
+    );
+    $row[] = '<label for="' . $form[$cache]['#id'] . '"><strong>' . $name . '</strong></label>';
+    $row[] = array(
+      'data' => $description,
+      'class' => 'description',
+    );
+    $rows[] = $row;
+  }
+
+  $header = array(
+    array(
+      'data' => t('Clear'),
+      'class' => 'checkbox'
+    ),
+    t('Cache'),
+    t('Description'),
+  );
+
+  return theme('table', $header, $rows) . drupal_render_children($form);
 }
 
 /**
@@ -1386,9 +1446,21 @@ function system_performance_settings() {
  *
  * @ingroup forms
  */
-function system_clear_cache_submit($form, &$form_state) {
-  drupal_flush_all_caches();
-  drupal_set_message(t('Caches cleared.'));
+function system_clear_caches_submit($form, &$form_state) {
+  $modules = array();
+  $names = array();
+  foreach (module_implements('cache_info') as $module) {
+    if ($form_state['values'][$module]) {
+      $module_info = drupal_parse_info_file(drupal_get_path('module', $module) . "/$module.info");
+      $names[] = $module_info['name'];
+      $modules[] = $module;
+    }
+  }
+
+  if (count($modules)) {
+    caches_clear($modules);
+    drupal_set_message(t('Caches cleared for @modules.', array('@modules' => implode(', ', $names))));
+  }
 }
 
 /**
Index: modules/system/system.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v
retrieving revision 1.42
diff -u -p -r1.42 system.api.php
--- modules/system/system.api.php	18 Jun 2009 10:20:22 -0000	1.42
+++ modules/system/system.api.php	21 Jun 2009 01:43:47 -0000
@@ -1759,5 +1759,32 @@ function hook_registry_files_alter(&$fil
 }
 
 /**
+ * Expose caches to other modules.
+ *
+ * Modules that cache data should expose their caches through this hook.
+ *
+ * @return
+ *   An associative array where keys are cache names and values are arrays with
+ *   the following keys:
+ *   - "title" A required title of the cache.
+ *   - "description" An optional description of what the cache does.
+ *   - "callback" An optional callback function that should be called when this cache is cleared.
+ *   - "bin" An optional name of the cache bin (i.e. a database table) associated with this cache.
+ *   Either "callback" or "bin" (or both) is required for each cache.
+ */
+function hook_cache_info() {
+  return array(
+    'description' => t('Clear the CSS, JavaScript, theme and node type caches and rebuild the registry.'),
+    // Don't clear cache_form - in-progress form submissions may break.
+    // Ordered so clearing the page cache will always be the last action.
+    'tables' => array(
+      'cache',
+      'cache_filter',
+      'cache_registry',
+      'cache_page',
+    ),
+  );
+}
+/**
  * @} End of "addtogroup hooks".
  */
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.712
diff -u -p -r1.712 system.module
--- modules/system/system.module	16 Jun 2009 08:41:35 -0000	1.712
+++ modules/system/system.module	21 Jun 2009 01:43:49 -0000
@@ -154,6 +154,10 @@ function system_theme() {
       'arguments' => array('form' => NULL),
       'file' => 'system.admin.inc',
     ),
+    'system_clear_caches' => array(
+      'arguments' => array('form' => NULL),
+      'file' => 'system.admin.inc',
+    ),
     'status_report' => array(
       'arguments' => array('requirements' => NULL),
       'file' => 'system.admin.inc',
@@ -607,6 +611,13 @@ function system_menu() {
     'access callback' => 'system_admin_menu_block_access',
     'access arguments' => array('admin/development', 'access administration pages'),
   );
+  $items['admin/development/clear-caches'] = array(
+    'title' => 'Clear caches',
+    'description' => 'Clear the caches of specific modules.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('system_clear_caches'),
+    'access arguments' => array('administer site configuration'),
+  );
 
   // Actions.
   $items['admin/settings/actions'] = array(
@@ -789,6 +800,39 @@ function system_menu() {
 }
 
 /**
+ * Implement hook_cache_info().
+ */
+function system_cache_info() {
+  $caches['general'] = array(
+    'title' => t('General cache'),
+    'bin' => 'cache',
+  );
+  $caches['page'] = array(
+    'title' => t('Page cache'),
+    'bin' => 'cache_page',
+  );
+  $caches['css_js'] = array(
+    'title' => t('CSS and JavaScript files'),
+    'description' => t('Clear cached aggregated and compressed CSS and JavaScript files.'),
+    'callback' => '_cache_clear_css_js',
+  );
+  $caches['code_registry'] = array(
+    'title' => t('Code registry'),
+    'bin' => 'cache_registry',
+  );
+  $caches['theme_registry'] = array(
+    'title' => t('Theme cache'),
+    'callback' => '_system_cache_clear_themes',
+  );
+  $caches['menu'] = array(
+    'title' => t('Menu'),
+    'bin' => 'cache_menu',
+  );
+
+  return $caches;
+}
+
+/**
  * Retrieve a blocked IP address from the database.
  *
  * @param $iid integer
@@ -1588,9 +1632,6 @@ function system_settings_form_submit($fo
   else {
     drupal_set_message(t('The configuration options have been saved.'));
   }
-
-  cache_clear_all();
-  drupal_theme_rebuild();
 }
 
 /**
@@ -1765,11 +1806,7 @@ function system_cron() {
     }
   }
 
-  $core = array('cache', 'cache_filter', 'cache_page', 'cache_form', 'cache_menu');
-  $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
-  foreach ($cache_tables as $table) {
-    cache_clear_all(NULL, $table);
-  }
+  cache_clear_all();
 
   // Reset expired items in the default queue implementation table. If that's
   // not used, this will simply be a no-op.
Index: modules/update/update.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/update/update.module,v
retrieving revision 1.37
diff -u -p -r1.37 update.module
--- modules/update/update.module	8 Jun 2009 05:00:11 -0000	1.37
+++ modules/update/update.module	21 Jun 2009 01:43:49 -0000
@@ -168,6 +168,38 @@ function update_theme() {
 }
 
 /**
+ * Implement hook_cache_info().
+ */
+function update_cache_info() {
+  $caches['status'] = array(
+    'title' => t('Update status'),
+    'callback' => 'updae_cache_clear',
+  );
+}
+
+/**
+ * Clear the update status cache.
+ *
+ * Called from update.php (among others) to flush the caches.
+ * We might be running update.php, in which case we are likely to install a new
+ * version of something, in which case, we want to check for available update
+ * data again. However, because we have our own caching system, we need to
+ * directly clear the database table ourselves at this point and return nothing,
+ * for example, on sites that use memcache where cache_clear() won't know
+ * how to purge this data.
+ *
+ * However, we only want to do this from update.php, since otherwise, we'd
+ * lose all the available update data on every cron run. So, we specifically
+ * check if the site is in MAINTENANCE_MODE == 'update' (which indicates
+ * update.php is running, not update module... alas for overloaded names).
+ */
+function update_cache_clear() {
+  if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
+    _update_cache_clear();
+  }
+}
+
+/**
  * Implement hook_requirements().
  *
  * @return
@@ -607,28 +639,5 @@ function _update_cache_clear($cid = NULL
 }
 
 /**
- * Implement hook_flush_caches().
- *
- * Called from update.php (among others) to flush the caches.
- * Since we're running update.php, we are likely to install a new version of
- * something, in which case, we want to check for available update data again.
- * However, because we have our own caching system, we need to directly clear
- * the database table ourselves at this point and return nothing, for example,
- * on sites that use memcache where cache_clear_all() won't know how to purge
- * this data.
- *
- * However, we only want to do this from update.php, since otherwise, we'd
- * lose all the available update data on every cron run. So, we specifically
- * check if the site is in MAINTENANCE_MODE == 'update' (which indicates
- * update.php is running, not update module... alas for overloaded names).
- */
-function update_flush_caches() {
-  if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
-    _update_cache_clear();
-  }
-  return array();
-}
-
-/**
  * @} End of "defgroup update_status_cache".
  */
