diff --git a/includes/cache-install.inc b/includes/cache-install.inc
index d9bb0f9..8bcf8b7 100644
--- a/includes/cache-install.inc
+++ b/includes/cache-install.inc
@@ -26,6 +26,16 @@ class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterfac
   function set($cid, $data, $expire = CACHE_PERMANENT) {
   }
 
+  function deletePrefix($cid) {
+    try {
+      if (class_exists('Database')) {
+        parent::deletePrefix($cid);
+      }
+    }
+    catch (Exception $e) {
+    }
+  }
+
   function clear($cid = NULL, $wildcard = FALSE) {
     // If there is a database cache, attempt to clear it whenever possible. The
     // reason for doing this is that the database cache can accumulate data
diff --git a/includes/cache.inc b/includes/cache.inc
index 8666874..c811627 100644
--- a/includes/cache.inc
+++ b/includes/cache.inc
@@ -138,6 +138,73 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
 }
 
 /**
+ * Delete an item from the cache.
+ *
+ * @param $cid
+ *   A cache ID to delete.
+ * @param $bin
+ *   A cache bin.
+ */
+function cache_delete($cid, $bin) {
+  return _cache_get_object($bin)->delete($cid, $wildcard);
+}
+
+/**
+ * Delete multiple items from the cache.
+ *
+ * @param $cids
+ *   An array of $cids to delete.
+ * @param $bin
+ *   A cache bin.
+ */
+function cache_delete_multiple(Array $cids, $bin) {
+  return _cache_get_object($bin)->deleteMultiple($cid);
+}
+
+/**
+ * Delete items from the cache using a wildcard prefix.
+ *
+ * @param $prefix
+ *   A wildcard prefix.
+ * @param $bin
+ *   A cache bin.
+ */
+function cache_delete_prefix($prefix, $bin) {
+  return _cache_get_object($bin)->deletePrefix($prefix);
+}
+
+/**
+ * Clear temporary items from cache.
+ *
+ * @todo: this should not be hard-coded to the block and page caches.
+ */
+function cache_clear_temporary() {
+  // Clear the block cache first, so stale data will
+  // not end up in the page cache.
+  if (module_exists('block')) {
+    _cache_get_object('cache_block')->clearTemporary();
+  }
+  _cache_get_object('cache_page')->clearTemporary();
+}
+
+/**
+ * Perform garbage collection on a cache bin.
+ *
+ * @param $bin
+ *   A cache bin.
+ */
+function cache_garbage_collection($bin) {
+  _cache_get_object($bin)->garbageCollection();
+}
+
+/**
+ * Flush all cache items in a bin.
+ */
+function cache_flush($bin) {
+  _cache_get_object($bin)->flush();
+}
+
+/**
  * Expire data from the cache.
  *
  * If called without arguments, expirable entries will be cleared from the
@@ -158,12 +225,7 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
  */
 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');
+    cache_clear_temporary();
     return;
   }
   return _cache_get_object($bin)->clear($cid, $wildcard);
