=== modified file 'includes/bootstrap.inc'
--- includes/bootstrap.inc	2009-01-31 16:50:56 +0000
+++ includes/bootstrap.inc	2009-02-01 04:24:14 +0000
@@ -1130,14 +1130,12 @@ function _drupal_bootstrap($phase) {
       break;
 
     case DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE:
-      // Allow specifying special cache handlers in settings.php, like
-      // using memcached or files for storing cache information.
-      require_once DRUPAL_ROOT . '/' . variable_get('cache_inc', 'includes/cache.inc');
-      // If the page_cache_fastpath is set to TRUE in settings.php and
-      // page_cache_fastpath (implemented in the special implementation of
-      // cache.inc) printed the page and indicated this with a returned TRUE
-      // then we are done.
-      if (variable_get('page_cache_fastpath', FALSE) && page_cache_fastpath()) {
+      require_once DRUPAL_ROOT . '/includes/cache.inc';
+      // If the page_cache_fastpath is set to TRUE in settings.php then page
+      // caching is handled by something other than the default so we can try
+      // retrieving.
+      if (variable_get('page_cache_fastpath', FALSE) && ($cache = page_get_cache(TRUE))) {
+        drupal_page_cache_header($cache);
         exit;
       }
       break;
@@ -1615,3 +1613,30 @@ function registry_rebuild() {
 /**
  * @} End of "ingroup registry".
  */
+
+/**
+ * Get the handler configuration for a slot and target.
+ *
+ * @param $slot
+ *   The internal ID of the slot for which we want to set a handler, for
+ *   example cache or session.
+ * @param $target
+ *   The target for which we want set the handler, for cache it can be
+ *   cache_page, cache_filter etc.
+ * @return
+ *   A handler object.
+ */
+function handler($slot, $target = 'default') {
+  static $handlers, $instances = array();
+  if (!isset($instances[$slot][$target])) {
+    if (!isset($handlers)) {
+      $handlers = variable_get('handlers', array());
+    }
+    $handler = isset($handlers['handlers'][$slot][$target]) ? $handlers['handlers'][$slot][$target] : $handlers['defaults'][$slot];
+    if (!empty($handler['file'])) {
+      require_once DRUPAL_ROOT . '/' . $handler['file'];
+    }
+    $instances[$slot][$target] = new $handler['class'];
+  }
+  return $instances[$slot][$target];
+}

=== added file 'includes/cache-default.inc'
--- includes/cache-default.inc	1970-01-01 00:00:00 +0000
+++ includes/cache-default.inc	2009-02-01 01:51:52 +0000
@@ -0,0 +1,132 @@
+<?php
+// $Id$
+
+class drupalCache implements drupalCacheInterface {
+  function get($cid, $table = 'cache') {
+    global $user;
+
+    // Garbage collection necessary when enforcing a minimum cache lifetime
+    $cache_flush = variable_get('cache_flush', 0);
+    if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= REQUEST_TIME)) {
+      // Reset the variable immediately to prevent a meltdown in heavy load situations.
+      variable_set('cache_flush', 0);
+      // Time to flush old cache data
+      db_delete($table)
+        ->condition('expire', CACHE_PERMANENT, '<>')
+        ->condition('expire', $cache_flush, '<=')
+        ->execute();
+    }
+
+    $cache = db_query("SELECT data, created, headers, expire, serialized FROM {" . $table . "} WHERE cid = :cid", array(':cid' => $cid))->fetchObject();
+    if (isset($cache->data)) {
+      // If the data is permanent or we're not enforcing a minimum cache lifetime
+      // always return the cached data.
+      if ($cache->expire == CACHE_PERMANENT || !variable_get('cache_lifetime', 0)) {
+        if ($cache->serialized) {
+          $cache->data = unserialize($cache->data);
+        }
+      }
+      // If enforcing a minimum cache lifetime, validate that the data is
+      // currently valid for this user before we return it by making sure the
+      // cache entry was created before the timestamp in the current session's
+      // cache timer. The cache variable is loaded into the $user object by
+      // _sess_read() in session.inc.
+      else {
+        if ($user->cache > $cache->created) {
+          // This cache data is too old and thus not valid for us, ignore it.
+          return FALSE;
+        }
+        else {
+          if ($cache->serialized) {
+            $cache->data = unserialize($cache->data);
+          }
+        }
+      }
+      return $cache;
+    }
+    return FALSE;
+  }
+
+  function set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
+    $fields = array(
+      'serialized' => 0,
+      'created' => REQUEST_TIME,
+      'expire' => $expire,
+      'headers' => $headers,
+    );
+    if (!is_string($data)) {
+      $fields['data'] = serialize($data);
+      $fields['serialized'] = 1;
+    }
+    else {
+      $fields['data'] = $data;
+      $fields['serialized'] = 0;
+    }
+
+    db_merge($table)
+      ->key(array('cid' => $cid))
+      ->fields($fields)
+      ->execute();
+  }
+
+  function clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
+    global $user;
+
+    if (!isset($cid) && !isset($table)) {
+      // Clear the block cache first, so stale data will
+      // not end up in the page cache.
+      cache_clear_all(NULL, 'cache_block');
+      cache_clear_all(NULL, 'cache_page');
+      return;
+    }
+
+    if (empty($cid)) {
+      if (variable_get('cache_lifetime', 0)) {
+        // We store the time in the current user's $user->cache variable which
+        // will be saved into the sessions table by _sess_write(). We then
+        // simulate that the cache was flushed for this user by not returning
+        // cached data that was cached before the timestamp.
+        $user->cache = REQUEST_TIME;
+
+        $cache_flush = variable_get('cache_flush', 0);
+        if ($cache_flush == 0) {
+          // This is the first request to clear the cache, start a timer.
+          variable_set('cache_flush', REQUEST_TIME);
+        }
+        elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
+          // Clear the cache for everyone, cache_flush_delay seconds have
+          // passed since the first request to clear the cache.
+          db_delete($table)
+            ->condition('expire', CACHE_PERMANENT, '<>')
+            ->condition('expire', REQUEST_TIME, '<')
+            ->execute();
+          variable_set('cache_flush', 0);
+        }
+      }
+      else {
+        // No minimum cache lifetime, flush all temporary cache entries now.
+        db_delete($table)
+          ->condition('expire', CACHE_PERMANENT, '<>')
+          ->condition('expire', REQUEST_TIME, '<')
+          ->execute();
+      }
+    }
+    else {
+      if ($wildcard) {
+        if ($cid == '*') {
+          db_delete($table)->execute();
+        }
+        else {
+          db_delete($table)
+            ->condition('cid', $cid . '%', 'LIKE')
+            ->execute();
+        }
+      }
+      else {
+        db_delete($table)
+          ->condition('cid', $cid)
+          ->execute();
+      }
+    }
+  }
+}

