diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php
index ae349bfcd3a5b18499a59b4c20d2f1e96a7c048f..fcd3a617adafd4a677fe907aefd87b34271888ed 100644
--- a/apps/files_external/ajax/addRootCertificate.php
+++ b/apps/files_external/ajax/addRootCertificate.php
@@ -4,7 +4,7 @@ OCP\JSON::checkAppEnabled('files_external');
 OCP\JSON::callCheck();
 
 if ( ! ($filename = $_FILES['rootcert_import']['name']) ) {
-	header("Location: settings/personal.php");
+	header('Location:' . OCP\Util::linkToRoute( "settings_personal" ));
 	exit;
 }
 
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php
index 94dc5fb7ad877ca1243795c1fa9a30b2fcccfeb1..b2109e5eacde2290d786502e1c1a7ccef964ebdf 100755
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -352,9 +352,8 @@ class OC_Mount_Config {
 			$phpFile = OC_User::getHome(OCP\User::getUser()).'/mount.php';
 			$jsonFile = OC_User::getHome(OCP\User::getUser()).'/mount.json';
 		} else {
-			$datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
 			$phpFile = OC::$SERVERROOT.'/config/mount.php';
-			$jsonFile = $datadir . '/mount.json';
+			$jsonFile = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json");
 		}
 		if (is_file($jsonFile)) {
 			$mountPoints = json_decode(file_get_contents($jsonFile), true);
@@ -380,8 +379,7 @@ class OC_Mount_Config {
 		if ($isPersonal) {
 			$file = OC_User::getHome(OCP\User::getUser()).'/mount.json';
 		} else {
-			$datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
-			$file = $datadir . '/mount.json';
+			$file = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json");
 		}
 		$content = json_encode($data);
 		@file_put_contents($file, $content);
diff --git a/apps/user_ldap/lib/helper.php b/apps/user_ldap/lib/helper.php
index 9727d847d27bc33bdbc45e0b6164ffde22b4e3d3..7de7fe8667f7039a95437de4689f6942dceadb28 100644
--- a/apps/user_ldap/lib/helper.php
+++ b/apps/user_ldap/lib/helper.php
@@ -118,10 +118,16 @@ class Helper {
 			return false;
 		}
 
+		$saveOtherConfigurations = '';
+		if(empty($prefix)) {
+			$saveOtherConfigurations = 'AND `Configkey` NOT LIKE \'s%\'';
+		}
+
 		$query = \OCP\DB::prepare('
 			DELETE
 			FROM `*PREFIX*appconfig`
 			WHERE `configkey` LIKE ?
+				'.$saveOtherConfigurations.'
 				AND `appid` = \'user_ldap\'
 				AND `configkey` NOT IN (\'enabled\', \'installed_version\', \'types\', \'bgjUpdateGroupsLastRun\')
 		');
diff --git a/apps/user_ldap/tests/access.php b/apps/user_ldap/tests/access.php
new file mode 100644
index 0000000000000000000000000000000000000000..9beb2b973365a051b0436dbeb4d05358049d7cc4
--- /dev/null
+++ b/apps/user_ldap/tests/access.php
@@ -0,0 +1,71 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2013 Arthur Schiwon blizzz@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/>.
+*
+*/
+
+namespace OCA\user_ldap\tests;
+
+use \OCA\user_ldap\lib\Access;
+use \OCA\user_ldap\lib\Connection;
+use \OCA\user_ldap\lib\ILDAPWrapper;
+
+class Test_Access extends \PHPUnit_Framework_TestCase {
+	private function getConnecterAndLdapMock() {
+		static $conMethods;
+		static $accMethods;
+
+		if(is_null($conMethods) || is_null($accMethods)) {
+			$conMethods = get_class_methods('\OCA\user_ldap\lib\Connection');
+			$accMethods = get_class_methods('\OCA\user_ldap\lib\Access');
+		}
+		$lw  = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper');
+		$connector = $this->getMock('\OCA\user_ldap\lib\Connection',
+									$conMethods,
+									array($lw, null, null));
+
+		return array($lw, $connector);
+	}
+
+	public function testEscapeFilterPartValidChars() {
+		list($lw, $con) = $this->getConnecterAndLdapMock();
+		$access = new Access($con, $lw);
+
+		$input = 'okay';
+		$this->assertTrue($input === $access->escapeFilterPart($input));
+	}
+
+	public function testEscapeFilterPartEscapeWildcard() {
+		list($lw, $con) = $this->getConnecterAndLdapMock();
+		$access = new Access($con, $lw);
+
+		$input = '*';
+		$expected = '\\\\*';
+		$this->assertTrue($expected === $access->escapeFilterPart($input));
+	}
+
+	public function testEscapeFilterPartEscapeWildcard2() {
+		list($lw, $con) = $this->getConnecterAndLdapMock();
+		$access = new Access($con, $lw);
+
+		$input = 'foo*bar';
+		$expected = 'foo\\\\*bar';
+		$this->assertTrue($expected === $access->escapeFilterPart($input));
+	}
+}
\ No newline at end of file
diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php
index 9193a005ae5da9aa9d0861e1d085282756d02858..8c8d85b3c334fc156e31873f15d0dd88eb0e6a33 100644
--- a/apps/user_ldap/tests/user_ldap.php
+++ b/apps/user_ldap/tests/user_ldap.php
@@ -83,6 +83,12 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
 	 * @return void
 	 */
 	private function prepareAccessForCheckPassword(&$access) {
+		$access->expects($this->once())
+			   ->method('escapeFilterPart')
+			   ->will($this->returnCallback(function($uid) {
+				   return $uid;
+			   }));
+
 		$access->connection->expects($this->any())
 			   ->method('__get')
 			   ->will($this->returnCallback(function($name) {
@@ -116,17 +122,34 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
 			   }));
 	}
 
-	public function testCheckPassword() {
+	public function testCheckPasswordUidReturn() {
 		$access = $this->getAccessMock();
+
 		$this->prepareAccessForCheckPassword($access);
 		$backend = new UserLDAP($access);
 		\OC_User::useBackend($backend);
 
 		$result = $backend->checkPassword('roland', 'dt19');
 		$this->assertEquals('gunslinger', $result);
+	}
+
+	public function testCheckPasswordWrongPassword() {
+		$access = $this->getAccessMock();
+
+		$this->prepareAccessForCheckPassword($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = $backend->checkPassword('roland', 'wrong');
 		$this->assertFalse($result);
+	}
+
+	public function testCheckPasswordWrongUser() {
+		$access = $this->getAccessMock();
+
+		$this->prepareAccessForCheckPassword($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = $backend->checkPassword('mallory', 'evil');
 		$this->assertFalse($result);
@@ -140,9 +163,23 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
 
 		$result = \OCP\User::checkPassword('roland', 'dt19');
 		$this->assertEquals('gunslinger', $result);
+	}
+
+	public function testCheckPasswordPublicAPIWrongPassword() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForCheckPassword($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = \OCP\User::checkPassword('roland', 'wrong');
 		$this->assertFalse($result);
+	}
+
+	public function testCheckPasswordPublicAPIWrongUser() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForCheckPassword($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = \OCP\User::checkPassword('mallory', 'evil');
 		$this->assertFalse($result);
@@ -154,6 +191,12 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
 	 * @return void
 	 */
 	private function prepareAccessForGetUsers(&$access) {
+		$access->expects($this->once())
+			   ->method('escapeFilterPart')
+			   ->will($this->returnCallback(function($search) {
+				   return $search;
+			   }));
+
 		$access->expects($this->any())
 			   ->method('getFilterPartForUserSearch')
 			   ->will($this->returnCallback(function($search) {
@@ -191,28 +234,52 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
 			   ->will($this->returnArgument(0));
 	}
 
-	public function testGetUsers() {
+	public function testGetUsersNoParam() {
 		$access = $this->getAccessMock();
 		$this->prepareAccessForGetUsers($access);
 		$backend = new UserLDAP($access);
 
 		$result = $backend->getUsers();
 		$this->assertEquals(3, count($result));
+	}
+
+	public function testGetUsersLimitOffset() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
 
 		$result = $backend->getUsers('', 1, 2);
 		$this->assertEquals(1, count($result));
+	}
+
+	public function testGetUsersLimitOffset2() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
 
 		$result = $backend->getUsers('', 2, 1);
 		$this->assertEquals(2, count($result));
+	}
+
+	public function testGetUsersSearchWithResult() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
 
 		$result = $backend->getUsers('yo');
 		$this->assertEquals(2, count($result));
+	}
+
+	public function testGetUsersSearchEmptyResult() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
 
 		$result = $backend->getUsers('nix');
 		$this->assertEquals(0, count($result));
 	}
 
-	public function testGetUsersViaAPI() {
+	public function testGetUsersViaAPINoParam() {
 		$access = $this->getAccessMock();
 		$this->prepareAccessForGetUsers($access);
 		$backend = new UserLDAP($access);
@@ -220,15 +287,43 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
 
 		$result = \OCP\User::getUsers();
 		$this->assertEquals(3, count($result));
+	}
+
+	public function testGetUsersViaAPILimitOffset() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = \OCP\User::getUsers('', 1, 2);
 		$this->assertEquals(1, count($result));
+	}
+
+	public function testGetUsersViaAPILimitOffset2() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = \OCP\User::getUsers('', 2, 1);
 		$this->assertEquals(2, count($result));
+	}
+
+	public function testGetUsersViaAPISearchWithResult() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = \OCP\User::getUsers('yo');
 		$this->assertEquals(2, count($result));
+	}
+
+	public function testGetUsersViaAPISearchEmptyResult() {
+		$access = $this->getAccessMock();
+		$this->prepareAccessForGetUsers($access);
+		$backend = new UserLDAP($access);
+		\OC_User::useBackend($backend);
 
 		$result = \OCP\User::getUsers('nix');
 		$this->assertEquals(0, count($result));
diff --git a/config/config.sample.php b/config/config.sample.php
index d4cccd3443d2b28e930e1b9ce26286c8eefc2f1e..356843200b1e5427a7281b1205f9a039294661d7 100755
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -266,4 +266,7 @@ $CONFIG = array(
 
 /* all css and js files will be served by the web server statically in one js file and ons css file*/
 'asset-pipeline.enabled' => false,
+
+ /* where mount.json file should be stored, defaults to data/mount.json */
+ 'mount_file' => '',
 );
diff --git a/core/css/fixes.css b/core/css/fixes.css
index 4ee854addef4be4574cc0245bcbf9eb7aaa978e4..a33afd5cf77f945c9c007057d99ee097e6cba78e 100644
--- a/core/css/fixes.css
+++ b/core/css/fixes.css
@@ -54,11 +54,6 @@
 	background-color: #1B314D;
 }
 
-/* in IE9 the nav bar on the left side is too narrow and leave a white area - original width is 80px */
-.ie9 #navigation {
-	width: 100px;
-}
-
 /* IE8 isn't able to display transparent background. So it is specified using a gradient */
 .ie8 #nojavascript {
 	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#4c320000', endColorstr='#4c320000'); /* IE */
diff --git a/core/css/multiselect.css b/core/css/multiselect.css
index 60f2f47e698020cb1f3fac5f062a5900a562866a..8d949e7cdb7fd4b6e17fa22c09714921df80234a 100644
--- a/core/css/multiselect.css
+++ b/core/css/multiselect.css
@@ -48,7 +48,7 @@ ul.multiselectoptions > li input[type='checkbox']:checked+label {
 	font-weight: bold;
 }
 
-div.multiselect {
+div.multiselect, select.multiselect {
 	display: inline-block;
 	max-width: 400px;
 	min-width: 150px;
@@ -58,6 +58,12 @@ div.multiselect {
 	vertical-align: bottom;
 }
 
+/* To make a select look like a multiselect until it's initialized */
+select.multiselect {
+	height: 30px;
+	min-width: 113px;
+}
+
 div.multiselect.active {
 	background-color: #fff;
 	position: relative;
diff --git a/core/css/styles.css b/core/css/styles.css
index bee44785f123e259139f924b1580aefa652ec652..22ba60dd2b7ef99a02a9579d0d94ab72a66bdd3c 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -74,6 +74,19 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari
 	color: #aaa;
 }
 
+#header .logo {
+	background-image: url(../img/logo.svg);
+	width: 250px;
+	height: 118px;
+	margin: 0 auto;
+}
+
+#header .logo-wide {
+	background-image: url(../img/logo-wide.svg);
+	width: 147px;
+	height: 32px;
+}
+
 /* INPUTS */
 input[type="text"],
 input[type="password"],
@@ -933,3 +946,20 @@ div.crumb:active {
 	opacity:.7;
 }
 
+.appear {
+	opacity: 1;
+	transition: opacity 500ms ease 0s;
+	-moz-transition: opacity 500ms ease 0s;
+	-ms-transition: opacity 500ms ease 0s;
+	-o-transition: opacity 500ms ease 0s;
+	-webkit-transition: opacity 500ms ease 0s;
+}
+.appear.transparent {
+	opacity: 0;
+}
+
+/* for IE10 */
+@-ms-viewport {
+	width: device-width;
+}
+
diff --git a/core/img/filetypes/text-x-javascript.png b/core/img/filetypes/application-javascript.png
similarity index 100%
rename from core/img/filetypes/text-x-javascript.png
rename to core/img/filetypes/application-javascript.png
diff --git a/core/img/filetypes/text-x-javascript.svg b/core/img/filetypes/application-javascript.svg
similarity index 100%
rename from core/img/filetypes/text-x-javascript.svg
rename to core/img/filetypes/application-javascript.svg
diff --git a/core/img/filetypes/flash.png b/core/img/filetypes/application-x-shockwave-flash.png
similarity index 100%
rename from core/img/filetypes/flash.png
rename to core/img/filetypes/application-x-shockwave-flash.png
diff --git a/core/img/filetypes/flash.svg b/core/img/filetypes/application-x-shockwave-flash.svg
similarity index 100%
rename from core/img/filetypes/flash.svg
rename to core/img/filetypes/application-x-shockwave-flash.svg
diff --git a/core/img/filetypes/calendar.png b/core/img/filetypes/text-calendar.png
similarity index 100%
rename from core/img/filetypes/calendar.png
rename to core/img/filetypes/text-calendar.png
diff --git a/core/img/filetypes/calendar.svg b/core/img/filetypes/text-calendar.svg
similarity index 100%
rename from core/img/filetypes/calendar.svg
rename to core/img/filetypes/text-calendar.svg
diff --git a/core/js/config.php b/core/js/config.php
index b6875fb73f9aca2d7e3ff733461bda133f87eb0a..139c3b6d485bbec13c2acd92e54501b23f78fe8f 100644
--- a/core/js/config.php
+++ b/core/js/config.php
@@ -24,6 +24,7 @@ foreach(OC_App::getEnabledApps() as $app) {
 
 $array = array(
 	"oc_debug" => (defined('DEBUG') && DEBUG) ? 'true' : 'false',
+	"oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false',
 	"oc_webroot" => "\"".OC::$WEBROOT."\"",
 	"oc_appswebroots" =>  str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution
 	"datepickerFormatDate" => json_encode($l->l('jsdate', 'jsdate')),
diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php
index 6a96b17b100a03ab84693b6fe8b5b2a05c8bf247..91157b923a5cdc57b954888bc456d834212976bc 100644
--- a/core/templates/layout.guest.php
+++ b/core/templates/layout.guest.php
@@ -36,7 +36,7 @@
 	<body id="body-login">
 		<div class="wrapper"><!-- for sticky footer -->
 			<header><div id="header">
-				<img src="<?php print_unescaped(image_path('', 'logo.svg')); ?>" class="svg" alt="<?php p($theme->getName()); ?>" />
+				<div class='logo'></div>
 				<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
 			</div></header>
 
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index bc1c700402ee1bd25fbdb8a50b2a1d09015e2329..44413f5a2a87d3288139d8f5556669fac91a0ce0 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -45,8 +45,9 @@
 		<?php endif; ?>
 	</div>
 	<header><div id="header">
-			<a href="<?php print_unescaped(link_to('', 'index.php')); ?>" title="" id="owncloud"><img class="svg"
-				src="<?php print_unescaped(image_path('', 'logo-wide.svg')); ?>" alt="<?php p($theme->getName()); ?>" /></a>
+			<a href="<?php print_unescaped(link_to('', 'index.php')); ?>" title="" id="owncloud">
+				<div class='logo-wide'></div>
+			</a>
 			<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
 			<div id="settings" class="svg">
 				<span id="expand" tabindex="0" role="link">
diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php
index b6102f5c2451f1cea52b6ca4adfa891e80685181..952f9f9febffb6db80b408bd9cb2a34e551a3323 100644
--- a/lib/private/files/filesystem.php
+++ b/lib/private/files/filesystem.php
@@ -320,16 +320,16 @@ class Filesystem {
 		else {
 			self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user);
 		}
-		$datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
+		$mount_file = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json");
 
 		//move config file to it's new position
 		if (is_file(\OC::$SERVERROOT . '/config/mount.json')) {
-			rename(\OC::$SERVERROOT . '/config/mount.json', $datadir . '/mount.json');
+			rename(\OC::$SERVERROOT . '/config/mount.json', $mount_file);
 		}
 		// Load system mount points
-		if (is_file(\OC::$SERVERROOT . '/config/mount.php') or is_file($datadir . '/mount.json')) {
-			if (is_file($datadir . '/mount.json')) {
-				$mountConfig = json_decode(file_get_contents($datadir . '/mount.json'), true);
+		if (is_file(\OC::$SERVERROOT . '/config/mount.php') or is_file($mount_file)) {
+			if (is_file($mount_file)) {
+				$mountConfig = json_decode(file_get_contents($mount_file), true);
 			} elseif (is_file(\OC::$SERVERROOT . '/config/mount.php')) {
 				$mountConfig = $parser->parsePHP(file_get_contents(\OC::$SERVERROOT . '/config/mount.php'));
 			}
diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php
index 1bcdca7f47a59f42e94f87a2925021eb74640f97..26c952e694ac6aa8793823ca4a21dccb4ffe6089 100644
--- a/lib/private/files/storage/wrapper/quota.php
+++ b/lib/private/files/storage/wrapper/quota.php
@@ -15,12 +15,18 @@ class Quota extends Wrapper {
 	 */
 	protected $quota;
 
+	/**
+	 * @var string $sizeRoot
+	 */
+	protected $sizeRoot;
+
 	/**
 	 * @param array $parameters
 	 */
 	public function __construct($parameters) {
 		$this->storage = $parameters['storage'];
 		$this->quota = $parameters['quota'];
+		$this->sizeRoot = isset($parameters['root']) ? $parameters['root'] : '';
 	}
 
 	/**
@@ -46,7 +52,7 @@ class Quota extends Wrapper {
 		if ($this->quota < 0) {
 			return $this->storage->free_space($path);
 		} else {
-			$used = $this->getSize('');
+			$used = $this->getSize($this->sizeRoot);
 			if ($used < 0) {
 				return \OC\Files\SPACE_NOT_COMPUTED;
 			} else {
diff --git a/lib/private/helper.php b/lib/private/helper.php
index e5d1fa9b513f39406a7b29eaf0a8f541ad17d57c..1aab2f296e1f10766e49bd5167291a2fff12acf8 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -152,7 +152,32 @@ class OC_Helper {
 	public static function mimetypeIcon($mimetype) {
 		$alias = array(
 			'application/octet-stream' => 'file', // use file icon as fallback
-			'application/xml' => 'code/xml',
+
+			'application/illustrator' => 'image',
+			'application/coreldraw' => 'image',
+			'application/x-gimp' => 'image',
+			'application/x-photoshop' => 'image',
+
+			'application/x-font-ttf' => 'font',
+			'application/font-woff' => 'font',
+			'application/vnd.ms-fontobject' => 'font',
+
+			'application/json' => 'text/code',
+			'application/x-perl' => 'text/code',
+			'application/x-php' => 'text/code',
+			'text/x-shellscript' => 'text/code',
+			'application/xml' => 'text/html',
+			'text/css' => 'text/code',
+			'application/x-tex' => 'text',
+
+			'application/x-compressed' => 'package/x-generic',
+			'application/x-7z-compressed' => 'package/x-generic',
+			'application/x-deb' => 'package/x-generic',
+			'application/x-gzip' => 'package/x-generic',
+			'application/x-rar-compressed' => 'package/x-generic',
+			'application/x-tar' => 'package/x-generic',
+			'application/zip' => 'package/x-generic',
+
 			'application/msword' => 'x-office/document',
 			'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'x-office/document',
 			'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'x-office/document',
@@ -162,6 +187,7 @@ class OC_Helper {
 			'application/vnd.oasis.opendocument.text-template' => 'x-office/document',
 			'application/vnd.oasis.opendocument.text-web' => 'x-office/document',
 			'application/vnd.oasis.opendocument.text-master' => 'x-office/document',
+
 			'application/mspowerpoint' => 'x-office/presentation',
 			'application/vnd.ms-powerpoint' => 'x-office/presentation',
 			'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'x-office/presentation',
@@ -173,6 +199,7 @@ class OC_Helper {
 			'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'x-office/presentation',
 			'application/vnd.oasis.opendocument.presentation' => 'x-office/presentation',
 			'application/vnd.oasis.opendocument.presentation-template' => 'x-office/presentation',
+
 			'application/msexcel' => 'x-office/spreadsheet',
 			'application/vnd.ms-excel' => 'x-office/spreadsheet',
 			'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'x-office/spreadsheet',
@@ -183,6 +210,8 @@ class OC_Helper {
 			'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'x-office/spreadsheet',
 			'application/vnd.oasis.opendocument.spreadsheet' => 'x-office/spreadsheet',
 			'application/vnd.oasis.opendocument.spreadsheet-template' => 'x-office/spreadsheet',
+			'text/csv' => 'x-office/spreadsheet',
+
 			'application/msaccess' => 'database',
 		);
 
diff --git a/lib/private/image.php b/lib/private/image.php
index 42685ddab5cca91c6964c46826e225f5e2706a2c..17caaa012f5728f54ec57c75f821843b5284f88b 100644
--- a/lib/private/image.php
+++ b/lib/private/image.php
@@ -231,7 +231,7 @@ class OC_Image {
 	}
 
 	/**
-	* @returns Returns the image resource in any.
+	* @returns resource Returns the image resource in any.
 	*/
 	public function resource() {
 		return $this->resource;
diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php
index 174877d623b52070a77bd6479c7eb725d7715418..9bd07b89023aff45359f668719cc913d817acff4 100644
--- a/lib/private/mimetypes.list.php
+++ b/lib/private/mimetypes.list.php
@@ -24,11 +24,13 @@
  * Array mapping file extensions to mimetypes (in alphabetical order).
  */
 return array(
-	'accdb'=>'application/msaccess',
+	'7z' => 'application/x-7z-compressed',
+	'accdb' => 'application/msaccess',
 	'ai' => 'application/illustrator',
-	'avi'=>'video/x-msvideo',
+	'avi' => 'video/x-msvideo',
 	'bash' => 'text/x-shellscript',
-	'blend'=>'application/x-blender',
+	'blend' => 'application/x-blender',
+	'bin' => 'application/x-bin',
 	'cb7' => 'application/x-cbr',
 	'cba' => 'application/x-cbr',
 	'cbr' => 'application/x-cbr',
@@ -38,81 +40,91 @@ return array(
 	'cc' => 'text/x-c',
 	'cdr' => 'application/coreldraw',
 	'cpp' => 'text/x-c++src',
-	'css'=>'text/css',
+	'css' => 'text/css',
+	'csv' => 'text/csv',
 	'cvbdl' => 'application/x-cbr',
 	'c' => 'text/x-c',
 	'c++' => 'text/x-c++src',
-	'doc'=>'application/msword',
-	'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
-	'dot'=>'application/msword',
-	'dotx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
-	'dv'=>'video/dv',
+	'deb' => 'application/x-deb',
+	'doc' => 'application/msword',
+	'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+	'dot' => 'application/msword',
+	'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+	'dv' => 'video/dv',
+	'eot' => 'application/vnd.ms-fontobject',
 	'epub' => 'application/epub+zip',
-	'exe'=>'application/x-ms-dos-executable',
-	'flac'=>'audio/flac',
-	'gif'=>'image/gif',
-	'gz'=>'application/x-gzip',
-	'gzip'=>'application/x-gzip',
-	'html'=>'text/html',
-	'htm'=>'text/html',
-	'ical'=>'text/calendar',
-	'ics'=>'text/calendar',
+	'exe' => 'application/x-ms-dos-executable',
+	'flac' => 'audio/flac',
+	'gif' => 'image/gif',
+	'gz' => 'application/x-gzip',
+	'gzip' => 'application/x-gzip',
+	'html' => 'text/html',
+	'htm' => 'text/html',
+	'ical' => 'text/calendar',
+	'ics' => 'text/calendar',
 	'impress' => 'text/impress',
-	'jpeg'=>'image/jpeg',
-	'jpg'=>'image/jpeg',
-	'js'=>'application/javascript',
-	'keynote'=>'application/x-iwork-keynote-sffkey',
-	'kra'=>'application/x-krita',
-	'm2t'=>'video/mp2t',
-	'm4v'=>'video/mp4',
+	'jpeg' => 'image/jpeg',
+	'jpg' => 'image/jpeg',
+	'js' => 'application/javascript',
+	'json' => 'application/json',
+	'keynote' => 'application/x-iwork-keynote-sffkey',
+	'kra' => 'application/x-krita',
+	'm2t' => 'video/mp2t',
+	'm4v' => 'video/mp4',
 	'markdown' => 'text/markdown',
 	'mdown' => 'text/markdown',
 	'md' => 'text/markdown',
-	'mdb'=>'application/msaccess',
+	'mdb' => 'application/msaccess',
 	'mdwn' => 'text/markdown',
 	'mobi' => 'application/x-mobipocket-ebook',
-	'mov'=>'video/quicktime',
-	'mp3'=>'audio/mpeg',
-	'mp4'=>'video/mp4',
-	'mpeg'=>'video/mpeg',
-	'mpg'=>'video/mpeg',
-	'msi'=>'application/x-msi',
-	'numbers'=>'application/x-iwork-numbers-sffnumbers',
-	'odg'=>'application/vnd.oasis.opendocument.graphics',
-	'odp'=>'application/vnd.oasis.opendocument.presentation',
-	'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
-	'odt'=>'application/vnd.oasis.opendocument.text',
-	'oga'=>'audio/ogg',
-	'ogg'=>'audio/ogg',
-	'ogv'=>'video/ogg',
-	'pages'=>'application/x-iwork-pages-sffpages',
-	'pdf'=>'application/pdf',
-	'php'=>'application/x-php',
-	'pl'=>'application/x-pearl',
-	'png'=>'image/png',
-	'ppt'=>'application/mspowerpoint',
-	'pptx'=>'application/vnd.openxmlformats-officedocument.presentationml.presentation',
-	'psd'=>'application/x-photoshop',
-	'py'=>'text/x-script.python',
+	'mov' => 'video/quicktime',
+	'mp3' => 'audio/mpeg',
+	'mp4' => 'video/mp4',
+	'mpeg' => 'video/mpeg',
+	'mpg' => 'video/mpeg',
+	'msi' => 'application/x-msi',
+	'numbers' => 'application/x-iwork-numbers-sffnumbers',
+	'odg' => 'application/vnd.oasis.opendocument.graphics',
+	'odp' => 'application/vnd.oasis.opendocument.presentation',
+	'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
+	'odt' => 'application/vnd.oasis.opendocument.text',
+	'oga' => 'audio/ogg',
+	'ogg' => 'audio/ogg',
+	'ogv' => 'video/ogg',
+	'otf' => 'font/opentype',
+	'pages' => 'application/x-iwork-pages-sffpages',
+	'pdf' => 'application/pdf',
+	'php' => 'application/x-php',
+	'pl' => 'application/x-perl',
+	'png' => 'image/png',
+	'ppt' => 'application/mspowerpoint',
+	'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+	'psd' => 'application/x-photoshop',
+	'py' => 'text/x-python',
+	'rar' => 'application/x-rar-compressed',
 	'reveal' => 'text/reveal',
 	'sgf' => 'application/sgf',
 	'sh-lib' => 'text/x-shellscript',
 	'sh' => 'text/x-shellscript',
-	'svg'=>'image/svg+xml',
-	'tar'=>'application/x-tar',
-	'tar.gz'=>'application/x-compressed',
-	'tgz'=>'application/x-compressed',
-	'tiff'=>'image/tiff',
-	'tif'=>'image/tiff',
-	'txt'=>'text/plain',
+	'svg' => 'image/svg+xml',
+	'swf' => 'application/x-shockwave-flash',
+	'tar' => 'application/x-tar',
+	'tar.gz' => 'application/x-compressed',
+	'tex' => 'application/x-tex',
+	'tgz' => 'application/x-compressed',
+	'tiff' => 'image/tiff',
+	'tif' => 'image/tiff',
+	'ttf' => 'application/x-font-ttf',
+	'txt' => 'text/plain',
 	'vcard' => 'text/vcard',
 	'vcf' => 'text/vcard',
-	'wav'=>'audio/wav',
-	'webm'=>'video/webm',
-	'wmv'=>'video/x-ms-asf',
-	'xcf'=>'application/x-gimp',
-	'xls'=>'application/msexcel',
-	'xlsx'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
-	'xml'=>'application/xml',
-	'zip'=>'application/zip',
+	'wav' => 'audio/wav',
+	'webm' => 'video/webm',
+	'woff' => 'application/font-woff',
+	'wmv' => 'video/x-ms-asf',
+	'xcf' => 'application/x-gimp',
+	'xls' => 'application/msexcel',
+	'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+	'xml' => 'application/xml',
+	'zip' => 'application/zip',
 );
diff --git a/lib/private/urlgenerator.php b/lib/private/urlgenerator.php
index 4e3c11090007fdb23b91d52c7e9491659694665a..60da34f2d6e64d11f604db85ba8c91bf27b565b3 100644
--- a/lib/private/urlgenerator.php
+++ b/lib/private/urlgenerator.php
@@ -147,6 +147,7 @@ class URLGenerator implements IURLGenerator {
 	 * @return string the absolute version of the url
 	 */
 	public function getAbsoluteURL($url) {
-		return \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost() . $url;
+		$separator = $url[0] === '/' ? '' : '/';
+		return \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost() . $separator . $url;
 	}
 }
diff --git a/lib/private/user.php b/lib/private/user.php
index 86a01f96258ccc590274aac2024f5c0be078a8a1..08ead712028e894dc6211797b5eeb68480da47d1 100644
--- a/lib/private/user.php
+++ b/lib/private/user.php
@@ -246,7 +246,6 @@ class OC_User {
 		OC_Hook::emit( "OC_User", "pre_login", array( "run" => &$run, "uid" => $uid ));
 
 		if($uid) {
-			session_regenerate_id(true);
 			self::setUserId($uid);
 			self::setDisplayName($uid);
 			self::getUserSession()->setLoginName($uid);
diff --git a/lib/private/user/session.php b/lib/private/user/session.php
index 1740bad5abec22b1fdfa0aaf078e1c7dbb4b7fb8..cd03b30205fb3eb7c0bab2829e383aeba0fbade7 100644
--- a/lib/private/user/session.php
+++ b/lib/private/user/session.php
@@ -157,6 +157,7 @@ class Session implements Emitter, \OCP\IUserSession {
 		if($user !== false) {
 			if (!is_null($user)) {
 				if ($user->isEnabled()) {
+					session_regenerate_id(true);
 					$this->setUser($user);
 					$this->setLoginName($uid);
 					$this->manager->emit('\OC\User', 'postLogin', array($user, $password));
diff --git a/lib/private/util.php b/lib/private/util.php
index b39304c485c2274ac41c4697159b5867ce612b61..920161949ae417752a013ed20a157cc910e47704 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -63,7 +63,7 @@ class OC_Util {
 					$user = $storage->getUser()->getUID();
 					$quota = OC_Util::getUserQuota($user);
 					if ($quota !== \OC\Files\SPACE_UNLIMITED) {
-						return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota));
+						return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota, 'root' => 'files'));
 					}
 				}
 
diff --git a/remote.php b/remote.php
index 7884695b3a57ef1ba38e42d9317026352b60aeb0..9e18c8f80a9dd207d001f7c2912b2e4b38fb9690 100644
--- a/remote.php
+++ b/remote.php
@@ -32,11 +32,7 @@ try {
 		default:
 			OC_Util::checkAppEnabled($app);
 			OC_App::loadApp($app);
-			if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
-				$file = OC_App::getAppPath($app) .'/'. $parts[1];
-			}else{
-				$file = '/' . OC_App::getAppPath($app) .'/'. $parts[1];
-			}
+			$file = OC_App::getAppPath($app) .'/'. $parts[1];
 			break;
 	}
 	$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
diff --git a/settings/js/isadmin.php b/settings/js/isadmin.php
deleted file mode 100644
index 13a8ba1d312d8f7fcd3751c895ee60fb79f6a29b..0000000000000000000000000000000000000000
--- a/settings/js/isadmin.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-/**
- * Copyright (c) 2013 Lukas Reschke <lukas@statuscode.ch>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-// Set the content type to Javascript
-header("Content-type: text/javascript");
-
-// Disallow caching
-header("Cache-Control: no-cache, must-revalidate"); 
-header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); 
-
-if (OC_User::isAdminUser(OC_User::getUser())) {
-	echo("var isadmin = true;");
-} else {
-	echo("var isadmin = false;");
-}
diff --git a/settings/js/users.js b/settings/js/users.js
index 6886db668b501ef626eba7108ce6c554764918a6..160d0a8d9d2891a68614824964299d01d2183e9a 100644
--- a/settings/js/users.js
+++ b/settings/js/users.js
@@ -85,19 +85,24 @@ var UserList = {
 
 	add: function (username, displayname, groups, subadmin, quota, sort) {
 		var tr = $('tbody tr').first().clone();
-		if (tr.find('div.avatardiv')){
+		var subadminsEl;
+		var subadminSelect;
+		var groupsSelect;
+		if (tr.find('div.avatardiv').length){
 			$('div.avatardiv', tr).avatar(username, 32);
 		}
 		tr.attr('data-uid', username);
 		tr.attr('data-displayName', displayname);
 		tr.find('td.name').text(username);
 		tr.find('td.displayName > span').text(displayname);
-		var groupsSelect = $('<select multiple="multiple" class="groupsselect" data-placehoder="Groups" title="' + t('settings', 'Groups') + '"></select>')
+
+		// make them look like the multiselect buttons
+		// until they get time to really get initialized
+		groupsSelect = $('<select multiple="multiple" class="groupsselect multiselect button" data-placehoder="Groups" title="' + t('settings', 'Groups') + '"></select>')
 			.attr('data-username', username)
 			.data('user-groups', groups);
-		tr.find('td.groups').empty();
 		if (tr.find('td.subadmins').length > 0) {
-			var subadminSelect = $('<select multiple="multiple" class="subadminsselect" data-placehoder="subadmins" title="' + t('settings', 'Group Admin') + '">')
+			subadminSelect = $('<select multiple="multiple" class="subadminsselect multiselect button" data-placehoder="subadmins" title="' + t('settings', 'Group Admin') + '">')
 				.attr('data-username', username)
 				.data('user-groups', groups)
 				.data('subadmin', subadmin);
@@ -109,11 +114,10 @@ var UserList = {
 				subadminSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
 			}
 		});
-		tr.find('td.groups').append(groupsSelect);
-		UserList.applyMultiplySelect(groupsSelect);
-		if (tr.find('td.subadmins').length > 0) {
-			tr.find('td.subadmins').append(subadminSelect);
-			UserList.applyMultiplySelect(subadminSelect);
+		tr.find('td.groups').empty().append(groupsSelect);
+		subadminsEl = tr.find('td.subadmins');
+		if (subadminsEl.length > 0) {
+			subadminsEl.append(subadminSelect);
 		}
 		if (tr.find('td.remove img').length === 0 && OC.currentUser !== username) {
 			var rm_img = $('<img class="svg action">').attr({
@@ -139,11 +143,11 @@ var UserList = {
 			}
 		}
 		$(tr).appendTo('tbody');
+
 		if (sort) {
 			UserList.doSort();
 		}
 
-		quotaSelect.singleSelect();
 		quotaSelect.on('change', function () {
 			var uid = $(this).parent().parent().attr('data-uid');
 			var quota = $(this).val();
@@ -153,6 +157,16 @@ var UserList = {
 				}
 			});
 		});
+
+		// defer init so the user first sees the list appear more quickly
+		window.setTimeout(function(){
+			quotaSelect.singleSelect();
+			UserList.applyMultiplySelect(groupsSelect);
+			if (subadminSelect) {
+				UserList.applyMultiplySelect(subadminSelect);
+			}
+		}, 0);
+		return tr;
 	},
 	// From http://my.opera.com/GreyWyvern/blog/show.dml/1671288
 	alphanum: function(a, b) {
@@ -209,28 +223,39 @@ var UserList = {
 		if (UserList.updating) {
 			return;
 		}
+		$('table+.loading').css('visibility', 'visible');
 		UserList.updating = true;
 		$.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset, limit: UserList.usersToLoad }), function (result) {
+			var loadedUsers = 0;
+			var trs = [];
 			if (result.status === 'success') {
 				//The offset does not mirror the amount of users available,
 				//because it is backend-dependent. For correct retrieval,
 				//always the limit(requested amount of users) needs to be added.
-				UserList.offset += UserList.usersToLoad;
 				$.each(result.data, function (index, user) {
 					if($('tr[data-uid="' + user.name + '"]').length > 0) {
 						return true;
 					}
 					var tr = UserList.add(user.name, user.displayname, user.groups, user.subadmin, user.quota, false);
-					if (index === 9) {
-						$(tr).bind('inview', function (event, isInView, visiblePartX, visiblePartY) {
-							$(this).unbind(event);
-							UserList.update();
-						});
-					}
+					tr.addClass('appear transparent');
+					trs.push(tr);
+					loadedUsers++;
 				});
 				if (result.data.length > 0) {
 					UserList.doSort();
+					$('table+.loading').css('visibility', 'hidden');
 				}
+				else {
+					UserList.noMoreEntries = true;
+					$('table+.loading').remove();
+				}
+				UserList.offset += loadedUsers;
+				// animate
+				setTimeout(function() {
+					for (var i = 0; i < trs.length; i++) {
+						trs[i].removeClass('transparent');
+					}
+				}, 0);
 			}
 			UserList.updating = false;
 		});
@@ -239,7 +264,7 @@ var UserList = {
 	applyMultiplySelect: function (element) {
 		var checked = [];
 		var user = element.attr('data-username');
-		if ($(element).attr('class') === 'groupsselect') {
+		if ($(element).hasClass('groupsselect')) {
 			if (element.data('userGroups')) {
 				checked = element.data('userGroups');
 			}
@@ -248,7 +273,7 @@ var UserList = {
 					if (user === OC.currentUser && group === 'admin') {
 						return false;
 					}
-					if (!isadmin && checked.length === 1 && checked[0] === group) {
+					if (!oc_isadmin && checked.length === 1 && checked[0] === group) {
 						return false;
 					}
 					$.post(
@@ -280,7 +305,7 @@ var UserList = {
 				});
 			};
 			var label;
-			if (isadmin) {
+			if (oc_isadmin) {
 				label = t('settings', 'add group');
 			} else {
 				label = null;
@@ -295,7 +320,7 @@ var UserList = {
 				minWidth: 100
 			});
 		}
-		if ($(element).attr('class') === 'subadminsselect') {
+		if ($(element).hasClass('subadminsselect')) {
 			if (element.data('subadmin')) {
 				checked = element.data('subadmin');
 			}
@@ -330,18 +355,26 @@ var UserList = {
 				minWidth: 100
 			});
 		}
-	}
+	},
+
+	_onScroll: function(e) {
+		if (!!UserList.noMoreEntries) {
+			return;
+		}
+		if ($(window).scrollTop() + $(window).height() > $(document).height() - 500) {
+			UserList.update(true);
+		}
+	},
 };
 
 $(document).ready(function () {
 
 	UserList.doSort();
 	UserList.availableGroups = $('#content table').data('groups');
-	$('tbody tr:last').bind('inview', function (event, isInView, visiblePartX, visiblePartY) {
-		OC.Router.registerLoadedCallback(function () {
-			UserList.update();
-		});
+	OC.Router.registerLoadedCallback(function() {
+		$(window).scroll(function(e) {UserList._onScroll(e);});
 	});
+	$('table').after($('<div class="loading" style="height: 200px; visibility: hidden;"></div>'));
 
 	$('select[multiple]').each(function (index, element) {
 		UserList.applyMultiplySelect($(element));
diff --git a/settings/routes.php b/settings/routes.php
index 60f9d8e100193c87fcb248021bb9efde135982bd..895a9f5ccead91916334d751ffb70c3ada84648d 100644
--- a/settings/routes.php
+++ b/settings/routes.php
@@ -72,5 +72,3 @@ $this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php')
 	->actionInclude('settings/ajax/setloglevel.php');
 $this->create('settings_ajax_setsecurity', '/settings/ajax/setsecurity.php')
 	->actionInclude('settings/ajax/setsecurity.php');
-$this->create('isadmin', '/settings/js/isadmin.js')
-	->actionInclude('settings/js/isadmin.php');
diff --git a/settings/templates/users.php b/settings/templates/users.php
index aabda0fac2f0c80b23e6ddd472bf713493575ecd..937b40611b042a0791ee70df572cc6a261b117db 100644
--- a/settings/templates/users.php
+++ b/settings/templates/users.php
@@ -14,8 +14,6 @@ unset($items['admin']);
 $_['subadmingroups'] = array_flip($items);
 ?>
 
-<script type="text/javascript" src="<?php print_unescaped(OC_Helper::linkToRoute('isadmin'));?>"></script>
-
 <div id="controls">
 	<form id="newuser" autocomplete="off">
 		<input id="newusername" type="text" placeholder="<?php p($l->t('Login Name'))?>" /> <input
diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php
index e1b880255fb5c7b643489a5a1d677015de5aceb0..43eae78415df0c921bea7a6a5d3ccb4ec13a2a21 100644
--- a/tests/lib/files/storage/wrapper/quota.php
+++ b/tests/lib/files/storage/wrapper/quota.php
@@ -62,7 +62,7 @@ class Quota extends \Test\Files\Storage\Storage {
 		$this->assertEquals('foobarqwe', $instance->file_get_contents('foo'));
 	}
 
-	public function testReturnFalseWhenFopenFailed(){
+	public function testReturnFalseWhenFopenFailed() {
 		$failStorage = $this->getMock(
 			'\OC\Files\Storage\Local',
 			array('fopen'),
@@ -76,7 +76,7 @@ class Quota extends \Test\Files\Storage\Storage {
 		$this->assertFalse($instance->fopen('failedfopen', 'r'));
 	}
 
-	public function testReturnRegularStreamOnRead(){
+	public function testReturnRegularStreamOnRead() {
 		$instance = $this->getLimitedStorage(9);
 
 		// create test file first
@@ -95,11 +95,30 @@ class Quota extends \Test\Files\Storage\Storage {
 		fclose($stream);
 	}
 
-	public function testReturnQuotaStreamOnWrite(){
+	public function testReturnQuotaStreamOnWrite() {
 		$instance = $this->getLimitedStorage(9);
 		$stream = $instance->fopen('foo', 'w+');
 		$meta = stream_get_meta_data($stream);
 		$this->assertEquals('user-space', $meta['wrapper_type']);
 		fclose($stream);
 	}
+
+	public function testSpaceRoot() {
+		$storage = $this->getMockBuilder('\OC\Files\Storage\Local')->disableOriginalConstructor()->getMock();
+		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')->disableOriginalConstructor()->getMock();
+		$storage->expects($this->once())
+			->method('getCache')
+			->will($this->returnValue($cache));
+		$storage->expects($this->once())
+			->method('free_space')
+			->will($this->returnValue(2048));
+		$cache->expects($this->once())
+			->method('get')
+			->with('files')
+			->will($this->returnValue(array('size' => 50)));
+
+		$instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => 1024, 'root' => 'files'));
+
+		$this->assertEquals(1024 - 50, $instance->free_space(''));
+	}
 }