@@ -274,6 +336,46 @@ interface DrupalCacheInterface {
    */
   function set($cid, $data, $expire = CACHE_PERMANENT);
 
+  /**
+   * Delete an item from the cache.
+   *
+   * @param $cid
+   *    The cache ID to delete.
+   */
+  function delete($cid);
+
+  /**
+   * Delete multiple items from the cache.
+   *
+   * @param $cids
+   *   An array of $cids to delete.
+   */
+  function deleteMultiple(Array $cids);
+
+  /**
+   * Delete items from the cache using a wildcard prefix.
+   *
+   * @param $prefix
+   *   A wildcard prefix.
+   */
+  function deletePrefix($prefix);
+
+  /**
+   * Clear temporary items from cache.
+   *
+   * @todo: this should not be hard-coded to the block and page caches.
+   */
+  function clearTemporary();
+
+  /**
+   * Perform garbage collection on a cache bin.
+   */
+  function garbageCollection();
+
+  /**
+   * Flush all cache items in a bin.
+   */
+  function flush();
 
   /**
    * Expire data from the cache. If called without arguments, expirable
@@ -351,28 +453,6 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
   }
 
   /**
-   * Garbage collection for get() and getMultiple().
-   *
-   * @param $bin
-   *   The bin being requested.
-   */
-  protected function garbageCollection() {
-    global $user;
-
-    // Garbage collection necessary when enforcing a minimum cache lifetime.
-    $cache_flush = variable_get('cache_flush_' . $this->bin, 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_' . $this->bin, 0);
-      // Time to flush old cache data
-      db_delete($this->bin)
-        ->condition('expire', CACHE_PERMANENT, '<>')
-        ->condition('expire', $cache_flush, '<=')
-        ->execute();
-    }
-  }
-
-  /**
    * Prepare a cached item.
    *
    * Checks that items are either permanent or did not expire, and unserializes
@@ -434,64 +514,101 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
     }
   }
 
-  function clear($cid = NULL, $wildcard = FALSE) {
-    global $user;
+  function delete($cid) {
+    db_delete($this->bin)
+      ->condition('cid', $cid)
+      ->execute();
+  }
 
-    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 bin by _drupal_session_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_' . $this->bin, 0);
-        if ($cache_flush == 0) {
-          // This is the first request to clear the cache, start a timer.
-          variable_set('cache_flush_' . $this->bin, REQUEST_TIME);
-        }
-        elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
-          // Clear the cache for everyone, cache_lifetime seconds have
-          // passed since the first request to clear the cache.
-          db_delete($this->bin)
-            ->condition('expire', CACHE_PERMANENT, '<>')
-            ->condition('expire', REQUEST_TIME, '<')
-            ->execute();
-          variable_set('cache_flush_' . $this->bin, 0);
-        }
+  function deleteMultiple(Array $cids) {
+    // Delete in chunks when a large array is passed.
+    do {
+      db_delete($this->bin)
+        ->condition('cid', array_splice($cids, 0, 1000), 'IN')
+        ->execute();
+    }
+    while (count($cids));
+  }
+
+  function deletePrefix($prefix) {
+    db_delete($this->bin)
+      ->condition('cid', db_like($prefix) . '%', 'LIKE')
+      ->execute();
+  }
+
+  function clearTemporary() {
+    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 bin by _drupal_session_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_' . $this->bin, 0);
+      if ($cache_flush == 0) {
+        // This is the first request to clear the cache, start a timer.
+        variable_set('cache_flush_' . $this->bin, REQUEST_TIME);
       }
-      else {
-        // No minimum cache lifetime, flush all temporary cache entries now.
+      elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
+        // Clear the cache for everyone, cache_lifetime seconds have
+        // passed since the first request to clear the cache.
         db_delete($this->bin)
           ->condition('expire', CACHE_PERMANENT, '<>')
           ->condition('expire', REQUEST_TIME, '<')
           ->execute();
+        variable_set('cache_flush_' . $this->bin, 0);
       }
     }
     else {
+      // No minimum cache lifetime, flush all temporary cache entries now.
+      db_delete($this->bin)
+        ->condition('expire', CACHE_PERMANENT, '<>')
+        ->condition('expire', REQUEST_TIME, '<')
+        ->execute();
+    }
+  }
+
+  function garbageCollection() {
+    global $user;
+
+    // When cache lifetime is in force, avoid running garbage collection too
+    // often since this will remove temporary cache items indiscriminately.
+    $cache_flush = variable_get('cache_flush_' . $this->bin, 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_' . $this->bin, 0);
+      // Time to flush old cache data
+      db_delete($this->bin)
+        ->condition('expire', CACHE_PERMANENT, '<>')
+        ->condition('expire', $cache_flush, '<=')
+        ->execute();
+    }
+  }
+
+  function flush() {
+    db_truncate($this->bin)->execute();
+  }
+
+  function clear($cid = NULL, $wildcard = FALSE) {
+    global $user;
+
+    if (empty($cid)) {
+      $this->clearTemporary();
+    }
+    else {
       if ($wildcard) {
         if ($cid == '*') {
-          db_truncate($this->bin)->execute();
+          $this->flush();
         }
         else {
-          db_delete($this->bin)
-            ->condition('cid', db_like($cid) . '%', 'LIKE')
-            ->execute();
+          $this->deletePrefix($cid);
         }
       }
       elseif (is_array($cid)) {
-        // Delete in chunks when a large array is passed.
-        do {
-          db_delete($this->bin)
-            ->condition('cid', array_splice($cid, 0, 1000), 'IN')
-            ->execute();
-        }
-        while (count($cid));
+        $this->deleteMultiple($cid);
       }
       else {
-        db_delete($this->bin)
-          ->condition('cid', $cid)
-          ->execute();
+        $this->delete($cid);
       }
     }
   }