=== modified file 'includes/cache-install.inc'
--- includes/cache-install.inc	2007-08-07 08:39:35 +0000
+++ includes/cache-install.inc	2009-02-01 02:47:57 +0000
@@ -11,14 +11,14 @@
  * on performance.
  */
 
-function cache_get($key, $table = 'cache') {
-  return FALSE;
-}
+class drupalCacheInstall {
+  function get($key, $table = 'cache') {
+    return FALSE;
+  }
 
-function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
-  return;
-}
+  function set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
+  }
 
-function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
-  return;
+  function clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
+  }
 }

=== modified file 'includes/cache.inc'
--- includes/cache.inc	2008-10-12 04:30:05 +0000
+++ includes/cache.inc	2009-02-01 02:52:44 +0000
@@ -15,48 +15,7 @@
  * @return The cache or FALSE on failure.
  */
 function cache_get($cid, $table = 'cache') {
-  global $user;
-
-  // Garbage collection necessary when enforcing a minimum cache lifetime
-  $cache_flush = variable_get('cache_flush', 0);
-  if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= REQUEST_TIME)) {
-    // Reset the variable immediately to prevent a meltdown in heavy load situations.
-    variable_set('cache_flush', 0);
-    // Time to flush old cache data
-    db_delete($table)
-      ->condition('expire', CACHE_PERMANENT, '<>')
-      ->condition('expire', $cache_flush, '<=')
-      ->execute();
-  }
-
-  $cache = db_query("SELECT data, created, headers, expire, serialized FROM {" . $table . "} WHERE cid = :cid", array(':cid' => $cid))->fetchObject();
-  if (isset($cache->data)) {
-    // If the data is permanent or we're not enforcing a minimum cache lifetime
-    // always return the cached data.
-    if ($cache->expire == CACHE_PERMANENT || !variable_get('cache_lifetime', 0)) {
-      if ($cache->serialized) {
-        $cache->data = unserialize($cache->data);
-      }
-    }
-    // If enforcing a minimum cache lifetime, validate that the data is
-    // currently valid for this user before we return it by making sure the
-    // cache entry was created before the timestamp in the current session's
-    // cache timer. The cache variable is loaded into the $user object by
-    // _sess_read() in session.inc.
-    else {
-      if ($user->cache > $cache->created) {
-        // This cache data is too old and thus not valid for us, ignore it.
-        return FALSE;
-      }
-      else {
-        if ($cache->serialized) {
-          $cache->data = unserialize($cache->data);
-        }
-      }
-    }
-    return $cache;
-  }
-  return FALSE;
+  return handler('cache', $table)->get($cid, $table);
 }
 
 /**
@@ -105,25 +64,7 @@ function cache_get($cid, $table = 'cache
  *   A string containing HTTP header information for cached pages.
  */
 function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
