Index: contributions/modules/cacherouter/engines/wincache.php
--- contributions/modules/cacherouter/engines/wincache.php No Base Revision
+++ contributions/modules/cacherouter/engines/wincache.php Locally New
@@ -0,0 +1,236 @@
+<?php
+/**
+ * @file
+ *   WinCache engine class.
+ */
+
+class wincacheCacheRouterEngine extends CacheRouterEngine {
+  /**
+   * page_fast_cache
+   *   This tells CacheRouter to use page_fast_cache.
+   *
+   *   @return bool TRUE
+   */
+  function page_fast_cache() {
+    return $this->fast_cache;
+  }
+
+  /**
+   * get()
+   *   Return item from cache if it is available.
+   *
+   * @param string $key
+   *   The key to fetch.
+   * @return mixed object|bool
+   *   Returns either the cache object or FALSE on failure
+   */
+  function get($key) {
+    $cache = parent::get($this->key($key));
+    if (isset($cache)) {
+      return $cache;
+    }
+
+    $cache = wincache_ucache_get($this->key($key));
+    if (is_object($cache) && $cache->serialized) {
+      $cache->data = unserialize($cache->data);
+    }
+    parent::set($this->key($key), $cache);
+    return $cache;
+  }
+
+  /**
+   * set()
+   *   Add item into cache.
+   *
+   * @param string $key
+   *   The key to set.
+   * @param string $value
+   *   The data to store in the cache.
+   * @param string $expire
+   *   The time to expire in seconds.
+   * @param string $headers
+   *   The page headers.
+   * @return bool
+   *   Returns TRUE on success or FALSE on failure
+   */
+  function set($key, $value, $expire = CACHE_PERMANENT, $headers = NULL) {
+    // Create new cache object.
+    $cache = new stdClass;
+    $cache->cid = $key;
+    $cache->created = time();
+    $cache->expire = $expire;
+    $cache->headers = $headers;
+
+    if ($expire != CACHE_PERMANENT && $expire != CACHE_TEMPORARY) {
+      // Convert Drupal $expire, which is a timestamp, to a TTL
+      $ttl = $expire - time();
+    }
+    else {
+      $ttl = 0;
+    }
+
+    if (!is_string($value)) {
+      $cache->serialized = TRUE;
+      $cache->data = serialize($value);
+    }
+    else {
+      $cache->serialized = FALSE;
+      $cache->data = $value;
+    }
+
+    $return = FALSE;
+    if (!empty($key) && $this->lock()) {
+      // Get lookup table to be able to keep track of bins
+      $lookup = wincache_ucache_get($this->lookup);
+
+      // If the lookup table is empty, initialize table
+      if (empty($lookup)) {
+        $lookup = array();
+      }
+
+      // Set key to 1 so we can keep track of the bin
+      $lookup[$this->key($key)] = $expire;
+
+      // Attempt to store full key and value
+      if (!wincache_ucache_set($this->key($key), $cache, $ttl)) {
+        unset($lookup[$this->key($key)]);
+        $return = FALSE;
+      }
+      else {
+        // Update static cache
+        parent::set($this->key($key), $cache);
+        $return = TRUE;
+      }
+
+      // Resave the lookup table (even on failure)
+      wincache_ucache_set($this->lookup, $lookup);
+
+      // Remove lock.
+      $this->unlock();
+    }
+
+    return $return;
+  }
+
+  /**
+   * delete()
+   *   Remove item from cache.
+   *
+   * @param string $key
+   *   The key to set.
+   * @return mixed object|bool
+   *   Returns either the cache object or FALSE on failure
+   */
+  function delete($key) {
+    // Remove from static array cache.
+    parent::delete($this->key($key));
+
+    if (substr($key, strlen($key) - 1, 1) == '*') {
+      $key = $this->key(substr($key, 0, strlen($key) - 1));
+      $lookup = wincache_ucache_get($this->lookup);
+      if (!empty($lookup)) {
+        foreach ($lookup as $k => $v) {
+          if (substr($k, 0, strlen($key)) == $key) {
+            wincache_ucache_delete($k);
+            unset($lookup[$k]);
+          }
+        }
+      }
+
+      if ($this->lock()) {
+        wincache_ucache_set($this->lookup, $lookup);
+        $this->unlock();
+      }
+    }
+    else {
+      if (!empty($key)) {
+        if (!wincache_ucache_delete($this->key($key))) {
+          return FALSE;
+        } else {
+          return TRUE;
+        }
+      }
+    }
+  }
+
+  /**
+   * flush()
+   *   Flush the entire cache.
+   *
+   * @param none
+   * @return mixed bool
+   *   Returns TRUE
+   */
+  function flush() {
+    parent::flush();
+    if ($this->lock()) {
+      // Get lookup table to be able to keep track of bins
+      $lookup = wincache_ucache_get($this->lookup);
+
+      // If the lookup table is empty, remove lock and return
+      if (empty($lookup)) {
+        $this->unlock();
+        return TRUE;
+      }
+
+      // Cycle through keys and remove each entry from the cache
+      foreach ($lookup as $k => $expire) {
+        if ($expire != CACHE_PERMANENT && $expire <= time()) {
+          wincache_ucache_delete($k);
+          unset($lookup[$k]);
+        }
+      }
+
+      // Resave the lookup table (even on failure)
+      wincache_ucache_set($this->lookup, $lookup);
+
+      // Remove lock
+      $this->unlock();
+    }
+
+    return TRUE;
+  }
+
+ /**
+  * lock()
+  *   lock the cache from other writes.
+  *
+  * @param none
+  * @return string
+  *   Returns TRUE on success, FALSE on failure
+  */
+  function lock() {
+    return wincache_lock(basename($this->lock));
+  }
+
+  /**
+   * unlock()
+   *   unlock the cache from other writes.
+   *
+   * @param none
+   * @return bool
+   *   Returns TRUE on success, FALSE on failure
+   */
+  function unlock() {
+    return wincache_unlock(basename($this->lock));
+  }
+
+  function stats() {
+    $wincache_stats = wincache_ucache_info();
+    $wincache_memory_stats = wincache_ucache_meminfo();
+    $stats = array(
+      'uptime' => $wincache_stats['total_cache_uptime'],
+      'bytes_used' => $wincache_memory_stats['memory_total'] - $wincache_memory_stats['memory_free'],
+      'bytes_total' => $wincache_memory_stats['memory_total'],
+      'gets' => $wincache_stats['total_hit_count'],
+      //'sets' => $wincache_stats[''],
+      'hits' => $wincache_stats['total_hit_count'] + $wincache_stats['total_miss_count'],
+      'misses' => $wincache_stats['total_miss_count'],
+      'req_rate' => (($wincache_stats['total_hit_count'] + $wincache_stats['total_miss_count']) / $wincache_stats['total_cache_uptime']),
+      'hit_rate' => ($wincache_stats['total_hit_count'] / $wincache_stats['total_cache_uptime']),
+      'miss_rate' => ($wincache_stats['total_miss_count'] / $wincache_stats['total_cache_uptime']),
+      //'set_rate' => ($wincache_stats['num_inserts'] / $wincache_stats['total_cache_uptime']),
+    );
+    return $stats;
+  }
+}
\ No newline at end of file
Index: contributions/modules/cacherouter/README.txt
--- contributions/modules/cacherouter/README.txt Base (1.1.2.2)
+++ contributions/modules/cacherouter/README.txt Locally Modified (Based On 1.1.2.2)
@@ -47,8 +47,8 @@
 default is for the default caching engine. All valid cache tables or "bins" can 
 be added in addition, but you must have a default if you skip any bins.
 
-For engine, the current available options are: apc, db, file, memcache and 
-xcache.
+For engine, the current available options are: apc, db, file, memcache,
+wincache (1.1.0+) and xcache.
 
 servers is only used in memcache and should be an array of host:port 
 combinations. (e.g. 'servers' => array('localhost:11211', 'localhost:11212'))
