? .DS_Store
? clear_cache_00.patch
? clear_cache_01.patch
? clear_cache_02.patch
? clear_cache_03.patch
? clear_cache_04.patch
? installation_server_settings_00.patch
? performance_settings_06.patch
? modules/.DS_Store
? modules/field/.DS_Store
? modules/field/modules/.DS_Store
? modules/simpletest/.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	22 Jun 2009 00:59:19 -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	22 Jun 2009 00:59:20 -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	22 Jun 2009 00:59:20 -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	22 Jun 2009 00:59:20 -0000
@@ -34,15 +34,14 @@ function _cache_get_object($bin) {
  *
  * @param $cid
  *   The cache ID of the data to retrieve.
- * @param $bin
- *   The cache bin to store the data in. Valid core values are 'cache_block',
- *   'cache_field', 'cache_filter', 'cache_form', 'cache_menu', 'cache_page',
- *   'cache_path', 'cache_registry', 'cache_update' or 'cache' for the default
- *   cache.
+ * @param $cache
+ *   The cache to get the data from as defined in hook_cache_info().
  * @return The cache or FALSE on failure.
  */
-function cache_get($cid, $bin = 'cache') {
-  return _cache_get_object($bin)->get($cid);
+function cache_get($cid, $cache = 'general') {
+  $cache_info = cache_info();
+
+  return _cache_get_object($cache_info[$cache]['bin'])->get($cid);
 }
 
 /**
@@ -100,15 +99,12 @@ function cache_get($cid, $bin = 'cache')
  *   The data to store in the cache. Complex data types will be automatically
  *   serialized before insertion.
  *   Strings will be stored as plain text and not serialized.
- * @param $bin
- *   The cache bin to store the data in. Valid core values are 'cache_block',
- *   'cache_field', 'cache_filter', 'cache_form', 'cache_menu', 'cache_page',
- *   'cache_path', 'cache_registry', 'cache_update' or 'cache' for the default
- *   cache.
+ * @param $cache
+ *   The cache to store the data in as defined in hook_cache_info().
  * @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
@@ -116,40 +112,76 @@ function cache_get($cid, $bin = 'cache')
  * @param $headers
  *   A string containing HTTP header information for cached pages.
  */
-function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT, array $headers = NULL) {
-  return _cache_get_object($bin)->set($cid, $data, $expire, $headers);
+function cache_set($cid, $data, $cache = 'general', $expire = CACHE_PERMANENT, array $headers = NULL) {
+  $cache_info = cache_info();
+
+  return _cache_get_object($cache_info[$cache]['bin'])->set($cid, $data, $expire, $headers);
 }
 
 /**
- * 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.
+ * @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 caches.
  *
- * @param $cid
- *   If set, the cache ID to delete. Otherwise, all cache entries that can
- *   expire are deleted.
+ * @param $cache
+ *   The name of the cache to clear.
+ * @param ...
+ *   The names of additional caches to clear.
+ */
+function cache_clear() {
+  $cache_info = cache_info();
+
+  foreach (func_get_args() as $cache) {
+    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.
  *
- * @param $bin
- *   If set, the bin $bin to delete from. Mandatory
- *   argument if $cid is set.
+ * Only use this if you are sure you want to clear the form cache as well, which
+ * will break in-progress form submissions.
+ */
+function cache_clear_all() {
+  call_user_func_array('cache_clear', array_keys(cache_info()));
+}
+
+/**
+ * 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 +241,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	22 Jun 2009 00:59:23 -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	22 Jun 2009 00:59:25 -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	22 Jun 2009 00:59:26 -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	22 Jun 2009 00:59:28 -0000
@@ -1811,24 +1811,16 @@ 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) {
-    register_shutdown_function('cache_clear_all', 'links:' . $menu_name . ':', 'cache_menu', TRUE);
+    register_shutdown_function('cache_clear_item', 'links:' . $menu_name . ':', 'menu', TRUE);
     $cache_cleared[$menu_name] = 2;
   }
 }
 
 /**
- * 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')) {
@@ -2271,13 +2263,13 @@ function _menu_clear_page_cache() {
   // Clear the page and block caches, but at most twice, including at
   //  the end of the page load when there are multiple links saved or deleted.
   if ($cache_cleared == 0) {
-    cache_clear_all();
+    cache_clear('block', 'page');
     // Keep track of which menus have expanded items.
     _menu_set_expanded_menus();
     $cache_cleared = 1;
   }
   elseif ($cache_cleared == 1) {
-    register_shutdown_function('cache_clear_all');
+    register_shutdown_function('cache_clear', 'block', 'page');
     // Keep track of which menus have expanded items.
     register_shutdown_function('_menu_set_expanded_menus');
     $cache_cleared = 2;
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.143
diff -u -p -r1.143 module.inc
--- includes/module.inc	6 Jun 2009 16:05:26 -0000	1.143
+++ includes/module.inc	22 Jun 2009 00:59:29 -0000
@@ -333,7 +333,7 @@ function module_implements($hook, $sort 
     $sorted_implementations = array();
     $loaded = array();
     $cached_hooks = 0;
-    cache_clear_all('hooks', 'cache_registry');
+    cache_clear_item('hooks', 'code_registry');
     return;
   }
   if ($hook === MODULE_IMPLEMENTS_WRITE_CACHE) {
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	22 Jun 2009 00:59:29 -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	22 Jun 2009 00:59:31 -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/aggregator/aggregator.parser.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.parser.inc,v
retrieving revision 1.3
diff -u -p -r1.3 aggregator.parser.inc
--- modules/aggregator/aggregator.parser.inc	27 May 2009 18:33:54 -0000	1.3
+++ modules/aggregator/aggregator.parser.inc	22 Jun 2009 00:59:31 -0000
@@ -59,8 +59,7 @@ function aggregator_aggregator_parse($fe
       ))
       ->execute();
 
-    // Clear the cache.
-    cache_clear_all();
+    cache_clear('block', 'page');
 
     if (isset($feed->redirected)) {
       watchdog('aggregator', 'Updated URL for feed %title to %url.', array('%title' => $feed->title, '%url' => $feed->url));
Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.42
diff -u -p -r1.42 block.admin.inc
--- modules/block/block.admin.inc	7 Jun 2009 02:29:07 -0000	1.42
+++ modules/block/block.admin.inc	22 Jun 2009 00:59:32 -0000
@@ -115,7 +115,7 @@ function block_admin_display_form_submit
       ->execute();
   }
   drupal_set_message(t('The block settings have been updated.'));
-  cache_clear_all();
+  cache_clear('block', 'page');
 }
 
 /**
@@ -318,7 +318,7 @@ function block_admin_configure_submit($f
     $query->execute();
     module_invoke($form_state['values']['module'], 'block_save', $form_state['values']['delta'], $form_state['values']);
     drupal_set_message(t('The block configuration has been saved.'));
-    cache_clear_all();
+    cache_clear('block', 'page');
     $form_state['redirect'] = 'admin/build/block';
     return;
   }
@@ -381,7 +381,7 @@ function block_add_block_form_submit($fo
   $query->execute();
 
   drupal_set_message(t('The block has been created.'));
-  cache_clear_all();
+  cache_clear('block', 'page');
 
   $form_state['redirect'] = 'admin/build/block';
 }
@@ -409,7 +409,7 @@ function block_box_delete_submit($form, 
     ->condition('delta', $form_state['values']['bid'])
     ->execute();
   drupal_set_message(t('The block %name has been removed.', array('%name' => $form_state['values']['info'])));
-  cache_clear_all();
+  cache_clear('block', 'page');
   $form_state['redirect'] = 'admin/build/block';
   return;
 }
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	22 Jun 2009 00:59:32 -0000
@@ -20,10 +20,9 @@ define('BLOCK_REGION_NONE', -1);
  * BLOCK_CACHE_PER_ROLE is used as a default when no caching pattern is
  * specified.
  *
- * The block cache is cleared in cache_clear_all(), and uses the same clearing
- * policy than page cache (node, comment, user, taxonomy added or updated...).
- * Blocks requiring more fine-grained clearing might consider disabling the
- * built-in block cache (BLOCK_NO_CACHE) and roll their own.
+ * Normally cached blocks are cleared using cache_clear('block'), but modules
+ * that want to control caching of their blocks should set BLOCK_NO_CACHE and
+ * use their own caching methods.
  *
  * Note that user 1 is excluded from block caching.
  */
@@ -173,6 +172,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 +814,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/book/book.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.install,v
retrieving revision 1.30
diff -u -p -r1.30 book.install
--- modules/book/book.install	2 Jun 2009 06:58:15 -0000	1.30
+++ modules/book/book.install	22 Jun 2009 00:59:33 -0000
@@ -22,7 +22,7 @@ function book_install() {
 function book_uninstall() {
   // Delete menu links.
   db_query("DELETE FROM {menu_links} WHERE module = 'book'");
-  menu_cache_clear_all();
+  cache_clear('menu');
   // Remove tables.
   drupal_uninstall_schema('book');
 }
Index: modules/comment/comment.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.admin.inc,v
retrieving revision 1.24
diff -u -p -r1.24 comment.admin.inc
--- modules/comment/comment.admin.inc	19 Jun 2009 13:03:53 -0000	1.24
+++ modules/comment/comment.admin.inc	22 Jun 2009 00:59:33 -0000
@@ -145,7 +145,7 @@ function comment_admin_overview_submit($
         watchdog('content', 'Comment: updated %subject.', array('%subject' => $comment->subject), WATCHDOG_NOTICE, l(t('view'), 'node/' . $comment->nid, array('fragment' => 'comment-' . $comment->cid)));
       }
     }
-    cache_clear_all();
+    cache_clear('block', 'page');
     drupal_set_message(t('The update has been performed.'));
     $form_state['redirect'] = 'admin/content/comment';
   }
@@ -204,7 +204,7 @@ function comment_multiple_delete_confirm
       _comment_delete_thread($comment);
       _comment_update_node_statistics($comment->nid);
     }
-    cache_clear_all();
+    cache_clear('block', 'page');
     drupal_set_message(t('The comments have been deleted.'));
   }
   $form_state['redirect'] = 'admin/content/comment';
@@ -260,7 +260,7 @@ function comment_confirm_delete_submit($
   _comment_delete_thread($comment);
   _comment_update_node_statistics($comment->nid);
   // Clear the cache so an anonymous user sees that his comment was deleted.
-  cache_clear_all();
+  cache_clear('block', 'page');
 
   $form_state['redirect'] = "node/$comment->nid";
 }
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.725
diff -u -p -r1.725 comment.module
--- modules/comment/comment.module	19 Jun 2009 13:03:53 -0000	1.725
+++ modules/comment/comment.module	22 Jun 2009 00:59:35 -0000
@@ -984,7 +984,7 @@ function comment_save($edit) {
       }
       _comment_update_node_statistics($edit['nid']);
       // Clear the cache so an anonymous user can see his comment being added.
-      cache_clear_all();
+      cache_clear('block', 'page');
 
       // Explain the approval queue if necessary, and then
       // redirect the user to the node he's commenting on.
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	22 Jun 2009 00:59:36 -0000
@@ -648,7 +648,7 @@ function field_attach_insert($obj_type, 
 
   list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
   if ($cacheable) {
-    cache_clear_all("field:$obj_type:$id", 'cache_field');
+    cache_clear_item("field:$obj_type:$id", 'field');
   }
 }
 
@@ -676,7 +676,7 @@ function field_attach_update($obj_type, 
 
   list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
   if ($cacheable) {
-    cache_clear_all("field:$obj_type:$id", 'cache_field');
+    cache_clear_item("field:$obj_type:$id", 'field');
   }
 }
 
@@ -701,7 +701,7 @@ function field_attach_delete($obj_type, 
 
   list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
   if ($cacheable) {
-    cache_clear_all("field:$obj_type:$id", 'cache_field');
+    cache_clear_item("field:$obj_type:$id", 'field');
   }
 }
 
@@ -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	22 Jun 2009 00:59:36 -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.info.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.info.inc,v
retrieving revision 1.6
diff -u -p -r1.6 field.info.inc
--- modules/field/field.info.inc	5 Jun 2009 18:25:41 -0000	1.6
+++ modules/field/field.info.inc	22 Jun 2009 00:59:37 -0000
@@ -74,7 +74,7 @@ function _field_info_collate_types($rese
 
   if ($reset) {
     $info = NULL;
-    cache_clear_all('field_info_types', 'cache_field');
+    cache_clear_item('field_info_types', 'field');
     return;
   }
 
@@ -168,7 +168,7 @@ function _field_info_collate_fields($res
 
   if ($reset) {
     $info = NULL;
-    cache_clear_all('field_info_fields', 'cache_field');
+    cache_clear_item('field_info_fields', 'field');
     return;
   }
 
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	22 Jun 2009 00:59:37 -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	22 Jun 2009 00:59:39 -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.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.admin.inc,v
retrieving revision 1.30
diff -u -p -r1.30 filter.admin.inc
--- modules/filter/filter.admin.inc	12 Jun 2009 08:39:37 -0000	1.30
+++ modules/filter/filter.admin.inc	22 Jun 2009 00:59:39 -0000
@@ -260,7 +260,7 @@ function filter_admin_format_form_submit
     ->condition('format', $format)
     ->execute();
 
-  cache_clear_all($format . ':', 'cache_filter', TRUE);
+  cache_clear_item($format . ':', 'filter', TRUE);
 
   // If a new filter was added, return to the main list of filters. Otherwise, stay on edit filter page to show new changes.
   $return = 'admin/settings/formats';
@@ -324,7 +324,7 @@ function filter_admin_delete_submit($for
       ->execute();
   }
 
-  cache_clear_all($form_state['values']['format'] . ':', 'cache_filter', TRUE);
+  cache_clear_item($form_state['values']['format'] . ':', 'filter', TRUE);
   drupal_set_message(t('Deleted text format %format.', array('%format' => $form_state['values']['name'])));
 
   $form_state['redirect'] = 'admin/settings/formats';
@@ -370,7 +370,7 @@ function filter_admin_configure(&$form_s
  * Clear the filter's cache when configuration settings are saved.
  */
 function filter_admin_configure_submit($form, &$form_state) {
-  cache_clear_all($form_state['values']['format'] . ':', 'cache_filter', TRUE);
+  cache_clear_item($form_state['values']['format'] . ':', 'filter', TRUE);
 }
 
 /**
@@ -445,5 +445,5 @@ function filter_admin_order_submit($form
   }
   drupal_set_message(t('The filter ordering has been saved.'));
 
-  cache_clear_all($form_state['values']['format'] . ':', 'cache_filter', TRUE);
+  cache_clear_item($form_state['values']['format'] . ':', 'filter', TRUE);
 }
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	22 Jun 2009 00:59:40 -0000
@@ -162,7 +162,7 @@ function filter_perm() {
  * Expire outdated filter cache entries
  */
 function filter_cron() {
-  cache_clear_all(NULL, 'cache_filter');
+  cache_clear('filter');
 }
 
 /**
@@ -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/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.242
diff -u -p -r1.242 locale.module
--- modules/locale/locale.module	8 Jun 2009 05:00:11 -0000	1.242
+++ modules/locale/locale.module	22 Jun 2009 00:59:40 -0000
@@ -410,7 +410,7 @@ function locale($string = NULL, $context
           ->fields(array('version' => VERSION))
           ->condition('lid', $translation->lid)
           ->execute();
-        cache_clear_all('locale:', 'cache', TRUE);
+        cache_clear_item('locale:', 'general', TRUE);
       }
     }
     else {
@@ -426,7 +426,7 @@ function locale($string = NULL, $context
         ->execute();
       $locale_t[$langcode][$context][$string] = TRUE;
       // Clear locale cache so this string can be added in a later request.
-      cache_clear_all('locale:', 'cache', TRUE);
+      cache_clear_item('locale:', 'general', TRUE);
     }
   }
 
Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.49
diff -u -p -r1.49 menu.admin.inc
--- modules/menu/menu.admin.inc	7 Jun 2009 02:30:13 -0000	1.49
+++ modules/menu/menu.admin.inc	22 Jun 2009 00:59:41 -0000
@@ -524,8 +524,7 @@ function menu_delete_menu_confirm_submit
       ->condition('delta', $menu['menu_name'])
       ->execute();
   }
-  menu_cache_clear_all();
-  cache_clear_all();
+  cache_clear('menu', 'block', 'page');
   $t_args = array('%title' => $menu['title']);
   drupal_set_message(t('The custom menu %title has been deleted.', $t_args));
   watchdog('menu', 'Deleted custom menu %title and all its menu links.', $t_args, WATCHDOG_NOTICE);
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.192
diff -u -p -r1.192 menu.module
--- modules/menu/menu.module	27 May 2009 18:33:58 -0000	1.192
+++ modules/menu/menu.module	22 Jun 2009 00:59:41 -0000
@@ -178,7 +178,7 @@ function menu_enable() {
       menu_link_save($link);
     }
   }
-  menu_cache_clear_all();
+  cache_clear('menu');
 }
 
 /**
Index: modules/node/node.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v
retrieving revision 1.54
diff -u -p -r1.54 node.admin.inc
--- modules/node/node.admin.inc	5 Jun 2009 05:28:28 -0000	1.54
+++ modules/node/node.admin.inc	22 Jun 2009 00:59:42 -0000
@@ -545,7 +545,7 @@ function node_admin_nodes_submit($form, 
     }
     call_user_func_array($function, $args);
 
-    cache_clear_all();
+    cache_clear('block', 'page');
   }
   else {
     // We need to rebuild the form to go to a second step. For example, to
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1071
diff -u -p -r1.1071 node.module
--- modules/node/node.module	18 Jun 2009 21:19:02 -0000	1.1071
+++ modules/node/node.module	22 Jun 2009 00:59:44 -0000
@@ -1032,8 +1032,7 @@ function node_save($node) {
   // Clear internal properties.
   unset($node->is_new);
 
-  // Clear the page and block caches.
-  cache_clear_all();
+  cache_clear('block', 'page');
 }
 
 /**
@@ -1097,8 +1096,7 @@ function node_delete_multiple($nids) {
     }
   }
 
-  // Clear the page and block and node_load_multiple caches.
-  cache_clear_all();
+  cache_clear('block', 'page');
   drupal_static_reset('node_load_multiple');
 }
 
@@ -2710,7 +2708,7 @@ function node_access_rebuild($batch_mode
   if (!isset($batch)) {
     drupal_set_message(t('Content permissions have been rebuilt.'));
     node_access_needs_rebuild(FALSE);
-    cache_clear_all();
+    cache_clear('block', 'page');
   }
 }
 
@@ -2760,7 +2758,7 @@ function _node_access_rebuild_batch_fini
   else {
     drupal_set_message(t('The content access permissions have not been properly rebuilt.'), 'error');
   }
-  cache_clear_all();
+  cache_clear('block', 'page');
 }
 
 /**
Index: modules/path/path.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/path/path.module,v
retrieving revision 1.159
diff -u -p -r1.159 path.module
--- modules/path/path.module	11 Jun 2009 04:59:26 -0000	1.159
+++ modules/path/path.module	22 Jun 2009 00:59:44 -0000
@@ -68,6 +68,18 @@ function path_menu() {
 }
 
 /**
+ * Implement hook_cache_info().
+ */
+function path_cache_info() {
+  $caches['path'] = array(
+    'title' => t('Paths'),
+    'bin' => 'cache_path',
+  );
+
+  return $caches;
+}
+
+/**
  * Post-confirmation; delete an URL alias.
  */
 function path_admin_delete($pid = 0) {
Index: modules/path/path.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/path/path.test,v
retrieving revision 1.13
diff -u -p -r1.13 path.test
--- modules/path/path.test	12 Jun 2009 08:39:38 -0000	1.13
+++ modules/path/path.test	22 Jun 2009 00:59:45 -0000
@@ -41,12 +41,12 @@ class PathTestCase extends DrupalWebTest
 
     // Visit the system path for the node and confirm a cache entry is
     // created.
-    cache_clear_all('*', 'cache_path', TRUE);
+    cache_clear_item('*', 'path', TRUE);
     $this->drupalGet($edit['src']);
     $this->assertTrue(cache_get($edit['src'], 'cache_path'), t('Cache entry was created.'));
 
     // Visit the alias for the node and confirm a cache entry is created.
-    cache_clear_all('*', 'cache_path', TRUE);
+    cache_clear_item('*', 'path', TRUE);
     $this->drupalGet($edit['dst']);
     $this->assertTrue(cache_get($edit['src'], 'cache_path'), t('Cache entry was created.'));
   }
Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.299
diff -u -p -r1.299 poll.module
--- modules/poll/poll.module	4 Jun 2009 03:33:28 -0000	1.299
+++ modules/poll/poll.module	22 Jun 2009 00:59:45 -0000
@@ -685,7 +685,7 @@ function poll_vote($form, &$form_state) 
     ->condition('chid', $choice)
     ->execute();
 
-  cache_clear_all();
+  cache_clear('block', 'page');
   drupal_set_message(t('Your vote was recorded.'));
 
   // Return the user to whatever page they voted from.
Index: modules/profile/profile.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.admin.inc,v
retrieving revision 1.25
diff -u -p -r1.25 profile.admin.inc
--- modules/profile/profile.admin.inc	26 May 2009 10:41:06 -0000	1.25
+++ modules/profile/profile.admin.inc	22 Jun 2009 00:59:46 -0000
@@ -86,7 +86,7 @@ function profile_admin_overview_submit($
   }
 
   drupal_set_message(t('Profile fields have been updated.'));
-  cache_clear_all();
+  cache_clear('block', 'page');
   menu_rebuild();
 }
 
@@ -370,7 +370,7 @@ function profile_field_form_submit($form
       ->exeucte();
     drupal_set_message(t('The field has been updated.'));
   }
-  cache_clear_all();
+  cache_clear('block', 'page');
   menu_rebuild();
 
   $form_state['redirect'] = 'admin/user/profile';
@@ -406,7 +406,7 @@ function profile_field_delete_submit($fo
     ->condition('fid', $form_state['values']['fid'])
     ->execute();
 
-  cache_clear_all();
+  cache_clear('block', 'page');
 
   drupal_set_message(t('The field %field has been deleted.', array('%field' => $form_state['values']['title'])));
   watchdog('profile', 'Profile field %field deleted.', array('%field' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/user/profile'));
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	22 Jun 2009 00:59:48 -0000
@@ -1071,7 +1071,7 @@ class DrupalWebTestCase extends DrupalTe
    */
   protected function refreshVariables() {
     global $conf;
-    cache_clear_all('variables', 'cache');
+    cache_clear_item('variables', 'general');
     $conf = variable_init();
   }
 
@@ -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/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.55
diff -u -p -r1.55 simpletest.module
--- modules/simpletest/simpletest.module	13 Jun 2009 11:29:25 -0000	1.55
+++ modules/simpletest/simpletest.module	22 Jun 2009 00:59:49 -0000
@@ -101,7 +101,7 @@ function _simpletest_format_summary_line
  *   drupal being the default.
  */
 function simpletest_run_tests($test_list, $reporter = 'drupal') {
-  cache_clear_all();
+  cache_clear('block', 'page');
   $test_id = db_insert('simpletest_test_id')
     ->useDefaults(array('test_id'))
     ->execute();
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	22 Jun 2009 00:59:52 -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,32 +1380,91 @@ 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) {
+    if (isset($cache_info['title'])) {
+      $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 (cache_info() as $cache => $cache_info) {
+    if (isset($cache_info['title'])) {
+      $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);
 }
 
 /**
- * Submit callback; clear system caches.
+ * Submit callback for system_clear_caches().
  *
  * @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	22 Jun 2009 00:59:53 -0000
@@ -1759,5 +1759,35 @@ 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 optional keys:
+ *   - "title" The title of the cache. Required if the cache may be cleared
+ *   through the UI.
+ *   - "description" A description of what the cache does.
+ *   - "callback" A callback function that should be called when this cache is
+ *   cleared.
+ *   - "bin" A 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	22 Jun 2009 00:59:58 -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,42 @@ 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',
+  );
+  $caches['form'] = array(
+    'bin' => 'cache_form',
+  );
+
+  return $caches;
+}
+
+/**
  * Retrieve a blocked IP address from the database.
  *
  * @param $iid integer
@@ -1588,9 +1635,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 +1809,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/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.478
diff -u -p -r1.478 taxonomy.module
--- modules/taxonomy/taxonomy.module	12 Jun 2009 13:59:56 -0000	1.478
+++ modules/taxonomy/taxonomy.module	22 Jun 2009 01:00:00 -0000
@@ -293,7 +293,7 @@ function taxonomy_vocabulary_save($vocab
     module_invoke_all('taxonomy_vocabulary_insert', $vocabulary);
   }
 
-  cache_clear_all();
+  cache_clear('block', 'page');
   drupal_static_reset('taxonomy_vocabulary_load_multiple');
 
   return $status;
@@ -324,7 +324,7 @@ function taxonomy_vocabulary_delete($vid
   field_attach_delete_bundle($vocabulary['machine_name']);
   module_invoke_all('taxonomy', 'delete', 'vocabulary', $vocabulary);
 
-  cache_clear_all();
+  cache_clear('block', 'page');
   drupal_static_reset('taxonomy_vocabulary_load_multiple');
 
   return SAVED_DELETED;
@@ -473,7 +473,7 @@ function taxonomy_term_save($term) {
     $query->execute();
   }
 
-  cache_clear_all();
+  cache_clear('block', 'page');
   taxonomy_terms_static_reset();
 
   return $status;
@@ -531,7 +531,7 @@ function taxonomy_term_delete($tid) {
     $tids = $orphans;
   }
 
-  cache_clear_all();
+  cache_clear('block', 'page');
   taxonomy_terms_static_reset();
 
   return SAVED_DELETED;
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	22 Jun 2009 01:00:00 -0000
@@ -168,6 +168,38 @@ function update_theme() {
 }
 
 /**
+ * Implement hook_cache_info().
+ */
+function update_cache_info() {
+  $caches['status'] = array(
+    'title' => t('Update status'),
+    'callback' => 'update_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
@@ -530,7 +562,7 @@ function _update_project_status_sort($a,
  * plug-able cache system that assumes volatile caches.
  *
  * Update module still uses the {cache_update} table, but instead of using
- * cache_set(), cache_get(), and cache_clear_all(), there are private helper
+ * cache_set(), cache_get(), and cache_clear_item(), there are private helper
  * functions that implement these same basic tasks but ensure that the cache
  * is not prematurely cleared, and that the data is always stored in the
  * database, even if memcache or another cache backend is in use.
@@ -549,7 +581,7 @@ function _update_project_status_sort($a,
  * @param $expire
  *   One of the following values:
  *   - CACHE_PERMANENT: Indicates that the item should never be removed except
- *     by explicitly using _update_cache_clear().
+ *     by explicitly using _update_cache_clear_item().
  *   - A Unix timestamp: Indicates that the item should be kept at least until
  *     the given time, after which it will be invalidated.
  */
@@ -595,10 +627,9 @@ function _update_cache_get($cid) {
  * Invalidates cached data relating to update status.
  *
  * @param $cid
- *   Optional cache ID of the record to clear from the private update module
- *   cache. If empty, all records will be cleared from the table.
+ *   Cache ID of the record to clear from the private Update.module cache.
  */
-function _update_cache_clear($cid = NULL) {
+function _update_cache_clear_item($cid) {
   $query = db_delete('cache_update');
   if (!empty($cid)) {
     $query->condition('cid', $cid);
@@ -607,26 +638,10 @@ 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).
+ * Clear the private Update.module cache.
  */
-function update_flush_caches() {
-  if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
-    _update_cache_clear();
-  }
-  return array();
+function _update_cache_clear() {
+  db_delete('cache_update')->execute();
 }
 
 /**
Index: modules/user/user.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v
retrieving revision 1.58
diff -u -p -r1.58 user.admin.inc
--- modules/user/user.admin.inc	15 Jun 2009 09:49:58 -0000	1.58
+++ modules/user/user.admin.inc	22 Jun 2009 01:00:01 -0000
@@ -666,8 +666,7 @@ function user_admin_perm_submit($form, &
 
   drupal_set_message(t('The changes have been saved.'));
 
-  // Clear the cached pages and blocks.
-  cache_clear_all();
+  cache_clear('block', 'page');
 }
 
 /**
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1001
diff -u -p -r1.1001 user.module
--- modules/user/user.module	13 Jun 2009 20:40:09 -0000	1.1001
+++ modules/user/user.module	22 Jun 2009 01:00:02 -0000
@@ -2029,7 +2029,7 @@ function _user_cancel($edit, $account, $
   }
 
   // Clear the cache for anonymous users.
-  cache_clear_all();
+  cache_clear('block', 'page');
 }
 
 /**
Index: modules/user/user.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v
retrieving revision 1.40
diff -u -p -r1.40 user.pages.inc
--- modules/user/user.pages.inc	18 Jun 2009 21:19:02 -0000	1.40
+++ modules/user/user.pages.inc	22 Jun 2009 01:00:03 -0000
@@ -305,7 +305,7 @@ function user_profile_form_submit($form,
   user_save($account, $edit, $category);
 
   // Clear the page cache because pages can contain usernames and/or profile information:
-  cache_clear_all();
+  cache_clear('block', 'page');
 
   drupal_set_message(t('The changes have been saved.'));
   return;
@@ -540,7 +540,7 @@ function user_edit_submit($form, &$form_
   user_save($account, $form_state['values'], $category);
 
   // Clear the page cache because pages can contain usernames and/or profile information:
-  cache_clear_all();
+  cache_clear('block', 'page');
 
   drupal_set_message(t('The changes have been saved.'));
   return;