-  $fields = array(
-    'serialized' => 0,
-    'created' => REQUEST_TIME,
-    'expire' => $expire,
-    'headers' => $headers,
-  );
-  if (!is_string($data)) {
-    $fields['data'] = serialize($data);
-    $fields['serialized'] = 1;
-  }
-  else {
-    $fields['data'] = $data;
-    $fields['serialized'] = 0;
-  }
-
-  db_merge($table)
-    ->key(array('cid' => $cid))
-    ->fields($fields)
-    ->execute();
+  return handler('cache', $table)->set($cid, $data, $table, $expire, $headers);
 }
 
 /**
@@ -145,62 +86,89 @@ function cache_set($cid, $data, $table =
  *   match. If '*' is given as $cid, the table $table will be emptied.
  */
 function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
-  global $user;
-
-  if (!isset($cid) && !isset($table)) {
-    // Clear the block cache first, so stale data will
-    // not end up in the page cache.
-    cache_clear_all(NULL, 'cache_block');
-    cache_clear_all(NULL, 'cache_page');
-    return;
-  }
-
-  if (empty($cid)) {
-    if (variable_get('cache_lifetime', 0)) {
-      // We store the time in the current user's $user->cache variable which
-      // will be saved into the sessions table by _sess_write(). We then
-      // simulate that the cache was flushed for this user by not returning
-      // cached data that was cached before the timestamp.
-      $user->cache = REQUEST_TIME;
+  return handler('cache', $table)->clear_all($cid, $table, $wildcard);
+}
 
-      $cache_flush = variable_get('cache_flush', 0);
-      if ($cache_flush == 0) {
-        // This is the first request to clear the cache, start a timer.
-        variable_set('cache_flush', REQUEST_TIME);
-      }
-      elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
-        // Clear the cache for everyone, cache_flush_delay seconds have
-        // passed since the first request to clear the cache.
-        db_delete($table)
-          ->condition('expire', CACHE_PERMANENT, '<>')
-          ->condition('expire', REQUEST_TIME, '<')
-          ->execute();
-        variable_set('cache_flush', 0);
-      }
-    }
-    else {
-      // No minimum cache lifetime, flush all temporary cache entries now.
-      db_delete($table)
-        ->condition('expire', CACHE_PERMANENT, '<>')
-        ->condition('expire', REQUEST_TIME, '<')
-        ->execute();
-    }
-  }
-  else {
-    if ($wildcard) {
-      if ($cid == '*') {
-        db_delete($table)->execute();
-      }
-      else {
-        db_delete($table)
-          ->condition('cid', $cid . '%', 'LIKE')
-          ->execute();
-      }
-    }
-    else {
-      db_delete($table)
-        ->condition('cid', $cid)
-        ->execute();
-    }
-  }
+interface drupalCacheInterface {
+  /**
+   * Return data from the persistent cache. Data may be stored as either plain
+   * text or as serialized data. cache_get will automatically return
+   * unserialized objects and arrays.
+   *
+   * @param $cid
+   *   The cache ID of the data to retrieve.
+   * @param $table
+   *   The table $table to store the data in. Valid core values are
+   *   'cache_filter', 'cache_menu', 'cache_page', or 'cache' for
+   *   the default cache.
+   * @return The cache or FALSE on failure.
+   */
+  function get($cid, $table = 'cache');
+
+  /**
+   * Store data in the persistent cache.
+   *
+   * The persistent cache is split up into four database
+   * tables. Contributed modules can add additional tables.
+   *
+   * 'cache_page': This table stores generated pages for anonymous
+   * users. This is the only table affected by the page cache setting on
+   * the administrator panel.
+   *
+   * 'cache_menu': Stores the cachable part of the users' menus.
+   *
+   * 'cache_filter': Stores filtered pieces of content. This table is
+   * periodically cleared of stale entries by cron.
+   *
+   * 'cache': Generic cache storage table.
+   *
+   * The reasons for having several tables are as follows:
+   *
+   * - smaller tables allow for faster selects and inserts
+   * - we try to put fast changing cache items and rather static
+   *   ones into different tables. The effect is that only the fast
+   *   changing tables will need a lot of writes to disk. The more
+   *   static tables will also be better cachable with MySQL's query cache
+   *
+   * @param $cid
+   *   The cache ID of the data to store.
+   * @param $data
+   *   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 $table
+   *   The table $table to store the data in. Valid core values are
+   *   'cache_filter', 'cache_menu', 'cache_page', or '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.
+   *   - 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
+   *     the given time, after which it behaves like CACHE_TEMPORARY.
+   * @param $headers
+   *   A string containing HTTP header information for cached pages.
+   */
+  function set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL);
+
+  /**
+   *
+   * Expire data from the cache. If called without arguments, expirable
+   * entries will be cleared from the cache_page and cache_block tables.
+   *
+   * @param $cid
+   *   If set, the cache ID to delete. Otherwise, all cache entries that can
+   *   expire are deleted.
+   *
+   * @param $table
+   *   If set, the table $table to delete from. Mandatory
+   *   argument if $cid is set.
+   *
+   * @param $wildcard
+   *   If set to TRUE, the $cid is treated as a substring
+   *   to match rather than a complete ID. The match is a right hand
+   *   match. If '*' is given as $cid, the table $table will be emptied.
+   */
+  function clear_all($cid = NULL, $table = NULL, $wildcard = FALSE);
 }

