diff --git a/README.md b/README.md
index ca7b04a925a940f808ea95efdacf2b2802816333..3f76c1a4773bc3a2f37794f9422ae0476b01802e 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,9 @@
 A personal cloud which runs on your own server.
 
 ### Build Status on [Jenkins CI](https://ci.owncloud.org/)
-Git master: [![Build Status](https://ci.owncloud.org/buildStatus/icon?job=ownCloud-Server%28master%29)](https://ci.owncloud.org/job/ownCloud-Server%28master%29/)
+Git master: [![Build Status](https://ci.owncloud.org/job/server-master-linux/badge/icon)](https://ci.owncloud.org/job/server-master-linux/)
+
+Quality: [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/owncloud/core/badges/quality-score.png?s=ce2f5ded03d4ac628e9ee5c767243fa7412e644f)](https://scrutinizer-ci.com/g/owncloud/core/)
 
 ### Installation instructions
 http://doc.owncloud.org/server/5.0/developer_manual/app/gettingstarted.html
diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php
index 8f6c42d6620b49a7718c07085038b8e81cf4d69d..754c34ef088b46e70b7584fe680aa4743f63b0de 100644
--- a/apps/files/ajax/upload.php
+++ b/apps/files/ajax/upload.php
@@ -139,7 +139,8 @@ if (strpos($dir, '..') === false) {
 							'originalname' => $files['tmp_name'][$i],
 							'uploadMaxFilesize' => $maxUploadFileSize,
 							'maxHumanFilesize' => $maxHumanFileSize,
-							'permissions' => $meta['permissions'] & $allowedPermissions
+							'permissions' => $meta['permissions'] & $allowedPermissions,
+							'directory' => \OC\Files\Filesystem::normalizePath(stripslashes($dir)),
 						);
 					}
 
@@ -166,7 +167,8 @@ if (strpos($dir, '..') === false) {
 					'originalname' => $files['tmp_name'][$i],
 					'uploadMaxFilesize' => $maxUploadFileSize,
 					'maxHumanFilesize' => $maxHumanFileSize,
-					'permissions' => $meta['permissions'] & $allowedPermissions
+					'permissions' => $meta['permissions'] & $allowedPermissions,
+					'directory' => \OC\Files\Filesystem::normalizePath(stripslashes($dir)),
 				);
 			}
 		}
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 81c52e2a863d8ccb31c98ac9e9a701b12de57d9e..a855d6cbe593e55647f76c511260fdcd1a3208ec 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -40,7 +40,8 @@ window.FileList={
 		}
 		FileList.updateFileSummary();
 		procesSelection();
-		
+
+		$(window).scrollTop(0);
 		$fileList.trigger(jQuery.Event("updated"));
 	},
 	createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions) {
@@ -407,7 +408,7 @@ window.FileList={
 			}
 			return true;
 		};
