diff --git a/lib/cache.php b/lib/cache.php
index bc74ed83f8bf150b7c596b306a4df6de38867aaf..48b9964ba9d19dd0713f3b5d188e0daa9b20e4e0 100644
--- a/lib/cache.php
+++ b/lib/cache.php
@@ -15,41 +15,14 @@ class OC_Cache {
 	 * @var OC_Cache $global_cache
 	 */
 	static protected $global_cache;
-	/**
-	 * @var OC_Cache $global_cache_fast
-	 */
-	static protected $global_cache_fast;
-	/**
-	 * @var OC_Cache $user_cache_fast
-	 */
-	static protected $user_cache_fast;
-	static protected $isFast=null;
 
 	/**
 	 * get the global cache
 	 * @return OC_Cache
 	 */
-	static public function getGlobalCache($fast=false) {
+	static public function getGlobalCache() {
 		if (!self::$global_cache) {
-			self::$global_cache_fast = null;
-			if (!self::$global_cache_fast && function_exists('xcache_set')) {
-				self::$global_cache_fast = new OC_Cache_XCache(true);
-			}
-			if (!self::$global_cache_fast && function_exists('apc_store')) {
-				self::$global_cache_fast = new OC_Cache_APC(true);
-			}
-
 			self::$global_cache = new OC_Cache_FileGlobal();
-			if (self::$global_cache_fast) {
-				self::$global_cache = new OC_Cache_Broker(self::$global_cache_fast, self::$global_cache);
-			}
-		}
-		if($fast) {
-			if(self::$global_cache_fast) {
-				return self::$global_cache_fast;
-			}else{
-				return false;
-			}
 		}
 		return self::$global_cache;
 	}
@@ -58,34 +31,16 @@ class OC_Cache {
 	 * get the user cache
 	 * @return OC_Cache
 	 */
-	static public function getUserCache($fast=false) {
+	static public function getUserCache() {
 		if (!self::$user_cache) {
-			self::$user_cache_fast = null;
-			if (!self::$user_cache_fast && function_exists('xcache_set')) {
-				self::$user_cache_fast = new OC_Cache_XCache();
-			}
-			if (!self::$user_cache_fast && function_exists('apc_store')) {
-				self::$user_cache_fast = new OC_Cache_APC();
-			}
-
 			self::$user_cache = new OC_Cache_File();
-			if (self::$user_cache_fast) {
-				self::$user_cache = new OC_Cache_Broker(self::$user_cache_fast, self::$user_cache);
-			}
-		}
-
-		if($fast) {
-			if(self::$user_cache_fast) {
-				return self::$user_cache_fast;
-			}else{
-				return false;
-			}
 		}
 		return self::$user_cache;
 	}
 
 	/**
 	 * get a value from the user cache
+	 * @param string $key
 	 * @return mixed
 	 */
 	static public function get($key) {
@@ -95,6 +50,9 @@ class OC_Cache {
 
 	/**
 	 * set a value in the user cache
+	 * @param string $key
+	 * @param mixed $value
+	 * @param int $ttl
 	 * @return bool
 	 */
 	static public function set($key, $value, $ttl=0) {
@@ -107,6 +65,7 @@ class OC_Cache {
 
 	/**
 	 * check if a value is set in the user cache
+	 * @param string $key
 	 * @return bool
 	 */
 	static public function hasKey($key) {
@@ -116,6 +75,7 @@ class OC_Cache {
 
 	/**
 	 * remove an item from the user cache
+	 * @param string $key
 	 * @return bool
 	 */
 	static public function remove($key) {
@@ -133,17 +93,6 @@ class OC_Cache {
 		return $user_cache->clear($prefix);
 	}
 
-	/**
-	 * check if a fast memory based cache is available
-	 * @return true
-	 */
-	static public function isFast() {
-		if(is_null(self::$isFast)) {
-			self::$isFast=function_exists('xcache_set') || function_exists('apc_store');
-		}
-		return self::$isFast;
-	}
-
 	static public function generateCacheKeyFromFiles($files) {
 		$key = '';
 		sort($files);
diff --git a/lib/cache/apc.php b/lib/cache/apc.php
deleted file mode 100644
index 895d307ea26bd9c5d9a2fc6529660568e912642d..0000000000000000000000000000000000000000
--- a/lib/cache/apc.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-class OC_Cache_APC {
-	protected $prefix;
-
-	public function __construct($global = false) {
-		$this->prefix = OC_Util::getInstanceId().'/';
-		if (!$global) {
-			$this->prefix .= OC_User::getUser().'/';
-		}
-	}
-
-	/**
-	 * entries in APC gets namespaced to prevent collisions between owncloud instances and users
-	 */
-	protected function getNameSpace() {
-		return $this->prefix;
-	}
-
-	public function get($key) {
-		$result = apc_fetch($this->getNamespace().$key, $success);
-		if (!$success) {
-			return null;
-		}
-		return $result;
-	}
-
-	public function set($key, $value, $ttl=0) {
-		return apc_store($this->getNamespace().$key, $value, $ttl);
-	}
-
-	public function hasKey($key) {
-		return apc_exists($this->getNamespace().$key);
-	}
-
-	public function remove($key) {
-		return apc_delete($this->getNamespace().$key);
-	}
-
-	public function clear($prefix='') {
-		$ns = $this->getNamespace().$prefix;
-		$cache = apc_cache_info('user');
-		foreach($cache['cache_list'] as $entry) {
-			if (strpos($entry['info'], $ns) === 0) {
-				apc_delete($entry['info']);
-			}
-		}
-		return true;
-	}
-}
-if(!function_exists('apc_exists')) {
-	function apc_exists($keys)
-	{
-		$result=false;
-		apc_fetch($keys, $result);
-		return $result;
-	}
-}
diff --git a/lib/memcache/apc.php b/lib/memcache/apc.php
new file mode 100644
index 0000000000000000000000000000000000000000..575ee4427db6d5773466ec573e906026fcc3f740
--- /dev/null
+++ b/lib/memcache/apc.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Memcache;
+
+class APC extends Cache {
+	/**
+	 * entries in APC gets namespaced to prevent collisions between owncloud instances and users
+	 */
+	protected function getNameSpace() {
+		return $this->prefix;
+	}
+
+	public function get($key) {
+		$result = apc_fetch($this->getNamespace() . $key, $success);
+		if (!$success) {
+			return null;
+		}
+		return $result;
+	}
+
+	public function set($key, $value, $ttl = 0) {
+		return apc_store($this->getNamespace() . $key, $value, $ttl);
+	}
+
+	public function hasKey($key) {
+		return apc_exists($this->getNamespace() . $key);
+	}
+
+	public function remove($key) {
+		return apc_delete($this->getNamespace() . $key);
+	}
+
+	public function clear($prefix = '') {
+		$ns = $this->getNamespace() . $prefix;
+		$cache = apc_cache_info('user');
+		foreach ($cache['cache_list'] as $entry) {
+			if (strpos($entry['info'], $ns) === 0) {
+				apc_delete($entry['info']);
+			}
+		}
+		return true;
+	}
+
+	static public function isAvailable() {
+		if (!extension_loaded('apc')) {
+			return false;
+		} elseif (!ini_get('apc.enable_cli') && \OC::$CLI) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+}
+
+if (!function_exists('apc_exists')) {
+	function apc_exists($keys) {
+		$result = false;
+		apc_fetch($keys, $result);
+		return $result;
+	}
+}
diff --git a/lib/memcache/cache.php b/lib/memcache/cache.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ad1cc7ec0391025ef11be3296b9aa992375d0fa
--- /dev/null
+++ b/lib/memcache/cache.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Memcache;
+
+abstract class Cache implements \ArrayAccess {
+	/**
+	 * @var string $prefix
+	 */
+	protected $prefix;
+
+	/**
+	 * @param string $prefix
+	 */
+	public function __construct($prefix = '') {
+		$this->prefix = \OC_Util::getInstanceId() . '/' . $prefix;
+	}
+
+	public function getPrefix() {
+		return $this->prefix;
+	}
+
+	/**
+	 * @param string $key
+	 * @return mixed
+	 */
+	abstract public function get($key);
+
+	/**
+	 * @param string $key
+	 * @param mixed $value
+	 * @param int $ttl
+	 * @return mixed
+	 */
+	abstract public function set($key, $value, $ttl = 0);
+
+	/**
+	 * @param string $key
+	 * @return mixed
+	 */
+	abstract public function hasKey($key);
+
+	/**
+	 * @param string $key
+	 * @return mixed
+	 */
+	abstract public function remove($key);
+
+	/**
+	 * @param string $prefix
+	 * @return mixed
+	 */
+	abstract public function clear($prefix = '');
+
+	//implement the ArrayAccess interface
+
+	public function offsetExists($offset) {
+		return $this->hasKey($offset);
+	}
+
+	public function offsetSet($offset, $value) {
+		$this->set($offset, $value);
+	}
+
+	public function offsetGet($offset) {
+		return $this->get($offset);
+	}
+
+	public function offsetUnset($offset) {
+		$this->remove($offset);
+	}
+}
diff --git a/lib/memcache/factory.php b/lib/memcache/factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..b1b49971031f2063e0f9f3d431c2925bb841782f
--- /dev/null
+++ b/lib/memcache/factory.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Memcache;
+
+class Factory {
+	/**
+	 * get a cache instance, will return null if no backend is available
+	 *
+	 * @param string $prefix
+	 * @return \OC\Memcache\Cache
+	 */
+	function create($prefix = '') {
+		if (XCache::isAvailable()) {
+			return new XCache($prefix);
+		} elseif (APC::isAvailable()) {
+			return new APC($prefix);
+		} elseif (Memcached::isAvailable()) {
+			return new Memcached($prefix);
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * check if there is a memcache backend available
+	 *
+	 * @return bool
+	 */
+	public function isAvailable() {
+		return XCache::isAvailable() || APC::isAvailable() || Memcached::isAvailable();
+	}
+}
diff --git a/lib/memcache/memcached.php b/lib/memcache/memcached.php
new file mode 100644
index 0000000000000000000000000000000000000000..978e6c2eff12b398beead40859e2eb87a2367e10
--- /dev/null
+++ b/lib/memcache/memcached.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Memcache;
+
+class Memcached extends Cache {
+	/**
+	 * @var \Memcached $cache
+	 */
+	private static $cache = null;
+
+	public function __construct($prefix = '') {
+		parent::__construct($prefix);
+		if (is_null(self::$cache)) {
+			self::$cache = new \Memcached();
+			list($host, $port) = \OC_Config::getValue('memcached_server', array('localhost', 11211));
+			self::$cache->addServer($host, $port);
+		}
+	}
+
+	/**
+	 * entries in XCache gets namespaced to prevent collisions between owncloud instances and users
+	 */
+	protected function getNameSpace() {
+		return $this->prefix;
+	}
+
+	public function get($key) {
+		$result = self::$cache->get($this->getNamespace() . $key);
+		if ($result === false and self::$cache->getResultCode() == \Memcached::RES_NOTFOUND) {
+			return null;
+		} else {
+			return $result;
+		}
+	}
+
+	public function set($key, $value, $ttl = 0) {
+		if ($ttl > 0) {
+			return self::$cache->set($this->getNamespace() . $key, $value, $ttl);
+		} else {
+			return self::$cache->set($this->getNamespace() . $key, $value);
+		}
+	}
+
+	public function hasKey($key) {
+		self::$cache->get($this->getNamespace() . $key);
+		return self::$cache->getResultCode() !== \Memcached::RES_NOTFOUND;
+	}
+
+	public function remove($key) {
+		return self::$cache->delete($this->getNamespace() . $key);
+	}
+
+	public function clear($prefix = '') {
+		$prefix = $this->getNamespace() . $prefix;
+		$allKeys = self::$cache->getAllKeys();
+		$keys = array();
+		$prefixLength = strlen($prefix);
+		foreach ($allKeys as $key) {
+			if (substr($key, 0, $prefixLength) === $prefix) {
+				$keys[] = $key;
+			}
+		}
+		self::$cache->deleteMulti($keys);
+		return true;
+	}
+
+	static public function isAvailable() {
+		return extension_loaded('memcached');
+	}
+}
diff --git a/lib/cache/xcache.php b/lib/memcache/xcache.php
similarity index 69%
rename from lib/cache/xcache.php
rename to lib/memcache/xcache.php
index 9f380f870b98da0d83b72e77a90074abfdeddc8a..33de30562f901e7bbaef111cc823f70db700ec95 100644
--- a/lib/cache/xcache.php
+++ b/lib/memcache/xcache.php
@@ -6,16 +6,9 @@
  * See the COPYING-README file.
  */
 
-class OC_Cache_XCache {
-	protected $prefix;
-
-	public function __construct($global = false) {
-		$this->prefix = OC_Util::getInstanceId().'/';
-		if (!$global) {
-			$this->prefix .= OC_User::getUser().'/';
-		}
-	}
+namespace OC\Memcache;
 
+class XCache extends Cache {
 	/**
 	 * entries in XCache gets namespaced to prevent collisions between owncloud instances and users
 	 */
@@ -44,13 +37,24 @@ class OC_Cache_XCache {
 	}
 
 	public function clear($prefix='') {
-		if(!function_exists('xcache_unset_by_prefix')) {
-			function xcache_unset_by_prefix($prefix) {
-				// Since we can't clear targetted cache, we'll clear all. :(
-				xcache_clear_cache(XC_TYPE_VAR, 0);
-			}
-		}
 		xcache_unset_by_prefix($this->getNamespace().$prefix);
 		return true;
 	}
+
+	static public function isAvailable(){
+		if (!extension_loaded('xcache')) {
+			return false;
+		} elseif (\OC::$CLI) {
+			return false;
+		}else{
+			return true;
+		}
+	}
+}
+
+if(!function_exists('xcache_unset_by_prefix')) {
+	function xcache_unset_by_prefix($prefix) {
+		// Since we can't clear targetted cache, we'll clear all. :(
+		xcache_clear_cache(\XC_TYPE_VAR, 0);
+	}
 }
diff --git a/tests/lib/cache/apc.php b/tests/lib/cache/apc.php
deleted file mode 100644
index bb5eb483dbf150bcb523c2907f64eed31cf09998..0000000000000000000000000000000000000000
--- a/tests/lib/cache/apc.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
-* ownCloud
-*
-* @author Robin Appelman
-* @copyright 2012 Robin Appelman icewind@owncloud.com
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-class Test_Cache_APC extends Test_Cache {
-	public function setUp() {
-		if(!extension_loaded('apc')) {
-			$this->markTestSkipped('The apc extension is not available.');
-			return;
-		}
-		if(!ini_get('apc.enable_cli') && OC::$CLI) {
-			$this->markTestSkipped('apc not available in CLI.');
-			return;
-		}
-		$this->instance=new OC_Cache_APC();
-	}
-}
diff --git a/tests/lib/cache/xcache.php b/tests/lib/cache/xcache.php
deleted file mode 100644
index 43bed2db037a5f30ab45c2d280b42edcc83ddfd7..0000000000000000000000000000000000000000
--- a/tests/lib/cache/xcache.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
-* ownCloud
-*
-* @author Robin Appelman
-* @copyright 2012 Robin Appelman icewind@owncloud.com
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-class Test_Cache_XCache extends Test_Cache {
-	public function setUp() {
-		if(!function_exists('xcache_get')) {
-			$this->markTestSkipped('The xcache extension is not available.');
-			return;
-		}
-		$this->instance=new OC_Cache_XCache();
-	}
-}
diff --git a/tests/lib/memcache/apc.php b/tests/lib/memcache/apc.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b2a49470ba21d7391ae6920c2f83e33ff27222a
--- /dev/null
+++ b/tests/lib/memcache/apc.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Memcache;
+
+class APC extends Cache {
+	public function setUp() {
+		if(!\OC\Memcache\APC::isAvailable()) {
+			$this->markTestSkipped('The apc extension is not available.');
+			return;
+		}
+		$this->instance=new \OC\Memcache\APC(uniqid());
+	}
+}
diff --git a/tests/lib/memcache/cache.php b/tests/lib/memcache/cache.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2643b9fcd94bb0880f61cb15701f1b4459fa5e9
--- /dev/null
+++ b/tests/lib/memcache/cache.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Memcache;
+
+class Cache extends \Test_Cache {
+	public function testExistsAfterSet() {
+		$this->assertFalse($this->instance->hasKey('foo'));
+		$this->instance->set('foo', 'bar');
+		$this->assertTrue($this->instance->hasKey('foo'));
+	}
+
+	public function testGetAfterSet() {
+		$this->assertNull($this->instance->get('foo'));
+		$this->instance->set('foo', 'bar');
+		$this->assertEquals('bar', $this->instance->get('foo'));
+	}
+
+	public function testDoesNotExistAfterRemove() {
+		$this->instance->set('foo', 'bar');
+		$this->instance->remove('foo');
+		$this->assertFalse($this->instance->hasKey('foo'));
+	}
+
+	public function testArrayAccessSet() {
+		$this->instance['foo'] = 'bar';
+		$this->assertEquals('bar', $this->instance->get('foo'));
+	}
+
+	public function testArrayAccessGet() {
+		$this->instance->set('foo', 'bar');
+		$this->assertEquals('bar', $this->instance['foo']);
+	}
+
+	public function testArrayAccessExists() {
+		$this->assertFalse(isset($this->instance['foo']));
+		$this->instance->set('foo', 'bar');
+		$this->assertTrue(isset($this->instance['foo']));
+	}
+
+	public function testArrayAccessUnset() {
+		$this->instance->set('foo', 'bar');
+		unset($this->instance['foo']);
+		$this->assertFalse($this->instance->hasKey('foo'));
+	}
+
+	public function tearDown() {
+		if ($this->instance) {
+			$this->instance->clear();
+		}
+	}
+}
diff --git a/tests/lib/memcache/memcached.php b/tests/lib/memcache/memcached.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b38ae8ef3c54b3e92011ceb55b13b23efba0453
--- /dev/null
+++ b/tests/lib/memcache/memcached.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Memcache;
+
+class Memcached extends Cache {
+	public function setUp() {
+		if (!\OC\Memcache\Memcached::isAvailable()) {
+			$this->markTestSkipped('The memcached extension is not available.');
+			return;
+		}
+		$this->instance = new \OC\Memcache\Memcached(uniqid());
+	}
+}
diff --git a/tests/lib/memcache/xcache.php b/tests/lib/memcache/xcache.php
new file mode 100644
index 0000000000000000000000000000000000000000..f59afda396664ec1c63e94a7c37816a80cd21ba1
--- /dev/null
+++ b/tests/lib/memcache/xcache.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Memcache;
+
+class XCache extends Cache {
+	public function setUp() {
+		if (!\OC\Memcache\XCache::isAvailable()) {
+			$this->markTestSkipped('The xcache extension is not available.');
+			return;
+		}
+		$this->instance = new \OC\Memcache\XCache(uniqid());
+	}
+}