=== modified file 'includes/common.inc'
--- includes/common.inc	2009-01-31 19:07:45 +0000
+++ includes/common.inc	2009-02-01 04:26:30 +0000
@@ -4142,3 +4142,86 @@ function _drupal_flush_css_js() {
   }
   variable_set('css_js_query_string', $new_character . substr($string_history, 0, 19));
 }
+
+/**
+ * Rebuild the handler information.
+ *
+ * @param $revert_to_defaults
+ *   Delete all the specific classes previously set by handler_set. Use with
+ *   extreme caution. Defaults to FALSE.
+ */
+function handler_rebuild($revert_to_defaults = FALSE) {
+  $handlers = variable_get('handlers', array());
+  if ($revert_to_defaults) {
+    unset($handlers['handlers']);
+  }
+  // We only keep the default handler information, the rest is documentation.
+  foreach (module_invoke_all('handler') as $slot => $definitions) {
+    $handlers['defaults'][$slot] = array('class' => $definitions['default']['class']);
+    if (isset($definitions['default']['file'])) {
+      $handlers['defaults'][$slot]['file'] = $definitions['default']['file'];
+    }
+  }
+  variable_set('handlers', $handlers);
+}
+
+/**
+ * Gets the information for a given handler.
+ * @param $slot
+ *   The internal ID of the slot for which we want to set a handler, for
+ *   example cache or session.
+ * @param $target
+ *   The target for which we want set the handler, for cache it can be
+ *   cache_page, cache_filter etc.
+ * @param $return
+ *   Returns an associative array. The value of the defaults key is a bool,
+ *   TRUE when the handler is coming from defaults, FALSE when the handler is
+ *   specific for this target. handler is the name of the handler. definition
+ *   is an array containing description, class and optionally file as
+ *   described in hook_handler.
+ */
+function handler_get($slot, $target) {
+  $handlers = variable_get('handlers', array());
+  if (isset($handlers['handlers'][$slot][$target])) {
+    $class = $handlers['handlers'][$slot][$target]['class'];
+    $defaults = FALSE;
+  }
+  else {
+   $class = $handlers['defaults'][$slot]['class'];
+   $defaults = TRUE;
+  }
+  foreach (module_invoke_all('handler') as $slot => $definitons) {
+    foreach ($definitons as $handler => $definition) {
+      if ($definition['class'] == $class) {
+        return array('defaults' => $defaults, 'handler' => $handler, 'definition' => $definition);
+      }
+    }
+  }
+}
+
+/**
+ * Set a specific handler for a slot and optionally a target.
+ *
+ * @param $slot
+ *   The internal ID of the slot for which we want to set a handler, for
+ *   example cache or session.
+ * @param $handler
+ *   The identifier of this handler, for example apc as defined in
+ *   system.api.php
+ * @param $target
+ *   The target for which we want set the handler, for cache it can be page,
+ *   filter etc. Defaults to NULL, setting a default handler.
+ */
+function handler_set($slot, $handler, $target = NULL) {
+  $handlers = variable_get('handlers', array());
+  $handler_info = module_invoke_all('handler');;
+  $definition = array('class' => $handler_info[$slot][$handler]['class']);
+  // We only keep the class, the rest is documentation.
+  if (isset($target)) {
+    $handlers['handlers'][$slot][$target] = $definition;
+  }
+  else {
+    $handlers['defaults'][$slot] = $definition;
+  }
+  variable_set('handlers', $handlers);
+}