-		
+
 		form.submit(function(event) {
 			event.stopPropagation();
 			event.preventDefault();
@@ -434,10 +435,9 @@ window.FileList={
 								tr.attr('data-file', newname);
 								var path = td.children('a.name').attr('href');
 								td.children('a.name').attr('href', path.replace(encodeURIComponent(oldname), encodeURIComponent(newname)));
+								var basename = newname;
 								if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') {
-									var basename=newname.substr(0,newname.lastIndexOf('.'));
-								} else {
-									var basename=newname;
+									basename = newname.substr(0,newname.lastIndexOf('.'));
 								}
 								td.find('a.name span.nametext').text(basename);
 								if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') {
@@ -481,7 +481,7 @@ window.FileList={
 				var basename = newname;
 				if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') {
 					basename = newname.substr(0, newname.lastIndexOf('.'));
-				} 
+				}
 				td.find('a.name span.nametext').text(basename);
 				if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') {
 					if ( ! td.find('a.name span.extension').exists() ) {
@@ -543,10 +543,9 @@ window.FileList={
 		td.children('a.name .span').text(newName);
 		var path = td.children('a.name').attr('href');
 		td.children('a.name').attr('href', path.replace(encodeURIComponent(oldName), encodeURIComponent(newName)));
+		var basename = newName;
 		if (newName.indexOf('.') > 0) {
-			var basename = newName.substr(0, newName.lastIndexOf('.'));
-		} else {
-			var basename = newName;
+			basename = newName.substr(0, newName.lastIndexOf('.'));
 		}
 		td.children('a.name').empty();
 		var span = $('<span class="nametext"></span>');
@@ -886,7 +885,7 @@ $(document).ready(function() {
 	 */
 	file_upload_start.on('fileuploaddone', function(e, data) {
 		OC.Upload.log('filelist handle fileuploaddone', e, data);
-		
+
 		var response;
 		if (typeof data.result === 'string') {
 			response = data.result;
@@ -923,8 +922,8 @@ $(document).ready(function() {
 				data.context.find('td.filesize').text(humanFileSize(size));
 
 			} else {
-				// only append new file if dragged onto current dir's crumb (last)
-				if (data.context && data.context.hasClass('crumb') && !data.context.hasClass('last')) {
+				// only append new file if uploaded into the current folder
+				if (file.directory !== FileList.getCurrentDirectory()) {
 					return;
 				}
 
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index a535700c1b33949beb5c5a5d20fc6a08e539a6bc..1ec4c4ec7abf5edfdc9db81ca3e298d094b9c8a1 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -405,7 +405,7 @@ $(document).ready(function() {
 	Files.resizeBreadcrumbs(width, true);
 
 	// display storage warnings
-	setTimeout ( "Files.displayStorageWarnings()", 100 );
+	setTimeout(Files.displayStorageWarnings, 100);
 	OC.Notification.setDefault(Files.displayStorageWarnings);
 
 	// only possible at the moment if user is logged in
diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
index 09d5687e2269f6d6851211c4613b4390ea3a0608..83abf3ba9de61700f3f8990d915068fd26a381e3 100644
--- a/apps/files_encryption/hooks/hooks.php
+++ b/apps/files_encryption/hooks/hooks.php
@@ -32,6 +32,8 @@ class Hooks {
 
 	// file for which we want to rename the keys after the rename operation was successful
 	private static $renamedFiles = array();
+	// file for which we want to delete the keys after the delete operation was successful
+	private static $deleteFiles = array();
 
 	/**
 	 * @brief Startup encryption backend upon user login
@@ -78,8 +80,15 @@ class Hooks {
 
 		// Check if first-run file migration has already been performed
 		$ready = false;
-		if ($util->getMigrationStatus() === Util::MIGRATION_OPEN) {
+		$migrationStatus = $util->getMigrationStatus();
+		if ($migrationStatus === Util::MIGRATION_OPEN) {
 			$ready = $util->beginMigration();
+		} elseif ($migrationStatus === Util::MIGRATION_IN_PROGRESS) {
+			// refuse login as long as the initial encryption is running
+			while ($migrationStatus === Util::MIGRATION_IN_PROGRESS) {
+				sleep(60);
+				$migrationStatus = $util->getMigrationStatus();
+			}
 		}
 
 		// If migration not yet done
@@ -630,4 +639,66 @@ class Hooks {
 		}
 	}
 
+	/**
+	 * @brief if the file was really deleted we remove the encryption keys
+	 * @param array $params
+	 * @return boolean
+	 */
+	public static function postDelete($params) {
+
+		if (!isset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]])) {
+			return true;
+		}
+
+		$deletedFile = self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]];
+		$path = $deletedFile['path'];
+		$user = $deletedFile['uid'];
+
+		// we don't need to remember the file any longer
+		unset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]]);
+
+		$view = new \OC\Files\View('/');
+
+		// return if the file still exists and wasn't deleted correctly
+		if ($view->file_exists('/' . $user . '/files/' . $path)) {
+			return true;
+		}
+
+		// Disable encryption proxy to prevent recursive calls
+		$proxyStatus = \OC_FileProxy::$enabled;
+		\OC_FileProxy::$enabled = false;
+
+		// Delete keyfile & shareKey so it isn't orphaned
+		if (!Keymanager::deleteFileKey($view, $path, $user)) {
+			\OCP\Util::writeLog('Encryption library',
+				'Keyfile or shareKey could not be deleted for file "' . $user.'/files/'.$path . '"', \OCP\Util::ERROR);
+		}
+
+		Keymanager::delAllShareKeys($view, $user, $path);
+
+		\OC_FileProxy::$enabled = $proxyStatus;
+	}
+
+	/**
+	 * @brief remember the file which should be deleted and it's owner
+	 * @param array $params
+	 * @return boolean
+	 */
+	public static function preDelete($params) {
+		$path = $params[\OC\Files\Filesystem::signal_param_path];
+
+		// skip this method if the trash bin is enabled or if we delete a file
+		// outside of /data/user/files
+		if (\OCP\App::isEnabled('files_trashbin')) {
+			return true;
+		}
+
+		$util = new Util(new \OC_FilesystemView('/'), \OCP\USER::getUser());
+		list($owner, $ownerPath) = $util->getUidAndFilename($path);
+
+		self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]] = array(
+			'uid' => $owner,
+			'path' => $ownerPath);
+	}
+
 }
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index 5dcb05fa1961cb3f69406cc16fefe60657b24e37..bb06a57c7143191ee801175a13617abe5df4b8c7 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -63,6 +63,8 @@ class Helper {
 
 		\OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename');
 		\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename');
+		\OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete');
+		\OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete');
 	}
 
 	/**
diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
index b2c756894b4a99fc71cccbe9db00d82f635a29a6..7abc565f60901e59d3b5d65bc7eb608830c4fb0c 100755
--- a/apps/files_encryption/lib/keymanager.php
+++ b/apps/files_encryption/lib/keymanager.php
@@ -214,15 +214,24 @@ class Keymanager {
 	 *
 	 * @param \OC_FilesystemView $view
 	 * @param string $path path of the file the key belongs to
+	 * @param string $userId the user to whom the file belongs
 	 * @return bool Outcome of unlink operation
 	 * @note $path must be relative to data/user/files. e.g. mydoc.txt NOT
 	 *       /data/admin/files/mydoc.txt
 	 */
-	public static function deleteFileKey(\OC_FilesystemView $view, $path) {
+	public static function deleteFileKey($view, $path, $userId=null) {
 
 		$trimmed = ltrim($path, '/');
 
-		$userId = Helper::getUser($path);
+		if ($trimmed === '') {
+			\OCP\Util::writeLog('Encryption library',
+				'Can\'t delete file-key empty path given!', \OCP\Util::ERROR);
+			return false;
+		}
+
+		if ($userId === null) {
+			$userId = Helper::getUser($path);
+		}
 		$util = new Util($view, $userId);
 
 		if($util->isSystemWideMountPoint($path)) {
@@ -402,7 +411,15 @@ class Keymanager {
 	 * @param string $userId owner of the file
 	 * @param string $filePath path to the file, relative to the owners file dir
 	 */
-	public static function delAllShareKeys(\OC_FilesystemView $view, $userId, $filePath) {
+	public static function delAllShareKeys($view, $userId, $filePath) {
+
+		$filePath = ltrim($filePath, '/');
+
+		if ($filePath === '') {
+			\OCP\Util::writeLog('Encryption library',
+					'Can\'t delete share-keys empty path given!', \OCP\Util::ERROR);
+			return false;
+		}
 
 		$util = new util($view, $userId);
 
@@ -413,17 +430,15 @@ class Keymanager {
 		}
 
 
-		if ($view->is_dir($userId . '/files/' . $filePath)) {
+		if ($view->is_dir($baseDir . $filePath)) {
 			$view->unlink($baseDir . $filePath);
 		} else {
-			$localKeyPath = $view->getLocalFile($baseDir . $filePath);
-			$escapedPath = Helper::escapeGlobPattern($localKeyPath);
-			$matches = glob($escapedPath . '*.shareKey');
-			foreach ($matches as $ma) {
-				$result = unlink($ma);
-				if (!$result) {
-					\OCP\Util::writeLog('Encryption library',
-						'Keyfile or shareKey could not be deleted for file "' . $filePath . '"', \OCP\Util::ERROR);
+			$parentDir = dirname($baseDir . $filePath);
+			$filename = pathinfo($filePath, PATHINFO_BASENAME);
+			foreach($view->getDirectoryContent($parentDir) as $content) {
+				$path = $content['path'];
+				if (self::getFilenameFromShareKey($content['name'])  === $filename) {
+					$view->unlink('/' . $userId . '/' . $path);
 				}
 			}
 		}
@@ -523,4 +538,20 @@ class Keymanager {
 		return $targetPath;
 
 	}
+
+	/**
+	 * @brief extract filename from share key name
+	 * @param string $shareKey (filename.userid.sharekey)
+	 * @return mixed filename or false
+	 */
+	protected static function getFilenameFromShareKey($shareKey) {
+		$parts = explode('.', $shareKey);
+
+		$filename = false;
+		if(count($parts) > 2) {
+			$filename = implode('.', array_slice($parts, 0, count($parts)-2));
+		}
+
+		return $filename;
+	}
 }
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index 4e71ab1dd5dedee81c5ed825f495e7c090b9445e..1104800596972c49f9809890072caad5d26fad98 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -203,47 +203,6 @@ class Proxy extends \OC_FileProxy {
 
 	}
 
-	/**
-	 * @brief When a file is deleted, remove its keyfile also
-	 */
-	public function preUnlink($path) {
-
-		$relPath = Helper::stripUserFilesPath($path);
-
-		// skip this method if the trash bin is enabled or if we delete a file
-		// outside of /data/user/files
-		if (\OCP\App::isEnabled('files_trashbin') || $relPath === false) {
-			return true;
-		}
-
-		// Disable encryption proxy to prevent recursive calls
-		$proxyStatus = \OC_FileProxy::$enabled;
-		\OC_FileProxy::$enabled = false;
-
-		$view = new \OC_FilesystemView('/');
-
-		$userId = \OCP\USER::getUser();
-
-		$util = new Util($view, $userId);
-
-		list($owner, $ownerPath) = $util->getUidAndFilename($relPath);
-
-		// Delete keyfile & shareKey so it isn't orphaned
-		if (!Keymanager::deleteFileKey($view, $ownerPath)) {
-			\OCP\Util::writeLog('Encryption library',
-				'Keyfile or shareKey could not be deleted for file "' . $ownerPath . '"', \OCP\Util::ERROR);
-		}
-
-		Keymanager::delAllShareKeys($view, $owner, $ownerPath);
-
-		\OC_FileProxy::$enabled = $proxyStatus;
-
-		// If we don't return true then file delete will fail; better
-		// to leave orphaned keyfiles than to disallow file deletion
-		return true;
-
-	}
-
 	/**
 	 * @param $path
 	 * @return bool
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 8816d4d649a55ca7f834502613f3aa653a96e586..ae3e2a2e15a529d31d3a765fa96487cf30810eb0 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -57,7 +57,7 @@ class Util {
 	 * @param $userId
 	 * @param bool $client
 	 */
-	public function __construct(\OC_FilesystemView $view, $userId, $client = false) {
+	public function __construct($view, $userId, $client = false) {
 
 		$this->view = $view;
 		$this->client = $client;
diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php
new file mode 100644
index 0000000000000000000000000000000000000000..44525791743cbb3bc5475340c86cfe2e3daa5118
--- /dev/null
+++ b/apps/files_encryption/tests/hooks.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Bjoern Schiessle
+ * @copyright 2014 Bjoern Schiessle <schiessle@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/>.
+ *
+ */
+
+require_once __DIR__ . '/../../../lib/base.php';
+require_once __DIR__ . '/../lib/crypt.php';
+require_once __DIR__ . '/../lib/keymanager.php';
+require_once __DIR__ . '/../lib/stream.php';
+require_once __DIR__ . '/../lib/util.php';
+require_once __DIR__ . '/../appinfo/app.php';
+require_once __DIR__ . '/util.php';
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Hooks
+ * @brief this class provide basic hook app tests
+ */
+class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase {
+
+	const TEST_ENCRYPTION_HOOKS_USER1 = "test-encryption-hooks-user1";
+	const TEST_ENCRYPTION_HOOKS_USER2 = "test-encryption-hooks-user2";
+
+	/**
+	 * @var \OC_FilesystemView
+	 */
+	public $user1View;     // view on /data/user1/files
+	public $user2View;     // view on /data/user2/files
+	public $rootView; // view on /data/user
+	public $data;
+	public $filename;
+
+	public static function setUpBeforeClass() {
+		// reset backend
+		\OC_User::clearBackends();
+		\OC_User::useBackend('database');
+
+		\OC_Hook::clear('OC_Filesystem');
+		\OC_Hook::clear('OC_User');
+
+		// clear share hooks
+		\OC_Hook::clear('OCP\\Share');
+		\OC::registerShareHooks();
+		\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
+
+		// Filesystem related hooks
+		\OCA\Encryption\Helper::registerFilesystemHooks();
+
+		// Sharing related hooks
+		\OCA\Encryption\Helper::registerShareHooks();
+
+		// clear and register proxies
+		\OC_FileProxy::clearProxies();
+		\OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+		// create test user
+		\Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1, true);
+		\Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2, true);
+	}
+
+	function setUp() {
+		// set user id
+		\Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1);
+		\OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1);
+
+		// init filesystem view
+		$this->user1View = new \OC_FilesystemView('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '/files');
+		$this->user2View = new \OC_FilesystemView('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '/files');
+		$this->rootView = new \OC_FilesystemView('/');
+
+		// init short data
+		$this->data = 'hats';
+		$this->filename = 'enc_hooks_tests-' . uniqid() . '.txt';
+
+	}
+
+	public static function tearDownAfterClass() {
+		// cleanup test user
+		\OC_User::deleteUser(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1);
+		\OC_User::deleteUser(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2);
+	}
+
+	function testDeleteHooks() {
+
+		// remember files_trashbin state
+		$stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+		// we want to tests with app files_trashbin disabled
+		\OC_App::disable('files_trashbin');
+
+		// make sure that the trash bin is disabled
+		$this->assertFalse(\OC_APP::isEnabled('files_trashbin'));
+
+		$this->user1View->file_put_contents($this->filename, $this->data);
+
+		// check if all keys are generated
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+
+		\Test_Encryption_Util::logoutHelper();
+		\Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2);
+		\OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2);
+
+
+		$this->user2View->file_put_contents($this->filename, $this->data);
+
+		// check if all keys are generated
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey'));
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+
+		// create a dummy file that we can delete something outside of data/user/files
+		// in this case no share or file keys should be deleted
+		$this->rootView->file_put_contents(self::TEST_ENCRYPTION_HOOKS_USER2 . "/" . $this->filename, $this->data);
+
+		// delete dummy file outside of data/user/files
+		$this->rootView->unlink(self::TEST_ENCRYPTION_HOOKS_USER2 . "/" . $this->filename);
+
+		// all keys should still exist
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey'));
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+
+		// delete the file in data/user/files
+		// now the correspondig share and file keys from user2 should be deleted
+		$this->user2View->unlink($this->filename);
+
+		// check if keys from user2 are really deleted
+		$this->assertFalse($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey'));
+		$this->assertFalse($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+		// but user1 keys should still exist
+		$this->assertTrue($this->rootView->file_exists(
+				self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+				. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+		$this->assertTrue($this->rootView->file_exists(
+				self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+		if ($stateFilesTrashbin) {
+			OC_App::enable('files_trashbin');
+		}
+		else {
+			OC_App::disable('files_trashbin');
+		}
+	}
+
+	function testDeleteHooksForSharedFiles() {
+
+		\Test_Encryption_Util::logoutHelper();
+		\Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1);
+		\OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1);
+
+		// remember files_trashbin state
+		$stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+		// we want to tests with app files_trashbin disabled
+		\OC_App::disable('files_trashbin');
+
+		// make sure that the trash bin is disabled
+		$this->assertFalse(\OC_APP::isEnabled('files_trashbin'));
+
+		$this->user1View->file_put_contents($this->filename, $this->data);
+
+		// check if all keys are generated
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+		// get the file info from previous created file
+		$fileInfo = $this->user1View->getFileInfo($this->filename);
+
+		// check if we have a valid file info
+		$this->assertTrue(is_array($fileInfo));
+
+		// share the file with user2
+		\OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_HOOKS_USER2, OCP\PERMISSION_ALL);
+
+		// check if new share key exists
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey'));
+
+		\Test_Encryption_Util::logoutHelper();
+		\Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2);
+		\OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2);
+
+		// user2 has a local file with the same name
+		$this->user2View->file_put_contents($this->filename, $this->data);
+
+		// check if all keys are generated
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey'));
+		$this->assertTrue($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+		// delete the Shared file from user1 in data/user2/files/Shared
+		$this->user2View->unlink('/Shared/' . $this->filename);
+
+		// now keys from user1s home should be gone
+		$this->assertFalse($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+			. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+		$this->assertFalse($this->rootView->file_exists(
+				self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+				. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey'));
+		$this->assertFalse($this->rootView->file_exists(
+			self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+		// but user2 keys should still exist
+		$this->assertTrue($this->rootView->file_exists(
+				self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/'
+				. $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey'));
+		$this->assertTrue($this->rootView->file_exists(
+				self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key'));
+
+		// cleanup
+
+		$this->user2View->unlink($this->filename);
+
+		\Test_Encryption_Util::logoutHelper();
+		\Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1);
+		\OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1);
+
+		// unshare the file
+		\OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_HOOKS_USER2);
+
+		$this->user1View->unlink($this->filename);
+
+		if ($stateFilesTrashbin) {
+			OC_App::enable('files_trashbin');
+		}
+		else {
+			OC_App::disable('files_trashbin');
+		}
+	}
+
+}
diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php
index 58a57ee5af4a86e0c94a0428ae4627bae53b7ea7..6f32c50743ce8b86fb135357a909ae2f54df6a5f 100644
--- a/apps/files_encryption/tests/keymanager.php
+++ b/apps/files_encryption/tests/keymanager.php
@@ -136,6 +136,17 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
 		$this->assertArrayHasKey('key', $sslInfo);
 	}
 
+	/**
+	 * @small
+	 */
+	function testGetFilenameFromShareKey() {
+		$this->assertEquals("file",
+				\TestProtectedKeymanagerMethods::testGetFilenameFromShareKey("file.user.shareKey"));
+		$this->assertEquals("file.name.with.dots",
+				\TestProtectedKeymanagerMethods::testGetFilenameFromShareKey("file.name.with.dots.user.shareKey"));
+		$this->assertFalse(\TestProtectedKeymanagerMethods::testGetFilenameFromShareKey("file.txt"));
+	}
+
 	/**
 	 * @medium
 	 */
@@ -234,3 +245,12 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
 		\OC_FileProxy::$enabled = $proxyStatus;
 	}
 }
+
+/**
+ * dummy class to access protected methods of \OCA\Encryption\Keymanager for testing
+ */
+class TestProtectedKeymanagerMethods extends \OCA\Encryption\Keymanager {
+	public static function testGetFilenameFromShareKey($sharekey) {
+		return self::getFilenameFromShareKey($sharekey);
+	}
+}
\ No newline at end of file
diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php
index c3006274d6de2dbc6f5fb8f3c1832f222e7b83ea..51cc0b795e38bdd3d7c9aede64417d3b3ede5d87 100644
--- a/apps/files_encryption/tests/proxy.php
+++ b/apps/files_encryption/tests/proxy.php
@@ -112,54 +112,4 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase {
 
 	}
 
-	function testPreUnlinkWithoutTrash() {
-
-		// remember files_trashbin state
-		$stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
-
-		// we want to tests with app files_trashbin enabled
-		\OC_App::disable('files_trashbin');
-
-		$this->view->file_put_contents($this->filename, $this->data);
-
-		// create a dummy file that we can delete something outside of data/user/files
-		$this->rootView->file_put_contents("dummy.txt", $this->data);
-
-		// check if all keys are generated
-		$this->assertTrue($this->rootView->file_exists(
-			'/files_encryption/share-keys/'
-			. $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey'));
-		$this->assertTrue($this->rootView->file_exists(
-			'/files_encryption/keyfiles/' . $this->filename . '.key'));
-
-
-		// delete dummy file outside of data/user/files
-		$this->rootView->unlink("dummy.txt");
-
-		// all keys should still exist
-		$this->assertTrue($this->rootView->file_exists(
-			'/files_encryption/share-keys/'
-			. $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey'));
-		$this->assertTrue($this->rootView->file_exists(
-			'/files_encryption/keyfiles/' . $this->filename . '.key'));
-
-
-		// delete the file in data/user/files
-		$this->view->unlink($this->filename);
-
-		// now also the keys should be gone
-		$this->assertFalse($this->rootView->file_exists(
-			'/files_encryption/share-keys/'
-			. $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey'));
-		$this->assertFalse($this->rootView->file_exists(
-			'/files_encryption/keyfiles/' . $this->filename . '.key'));
-
-		if ($stateFilesTrashbin) {
-			OC_App::enable('files_trashbin');
-		}
-		else {
-			OC_App::disable('files_trashbin');
-		}
-	}
-
 }
diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php
index e55427620a6e55ca7cef0d4baa8a4e3f8eb9e39f..acf408a07f07c20c9900f8eb6bbda727653df5ec 100755
--- a/apps/files_encryption/tests/share.php
+++ b/apps/files_encryption/tests/share.php
@@ -194,8 +194,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 				. $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
 
 			// cleanup
-			$this->view->unlink(
-				'/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+			$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/');
+			$this->view->unlink($this->filename);
+			$this->view->chroot('/');
 
 			// check if share key not exists
 			$this->assertFalse($this->view->file_exists(
@@ -265,8 +266,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 				. $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
 
 			// cleanup
-			$this->view->unlink(
-				'/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+			$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/');
+			$this->view->unlink($this->filename);
+			$this->view->chroot('/');
 
 			// check if share key not exists
 			$this->assertFalse($this->view->file_exists(
@@ -352,7 +354,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 				. $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
 
 			// cleanup
-			$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1);
+			$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files');
+			$this->view->unlink($this->folder1);
+			$this->view->chroot('/');
 
 			// check if share key not exists
 			$this->assertFalse($this->view->file_exists(
@@ -482,9 +486,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 				. $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
 
 			// cleanup
-			$this->view->unlink(
-				'/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1 . $this->subfolder
-				. $this->subsubfolder . '/' . $this->filename);
+			$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files');
+			$this->view->unlink($this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename);
+			$this->view->chroot('/');
 
 			// check if share key not exists
 			$this->assertFalse($this->view->file_exists(
@@ -559,7 +563,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 			. $this->filename . '.' . $publicShareKeyId . '.shareKey'));
 
 		// cleanup
-		$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+		$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/');
+		$this->view->unlink($this->filename);
+		$this->view->chroot('/');
 
 		// check if share key not exists
 		$this->assertFalse($this->view->file_exists(
@@ -636,7 +642,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 			. $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey'));
 
 		// cleanup
-		$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+		$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/');
+		$this->view->unlink($this->filename);
+		$this->view->chroot('/');
 
 		// check if share key not exists
 		$this->assertFalse($this->view->file_exists(
@@ -731,8 +739,10 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 			. $this->filename . '.' . $recoveryKeyId . '.shareKey'));
 
 		// cleanup
-		$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
-		$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->folder1);
+		$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/');
+		$this->view->unlink($this->filename);
+		$this->view->unlink($this->folder1);
+		$this->view->chroot('/');
 
 		// check if share key for recovery not exists
 		$this->assertFalse($this->view->file_exists(
@@ -828,8 +838,10 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 		$this->assertEquals($this->dataShort, $retrievedCryptedFile2);
 
 		// cleanup
-		$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1);
-		$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename);
+		$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/');
+		$this->view->unlink($this->folder1);
+		$this->view->unlink($this->filename);
+		$this->view->chroot('/');
 
 		// check if share key for user and recovery exists
 		$this->assertFalse($this->view->file_exists(
@@ -930,7 +942,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
 			. $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
 
 		// cleanup
-		$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+		$this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/');
+		$this->view->unlink($this->filename);
+		$this->view->chroot('/');
 	}
 
 }
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php
index 425d51113b16aef4c93f81df51852719013ea557..1b102f9e5f8e74ef6058cdc9bb792361e7809a8c 100644
--- a/apps/files_sharing/lib/cache.php
+++ b/apps/files_sharing/lib/cache.php
@@ -92,12 +92,11 @@ class Shared_Cache extends Cache {
 		} else {
 			$query = \OC_DB::prepare(
 				'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`,'
-				.' `size`, `mtime`, `encrypted`'
+				.' `size`, `mtime`, `encrypted`, `unencrypted_size`'
 				.' FROM `*PREFIX*filecache` WHERE `fileid` = ?');
 			$result = $query->execute(array($file));
 			$data = $result->fetchRow();
 			$data['fileid'] = (int)$data['fileid'];
-			$data['size'] = (int)$data['size'];
 			$data['mtime'] = (int)$data['mtime'];
 			$data['storage_mtime'] = (int)$data['storage_mtime'];
 			$data['encrypted'] = (bool)$data['encrypted'];
@@ -106,6 +105,12 @@ class Shared_Cache extends Cache {
 			if ($data['storage_mtime'] === 0) {
 				$data['storage_mtime'] = $data['mtime'];
 			}
+			if ($data['encrypted'] or ($data['unencrypted_size'] > 0 and $data['mimetype'] === 'httpd/unix-directory')) {
+				$data['encrypted_size'] = (int)$data['size'];
+				$data['size'] = (int)$data['unencrypted_size'];
+			} else {
+				$data['size'] = (int)$data['size'];
+			}
 			return $data;
 		}
 		return false;
@@ -259,17 +264,38 @@ class Shared_Cache extends Cache {
 	 * @return array
 	 */
 	public function searchByMime($mimetype) {
-
-		if (strpos($mimetype, '/')) {
-			$where = '`mimetype` = ? AND ';
-		} else {
-			$where = '`mimepart` = ? AND ';
+		$mimepart = null;
+		if (strpos($mimetype, '/') === false) {
+			$mimepart = $mimetype;
+			$mimetype = null;
 		}
 
-		$value = $this->getMimetypeId($mimetype);
-
-		return $this->searchWithWhere($where, $value);
-
+		// note: searchWithWhere is currently broken as it doesn't
+		// recurse into subdirs nor returns the correct
+		// file paths, so using getFolderContents() for now
+
+		$result = array();
+		$exploreDirs = array('');
+		while (count($exploreDirs) > 0) {
+			$dir = array_pop($exploreDirs);
+			$files = $this->getFolderContents($dir);
+			// no results?
+			if (!$files) {
+				continue;
+			}
+			foreach ($files as $file) {
+				if ($file['mimetype'] === 'httpd/unix-directory') {
+					$exploreDirs[] = ltrim($dir . '/' . $file['name'], '/');
+				}
+				else if (($mimepart && $file['mimepart'] === $mimepart) || ($mimetype && $file['mimetype'] === $mimetype)) {
+					// usersPath not reliable
+					//$file['path'] = $file['usersPath'];
+					$file['path'] = ltrim($dir . '/' . $file['name'], '/');
+					$result[] = $file;
+				}
+			}
+		}
+		return $result;
 	}
 
 	/**
@@ -313,6 +339,12 @@ class Shared_Cache extends Cache {
 				}
 				$row['mimetype'] = $this->getMimetype($row['mimetype']);
 				$row['mimepart'] = $this->getMimetype($row['mimepart']);
+				if ($row['encrypted'] or ($row['unencrypted_size'] > 0 and $row['mimetype'] === 'httpd/unix-directory')) {
+					$row['encrypted_size'] = $row['size'];
+					$row['size'] = $row['unencrypted_size'];
+				} else {
+					$row['size'] = $row['size'];
+				}
 				$files[] = $row;
 			}
 		}
diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php
index c956c55a1dfea209a75a8e7fab0f54b93deee727..ec0f368386fef3560595496259982bebfa3e3316 100644
--- a/apps/files_sharing/lib/share/file.php
+++ b/apps/files_sharing/lib/share/file.php
@@ -91,10 +91,17 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
 				$file['name'] = basename($item['file_target']);
 				$file['mimetype'] = $item['mimetype'];
 				$file['mimepart'] = $item['mimepart'];
-				$file['size'] = $item['size'];
 				$file['mtime'] = $item['mtime'];
 				$file['encrypted'] = $item['encrypted'];
 				$file['etag'] = $item['etag'];
+				$storage = \OC\Files\Filesystem::getStorage('/');
+				$cache = $storage->getCache();
+				if ($item['encrypted'] or ($item['unencrypted_size'] > 0 and $cache->getMimetype($item['mimetype']) === 'httpd/unix-directory')) {
+					$file['size'] = $item['unencrypted_size'];
+					$file['encrypted_size'] = $item['size'];
+				} else {
+					$file['size'] = $item['size'];
+				}
 				$files[] = $file;
 			}
 			return $files;
diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php
index b187da41324eb31a4f715ce292dcc160fec097be..f03ac7205a35f287d53a888cecec12facd1e3a13 100644
--- a/apps/files_sharing/public.php
+++ b/apps/files_sharing/public.php
@@ -143,18 +143,13 @@ if (isset($path)) {
 		OCP\Util::addScript('files', 'jquery.iframe-transport');
 		OCP\Util::addScript('files', 'jquery.fileupload');
 		$maxUploadFilesize=OCP\Util::maxUploadFilesize($path);
-		$freeSpace=OCP\Util::freeSpace($dir);
-		$uploadLimit=OCP\Util::uploadLimit();
 		$tmpl = new OCP\Template('files_sharing', 'public', 'base');
-		$tmpl->assign('uidOwner', $shareOwner);
 		$tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner));
 		$tmpl->assign('filename', $file);
 		$tmpl->assign('directory_path', $linkItem['file_target']);
 		$tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path));
-		$tmpl->assign('fileTarget', basename($linkItem['file_target']));
 		$tmpl->assign('dirToken', $linkItem['token']);
 		$tmpl->assign('sharingToken', $token);
-		$tmpl->assign('disableSharing', true);
 		$allowPublicUploadEnabled = (bool) ($linkItem['permissions'] & OCP\PERMISSION_CREATE);
 		if (OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') {
 			$allowPublicUploadEnabled = false;
@@ -162,10 +157,6 @@ if (isset($path)) {
 		if ($linkItem['item_type'] !== 'folder') {
 			$allowPublicUploadEnabled = false;
 		}
-		$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
-		$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
-		$tmpl->assign('freeSpace', $freeSpace);
-		$tmpl->assign('uploadLimit', $uploadLimit); // PHP upload limit
 
 		$urlLinkIdentifiers= (isset($token)?'&t='.$token:'')
 							.(isset($_GET['dir'])?'&dir='.$_GET['dir']:'')
@@ -226,6 +217,9 @@ if (isset($path)) {
 			$maxUploadFilesize=OCP\Util::maxUploadFilesize($path);
 			$fileHeader = (!isset($files) or count($files) > 0);
 			$emptyContent = ($allowPublicUploadEnabled and !$fileHeader);
+
+			$freeSpace=OCP\Util::freeSpace($path);
+			$uploadLimit=OCP\Util::uploadLimit();
 			$folder = new OCP\Template('files', 'index', '');
 			$folder->assign('fileList', $list->fetchPage());
 			$folder->assign('breadcrumb', $breadcrumbNav->fetchPage());
@@ -238,6 +232,8 @@ if (isset($path)) {
 			$folder->assign('files', $files);
 			$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
 			$folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
+			$folder->assign('freeSpace', $freeSpace);
+			$folder->assign('uploadLimit', $uploadLimit); // PHP upload limit
 			$folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
 			$folder->assign('usedSpacePercent', 0);
 			$folder->assign('fileHeader', $fileHeader);
diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php
new file mode 100644
index 0000000000000000000000000000000000000000..56a51c83f6b1f1e94f519122c453164600306f3b
--- /dev/null
+++ b/apps/files_sharing/tests/cache.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Vincent Petry
+ * @copyright 2014 Vincent Petry <pvince81@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/>.
+ *
+ */
+require_once __DIR__ . '/base.php';
+
+class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base {
+
+	function setUp() {
+		parent::setUp();
+
+		self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+		// prepare user1's dir structure
+		$textData = "dummy file data\n";
+		$this->view->mkdir('container');
+		$this->view->mkdir('container/shareddir');
+		$this->view->mkdir('container/shareddir/subdir');
+		$this->view->mkdir('container/shareddir/emptydir');
+
+		$textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+		$this->view->file_put_contents('container/not shared.txt', $textData);
+		$this->view->file_put_contents('container/shared single file.txt', $textData);
+		$this->view->file_put_contents('container/shareddir/bar.txt', $textData);
+		$this->view->file_put_contents('container/shareddir/subdir/another.txt', $textData);
+		$this->view->file_put_contents('container/shareddir/subdir/another too.txt', $textData);
+		$this->view->file_put_contents('container/shareddir/subdir/not a text file.xml', '<xml></xml>');
+
+		list($this->ownerStorage, $internalPath) = $this->view->resolvePath('');
+		$this->ownerCache = $this->ownerStorage->getCache();
+		$this->ownerStorage->getScanner()->scan('');
+
+		// share "shareddir" with user2
+		$fileinfo = $this->view->getFileInfo('container/shareddir');
+		\OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+			self::TEST_FILES_SHARING_API_USER2, 31);
+
+		$fileinfo = $this->view->getFileInfo('container/shared single file.txt');
+		\OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+			self::TEST_FILES_SHARING_API_USER2, 31);
+
+		// login as user2
+		self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+		// retrieve the shared storage
+		$secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
+		list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/Shared/shareddir');
+		$this->sharedCache = $this->sharedStorage->getCache();
+	}
+
+	function tearDown() {
+		$this->sharedCache->clear();
+
+		self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+		$fileinfo = $this->view->getFileInfo('container/shareddir');
+		\OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+			self::TEST_FILES_SHARING_API_USER2);
+
+		$fileinfo = $this->view->getFileInfo('container/shared single file.txt');
+		\OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+			self::TEST_FILES_SHARING_API_USER2);
+
+		$this->view->deleteAll('container');
+
+		$this->ownerCache->clear();
+
+		parent::tearDown();
+	}
+
+	/**
+	 * Test searching by mime type
+	 */
+	function testSearchByMime() {
+		$results = $this->sharedStorage->getCache()->searchByMime('text');
+		$check = array(
+				array(
+					'name' => 'shared single file.txt',
+					'path' => 'shared single file.txt'
+				),
+				array(
+					'name' => 'bar.txt',
+					'path' => 'shareddir/bar.txt'
+				),
+				array(
+					'name' => 'another too.txt',
+					'path' => 'shareddir/subdir/another too.txt'
+				),
+				array(
+					'name' => 'another.txt',
+					'path' => 'shareddir/subdir/another.txt'
+				),
+			);
+		$this->verifyFiles($check, $results);
+
+		$results2 = $this->sharedStorage->getCache()->searchByMime('text/plain');
+
+		$this->verifyFiles($check, $results);
+	}
+
+	/**
+	 * Checks that all provided attributes exist in the files list,
+	 * only the values provided in $examples will be used to check against
+	 * the file list. The files order also needs to be the same.
+	 *
+	 * @param array $examples array of example files
+	 * @param array $files array of files
+	 */
+	private function verifyFiles($examples, $files) {
+		$this->assertEquals(count($examples), count($files));
+		foreach ($files as $i => $file) {
+			foreach ($examples[$i] as $key => $value) {
+				$this->assertEquals($value, $file[$key]);
+			}
+		}
+	}
+}
diff --git a/apps/user_ldap/appinfo/info.xml b/apps/user_ldap/appinfo/info.xml
index 148a72cecbb4449d27a248719a1f1e3d70de5609..9cc908e8522220f1c045d475e511d45fde81a51b 100644
--- a/apps/user_ldap/appinfo/info.xml
+++ b/apps/user_ldap/appinfo/info.xml
@@ -14,4 +14,7 @@
 	<types>
 		<authentication/>
 	</types>
+	<documentation>
+		<admin>http://doc.owncloud.org/server/6.0/go.php?to=admin-ldap</admin>
+	</documentation>
 </info>
diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js
index acf88ef58a4bade9e198744a8086301b8431a833..792638f2b58cab8a65c89c8afff66c988e432363 100644
--- a/apps/user_ldap/js/settings.js
+++ b/apps/user_ldap/js/settings.js
@@ -240,6 +240,7 @@ var LdapWizard = {
 					LdapWizard.hideSpinner('#ldap_base');
 					LdapWizard.showInfoBox('Please specify a Base DN');
 					LdapWizard.showInfoBox('Could not determine Base DN');
+					$('#ldap_base').prop('disabled', false);
 				}
 			);
 		}
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index 72f9c740921233e84820b3e35cce8860f7da093b..b619f62f29695151d1132c5ed10667647809cf60 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -729,7 +729,7 @@ class Access extends LDAPUtility {
 			}
 		} else {
 			if(!is_null($limit)) {
-				\OCP\Util::writeLog('user_ldap', 'Paged search failed :(', \OCP\Util::INFO);
+				\OCP\Util::writeLog('user_ldap', 'Paged search was not available', \OCP\Util::INFO);
 			}
 		}
 	}
diff --git a/apps/user_ldap/lib/ildapwrapper.php b/apps/user_ldap/lib/ildapwrapper.php
index 20587cba7dbdc5faaae067168fcfca46036e95b3..e60cf5ec63f97b3fb5913206392dc728ff71d52e 100644
--- a/apps/user_ldap/lib/ildapwrapper.php
+++ b/apps/user_ldap/lib/ildapwrapper.php
@@ -145,9 +145,11 @@ interface ILDAPWrapper {
 	 * @param $baseDN The DN of the entry to read from
 	 * @param $filter An LDAP filter
 	 * @param $attr array of the attributes to read
+	 * @param $attrsonly optional, 1 if only attribute types shall be returned
+	 * @param $limit optional, limits the result entries
 	 * @return an LDAP search result resource, false on error
 	 */
-	public function search($link, $baseDN, $filter, $attr);
+	public function search($link, $baseDN, $filter, $attr, $attrsonly = 0, $limit = 0);
 
 	/**
 	 * @brief Sets the value of the specified option to be $value
diff --git a/apps/user_ldap/lib/ldap.php b/apps/user_ldap/lib/ldap.php
index dda8533c41fc9dde4bf37c9955839a0152423e57..a99c6480121551696084d3e4a4a8af3aad689098 100644
--- a/apps/user_ldap/lib/ldap.php
+++ b/apps/user_ldap/lib/ldap.php
@@ -85,9 +85,9 @@ class LDAP implements ILDAPWrapper {
 		return $this->invokeLDAPMethod('read', $link, $baseDN, $filter, $attr);
 	}
 
-	public function search($link, $baseDN, $filter, $attr) {
-		return $this->invokeLDAPMethod('search', $link, $baseDN,
-										$filter, $attr);
+	public function search($link, $baseDN, $filter, $attr, $attrsonly = 0, $limit = 0) {
+		return $this->invokeLDAPMethod('search', $link, $baseDN, $filter,
+										$attr, $attrsonly, $limit);
 	}
 
 	public function setOption($link, $option, $value) {
diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php
index b70ede8599c5e93772279b1efb7c983427a14198..00623b74fb1d57b676601c78557823bf0159054e 100644
--- a/apps/user_ldap/lib/wizard.php
+++ b/apps/user_ldap/lib/wizard.php
@@ -567,6 +567,10 @@ class Wizard extends LDAPUtility {
 		//get a result set > 0 on a proper base
 		$rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1);
 		if(!$this->ldap->isResource($rr)) {
+			$errorNo  = $this->ldap->errno($cr);
+			$errorMsg = $this->ldap->error($cr);
+			\OCP\Util::writeLog('user_ldap', 'Wiz: Could not search base '.$base.
+							' Error '.$errorNo.': '.$errorMsg, \OCP\Util::INFO);
 			return false;
 		}
 		$entries = $this->ldap->countEntries($cr, $rr);
@@ -1010,6 +1014,7 @@ class Wizard extends LDAPUtility {
 			$this->configuration->ldapPort);
 
 		$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
+		$this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
 		$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
 		if($this->configuration->ldapTLS === 1) {
 			$this->ldap->startTls($cr);
diff --git a/autotest.sh b/autotest.sh
index 94fc692a94dafa400a0da914f62cd02a25e828a9..b88e9cf68b4c74829002e2bc54db7385b9d1c07b 100755
--- a/autotest.sh
+++ b/autotest.sh
@@ -185,19 +185,23 @@ EOF
 	cp $BASEDIR/tests/autoconfig-$1.php $BASEDIR/config/autoconfig.php
 
 	# trigger installation
-	php -f index.php
+	echo "INDEX"
+	php -f index.php | grep -i -C9999 error && echo "Error during setup" && exit 101
+	echo "END INDEX"
 
 	#test execution
 	echo "Testing with $1 ..."
 	cd tests
 	rm -rf coverage-html-$1
 	mkdir coverage-html-$1
-	php -f enable_all.php
+	php -f enable_all.php | grep -i -C9999 error && echo "Error during setup" && exit 101
 	if [ -z "$NOCOVERAGE" ]; then
 		$PHPUNIT --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml --coverage-clover autotest-clover-$1.xml --coverage-html coverage-html-$1 $2 $3
+		RESULT=$?
 	else
 		echo "No coverage"
 		$PHPUNIT --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml $2 $3
+		RESULT=$?
 	fi
 }
 
diff --git a/config/config.sample.php b/config/config.sample.php
index ef5fb7ea5a5f685fa2a60e857d9738e9c37ad848..0cd321d095d9035e8a962e7148451bbd804dc29f 100755
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -120,8 +120,14 @@ $CONFIG = array(
 /* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
 "mail_smtppassword" => "",
 
-/* memcached hostname and port (Only used when xCache, APC and APCu are absent.) */
-"memcached_server" => array('localhost', 11211),
+/* memcached servers (Only used when xCache, APC and APCu are absent.) */
+"memcached_servers" => array(
+	// hostname, port and optional weight. Also see:
+	// http://www.php.net/manual/en/memcached.addservers.php
+	// http://www.php.net/manual/en/memcached.addserver.php
+	array('localhost', 11211),
+	//array('other.host.local', 11211),
+),
 
 /* How long should ownCloud keep deleted files in the trash bin, default value:  30 days */
 'trashbin_retention_obligation' => 30,
diff --git a/core/setup/controller.php b/core/setup/controller.php
index c628bda609b6e10108fed4cd9431feeba3e74910..697408cfb576ee603f1a162a8cb24277e307e9ab 100644
--- a/core/setup/controller.php
+++ b/core/setup/controller.php
@@ -56,17 +56,18 @@ class Controller {
 	}
 
 	public function loadAutoConfig($post) {
-		$dbIsSet = isset($post['dbtype']);
-		$directoryIsSet = isset($post['directory']);
-		$adminAccountIsSet = isset($post['adminlogin']);
-
 		$autosetup_file = \OC::$SERVERROOT.'/config/autoconfig.php';
 		if( file_exists( $autosetup_file )) {
 			\OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', \OC_Log::INFO);
+			$AUTOCONFIG = array();
 			include $autosetup_file;
 			$post = array_merge ($post, $AUTOCONFIG);
 		}
 
+		$dbIsSet = isset($post['dbtype']);
+		$directoryIsSet = isset($post['directory']);
+		$adminAccountIsSet = isset($post['adminlogin']);
+
 		if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) {
 			$post['install'] = 'true';
 			if( file_exists( $autosetup_file )) {
@@ -90,7 +91,7 @@ class Controller {
 			$databases['sqlite'] = 'SQLite';
 		}
 		if ($hasMySQL) {
-			$databases['mysql'] = 'MySQL';
+			$databases['mysql'] = 'MySQL/MariaDB';
 		}
 		if ($hasPostgreSQL) {
 			$databases['pgsql'] = 'PostgreSQL';
diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php
index d7cc9ebbf4e9a5cb905bf9b8f5e25a989d9c0986..11e439032ce3df8feeff5eaa60889942e92cc9ba 100644
--- a/lib/private/files/type/detection.php
+++ b/lib/private/files/type/detection.php
@@ -72,11 +72,12 @@ class Detection {
 			and function_exists('finfo_file') and $finfo = finfo_open(FILEINFO_MIME)
 		) {
 			$info = @strtolower(finfo_file($finfo, $path));
+			finfo_close($finfo);
 			if ($info) {
 				$mimeType = substr($info, 0, strpos($info, ';'));
 				return empty($mimeType) ? 'application/octet-stream' : $mimeType;
 			}
-			finfo_close($finfo);
+
 		}
 		$isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://');
 		if (!$isWrapped and $mimeType === 'application/octet-stream' && function_exists("mime_content_type")) {
diff --git a/lib/private/image.php b/lib/private/image.php
index 7761a3c7737f3f80722c8f8cb62b0720d4b9c235..91a9f91e1d6aa1e2ecd7e1216138305e55d6d051 100644
--- a/lib/private/image.php
+++ b/lib/private/image.php
@@ -409,14 +409,14 @@ class OC_Image {
 
 	/**
 	* @brief Loads an image from a local file.
-	* @param $imageref The path to a local file.
+	* @param $imagePath The path to a local file.
 	* @returns An image resource or false on error
 	*/
 	public function loadFromFile($imagePath=false) {
 		// exif_imagetype throws "read error!" if file is less than 12 byte
 		if(!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) {
 			// Debug output disabled because this method is tried before loadFromBase64?
-			OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagePath, OC_Log::DEBUG);
+			OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: ' . (string) urlencode($imagePath), OC_Log::DEBUG);
 			return false;
 		}
 		$iType = exif_imagetype($imagePath);
diff --git a/lib/private/l10n.php b/lib/private/l10n.php
index 98665c84c55f30c28823f8d59dbf1dd8ecf9c6cb..1aa1dc5ea28d90d03eb7edd02fbf3e60c8dbac53 100644
--- a/lib/private/l10n.php
+++ b/lib/private/l10n.php
@@ -132,10 +132,10 @@ class OC_L10N implements \OCP\IL10N {
 			$i18ndir = self::findI18nDir($app);
 			// Localization is in /l10n, Texts are in $i18ndir
 			// (Just no need to define date/time format etc. twice)
-			if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/')
-				|| OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')
+			if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')
 				|| OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/')
 				|| OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings')
+				|| OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/')
 				)
 				&& file_exists($i18ndir.$lang.'.php')) {
 				// Include the file, save the data from $CONFIG
diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php
index 978e6c2eff12b398beead40859e2eb87a2367e10..075828eebad2c562257a2e1cf18284ee05a5e6c7 100644
--- a/lib/private/memcache/memcached.php
+++ b/lib/private/memcache/memcached.php
@@ -18,8 +18,16 @@ class Memcached extends Cache {
 		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);
+			$servers = \OC_Config::getValue('memcached_servers');
+			if (!$servers) {
+				$server = \OC_Config::getValue('memcached_server');
+				if ($server) {
+					$servers = array($server);
+				} else {
+					$servers = array(array('localhost', 11211));
+				}
+			}
+			self::$cache->addServers($servers);
 		}
 	}
 
diff --git a/lib/private/preview/office.php b/lib/private/preview/office.php
index 7a4826c76ecbdb535ff22bce60770aac662bef64..884b6e7dc9bac4af546bd7d7ebcfed56d577769e 100644
--- a/lib/private/preview/office.php
+++ b/lib/private/preview/office.php
@@ -6,7 +6,7 @@
  * See the COPYING-README file.
  */
 //both, libreoffice backend and php fallback, need imagick
-if (extension_loaded('imagick')) {
+if (extension_loaded('imagick') && count(\Imagick::queryFormats("PDF")) === 1) {
 	$isShellExecEnabled = \OC_Helper::is_function_enabled('shell_exec');
 
 	// LibreOffice preview is currently not supported on Windows
diff --git a/lib/private/preview/pdf.php b/lib/private/preview/pdf.php
index cc974b68818662a8ebe9e0c15c14760af9bc26fd..572b8788ac92a1a52a0633e409ace52addc1cfbf 100644
--- a/lib/private/preview/pdf.php
+++ b/lib/private/preview/pdf.php
@@ -7,7 +7,7 @@
  */
 namespace OC\Preview;
 
-if (extension_loaded('imagick')) {
+if (extension_loaded('imagick') && count(\Imagick::queryFormats("PDF")) === 1) {
 
 	class PDF extends Provider {
 
diff --git a/lib/private/preview/svg.php b/lib/private/preview/svg.php
index b49e51720fa140f304d7ddd71c38e371de2cc30c..07a37e8f8c13aded24f57d1ac746c800cd9ab777 100644
--- a/lib/private/preview/svg.php
+++ b/lib/private/preview/svg.php
@@ -7,7 +7,7 @@
  */
 namespace OC\Preview;
 
-if (extension_loaded('imagick')) {
+if (extension_loaded('imagick') && count(\Imagick::queryFormats("SVG")) === 1) {
 
 	class SVG extends Provider {
 
diff --git a/lib/private/preview/unknown.php b/lib/private/preview/unknown.php
index 4747f9e25ed0633010d08eac3ea1d4249af515a0..8145c826149211b53a8f479858d2462677987196 100644
--- a/lib/private/preview/unknown.php
+++ b/lib/private/preview/unknown.php
@@ -22,7 +22,7 @@ class Unknown extends Provider {
 
 		$svgPath = substr_replace($path, 'svg', -3);
 
-		if (extension_loaded('imagick') && file_exists($svgPath)) {
+		if (extension_loaded('imagick') && file_exists($svgPath) && count(\Imagick::queryFormats("SVG")) === 1) {
 
 			// http://www.php.net/manual/de/imagick.setresolution.php#85284
 			$svg = new \Imagick();
diff --git a/lib/private/request.php b/lib/private/request.php
index d9d5ae08e283896bcb0bad374c60a9cba90e14b5..2c5b907846ef51911f53301cf490b4b3bc6c602b 100755
--- a/lib/private/request.php
+++ b/lib/private/request.php
@@ -11,6 +11,7 @@ class OC_Request {
 	const USER_AGENT_IE = '/MSIE/';
 	// Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent
 	const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#';
+	const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#';
 
 	/**
 	 * @brief Check overwrite condition
diff --git a/lib/private/response.php b/lib/private/response.php
index 047464373472d50e0233a4e67a0036a542fb1cfe..52dbb9d90f88b1c44d1b0ee0367431186be7c2d9 100644
--- a/lib/private/response.php
+++ b/lib/private/response.php
@@ -153,7 +153,11 @@ class OC_Response {
 	 * @param string $type disposition type, either 'attachment' or 'inline'
 	 */
 	static public function setContentDispositionHeader( $filename, $type = 'attachment' ) {
-		if (OC_Request::isUserAgent(array(OC_Request::USER_AGENT_IE, OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME))) {
+		if (OC_Request::isUserAgent(array(
+				OC_Request::USER_AGENT_IE,
+				OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME,
+				OC_Request::USER_AGENT_FREEBOX
+			))) {
 			header( 'Content-Disposition: ' . rawurlencode($type) . '; filename="' . rawurlencode( $filename ) . '"' );
 		} else {
 			header( 'Content-Disposition: ' . rawurlencode($type) . '; filename*=UTF-8\'\'' . rawurlencode( $filename )
diff --git a/lib/private/setup/mysql.php b/lib/private/setup/mysql.php
index d97b6d2602fac048aa187ed9407d379b6786c612..b2c28173b1c61a57fb964ada4d28d7f15d5b77e7 100644
--- a/lib/private/setup/mysql.php
+++ b/lib/private/setup/mysql.php
@@ -3,13 +3,13 @@
 namespace OC\Setup;
 
 class MySQL extends AbstractDatabase {
-	public $dbprettyname = 'MySQL';
+	public $dbprettyname = 'MySQL/MariaDB';
 
 	public function setupDatabase($username) {
 		//check if the database user has admin right
 		$connection = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpassword);
 		if(!$connection) {
-			throw new \DatabaseSetupException($this->trans->t('MySQL username and/or password not valid'),
+			throw new \DatabaseSetupException($this->trans->t('MySQL/MariaDB username and/or password not valid'),
 				$this->trans->t('You need to enter either an existing account or the administrator.'));
 		}
 		$oldUser=\OC_Config::getValue('dbuser', false);
@@ -82,14 +82,14 @@ class MySQL extends AbstractDatabase {
 		$query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'";
 		$result = mysql_query($query, $connection);
 		if (!$result) {
-			throw new \DatabaseSetupException($this->trans->t("MySQL user '%s'@'localhost' exists already.", array($name)),
-				$this->trans->t("Drop this user from MySQL", array($name)));
+			throw new \DatabaseSetupException($this->trans->t("MySQL/MariaDB user '%s'@'localhost' exists already.", array($name)),
+				$this->trans->t("Drop this user from MySQL/MariaDB", array($name)));
 		}
 		$query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'";
 		$result = mysql_query($query, $connection);
 		if (!$result) {
-			throw new \DatabaseSetupException($this->trans->t("MySQL user '%s'@'%%' already exists", array($name)),
-				$this->trans->t("Drop this user from MySQL."));
+			throw new \DatabaseSetupException($this->trans->t("MySQL/MariaDB user '%s'@'%%' already exists", array($name)),
+				$this->trans->t("Drop this user from MySQL/MariaDB."));
 		}
 	}
 }
diff --git a/lib/public/share.php b/lib/public/share.php
index f832d04a70f6292dc28268258983b4d2d27c9777..ae7d29e8b87f7ff6027fd96dcdca946e8fcfd561 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -1152,7 +1152,7 @@ class Share {
 						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, '
 							.'`share_type`, `share_with`, `file_source`, `path`, `file_target`, '
 							.'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, '
-							.'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`';
+							.'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `unencrypted_size`, `encrypted`, `etag`, `mail_send`';
 					} else {
 						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,
 							`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,
diff --git a/settings/js/personal.js b/settings/js/personal.js
index e6e1d538a194d5fba98cc9738c8d2aa638ef9848..3b8764677561523f106d7cdbdcd85464b5928a9d 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -158,7 +158,7 @@ $(document).ready(function(){
             if(typeof timeout !== 'undefined'){
                 clearTimeout(timeout);
             }
-            timeout = setTimeout('changeDisplayName()',1000);
+            timeout = setTimeout(changeDisplayName, 1000);
         }
     });
 
@@ -173,7 +173,7 @@ $(document).ready(function(){
             if(typeof timeout !== 'undefined'){
                 clearTimeout(timeout);
             }
-            timeout = setTimeout('changeEmailAddress()',1000);
+            timeout = setTimeout(changeEmailAddress, 1000);
         }
     });
 
diff --git a/settings/templates/apps.php b/settings/templates/apps.php
index e04815f9b99d7f1ec84578fcc46ce396b729283e..4c77c62f511122709e4e3b0eb856057e5ede6815 100644
--- a/settings/templates/apps.php
+++ b/settings/templates/apps.php
@@ -9,9 +9,11 @@
 
 
 <ul id="leftcontent" class="applist">
+	<?php if(OC_Config::getValue('appstoreenabled', true) === true): ?>
 	<li>
 		<a class="app-external" target="_blank" href="http://owncloud.org/dev"><?php p($l->t('Add your App'));?> …</a>
 	</li>
+	<?php endif; ?>
 
 	<?php foreach($_['apps'] as $app):?>
 	<li <?php if($app['active']) print_unescaped('class="active"')?> data-id="<?php p($app['id']) ?>"
@@ -24,9 +26,11 @@
 	</li>
 	<?php endforeach;?>
 
+	<?php if(OC_Config::getValue('appstoreenabled', true) === true): ?>
 	<li>
 		<a class="app-external" target="_blank" href="http://apps.owncloud.com"><?php p($l->t('More Apps'));?> …</a>
 	</li>
+	<?php endif; ?>
 </ul>
 <div id="rightcontent">
 	<div class="appinfo">
diff --git a/tests/lib/request.php b/tests/lib/request.php
index c6401a571445fd8d648b79909c3eb767e728d7f9..1d77acc70ae8ca90a99f4dd9ab376864ce4b82bd 100644
--- a/tests/lib/request.php
+++ b/tests/lib/request.php
@@ -118,6 +118,21 @@ class Test_Request extends PHPUnit_Framework_TestCase {
 				),
 				true
 			),
+			array(
+				'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
+				OC_Request::USER_AGENT_FREEBOX,
+				false
+			),
+			array(
+				'Mozilla/5.0',
+				OC_Request::USER_AGENT_FREEBOX,
+				true
+			),
+			array(
+				'Fake Mozilla/5.0',
+				OC_Request::USER_AGENT_FREEBOX,
+				false
+			),
 		);
 	}
 }