=== modified file 'install.php'
--- install.php	2009-01-22 19:31:07 +0000
+++ install.php	2009-02-01 04:28:53 +0000
@@ -48,6 +48,9 @@ function install_main() {
   // Set up $language, so t() caller functions will still work.
   drupal_init_language();
 
+  // Set up cache system.
+  require_once DRUPAL_ROOT . '/includes/cache.inc';
+
   // Load module basics (needed for hook invokes).
   include_once DRUPAL_ROOT . '/includes/module.inc';
   include_once DRUPAL_ROOT . '/includes/session.inc';
@@ -67,9 +70,7 @@ function install_main() {
     // Since we have a database connection, we use the normal cache system.
     // This is important, as the installer calls into the Drupal system for
     // the clean URL checks, so we should maintain the cache properly.
-    require_once DRUPAL_ROOT . '/includes/cache.inc';
-    $conf['cache_inc'] = 'includes/cache.inc';
-
+    $conf['handlers']['defaults']['cache'] = array('class' => 'drupalCache', 'file' => 'includes/cache-default.inc');
     // Initialize the database system. Note that the connection
     // won't be initialized until it is actually requested.
     require_once DRUPAL_ROOT . '/includes/database/database.inc';
@@ -85,8 +86,7 @@ function install_main() {
     // for cached data will fail, we temporarily replace the normal cache
     // system with a stubbed-out version that short-circuits the actual
     // caching process and avoids any errors.
-    require_once DRUPAL_ROOT . '/includes/cache-install.inc';
-    $conf['cache_inc'] = 'includes/cache-install.inc';
+    $conf['handlers']['defaults']['cache'] = array('class' => 'drupalCacheInstall', 'file' => 'includes/cache-install.inc');
 
     $task = NULL;
   }

=== modified file 'modules/system/system.admin.inc'
--- modules/system/system.admin.inc	2009-01-27 00:22:24 +0000
+++ modules/system/system.admin.inc	2009-02-01 02:40:46 +0000
@@ -575,6 +575,7 @@ function system_modules($form_state = ar
   drupal_theme_rebuild();
   node_types_rebuild();
   cache_clear_all('schema', 'cache');
+  handler_rebuild();
   // Get current list of modules.
   $files = module_rebuild_cache();
 

=== modified file 'modules/system/system.api.php'
--- modules/system/system.api.php	2009-01-31 16:50:56 +0000
+++ modules/system/system.api.php	2009-02-01 04:27:10 +0000
@@ -212,7 +212,7 @@ function hook_js_alter(&$javascript) {
  *   $page['content']['nodes'][$nid]['#node']
  *   // The results pager.
  *   $page['content']['pager']
- * @code 
+ * @code
  *
  * Blocks may be referenced by their module/delta pair within a region:
  * @code
@@ -1636,5 +1636,73 @@ function hook_disable() {
 }
 
 /**
+ * Define one or more slots for the handlers system.
+ *
+ * This hook should return a nested array of slot definitions.  Each key
+ * in the array is the machine-readable slot name, and its value is an array
+ * of values that define the slot.
+ *
+ * description
+ *   A human-readable description of what the slot is for.
+ * interface
+ *   The PHP interface that defines this slot.
+ * default_class
+ *   The PHP class that will be used if hook_handler_info does not define a
+ *   specific class.
+ * default_file (optional)
+ *   A file to load which includes the class being loaded. Note that this should
+ *   only be used in cases where the registry is not available to automatincally load
+ *   the class.
+ *
+ * @return
+ *   A slot definition array.
+ */
+function hook_slot_info() {
+  return array(
+    'cache' => array(
+      'description' => 'Caching system',
+      'interface' => 'drupalCacheInterface',
+    ),
+  );
+}
+
+/**
+ * Define one or more handlers in the system.
+ *
+ * This hook should return a doubly-nested array of handler definitions.  The
+ * first key is an existing slot, the second key is the target.
+ *
+ * Each handler definition is an associative array of values that define the
+ * handler with the following possible keys:
+ *
+ * class
+ *   The PHP class that defines this handler.  The class must implement the
+ *   interface defined for this slot, but otherwise may be defined in any way
+ *   desired, including implementing the interface directly or indirectly by
+ *   subclassing another class that implements that interface. It may also be
+ *   placed in any file, depending on what would provide the most performance
+ *   for autoloading.
+ * file (optional)
+ *   A file to load which includes the class being loaded. Note that this should
+ *   only be used in cases where the registry is not available to automatincally load
+ *   the class.
+ * description
+ *   A human readable description of this handler.
+ *
+ * @return
+ *   A handler definition array.
+ */
+function hook_handler() {
+  return array(
+    'cache' => array(
+      'apc' => array(
+        'description' => t('Stores the filter cache in APC'),
+        'class' => 'apcCache',
+      ),
+    ),
+  );
+}
+
+/**
  * @} End of "addtogroup hooks".
  */

=== modified file 'modules/system/system.module'
--- modules/system/system.module	2009-01-31 15:55:05 +0000
+++ modules/system/system.module	2009-02-01 04:30:35 +0000
@@ -399,6 +399,30 @@ function system_elements() {
 }
 
 /**
+ * Implementation of hook_slot_info.
+ */
+function system_slot_info() {
+  return array(
+    'cache' => array(
+      'description' => t('Caching system'),
+      'interface' => 'drupalCacheInterface',
+    ),
+  );
+}
+
+function system_handler() {
+  return array(
+    'cache' => array(
+      'default' => array(
+        'description' => t('Caching in the default database'),
+        'class' => 'drupalCache',
+        'file' => 'includes/cache-default.inc',
+      ),
+    ),
+  );
+}
+
+/**
  * Implementation of hook_menu().
  */
 function system_menu() {

=== modified file 'sites/default/default.settings.php'
--- sites/default/default.settings.php	2008-12-23 19:59:17 +0000
+++ sites/default/default.settings.php	2009-02-01 04:21:25 +0000
@@ -46,7 +46,7 @@
 /**
  * Database settings:
  *
- * The $databases array specifies the database connection or 
+ * The $databases array specifies the database connection or
  * connections that Drupal may use.  Drupal is able to connect
  * to multiple databases, including multiple types of databases,
  * during the same request.
@@ -63,7 +63,7 @@
  *   'port' => 3306,
  * );
  *
- * The "driver" property indicates what Drupal database driver the 
+ * The "driver" property indicates what Drupal database driver the
  * connection should use.  This is usually the same as the name of the
  * database type, such as mysql or sqlite, but not always.  The other
  * properties will vary depending on the driver.  For SQLite, you must
@@ -80,7 +80,7 @@
  * A target database allows Drupal to try to send certain queries to a
  * different database if it can but fall back to the default connection if not.
  * That is useful for master/slave replication, as Drupal may try to connect
- * to a slave server when appropriate and if one is not available will simply 
+ * to a slave server when appropriate and if one is not available will simply
  * fall back to the single master server.
  *
  * The general format for the $databases array is as follows:
@@ -232,7 +232,7 @@ ini_set('session.cookie_lifetime', 20000
  *
  * Remove the leading hash signs to enable.
  */
-# $conf = array(
+$conf = array(
 #   'site_name' => 'My Drupal site',
 #   'theme_default' => 'minnelli',
 #   'anonymous' => 'Visitor',
@@ -273,7 +273,18 @@ ini_set('session.cookie_lifetime', 20000
  * your web server spoofing the X-Forwarded-For headers.
  */
 #   'reverse_proxy_addresses' => array('a.b.c.d', ...), // Leave the comma here.
-# );
+/**
+ * The default pluggable system configuration.
+ */
+  'handlers' => array(
+    'defaults' => array(
+      'cache' => array(
+        'class' => 'drupalCache',
+        'file' => 'includes/cache-default.inc',
+      ),
+    ),
+  ),
+);
 
 /**
  * String overrides:

