diff --git a/.gitignore b/.gitignore
index e61ec6f035930b0cf4da454aab61374f46b82c1c..b24edc912828e8f0f8653c3207bca152f6c0737e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -86,6 +86,11 @@ nbproject
 # Node Modules
 /build/node_modules/
 
+# nodejs
+/build/lib/
+/npm-debug.log
+
+
 # Tests - auto-generated files
 /data-autotest
 /tests/coverage*
diff --git a/.gitmodules b/.gitmodules
index b9c1a3702cfb2f5dbc88f54aca9a46a246c97550..bc2beee81adcc479e0b251f09063dcffb08f8d81 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
 [submodule "3rdparty"]
 	path = 3rdparty
-	url = git://github.com/owncloud/3rdparty.git
+	url = https://github.com/owncloud/3rdparty.git
diff --git a/apps/files/ajax/download.php b/apps/files/ajax/download.php
index 1f7e42e0d3e3b282487bd2e811e032ef93b95788..4b4a7f8948d4d2bbd1a2a19fec65484b79fa1285 100644
--- a/apps/files/ajax/download.php
+++ b/apps/files/ajax/download.php
@@ -21,12 +21,6 @@
 *
 */
 
-// only need filesystem apps
-$RUNTIME_APPTYPES=array('filesystem');
-
-// Init owncloud
-
-
 // Check if we are a user
 OCP\User::checkLoggedIn();
 \OC::$session->close();
diff --git a/apps/files/ajax/getstoragestats.php b/apps/files/ajax/getstoragestats.php
index 17415b6933f09d4b1ef35241bada4d35db3ec946..dd8af39bada3ec55abb2c0fde56b000463823faa 100644
--- a/apps/files/ajax/getstoragestats.php
+++ b/apps/files/ajax/getstoragestats.php
@@ -1,8 +1,5 @@
 <?php
 
-// only need filesystem apps
-$RUNTIME_APPTYPES = array('filesystem');
-
 $dir = '/';
 
 if (isset($_GET['dir'])) {
diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php
index 667209599a012a45a9c72c2a352ae42a40fa3d0f..3bb35579d5fd177f5e5e86818428347735af823a 100644
--- a/apps/files/ajax/list.php
+++ b/apps/files/ajax/list.php
@@ -1,11 +1,5 @@
 <?php
 
-// only need filesystem apps
-$RUNTIME_APPTYPES=array('filesystem');
-
-// Init owncloud
-
-
 OCP\JSON::checkLoggedIn();
 \OC::$session->close();
 
diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php
index 6c2569e2ebbc903d86d196ce55561724e3ea407a..f18bbffb74af980339038515439244d787ec0634 100644
--- a/apps/files/ajax/rawlist.php
+++ b/apps/files/ajax/rawlist.php
@@ -1,8 +1,5 @@
 <?php
 
-// only need filesystem apps
-$RUNTIME_APPTYPES = array('filesystem');
-
 OCP\JSON::checkLoggedIn();
 \OC::$session->close();
 
diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php
index 826f72fb0e61f3b75fd73973823e659bb22fd661..a8acfdb6e6e3c52ced7bf1c8603d97844c8905eb 100644
--- a/apps/files/appinfo/remote.php
+++ b/apps/files/appinfo/remote.php
@@ -22,12 +22,6 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-// load needed apps
-$RUNTIME_APPTYPES = array('filesystem', 'authentication', 'logging');
-
-OC_App::loadApps($RUNTIME_APPTYPES);
-
-OC_Util::obEnd();
 
 // Backends
 $authBackend = new OC_Connector_Sabre_Auth();
diff --git a/apps/files/command/scan.php b/apps/files/command/scan.php
index f334f29a939e3002600212d079b22b45c6087c5f..25ab70af3629a7d50940c589f1b6cd41c52dd62b 100644
--- a/apps/files/command/scan.php
+++ b/apps/files/command/scan.php
@@ -58,7 +58,6 @@ class Scan extends Command {
 
 	protected function execute(InputInterface $input, OutputInterface $output) {
 		if ($input->getOption('all')) {
-			\OC_App::loadApps('authentication');
 			$users = $this->userManager->search('');
 		} else {
 			$users = $input->getArgument('user_id');
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index af863aca33ebe14aac52dbfaa0ddb100c2334222..1bac5d2b7db26bdb2857d5d7c794debed1a67489 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -77,10 +77,10 @@
 }
 /* make sure there's enough room for the file actions */
 #body-user #filestable {
-	min-width: 750px;
+	min-width: 688px; /* 768 (mobile break) - 80 (nav width) */
 }
 #body-user #controls {
-	min-width: 600px;
+	min-width: 688px; /* 768 (mobile break) - 80 (nav width) */
 }
 
 #filestable tbody tr { background-color:#fff; height:40px; }
diff --git a/apps/files/css/mobile.css b/apps/files/css/mobile.css
new file mode 100644
index 0000000000000000000000000000000000000000..3ad7d63483869f99358a24f0c84afd611bb54354
--- /dev/null
+++ b/apps/files/css/mobile.css
@@ -0,0 +1,68 @@
+@media only screen and (max-width: 768px) {
+
+/* don’t require a minimum width for files table */
+#body-user #filestable {
+	min-width: initial !important;
+}
+
+/* do not show Deleted Files on mobile, not optimized yet and button too long */
+#controls #trash {
+	display: none;
+}
+
+/* hide size and date columns */
+table th#headerSize,
+table td.filesize,
+table th#headerDate,
+table td.date {
+	display: none;
+}
+
+/* remove shift for multiselect bar to account for missing navigation */
+table.multiselect thead {
+	padding-left: 0;
+}
+
+/* restrict length of displayed filename to prevent overflow */
+table td.filename .nametext {
+	max-width: 75% !important;
+}
+
+/* always show actions on mobile, not only on hover */
+#fileList a.action {
+	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)" !important;
+	filter: alpha(opacity=20) !important;
+	opacity: .2 !important;
+	display: inline !important;
+}
+/* do not show Rename or Versions on mobile */
+#fileList .action.action-rename,
+#fileList .action.action-versions {
+	display: none !important;
+}
+/* some padding for better clickability */
+#fileList a.action img {
+	padding: 0 6px 0 12px;
+}
+/* hide text of the actions on mobile */
+#fileList a.action span {
+	display: none;
+}
+
+/* ellipsis on file names */
+.nametext {
+	width: 60%;
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+
+/* proper notification area for multi line messages */
+#notification-container {
+	display: -webkit-box;
+	display: -moz-box;
+	display: -ms-flexbox;
+	display: -webkit-flex;
+	display: flex;
+}
+}
diff --git a/apps/files/index.php b/apps/files/index.php
index c66cd40fb56150a981079c7536f413cb40617ceb..73601d26217b44fb00a4a7ef9be9a3b245bf4457 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -27,6 +27,7 @@ OCP\User::checkLoggedIn();
 // Load the files we need
 OCP\Util::addStyle('files', 'files');
 OCP\Util::addStyle('files', 'upload');
+OCP\Util::addStyle('files', 'mobile');
 OCP\Util::addscript('files', 'file-upload');
 OCP\Util::addscript('files', 'jquery.iframe-transport');
 OCP\Util::addscript('files', 'jquery.fileupload');
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 9a69d7b368869138bf05948894de9e0f28dbdad7..a7d1fa9d8a2785b266fba23be6f474c31e08c7a3 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -15,21 +15,33 @@ var FileActions = {
 	defaults: {},
 	icons: {},
 	currentFile: null,
-	register: function (mime, name, permissions, icon, action) {
+	register: function (mime, name, permissions, icon, action, displayName) {
 		if (!FileActions.actions[mime]) {
 			FileActions.actions[mime] = {};
 		}
 		if (!FileActions.actions[mime][name]) {
 			FileActions.actions[mime][name] = {};
 		}
+		if (!displayName) {
+			displayName = t('files', name);
+		}
 		FileActions.actions[mime][name]['action'] = action;
 		FileActions.actions[mime][name]['permissions'] = permissions;
+		FileActions.actions[mime][name]['displayName'] = displayName;
 		FileActions.icons[name] = icon;
 	},
 	setDefault: function (mime, name) {
 		FileActions.defaults[mime] = name;
 	},
 	get: function (mime, type, permissions) {
+		var actions = this.getActions(mime, type, permissions);
+		var filteredActions = {};
+		$.each(actions, function (name, action) {
+			filteredActions[name] = action.action;
+		});
+		return filteredActions;
+	},
+	getActions: function (mime, type, permissions) {
 		var actions = {};
 		if (FileActions.actions.all) {
 			actions = $.extend(actions, FileActions.actions.all);
@@ -51,7 +63,7 @@ var FileActions = {
 		var filteredActions = {};
 		$.each(actions, function (name, action) {
 			if (action.permissions & permissions) {
-				filteredActions[name] = action.action;
+				filteredActions[name] = action;
 			}
 		});
 		return filteredActions;
@@ -82,7 +94,7 @@ var FileActions = {
 	 */
 	display: function (parent, triggerEvent) {
 		FileActions.currentFile = parent;
-		var actions = FileActions.get(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions());
+		var actions = FileActions.getActions(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions());
 		var file = FileActions.getCurrentFile();
 		var nameLinks;
 		if (FileList.findFileEl(file).data('renaming')) {
@@ -105,15 +117,16 @@ var FileActions = {
 			event.data.actionFunc(file);
 		};
 
-		var addAction = function (name, action) {
+		var addAction = function (name, action, displayName) {
 			// NOTE: Temporary fix to prevent rename action in root of Shared directory
 			if (name === 'Rename' && $('#dir').val() === '/Shared') {
 				return true;
 			}
 
 			if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') {
+
 				var img = FileActions.icons[name],
-					actionText = t('files', name),
+					actionText = displayName,
 					actionContainer = 'a.name>span.fileactions';
 
 				if (name === 'Rename') {
@@ -125,7 +138,7 @@ var FileActions = {
 				if (img.call) {
 					img = img(file);
 				}
-				var html = '<a href="#" class="action" data-action="' + name + '">';
+				var html = '<a href="#" class="action action-' + name.toLowerCase() + '" data-action="' + name + '">';
 				if (img) {
 					html += '<img class ="svg" src="' + img + '" />';
 				}
@@ -133,8 +146,7 @@ var FileActions = {
 
 				var element = $(html);
 				element.data('action', name);
-				//alert(element);
-				element.on('click', {a: null, elem: parent, actionFunc: actions[name]}, actionHandler);
+				element.on('click', {a: null, elem: parent, actionFunc: actions[name].action}, actionHandler);
 				parent.find(actionContainer).append(element);
 			}
 
@@ -142,12 +154,15 @@ var FileActions = {
 
 		$.each(actions, function (name, action) {
 			if (name !== 'Share') {
-				addAction(name, action);
+				displayName = action.displayName;
+				ah = action.action;
+
+				addAction(name, ah, displayName);
 			}
 		});
 		if(actions.Share && !($('#dir').val() === '/' && file === 'Shared')){
-			// t('files', 'Share')
-			addAction('Share', actions.Share);
+			displayName = t('files', 'Share');
+			addAction('Share', actions.Share, displayName);
 		}
 
 		// remove the existing delete action
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 503bf6811394453e9e0291338a1da1cae7ccc4f8..cda4e823a73b9eb4acfc4610f92a5db8ed40667f 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -71,7 +71,7 @@ window.FileList={
 		});
 		// filename td
 		td = $('<td></td>').attr({
-			"class": "filename",
+			"class": "filename svg",
 			"style": 'background-image:url('+iconurl+'); background-size: 32px;'
 		});
 		var rand = Math.random().toString(16).slice(2);
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 1186a72a44f4cab38544409f4b1c9b8998954e3d..1137364db4a8c2b91a3839d9989eb7ab8cffed68 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -196,11 +196,14 @@ var Files = {
 		if (width !== Files.lastWidth) {
 			if ((width < Files.lastWidth || firstRun) && width < Files.breadcrumbsWidth) {
 				if (Files.hiddenBreadcrumbs === 0) {
-					Files.breadcrumbsWidth -= $(Files.breadcrumbs[1]).get(0).offsetWidth;
-					$(Files.breadcrumbs[1]).find('a').hide();
-					$(Files.breadcrumbs[1]).append('<span>...</span>');
-					Files.breadcrumbsWidth += $(Files.breadcrumbs[1]).get(0).offsetWidth;
-					Files.hiddenBreadcrumbs = 2;
+					bc = $(Files.breadcrumbs[1]).get(0);
+					if (typeof bc != 'undefined') {
+						Files.breadcrumbsWidth -= bc.offsetWidth;
+						$(Files.breadcrumbs[1]).find('a').hide();
+						$(Files.breadcrumbs[1]).append('<span>...</span>');
+						Files.breadcrumbsWidth += bc.offsetWidth;
+						Files.hiddenBreadcrumbs = 2;
+					}
 				}
 				var i = Files.hiddenBreadcrumbs;
 				while (width < Files.breadcrumbsWidth && i > 1 && i < Files.breadcrumbs.length - 1) {
diff --git a/apps/files/l10n/ru.php b/apps/files/l10n/ru.php
index 2c0335f3cc302ad26cd1930cf0ae5ba2c45c3b4f..ac958e5dfd39cd8a8b322f692b338f4e594d5811 100644
--- a/apps/files/l10n/ru.php
+++ b/apps/files/l10n/ru.php
@@ -3,7 +3,9 @@ $TRANSLATIONS = array(
 "Could not move %s - File with this name already exists" => "Невозможно переместить %s - файл с таким именем уже существует",
 "Could not move %s" => "Невозможно переместить %s",
 "File name cannot be empty." => "Имя файла не может быть пустым.",
+"\"%s\" is an invalid file name." => "\"%s\" это не правильное имя файла.",
 "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неправильное имя: символы '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' недопустимы.",
+"The target folder has been moved or deleted." => "Целевой каталог был перемещен или удален.",
 "The name %s is already used in the folder %s. Please choose a different name." => "Имя %s уже используется для каталога %s. Пожалуйста, выберите другое имя.",
 "Not a valid source" => "Неправильный источник",
 "Server is not allowed to open URLs, please check the server configuration" => "Сервер не позволяет открывать URL-адреса, пожалуйста, проверьте настройки сервера",
@@ -27,6 +29,8 @@ $TRANSLATIONS = array(
 "Invalid directory." => "Неверный каталог.",
 "Files" => "Файлы",
 "Unable to upload {filename} as it is a directory or has 0 bytes" => "Невозможно загрузить {filename}, так как это либо каталог, либо файл нулевого размера",
+"Total file size {size1} exceeds upload limit {size2}" => "Полный размер файла {size1} превышает лимит по загрузке {size2}",
+"Not enough free space, you are uploading {size1} but only {size2} is left" => "Не достаточно свободного места, Вы загружаете {size1} но осталось только {size2}",
 "Upload cancelled." => "Загрузка отменена.",
 "Could not get result from server." => "Не удалось получить ответ от сервера.",
 "File upload is in progress. Leaving the page now will cancel the upload." => "Идёт загрузка файла. Покинув страницу, вы прервёте загрузку.",
@@ -48,6 +52,7 @@ $TRANSLATIONS = array(
 "_%n file_::_%n files_" => array("%n файл","%n файла","%n файлов"),
 "{dirs} and {files}" => "{dirs} и {files}",
 "_Uploading %n file_::_Uploading %n files_" => array("Закачка %n файла","Закачка %n файлов","Закачка %n файлов"),
+"\"{name}\" is an invalid file name." => "\"{name}\" это не правильное имя файла.",
 "Your storage is full, files can not be updated or synced anymore!" => "Ваше хранилище заполнено, произведите очистку перед загрузкой новых файлов.",
 "Your storage is almost full ({usedSpacePercent}%)" => "Ваше хранилище почти заполнено ({usedSpacePercent}%)",
 "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Приложение для шифрования активно, но ваши ключи не инициализированы, пожалуйста, перелогиньтесь",
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php
index 5b0bad7f3418fabff253ac34a812dcc2d5eb2b43..34acd9c4f51260745a43324c6293380501c560b1 100644
--- a/apps/files/templates/index.php
+++ b/apps/files/templates/index.php
@@ -5,15 +5,15 @@
 			<div id="new" class="button">
 				<a><?php p($l->t('New'));?></a>
 				<ul>
-					<li class="icon-filetype-text"
+					<li class="icon-filetype-text svg"
 						data-type="file" data-newname="<?php p($l->t('New text file')) ?>.txt">
 						<p><?php p($l->t('Text file'));?></p>
 					</li>
-					<li class="icon-filetype-folder"
+					<li class="icon-filetype-folder svg"
 						data-type="folder" data-newname="<?php p($l->t('New folder')) ?>">
 						<p><?php p($l->t('Folder'));?></p>
 					</li>
-					<li class="icon-link" data-type="web">
+					<li class="icon-link svg" data-type="web">
 						<p><?php p($l->t('From link'));?></p>
 					</li>
 				</ul>
diff --git a/apps/files/templates/part.breadcrumb.php b/apps/files/templates/part.breadcrumb.php
index 2a0df6227679307c6840d5cb5fcf839c422c0d24..69b4cbca10d559d443091368111a746977ccbefb 100644
--- a/apps/files/templates/part.breadcrumb.php
+++ b/apps/files/templates/part.breadcrumb.php
@@ -1,4 +1,4 @@
-<div class="crumb <?php if(!count($_["breadcrumb"])) p('last');?>" data-dir=''>
+<div class="crumb svg <?php if(!count($_["breadcrumb"])) p('last');?>" data-dir=''>
 	<a href="<?php print_unescaped($_['baseURL']); ?>">
 		<?php if(isset($_['rootBreadCrumb'])):
 			echo $_['rootBreadCrumb'];
diff --git a/apps/files_encryption/l10n/ru.php b/apps/files_encryption/l10n/ru.php
index bce245ce680296ccee29f14a91401a5ec530d5e9..ba98486893200cf01f125805184b6ecf976fa17a 100644
--- a/apps/files_encryption/l10n/ru.php
+++ b/apps/files_encryption/l10n/ru.php
@@ -16,6 +16,7 @@ $TRANSLATIONS = array(
 "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Пожалуйста, убедитесь, что версия PHP 5.3.3 или новее, а также, что OpenSSL и соответствующее расширение PHP включены и правильно настроены. На данный момент приложение шифрования отключено.",
 "Following users are not set up for encryption:" => "Для следующих пользователей шифрование не настроено:",
 "Initial encryption started... This can take some time. Please wait." => "Начато начальное шифрование... Это может занять какое-то время. Пожалуйста, подождите.",
+"Initial encryption running... Please try again later." => "Работает первоначальное шифрование... Пожалуйста, повторите попытку позже.",
 "Go directly to your " => "Перейти прямо в",
 "personal settings" => "персональные настройки",
 "Encryption" => "Шифрование",
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index bae1fded53d3376b7b076ab92535548d27a7aaa1..6549273c8f1e5539554548560f5d4b3c8429654f 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -128,6 +128,8 @@ class Proxy extends \OC_FileProxy {
 
 					// re-enable proxy - our work is done
 					\OC_FileProxy::$enabled = $proxyStatus;
+				} else {
+					return false;
 				}
 			}
 		}
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index cd2a3103eb72365656fddc715ecf7edc2883e73f..00793a614c20f5e3be668404cb84b003350e9ebe 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -181,16 +181,21 @@ $(document).ready(function() {
 		$.each(configurations, function(backend, parameters) {
 			if (backend == backendClass) {
 				$.each(parameters['configuration'], function(parameter, placeholder) {
-					if (placeholder.indexOf('*') != -1) {
-						td.append('<input type="password" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
-					} else if (placeholder.indexOf('!') != -1) {
+					var is_optional = false;
+					if (placeholder.indexOf('&') === 0) {
+						is_optional = true;
+						placeholder = placeholder.substring(1);
+					}
+					if (placeholder.indexOf('*') === 0) {
+						var class_string = is_optional ? ' class="optional"' : '';
+						td.append('<input type="password"' + class_string + ' data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
+					} else if (placeholder.indexOf('!') === 0) {
 						td.append('<label><input type="checkbox" data-parameter="'+parameter+'" />'+placeholder.substring(1)+'</label>');
-					} else if (placeholder.indexOf('&') != -1) {
-						td.append('<input type="text" class="optional" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
-					} else if (placeholder.indexOf('#') != -1) {
+					} else if (placeholder.indexOf('#') === 0) {
 						td.append('<input type="hidden" data-parameter="'+parameter+'" />');
 					} else {
-						td.append('<input type="text" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
+						var class_string = is_optional ? ' class="optional"' : '';
+						td.append('<input type="text"' + class_string + ' data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
 					}
 				});
 				if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length == 1) {
diff --git a/apps/files_external/l10n/ru.php b/apps/files_external/l10n/ru.php
index 66d6f9fa6b8d44dff6bcd23be701564025b56b39..8ed437839cd4452c4f076bbd853b818984481a88 100644
--- a/apps/files_external/l10n/ru.php
+++ b/apps/files_external/l10n/ru.php
@@ -5,6 +5,7 @@ $TRANSLATIONS = array(
 "Grant access" => "Предоставление доступа",
 "Please provide a valid Dropbox app key and secret." => "Пожалуйста, предоставьте действующий ключ Dropbox и пароль.",
 "Error configuring Google Drive storage" => "Ошибка при настройке хранилища Google Drive",
+"Saved" => "Сохранено",
 "<b>Warning:</b> \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "<b>Внимание:</b> \"smbclient\" не установлен. Подключение по CIFS/SMB невозможно. Пожалуйста, обратитесь к системному администратору, чтобы установить его.",
 "<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "<b>Внимание:</b> Поддержка FTP не включена в PHP. Подключение по FTP невозможно. Пожалуйста, обратитесь к системному администратору, чтобы включить.",
 "<b>Warning:</b> The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "<b>Внимание:</b> Поддержка Curl в PHP не включена или не установлена. Подключение ownCloud / WebDAV или GoogleDrive невозможно. Попросите вашего системного администратора установить его.",
@@ -21,6 +22,7 @@ $TRANSLATIONS = array(
 "Users" => "Пользователи",
 "Delete" => "Удалить",
 "Enable User External Storage" => "Включить пользовательские внешние носители",
+"Allow users to mount the following external storage" => "Разрешить пользователям монтировать следующую внешнюю систему хранения данных",
 "SSL root certificates" => "Корневые сертификаты SSL",
 "Import Root Certificate" => "Импортировать корневые сертификаты"
 );
diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php
index a6955d400f46fc7db0ba405bee0761d98a28b495..1337d9f581d30afa9bb5844c4749bbfbae319ba2 100644
--- a/apps/files_external/lib/swift.php
+++ b/apps/files_external/lib/swift.php
@@ -374,7 +374,7 @@ class Swift extends \OC\Files\Storage\Common {
 					'X-Object-Meta-Timestamp' => $mtime
 				)
 			);
-			return $object->Update($settings);
+			return $object->UpdateMetadata($settings);
 		} else {
 			$object = $this->container->DataObject();
 			if (is_null($mtime)) {
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index 8b01b7677e5c0b78affd2f42f9d87563c30e409e..a2bdbcf4632bcd461c00560b6e19e1c195962c64 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -43,29 +43,32 @@
 					<?php if (isset($mount['options'])): ?>
 						<?php foreach ($mount['options'] as $parameter => $value): ?>
 							<?php if (isset($_['backends'][$mount['class']]['configuration'][$parameter])): ?>
-								<?php $placeholder = $_['backends'][$mount['class']]['configuration'][$parameter]; ?>
-								<?php if (strpos($placeholder, '*') !== false): ?>
+								<?php
+									$placeholder = $_['backends'][$mount['class']]['configuration'][$parameter];
+									$is_optional = FALSE;
+									if (strpos($placeholder, '&') === 0) {
+										$is_optional = TRUE;
+										$placeholder = substr($placeholder, 1);
+									}
+								?>
+								<?php if (strpos($placeholder, '*') === 0): ?>
 									<input type="password"
+										   <?php if ($is_optional): ?> class="optional"<?php endif; ?>
 										   data-parameter="<?php p($parameter); ?>"
 										   value="<?php p($value); ?>"
 										   placeholder="<?php p(substr($placeholder, 1)); ?>" />
-								<?php elseif (strpos($placeholder, '!') !== false): ?>
+								<?php elseif (strpos($placeholder, '!') === 0): ?>
 									<label><input type="checkbox"
 												  data-parameter="<?php p($parameter); ?>"
 												  <?php if ($value == 'true'): ?> checked="checked"<?php endif; ?>
 												  /><?php p(substr($placeholder, 1)); ?></label>
-								<?php elseif (strpos($placeholder, '&') !== false): ?>
-									<input type="text"
-										   class="optional"
-										   data-parameter="<?php p($parameter); ?>"
-										   value="<?php p($value); ?>"
-										   placeholder="<?php p(substr($placeholder, 1)); ?>" />
-								<?php elseif (strpos($placeholder, '#') !== false): ?>
+								<?php elseif (strpos($placeholder, '#') === 0): ?>
 									<input type="hidden"
 										   data-parameter="<?php p($parameter); ?>"
 										   value="<?php p($value); ?>" />
 								<?php else: ?>
 									<input type="text"
+										   <?php if ($is_optional): ?> class="optional"<?php endif; ?>
 										   data-parameter="<?php p($parameter); ?>"
 										   value="<?php p($value); ?>"
 										   placeholder="<?php p($placeholder); ?>" />
diff --git a/apps/files_sharing/css/mobile.css b/apps/files_sharing/css/mobile.css
index 7d2116d190dc542564310b9ef8618304b8e8f242..333c4c77fc999c6acd16723d900384a1d3d110ee 100644
--- a/apps/files_sharing/css/mobile.css
+++ b/apps/files_sharing/css/mobile.css
@@ -1,4 +1,4 @@
-@media only screen and (max-width: 600px) {
+@media only screen and (max-width: 768px) {
 
 /* make header scroll up for single shares, more view of content on small screens */
 #header.share-file {
@@ -45,5 +45,13 @@ table td.filename .nametext {
 	display: none;
 }
 
+/* ellipsis on file names */
+.nametext {
+	width: 60%;
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+
 
 }
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index e2bbb548182498f8c08b6d3c551cefb45fd3a91f..e3c5b6e4315ab9c706faa778c46fe28a13cd49bd 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -886,5 +886,5 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
 class TestShareApi extends \OCA\Files\Share\Api {
 	public function correctPathTest($path, $folder) {
 		return self::correctPath($path, $folder);
-}
+	}
 }
diff --git a/apps/files_trashbin/ajax/list.php b/apps/files_trashbin/ajax/list.php
index 124a236bcbd505ea904181e4f2ce909766bb28b2..cec18c46525dd63dd61daccf2dc7695e05bb2ea2 100644
--- a/apps/files_trashbin/ajax/list.php
+++ b/apps/files_trashbin/ajax/list.php
@@ -1,11 +1,5 @@
 <?php
 
-// only need filesystem apps
-$RUNTIME_APPTYPES=array('filesystem');
-
-// Init owncloud
-
-
 OCP\JSON::checkLoggedIn();
 
 // Load the files
diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js
index 6aade210505e78cca7d1a94cde032d628a71234b..efe1e89f0bf3fc2c67a1d5e2f643d860995996bd 100644
--- a/apps/files_trashbin/js/trash.js
+++ b/apps/files_trashbin/js/trash.js
@@ -25,6 +25,11 @@ $(document).ready(function() {
 		enableActions();
 	}
 
+	Files.updateStorageStatistics = function() {
+		// no op because the trashbin doesn't have
+		// storage info like free space / used space
+	};
+
 	if (typeof FileActions !== 'undefined') {
 		FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) {
 			var tr = FileList.findFileEl(filename);
diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js
index 4adf14745de06c54fd495e63568ebaa89e882cc7..b452bc25b13d4c3c9bf5dd6d5afcdea78d8fb96d 100644
--- a/apps/files_versions/js/versions.js
+++ b/apps/files_versions/js/versions.js
@@ -11,7 +11,7 @@ $(document).ready(function(){
 		// Add versions button to 'files/index.php'
 		FileActions.register(
 			'file'
-			, t('files_versions', 'Versions')
+			, 'Versions'
 			, OC.PERMISSION_UPDATE
 			, function() {
 				// Specify icon for hitory button
@@ -36,6 +36,7 @@ $(document).ready(function(){
 					createVersionsDropdown(filename, file);
 				}
 			}
+			, t('files_versions', 'Versions')
 		);
 	}
 
diff --git a/apps/user_ldap/l10n/sl.php b/apps/user_ldap/l10n/sl.php
index b2a21b6e0296ee9901a4c8517001db62b5e6ad4e..b6df62ffb79f3eb0cba0964e33d7dd37c8657532 100644
--- a/apps/user_ldap/l10n/sl.php
+++ b/apps/user_ldap/l10n/sl.php
@@ -85,6 +85,7 @@ $TRANSLATIONS = array(
 "One Group Base DN per line" => "Eno osnovno ime skupine na vrstico",
 "Group Search Attributes" => "Skupinski atributi iskanja",
 "Group-Member association" => "Povezava član-skupina",
+"Nested Groups" => "Gnezdene skupine",
 "Special Attributes" => "Posebni atributi",
 "Quota Field" => "Polje količinske omejitve",
 "Quota Default" => "Privzeta količinska omejitev",
diff --git a/build/package.json b/build/package.json
index c9ed7b96c6c5b6af998c1f86a8a76f9bba4ea373..0c395839cf9cd00db2a12fd1dcfe4ec75330dbac 100644
--- a/build/package.json
+++ b/build/package.json
@@ -14,7 +14,9 @@
                 "karma": "*",
                 "karma-jasmine": "*",
                 "karma-junit-reporter": "*",
-	            "karma-coverage": "*"
+	            "karma-coverage": "*",
+                "karma-phantomjs-launcher": "*",
+                "phantomjs": "*"
         },
         "engine": "node >= 0.8"
 }
diff --git a/config/config.sample.php b/config/config.sample.php
index 891c2eb5fa1fe92afe0539239abb8f964379e7ac..140b75706ea59e016281a6cbb0faccd097039f06 100755
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -276,6 +276,15 @@ $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' => '',
+/* where mount.json file should be stored, defaults to data/mount.json */
+'mount_file' => '',
+
+/*
+ * Location of the cache folder, defaults to "data/$user/cache" where "$user" is the current user.
+ *
+ * When specified, the format will change to "$cache_path/$user" where "$cache_path" is the configured
+ * cache directory and "$user" is the user.
+ *
+ */
+'cache_path' => ''
 );
diff --git a/console.php b/console.php
index 25b8b312539309e2c4ff8b4dcdb29d98602e7470..dd2c1026e477ef1d345062517204db0d712961db 100644
--- a/console.php
+++ b/console.php
@@ -8,7 +8,6 @@
 
 use Symfony\Component\Console\Application;
 
-$RUNTIME_NOAPPS = true;
 require_once 'lib/base.php';
 
 // Don't do anything if ownCloud has not been installed yet
@@ -22,6 +21,9 @@ if (!OC::$CLI) {
 	exit(0);
 }
 
+// load all apps to get all api routes properly setup
+OC_App::loadApps();
+
 $defaults = new OC_Defaults;
 $application = new Application($defaults->getName(), \OC_Util::getVersionString());
 require_once 'core/register_command.php';
diff --git a/core/ajax/share.php b/core/ajax/share.php
index 3f04e1e4ad14691830b8f6d06ef6c7191aaa36b9..e667d9b5faae6a282845ff361976d4aabd31daca 100644
--- a/core/ajax/share.php
+++ b/core/ajax/share.php
@@ -21,7 +21,6 @@
 
 OC_JSON::checkLoggedIn();
 OCP\JSON::callCheck();
-OC_App::loadApps();
 
 $defaults = new \OCP\Defaults();
 
diff --git a/core/ajax/update.php b/core/ajax/update.php
index 2a0cbb2036d6e59be5121e57abfc60942a169a6e..55e8ab15ec22800be2aee0787a990577b21e2269 100644
--- a/core/ajax/update.php
+++ b/core/ajax/update.php
@@ -1,6 +1,5 @@
 <?php
 set_time_limit(0);
-$RUNTIME_NOAPPS = true;
 require_once '../../lib/base.php';
 
 if (OC::checkUpgrade(false)) {
diff --git a/core/command/upgrade.php b/core/command/upgrade.php
index cfccfb5d2f0363928c3d5cb5242c09c6e47b9c61..ed72d136e24b3c461dd4bcbafe029d80171b0065 100644
--- a/core/command/upgrade.php
+++ b/core/command/upgrade.php
@@ -34,9 +34,6 @@ class Upgrade extends Command {
 	 * @param OutputInterface $output output interface
 	 */
 	protected function execute(InputInterface $input, OutputInterface $output) {
-		global $RUNTIME_NOAPPS;
-
-		$RUNTIME_NOAPPS = true; //no apps, yet
 
 		require_once \OC::$SERVERROOT . '/lib/base.php';
 
diff --git a/core/command/user/report.php b/core/command/user/report.php
index 70c5a8566b722bf432504fd1b4df923766d08cd5..a5159310af1b45d6f17a0b8db84b37acc2fe4877 100644
--- a/core/command/user/report.php
+++ b/core/command/user/report.php
@@ -46,7 +46,6 @@ class Report extends Command {
 	}
 
 	private function countUsers() {
-		\OC_App::loadApps(array('authentication'));
 		$userManager = \OC::$server->getUserManager();
 		return $userManager->countUsers();
 	}
@@ -56,4 +55,4 @@ class Report extends Command {
 		$userDirectories = $dataview->getDirectoryContent('/', 'httpd/unix-directory');
 		return count($userDirectories);
 	}
-}
\ No newline at end of file
+}
diff --git a/core/css/jquery.ocdialog.css b/core/css/jquery.ocdialog.css
index 236968e3245b68e3ad7ba9138ec18c51aeac5be4..a1221137bc447da3394c3140d763f3ea35574dd7 100644
--- a/core/css/jquery.ocdialog.css
+++ b/core/css/jquery.ocdialog.css
@@ -43,7 +43,7 @@
 	background-color: #000;
 	opacity: .20;filter:Alpha(Opacity=20);
 	z-index: 999;
-	position: absolute;
+	position: fixed;
 	top: 0; left: 0;
 	width: 100%; height: 100%;
 }
diff --git a/core/css/mobile.css b/core/css/mobile.css
index a63aa902d347ce73850feac1a86ac1ac4e6b9522..c67ac3e5ecf82d3a3563c9ad2e7fade5593721f2 100644
--- a/core/css/mobile.css
+++ b/core/css/mobile.css
@@ -1,4 +1,12 @@
-@media only screen and (max-width: 600px) {
+@media only screen and (max-width: 768px) {
+
+/* show caret indicator next to logo to make clear it is tappable */
+#owncloud.menutoggle {
+	background-image: url('../img/actions/caret.svg');
+	background-repeat: no-repeat;
+	background-position: right 26px;
+	padding-right: 16px !important;
+}
 
 /* compress search box on mobile, expand when focused */
 .searchbox input[type="search"] {
@@ -18,5 +26,80 @@
 	display: none;
 }
 
+/* toggle navigation */
+#content-wrapper {
+	padding-left: 0;
+}
+
+#navigation {
+	top: 45px;
+	bottom: initial;
+	width: 255px;
+	max-height: 90%;
+	margin-top: 0;
+	top: 45px;
+	background-color: rgba(36, 40, 47, .97);
+	overflow-x: initial;
+	border-bottom-right-radius: 7px;
+	border-bottom: 1px #333 solid;
+	border-right: 1px #333 solid;
+	box-shadow: 0 0 7px rgba(29,45,68,.97);
+	display: none;
+}
+#navigation, #navigation * {
+	box-sizing:border-box; -moz-box-sizing:border-box;
+}
+#navigation li {
+	display: inline-block;
+}
+#navigation a {
+	width: 80px;
+	height: 80px;
+	display: inline-block;
+	text-align: center;
+	padding: 20px 0;
+}
+#navigation a span {
+	display: inline-block;
+	font-size: 13px;
+	padding-bottom: 0;
+	padding-left: 0;
+	width: 80px;
+}
+#navigation .icon {
+	margin: 0 auto;
+	padding: 0;
+}
+#navigation li:first-child .icon {
+	padding-top: 0;
+}
+/* Apps management as sticky footer */
+#navigation .wrapper {
+	min-height: initial;
+	margin: 0;
+}
+#apps-management, #navigation .push {
+	height: initial;
+}
+
+
+
+/* shift to account for missing navigation */
+#body-user #controls,
+#body-settings #controls {
+	padding-left: 0;
+}
+
+/* don’t require a minimum width for controls bar */
+#controls {
+	min-width: initial !important;
+}
+
+/* position share dropdown */
+#dropdown {
+	margin-right: 10% !important;
+	width: 80% !important;
+}
+
 
 }
diff --git a/core/css/styles.css b/core/css/styles.css
index 4420633e34ea7111dc7cc2121b9fda9216adf407..50e0314475ff60232ece5265f69d85b79deae6b5 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -77,6 +77,7 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari
 
 #header .logo {
 	background-image: url(../img/logo.svg);
+	background-repeat: no-repeat;
 	width: 250px;
 	height: 118px;
 	margin: 0 auto;
@@ -84,6 +85,7 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari
 
 #header .logo-wide {
 	background-image: url(../img/logo-wide.svg);
+	background-repeat: no-repeat;
 	width: 147px;
 	height: 32px;
 }
@@ -246,6 +248,7 @@ input[type="submit"].enabled {
 	-webkit-box-sizing: border-box;
 	box-sizing: border-box;
 	position: fixed;
+	top:45px;
 	right: 0;
 	left: 0;
 	height: 44px;
diff --git a/core/js/js.js b/core/js/js.js
index 3d3185f12c14ce2d4545dd0a9c0da3b9a6a54e51..302b6b4d9faba8a990fdf6838304e7286a682a95 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -482,6 +482,53 @@ var OC={
 				}).show();
 			}, 'html');
 		}
+	},
+
+	// for menu toggling
+	registerMenu: function($toggle, $menuEl) {
+		$menuEl.addClass('menu');
+		$toggle.addClass('menutoggle');
+		$toggle.on('click.menu', function(event) {
+			if ($menuEl.is(OC._currentMenu)) {
+				$menuEl.hide();
+				OC._currentMenu = null;
+				OC._currentMenuToggle = null;
+				return false;
+			}
+			// another menu was open?
+			else if (OC._currentMenu) {
+				// close it
+				OC._currentMenu.hide();
+			}
+			$menuEl.show();
+			OC._currentMenu = $menuEl;
+			OC._currentMenuToggle = $toggle;
+			return false
+		});
+	},
+
+	unregisterMenu: function($toggle, $menuEl) {
+		// close menu if opened
+		if ($menuEl.is(OC._currentMenu)) {
+			$menuEl.hide();
+			OC._currentMenu = null;
+			OC._currentMenuToggle = null;
+		}
+		$toggle.off('click.menu').removeClass('menutoggle');
+		$menuEl.removeClass('menu');
+	},
+
+	/**
+	 * Wrapper for matchMedia
+	 *
+	 * This is makes it possible for unit tests to
+	 * stub matchMedia (which doesn't work in PhantomJS)
+	 */
+	_matchMedia: function(media) {
+		if (window.matchMedia) {
+			return window.matchMedia(media);
+		}
+		return false;
 	}
 };
 OC.search.customResults={};
@@ -712,11 +759,11 @@ SVGSupport.checkMimeType=function(){
 						if(value[0]==='"'){
 							value=value.substr(1,value.length-2);
 						}
-						headers[parts[0]]=value;
+						headers[parts[0].toLowerCase()]=value;
 					}
 				}
 			});
-			if(headers["Content-Type"]!=='image/svg+xml'){
+			if(headers["content-type"]!=='image/svg+xml'){
 				replaceSVG();
 				SVGSupport.checkMimeType.correct=false;
 			}
@@ -940,6 +987,67 @@ function initCore() {
 	$('a.action').tipsy({gravity:'s', fade:true, live:true});
 	$('td .modified').tipsy({gravity:'s', fade:true, live:true});
 	$('input').tipsy({gravity:'w', fade:true});
+
+	// toggle for menus
+	$(document).on('mouseup.closemenus', function(event) {
+		var $el = $(event.target);
+		if ($el.closest('.menu').length || $el.closest('.menutoggle').length) {
+			// don't close when clicking on the menu directly or a menu toggle
+			return false;
+		}
+		if (OC._currentMenu) {
+			OC._currentMenu.hide();
+		}
+		OC._currentMenu = null;
+		OC._currentMenuToggle = null;
+	});
+
+
+	/**
+	 * Set up the main menu toggle to react to media query changes.
+	 * If the screen is small enough, the main menu becomes a toggle.
+	 * If the screen is bigger, the main menu is not a toggle any more.
+	 */
+	function setupMainMenu() {
+		// toggle the navigation on mobile
+		if (!OC._matchMedia) {
+			return;
+		}
+		var mq = OC._matchMedia('(max-width: 768px)');
+		var lastMatch = mq.matches;
+		var $toggle = $('#header #owncloud');
+		var $navigation = $('#navigation');
+
+		function updateMainMenu() {
+			// mobile mode ?
+			if (lastMatch && !$toggle.hasClass('menutoggle')) {
+				// init the menu
+				OC.registerMenu($toggle, $navigation);
+				$toggle.data('oldhref', $toggle.attr('href'));
+				$toggle.attr('href', '#');
+				$navigation.hide();
+			}
+			else {
+				OC.unregisterMenu($toggle, $navigation);
+				$toggle.attr('href', $toggle.data('oldhref'));
+				$navigation.show();
+			}
+		}
+
+		updateMainMenu();
+
+		// TODO: debounce this
+		$(window).resize(function() {
+			if (lastMatch !== mq.matches) {
+				lastMatch = mq.matches;
+				updateMainMenu();
+			}
+		});
+	}
+
+	if (window.matchMedia) {
+		setupMainMenu();
+	}
 }
 
 $(document).ready(initCore);
diff --git a/core/js/share.js b/core/js/share.js
index 9ee50ff6963473b11e6d1683dd340565f76d2cfc..e769edd0a216d811f84a157bc4fc212a401bb38b 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -48,7 +48,7 @@ OC.Share={
 					var action = $(file).find('.fileactions .action[data-action="Share"]');
 					var img = action.find('img').attr('src', image);
 					action.addClass('permanent');
-					action.html(' '+t('core', 'Shared')).prepend(img);
+					action.html(' <span>'+t('core', 'Shared')+'</span>').prepend(img);
 				} else {
 					var dir = $('#dir').val();
 					if (dir.length > 1) {
@@ -63,7 +63,7 @@ OC.Share={
 									if (img.attr('src') != OC.imagePath('core', 'actions/public')) {
 										img.attr('src', image);
 										$(action).addClass('permanent');
-										$(action).html(' '+t('core', 'Shared')).prepend(img);
+										$(action).html(' <span>'+t('core', 'Shared')+'</span>').prepend(img);
 									}
 								});
 							}
@@ -103,10 +103,10 @@ OC.Share={
 				var img = action.find('img').attr('src', image);
 				if (shares) {
 					action.addClass('permanent');
-					action.html(' '+ escapeHTML(t('core', 'Shared'))).prepend(img);
+					action.html(' <span>'+ escapeHTML(t('core', 'Shared'))+'</span>').prepend(img);
 				} else {
 					action.removeClass('permanent');
-					action.html(' '+ escapeHTML(t('core', 'Share'))).prepend(img);
+					action.html(' <span>'+ escapeHTML(t('core', 'Share'))+'</span>').prepend(img);
 				}
 			}
 		}
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 069546387c71c23483c7db84ff3b1f2c41a51263..57ea5be8be051599c9b91584bbe00d4c032e367b 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -279,5 +279,109 @@ describe('Core base tests', function() {
 			expect(OC.generateUrl('apps/files/download{file}', {file: '/Welcome.txt'})).toEqual(OC.webroot + '/index.php/apps/files/download/Welcome.txt');
 		});
 	});
+	describe('Main menu mobile toggle', function() {
+		var oldMatchMedia;
+		var $toggle;
+		var $navigation;
+
+		beforeEach(function() {
+			oldMatchMedia = OC._matchMedia;
+			// a separate method was needed because window.matchMedia
+			// cannot be stubbed due to a bug in PhantomJS:
+			// https://github.com/ariya/phantomjs/issues/12069
+			OC._matchMedia = sinon.stub();
+			$('#testArea').append('<div id="header">' +
+				'<a id="owncloud" href="#"></a>' +
+				'</div>' +
+				'<div id="navigation"></div>');
+			$toggle = $('#owncloud');
+			$navigation = $('#navigation');
+		});
+
+		afterEach(function() {
+			OC._matchMedia = oldMatchMedia;
+		});
+		it('Sets up menu toggle in mobile mode', function() {
+			OC._matchMedia.returns({matches: true});
+			window.initCore();
+			expect($toggle.hasClass('menutoggle')).toEqual(true);
+			expect($navigation.hasClass('menu')).toEqual(true);
+		});
+		it('Does not set up menu toggle in desktop mode', function() {
+			OC._matchMedia.returns({matches: false});
+			window.initCore();
+			expect($toggle.hasClass('menutoggle')).toEqual(false);
+			expect($navigation.hasClass('menu')).toEqual(false);
+		});
+		it('Switches on menu toggle when mobile mode changes', function() {
+			var mq = {matches: false};
+			OC._matchMedia.returns(mq);
+			window.initCore();
+			expect($toggle.hasClass('menutoggle')).toEqual(false);
+			mq.matches = true;
+			$(window).trigger('resize');
+			expect($toggle.hasClass('menutoggle')).toEqual(true);
+		});
+		it('Switches off menu toggle when mobile mode changes', function() {
+			var mq = {matches: true};
+			OC._matchMedia.returns(mq);
+			window.initCore();
+			expect($toggle.hasClass('menutoggle')).toEqual(true);
+			mq.matches = false;
+			$(window).trigger('resize');
+			expect($toggle.hasClass('menutoggle')).toEqual(false);
+		});
+		it('Clicking menu toggle toggles navigation in mobile mode', function() {
+			OC._matchMedia.returns({matches: true});
+			window.initCore();
+			$navigation.hide(); // normally done through media query triggered CSS
+			expect($navigation.is(':visible')).toEqual(false);
+			$toggle.click();
+			expect($navigation.is(':visible')).toEqual(true);
+			$toggle.click();
+			expect($navigation.is(':visible')).toEqual(false);
+		});
+		it('Clicking menu toggle does not toggle navigation in desktop mode', function() {
+			OC._matchMedia.returns({matches: false});
+			window.initCore();
+			expect($navigation.is(':visible')).toEqual(true);
+			$toggle.click();
+			expect($navigation.is(':visible')).toEqual(true);
+		});
+		it('Switching to mobile mode hides navigation', function() {
+			var mq = {matches: false};
+			OC._matchMedia.returns(mq);
+			window.initCore();
+			expect($navigation.is(':visible')).toEqual(true);
+			mq.matches = true;
+			$(window).trigger('resize');
+			expect($navigation.is(':visible')).toEqual(false);
+		});
+		it('Switching to desktop mode shows navigation', function() {
+			var mq = {matches: true};
+			OC._matchMedia.returns(mq);
+			window.initCore();
+			expect($navigation.is(':visible')).toEqual(false);
+			mq.matches = false;
+			$(window).trigger('resize');
+			expect($navigation.is(':visible')).toEqual(true);
+		});
+		it('Switch to desktop with opened menu then back to mobile resets toggle', function() {
+			var mq = {matches: true};
+			OC._matchMedia.returns(mq);
+			window.initCore();
+			expect($navigation.is(':visible')).toEqual(false);
+			$toggle.click();
+			expect($navigation.is(':visible')).toEqual(true);
+			mq.matches = false;
+			$(window).trigger('resize');
+			expect($navigation.is(':visible')).toEqual(true);
+			mq.matches = true;
+			$(window).trigger('resize');
+			expect($navigation.is(':visible')).toEqual(false);
+			$toggle.click();
+			expect($navigation.is(':visible')).toEqual(true);
+		});
+	});
 });
 
diff --git a/core/l10n/es.php b/core/l10n/es.php
index 7f4d46aa1f1a75feaa8401dc73198f57653b043e..52f1a15089abfdf211fee27f7ff527a6d37d09cd 100644
--- a/core/l10n/es.php
+++ b/core/l10n/es.php
@@ -1,6 +1,6 @@
 <?php
 $TRANSLATIONS = array(
-"Expiration date is in the past." => "La fecha de caducidad está en el pasado.",
+"Expiration date is in the past." => "Ha pasado la fecha de caducidad",
 "Couldn't send mail to following users: %s " => "No se pudo enviar el mensaje a los siguientes usuarios: %s",
 "Turned on maintenance mode" => "Modo mantenimiento activado",
 "Turned off maintenance mode" => "Modo mantenimiento desactivado",
@@ -105,7 +105,7 @@ $TRANSLATIONS = array(
 "Edit tags" => "Editar etiquetas",
 "Error loading dialog template: {error}" => "Error cargando plantilla de diálogo: {error}",
 "No tags selected for deletion." => "No hay etiquetas seleccionadas para borrar.",
-"Please reload the page." => "Vuelva a cargar la página.",
+"Please reload the page." => "Recargue/Actualice la página",
 "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "La actualización ha fracasado. Por favor, informe de este problema a la <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">Comunidad de ownCloud</a>.",
 "The update was successful. Redirecting you to ownCloud now." => "La actualización se ha realizado con éxito. Redireccionando a ownCloud ahora.",
 "%s password reset" => "%s restablecer contraseña",
@@ -179,6 +179,6 @@ $TRANSLATIONS = array(
 "Thank you for your patience." => "Gracias por su paciencia.",
 "Updating ownCloud to version %s, this may take a while." => "Actualizando ownCloud a la versión %s, esto puede demorar un tiempo.",
 "This ownCloud instance is currently being updated, which may take a while." => "Esta versión de owncloud se está actualizando, esto puede demorar un tiempo.",
-"Please reload this page after a short time to continue using ownCloud." => "Por favor , recargue esta instancia de onwcloud tras un corto periodo de tiempo y continue usándolo."
+"Please reload this page after a short time to continue using ownCloud." => "Por favor, recargue la página tras un corto periodo de tiempo para continuar usando ownCloud"
 );
 $PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/core/l10n/ru.php b/core/l10n/ru.php
index 8d84e7d31bc33888af8ae26b1ce18321517e03c0..e2fdc36be0be768010438c8f3b3ac3b10332fe95 100644
--- a/core/l10n/ru.php
+++ b/core/l10n/ru.php
@@ -1,5 +1,6 @@
 <?php
 $TRANSLATIONS = array(
+"Expiration date is in the past." => "Дата истечения срока действия в прошлом.",
 "Couldn't send mail to following users: %s " => "Невозможно отправить письмо следующим пользователям: %s",
 "Turned on maintenance mode" => "Режим отладки включён",
 "Turned off maintenance mode" => "Режим отладки отключён",
@@ -56,6 +57,11 @@ $TRANSLATIONS = array(
 "(all selected)" => "(выбраны все)",
 "({count} selected)" => "({count} выбрано)",
 "Error loading file exists template" => "Ошибка при загрузке шаблона существующего файла",
+"Very weak password" => "Очень слабый пароль",
+"Weak password" => "Слабый пароль",
+"So-so password" => "Так себе пароль",
+"Good password" => "Хороший пароль",
+"Strong password" => "Устойчивый к взлому пароль",
 "Shared" => "Общие",
 "Share" => "Открыть доступ",
 "Error" => "Ошибка",
@@ -103,6 +109,7 @@ $TRANSLATIONS = array(
 "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "При обновлении произошла ошибка. Пожалуйста сообщите об этом в <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud сообщество</a>.",
 "The update was successful. Redirecting you to ownCloud now." => "Обновление прошло успешно. Перенаправляемся в Ваш ownCloud...",
 "%s password reset" => "%s сброс пароля",
+"A problem has occurred whilst sending the email, please contact your administrator." => "Произошла ошибка при отправке сообщения электронной почты, пожалуйста, свяжитесь с Вашим администратором.",
 "Use the following link to reset your password: {link}" => "Используйте следующую ссылку чтобы сбросить пароль: {link}",
 "The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Ссылка для сброса пароля отправлена вам ​​по электронной почте.<br>Если вы не получите письмо в пределах одной-двух минут, проверьте папку Спам. <br>Если письма там нет, обратитесь к своему администратору.",
 "Request failed!<br>Did you make sure your email/username was right?" => "Запрос не удался. Вы уверены, что email или имя пользователя указаны верно?",
@@ -115,6 +122,8 @@ $TRANSLATIONS = array(
 "To login page" => "На страницу авторизации",
 "New password" => "Новый пароль",
 "Reset password" => "Сбросить пароль",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X не поддерживается и %s не будет работать правильно на этой платформе. Используйте ее на свой страх и риск!",
+"For the best results, please consider using a GNU/Linux server instead." => "Для достижения наилучших результатов, пожалуйста, рассмотрите возможность использовать взамен GNU/Linux сервер.",
 "Personal" => "Личное",
 "Users" => "Пользователи",
 "Apps" => "Приложения",
@@ -140,6 +149,7 @@ $TRANSLATIONS = array(
 "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Ваша папка с данными и файлы возможно доступны из интернета потому что файл .htaccess не работает.",
 "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "Для информации, как правильно настроить Ваш сервер, пожалуйста загляните в <a hrev=\"%s\"target=\"blank\">документацию</a>.",
 "Create an <strong>admin account</strong>" => "Создать <strong>учётную запись администратора</strong>",
+"Storage & database" => "Система хранения данных & база данных",
 "Data folder" => "Директория с данными",
 "Configure the database" => "Настройка базы данных",
 "will be used" => "будет использовано",
@@ -162,6 +172,7 @@ $TRANSLATIONS = array(
 "remember" => "запомнить",
 "Log in" => "Войти",
 "Alternative Logins" => "Альтернативные имена пользователя",
+"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Здравствуйте,<br><br>просто даём вам знать, что %s открыл доступ к %s для вас.<br><a href=\"%s\">Посмотреть!</a><br><br>",
 "This ownCloud instance is currently in single user mode." => "Эта установка ownCloud в настоящее время в однопользовательском режиме.",
 "This means only administrators can use the instance." => "Это значит, что только администраторы могут использовать эту установку.",
 "Contact your system administrator if this message persists or appeared unexpectedly." => "Обратитесь к вашему системному администратору если это сообщение не исчезает или появляется неожиданно.",
diff --git a/core/l10n/sl.php b/core/l10n/sl.php
index 2cfdfd11899c88d5096b448a82f93f2a4bba7490..49eb4f9aa6976b83f98880855bee642d87ed8534 100644
--- a/core/l10n/sl.php
+++ b/core/l10n/sl.php
@@ -122,6 +122,8 @@ $TRANSLATIONS = array(
 "To login page" => "Na prijavno stran",
 "New password" => "Novo geslo",
 "Reset password" => "Ponastavi geslo",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Sistem Mac OS X ni podprt, zato %s ne bo deloval zanesljivo v tem okolju. Program uporabljate na lastno odgovornost! ",
+"For the best results, please consider using a GNU/Linux server instead." => "Za najbolj še rezultate je priporočljivo uporabljati strežnik GNU/Linux.",
 "Personal" => "Osebno",
 "Users" => "Uporabniki",
 "Apps" => "Programi",
diff --git a/core/l10n/tr.php b/core/l10n/tr.php
index 03544cd3c0fb63fbd532450ef1180d295731c1c7..affa1b063d0ac9ec7b3e1b98235d1da9c1d7278f 100644
--- a/core/l10n/tr.php
+++ b/core/l10n/tr.php
@@ -111,7 +111,7 @@ $TRANSLATIONS = array(
 "%s password reset" => "%s parola sıfırlama",
 "A problem has occurred whilst sending the email, please contact your administrator." => "E-posta gönderilirken bir hata oluştu. Lütfen yönetinizle iletişime geçin.",
 "Use the following link to reset your password: {link}" => "Parolanızı sıfırlamak için bu bağlantıyı kullanın: {link}",
-"The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Parolanızı değiştirme bağlantısı e-posta adresinize gönderildi.<br>Eğer makül bir süre içerisinde mesajı almadıysanız spam/junk dizinini kontrol ediniz.<br> Eğer orada da bulamazsanız sistem yöneticinize sorunuz.",
+"The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Parolanızı değiştirme bağlantısı e-posta adresinize gönderildi.<br>Eğer makül bir süre içerisinde mesajı almadıysanız spam/junk/gereksiz dizinini kontrol ediniz.<br> Eğer yine bulamazsanız sistem yöneticinize sorunuz.",
 "Request failed!<br>Did you make sure your email/username was right?" => "İstek başarısız!<br>E-posta ve/veya kullanıcı adınızın doğru olduğundan emin misiniz?",
 "You will receive a link to reset your password via Email." => "Parolanızı sıfırlamak için bir bağlantıyı e-posta olarak alacaksınız.",
 "Username" => "Kullanıcı Adı",
diff --git a/core/setup/controller.php b/core/setup/controller.php
index bb9c9101fe29a22d2a5c41bde836f7b85c474baf..1a8e9b2b764ade3b7d7a0a0cf532fe970ac5dd9d 100644
--- a/core/setup/controller.php
+++ b/core/setup/controller.php
@@ -20,7 +20,7 @@ class Controller {
 			$errors = array('errors' => $e);
 
 			if(count($e) > 0) {
-				$options = array_merge($post, $opts, $errors);
+				$options = array_merge($opts, $post, $errors);
 				$this->display($options);
 			}
 			else {
@@ -28,7 +28,8 @@ class Controller {
 			}
 		}
 		else {
-			$this->display($opts);
+			$options = array_merge($opts, $post);
+			$this->display($options);
 		}
 	}
 
@@ -41,6 +42,7 @@ class Controller {
 			'dbname' => '',
 			'dbtablespace' => '',
 			'dbhost' => '',
+			'dbtype' => '',
 		);
 		$parameters = array_merge($defaults, $post);
 
diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php
index 91157b923a5cdc57b954888bc456d834212976bc..5788d1d5bd3aa60f3432b26f75e6d150fed1fc4a 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">
-				<div class='logo'></div>
+				<div class="logo svg"></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 3d89750348073ee79458d2017436f53c258eb89c..ba5f6ef9b541ae7f9705925ac49e05b84e990969 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -15,7 +15,7 @@
 		</title>
 		<meta charset="utf-8">
 		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=1.0">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="apple-itunes-app" content="app-id=543672169">
 		<link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" />
 		<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" />
@@ -46,7 +46,7 @@
 	</div>
 	<header><div id="header">
 			<a href="<?php print_unescaped(link_to('', 'index.php')); ?>" title="" id="owncloud">
-				<div class='logo-wide'></div>
+				<div class="logo-wide svg"></div>
 			</a>
 			<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
 			<div id="settings" class="svg">
diff --git a/cron.php b/cron.php
index 05d47124da062764b0681b7c5622085df00ef3dc..8fa72a319c0122405cb40c34ae232da4c0faceed 100644
--- a/cron.php
+++ b/cron.php
@@ -48,6 +48,9 @@ try {
 
 	require_once 'lib/base.php';
 
+	// load all apps to get all api routes properly setup
+	OC_App::loadApps();
+
 	\OC::$session->close();
 
 	$logger = \OC_Log::$object;
diff --git a/index.php b/index.php
index 0a2f15f9f5e74de24e2b5da2d908b8ee62796b00..bd94d0e908d641123a814246ffa59ccbc69cffd1 100755
--- a/index.php
+++ b/index.php
@@ -21,8 +21,6 @@
 *
 */
 
-$RUNTIME_NOAPPS = true; //no apps, yet
-
 try {
 	
 	require_once 'lib/base.php';
diff --git a/l10n/cs_CZ/settings.po b/l10n/cs_CZ/settings.po
index b092cba79c61c4f6a96ea885a1b26e6ddc52c8a9..3a2d8b6029bee06681cdbdbbbbfd1a91fd1fd112 100644
--- a/l10n/cs_CZ/settings.po
+++ b/l10n/cs_CZ/settings.po
@@ -14,9 +14,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-26 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 21:10+0000\n"
+"Last-Translator: m23 <black23@gmail.com>\n"
 "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -436,18 +436,18 @@ msgstr "Cron"
 #: templates/admin.php:167
 #, php-format
 msgid "Last cron was executed at %s."
-msgstr ""
+msgstr "Poslední cron byl spuštěn v %s."
 
 #: templates/admin.php:170
 #, php-format
 msgid ""
 "Last cron was executed at %s. This is more than an hour ago, something seems"
 " wrong."
-msgstr ""
+msgstr "Poslední cron byl spuštěn v  %s. To se stalo před více než hodinu. Vypadá to, že není něco v pořádku."
 
 #: templates/admin.php:174
 msgid "Cron was not executed yet!"
-msgstr ""
+msgstr "Cron ještě nebyl spuštěn!"
 
 #: templates/admin.php:184
 msgid "Execute one task with each page loaded"
diff --git a/l10n/es/core.po b/l10n/es/core.po
index 10724eb14340f941b4d2dd14f15efdc310e9c0b3..758f1024ad2f2c7bf1c69de9ae503f9fab1651e8 100644
--- a/l10n/es/core.po
+++ b/l10n/es/core.po
@@ -21,9 +21,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-23 01:55-0400\n"
-"PO-Revision-Date: 2014-03-22 18:40+0000\n"
-"Last-Translator: Art O. Pal <artopal@fastmail.fm>\n"
+"POT-Creation-Date: 2014-03-29 01:55-0400\n"
+"PO-Revision-Date: 2014-03-28 06:06+0000\n"
+"Last-Translator: victormce <victormce@gmail.com>\n"
 "Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -31,24 +31,24 @@ msgstr ""
 "Language: es\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ajax/share.php:88
+#: ajax/share.php:87
 msgid "Expiration date is in the past."
-msgstr "La fecha de caducidad está en el pasado."
+msgstr "Ha pasado la fecha de caducidad"
 
-#: ajax/share.php:120 ajax/share.php:162
+#: ajax/share.php:119 ajax/share.php:161
 #, php-format
 msgid "Couldn't send mail to following users: %s "
 msgstr "No se pudo enviar el mensaje a los siguientes usuarios: %s"
 
-#: ajax/update.php:11
+#: ajax/update.php:10
 msgid "Turned on maintenance mode"
 msgstr "Modo mantenimiento activado"
 
-#: ajax/update.php:14
+#: ajax/update.php:13
 msgid "Turned off maintenance mode"
 msgstr "Modo mantenimiento desactivado"
 
-#: ajax/update.php:17
+#: ajax/update.php:16
 msgid "Updated database"
 msgstr "Base de datos actualizada"
 
@@ -152,59 +152,59 @@ msgstr "Diciembre"
 msgid "Settings"
 msgstr "Ajustes"
 
-#: js/js.js:496
+#: js/js.js:543
 msgid "Saving..."
 msgstr "Guardando..."
 
-#: js/js.js:995
+#: js/js.js:1103
 msgid "seconds ago"
 msgstr "segundos antes"
 
-#: js/js.js:996
+#: js/js.js:1104
 msgid "%n minute ago"
 msgid_plural "%n minutes ago"
 msgstr[0] "Hace %n minuto"
 msgstr[1] "Hace %n minutos"
 
-#: js/js.js:997
+#: js/js.js:1105
 msgid "%n hour ago"
 msgid_plural "%n hours ago"
 msgstr[0] "Hace %n hora"
 msgstr[1] "Hace %n horas"
 
-#: js/js.js:998
+#: js/js.js:1106
 msgid "today"
 msgstr "hoy"
 
-#: js/js.js:999
+#: js/js.js:1107
 msgid "yesterday"
 msgstr "ayer"
 
-#: js/js.js:1000
+#: js/js.js:1108
 msgid "%n day ago"
 msgid_plural "%n days ago"
 msgstr[0] "Hace %n día"
 msgstr[1] "Hace %n días"
 
-#: js/js.js:1001
+#: js/js.js:1109
 msgid "last month"
 msgstr "el mes pasado"
 
-#: js/js.js:1002
+#: js/js.js:1110
 msgid "%n month ago"
 msgid_plural "%n months ago"
 msgstr[0] "Hace %n mes"
 msgstr[1] "Hace %n meses"
 
-#: js/js.js:1003
+#: js/js.js:1111
 msgid "months ago"
 msgstr "meses antes"
 
-#: js/js.js:1004
+#: js/js.js:1112
 msgid "last year"
 msgstr "el año pasado"
 
-#: js/js.js:1005
+#: js/js.js:1113
 msgid "years ago"
 msgstr "años antes"
 
@@ -467,7 +467,7 @@ msgstr "No hay etiquetas seleccionadas para borrar."
 
 #: js/update.js:8
 msgid "Please reload the page."
-msgstr "Vuelva a cargar la página."
+msgstr "Recargue/Actualice la página"
 
 #: js/update.js:17
 msgid ""
@@ -547,14 +547,14 @@ msgstr "Nueva contraseña"
 msgid "Reset password"
 msgstr "Restablecer contraseña"
 
-#: setup/controller.php:138
+#: setup/controller.php:140
 #, php-format
 msgid ""
 "Mac OS X is not supported and %s will not work properly on this platform. "
 "Use it at your own risk! "
 msgstr "Mac OS X no está soportado y %s no funcionará bien en esta plataforma. ¡Úsela a su propio riesgo! "
 
-#: setup/controller.php:142
+#: setup/controller.php:144
 msgid ""
 "For the best results, please consider using a GNU/Linux server instead."
 msgstr "Para óptimos resultados, considere utilizar un servidor GNU/Linux."
@@ -812,4 +812,4 @@ msgstr "Esta versión de owncloud se está actualizando, esto puede demorar un t
 
 #: templates/update.user.php:4
 msgid "Please reload this page after a short time to continue using ownCloud."
-msgstr "Por favor , recargue esta instancia de onwcloud tras un corto periodo de tiempo y continue usándolo."
+msgstr "Por favor, recargue la página tras un corto periodo de tiempo para continuar usando ownCloud"
diff --git a/l10n/es/files_sharing.po b/l10n/es/files_sharing.po
index dd65ca15edc1307f5dd6b5781b3e9ee7a4e94699..f44f8bcb5b90dba4b4f8a157f04aba76d187e71f 100644
--- a/l10n/es/files_sharing.po
+++ b/l10n/es/files_sharing.po
@@ -11,9 +11,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-12 01:54-0400\n"
-"PO-Revision-Date: 2014-03-11 15:20+0000\n"
-"Last-Translator: Art O. Pal <artopal@fastmail.fm>\n"
+"POT-Creation-Date: 2014-03-29 01:55-0400\n"
+"PO-Revision-Date: 2014-03-28 06:16+0000\n"
+"Last-Translator: victormce <victormce@gmail.com>\n"
 "Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
diff --git a/l10n/es/files_trashbin.po b/l10n/es/files_trashbin.po
index c4e1766460885d854cc7628a87654612b8729b56..2586fb2af3d704e0a474f53af33b89fea6dffc77 100644
--- a/l10n/es/files_trashbin.po
+++ b/l10n/es/files_trashbin.po
@@ -9,9 +9,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-15 02:13-0400\n"
-"PO-Revision-Date: 2014-03-15 05:40+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-29 01:55-0400\n"
+"PO-Revision-Date: 2014-03-28 06:24+0000\n"
+"Last-Translator: victormce <victormce@gmail.com>\n"
 "Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -33,11 +33,11 @@ msgstr "No se puede restaurar %s"
 msgid "Deleted files"
 msgstr "Archivos eliminados"
 
-#: js/trash.js:16 js/trash.js:103 js/trash.js:152
+#: js/trash.js:16 js/trash.js:108 js/trash.js:157
 msgid "Error"
 msgstr "Error"
 
-#: lib/trashbin.php:853 lib/trashbin.php:855
+#: lib/trashbin.php:859 lib/trashbin.php:861
 msgid "restored"
 msgstr "recuperado"
 
diff --git a/l10n/gl/settings.po b/l10n/gl/settings.po
index 8cb40f5bbb99728491bf75ea52f8e64c33167c41..2403bc7cc3e4c60a02ec8e86e86ca030d9cc5543 100644
--- a/l10n/gl/settings.po
+++ b/l10n/gl/settings.po
@@ -9,9 +9,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-26 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-29 01:55-0400\n"
+"PO-Revision-Date: 2014-03-28 19:40+0000\n"
+"Last-Translator: mbouzada <mbouzada@gmail.com>\n"
 "Language-Team: Galician (http://www.transifex.com/projects/p/owncloud/language/gl/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -66,7 +66,7 @@ msgid "Unable to load list from App Store"
 msgstr "Non foi posíbel cargar a lista desde a App Store"
 
 #: ajax/changedisplayname.php:25 ajax/removeuser.php:15 ajax/setquota.php:17
-#: ajax/togglegroups.php:20 changepassword/controller.php:55
+#: ajax/togglegroups.php:20 changepassword/controller.php:49
 msgid "Authentication error"
 msgstr "Produciuse un erro de autenticación"
 
@@ -128,32 +128,32 @@ msgstr "Non é posíbel eliminar o usuario do grupo %s"
 msgid "Couldn't update app."
 msgstr "Non foi posíbel actualizar o aplicativo."
 
-#: changepassword/controller.php:20
+#: changepassword/controller.php:17
 msgid "Wrong password"
 msgstr "Contrasinal incorrecto"
 
-#: changepassword/controller.php:42
+#: changepassword/controller.php:36
 msgid "No user supplied"
 msgstr "Non subministrado polo usuario"
 
-#: changepassword/controller.php:74
+#: changepassword/controller.php:68
 msgid ""
 "Please provide an admin recovery password, otherwise all user data will be "
 "lost"
 msgstr "Forneza un contrasinal de recuperación do administrador de recuperación, senón perderanse todos os datos do usuario"
 
-#: changepassword/controller.php:79
+#: changepassword/controller.php:73
 msgid ""
 "Wrong admin recovery password. Please check the password and try again."
 msgstr "Contrasinal de recuperación do administrador incorrecto. Comprobe o contrasinal e tenteo de novo."
 
-#: changepassword/controller.php:87
+#: changepassword/controller.php:81
 msgid ""
 "Back-end doesn't support password change, but the users encryption key was "
 "successfully updated."
 msgstr "A infraestrutura non admite o cambio de contrasinal, mais a chave de cifrado dos usuarios foi actualizada correctamente."
 
-#: changepassword/controller.php:92 changepassword/controller.php:103
+#: changepassword/controller.php:86 changepassword/controller.php:97
 msgid "Unable to change password"
 msgstr "Non é posíbel cambiar o contrasinal"
 
@@ -286,7 +286,7 @@ msgstr "Debe fornecer un contrasinal"
 msgid "Warning: Home directory for user \"{user}\" already exists"
 msgstr "Aviso: O directorio persoal para o usuario «{user}» xa existe"
 
-#: personal.php:49 personal.php:50
+#: personal.php:48 personal.php:49
 msgid "__language_name__"
 msgstr "Galego"
 
@@ -431,18 +431,18 @@ msgstr "Cron"
 #: templates/admin.php:167
 #, php-format
 msgid "Last cron was executed at %s."
-msgstr ""
+msgstr "O último «cron» executouse ás %s."
 
 #: templates/admin.php:170
 #, php-format
 msgid ""
 "Last cron was executed at %s. This is more than an hour ago, something seems"
 " wrong."
-msgstr ""
+msgstr "O último «cron» executouse ás %s. Isto supón que pasou máis dunha hora. polo que semella que algo vai mal."
 
 #: templates/admin.php:174
 msgid "Cron was not executed yet!"
-msgstr ""
+msgstr "«Cron» aínda non foi executado!"
 
 #: templates/admin.php:184
 msgid "Execute one task with each page loaded"
diff --git a/l10n/pt_BR/settings.po b/l10n/pt_BR/settings.po
index 2de5517c11ffe145528a5f0d2f9abba5368a1a57..aed155f749131c6f38b6a7409efdd656f780183a 100644
--- a/l10n/pt_BR/settings.po
+++ b/l10n/pt_BR/settings.po
@@ -9,9 +9,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-26 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 19:31+0000\n"
+"Last-Translator: Flávio Veras <flaviove@gmail.com>\n"
 "Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/owncloud/language/pt_BR/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -431,18 +431,18 @@ msgstr "Cron"
 #: templates/admin.php:167
 #, php-format
 msgid "Last cron was executed at %s."
-msgstr ""
+msgstr "Último cron foi executado em %s."
 
 #: templates/admin.php:170
 #, php-format
 msgid ""
 "Last cron was executed at %s. This is more than an hour ago, something seems"
 " wrong."
-msgstr ""
+msgstr "Última cron foi executado em %s. Isso é, mais do que uma hora atrás, algo parece errado."
 
 #: templates/admin.php:174
 msgid "Cron was not executed yet!"
-msgstr ""
+msgstr "Cron não foi executado ainda!"
 
 #: templates/admin.php:184
 msgid "Execute one task with each page loaded"
diff --git a/l10n/ru/core.po b/l10n/ru/core.po
index 1c955e4977698dc939d3c6e463305f8a6be7e3ea..fec52335def9c2233702d5a6c0166472a2294d73 100644
--- a/l10n/ru/core.po
+++ b/l10n/ru/core.po
@@ -13,6 +13,7 @@
 # stushev, 2013
 # eurekafag <rkfg@rkfg.me>, 2013
 # sk.avenger <sk.avenger@adygnet.ru>, 2013
+# Swab <swab@i.ua>, 2014
 # Victor Bravo <>, 2013
 # vsapronov <vladimir.sapronov@gmail.com>, 2013
 # not_your_conscience <hex.void@gmail.com>, 2013
@@ -23,9 +24,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-22 01:55-0400\n"
-"PO-Revision-Date: 2014-03-22 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 14:31+0000\n"
+"Last-Translator: Swab <swab@i.ua>\n"
 "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -35,7 +36,7 @@ msgstr ""
 
 #: ajax/share.php:88
 msgid "Expiration date is in the past."
-msgstr ""
+msgstr "Дата истечения срока действия в прошлом."
 
 #: ajax/share.php:120 ajax/share.php:162
 #, php-format
@@ -281,23 +282,23 @@ msgstr "Ошибка при загрузке шаблона существующ
 
 #: js/setup.js:84
 msgid "Very weak password"
-msgstr ""
+msgstr "Очень слабый пароль"
 
 #: js/setup.js:85
 msgid "Weak password"
-msgstr ""
+msgstr "Слабый пароль"
 
 #: js/setup.js:86
 msgid "So-so password"
-msgstr ""
+msgstr "Так себе пароль"
 
 #: js/setup.js:87
 msgid "Good password"
-msgstr ""
+msgstr "Хороший пароль"
 
 #: js/setup.js:88
 msgid "Strong password"
-msgstr ""
+msgstr "Устойчивый к взлому пароль"
 
 #: js/share.js:51 js/share.js:66 js/share.js:106
 msgid "Shared"
@@ -496,7 +497,7 @@ msgstr "%s сброс пароля"
 msgid ""
 "A problem has occurred whilst sending the email, please contact your "
 "administrator."
-msgstr ""
+msgstr "Произошла ошибка при отправке сообщения электронной почты, пожалуйста, свяжитесь с Вашим администратором."
 
 #: lostpassword/templates/email.php:2
 msgid "Use the following link to reset your password: {link}"
@@ -559,12 +560,12 @@ msgstr "Сбросить пароль"
 msgid ""
 "Mac OS X is not supported and %s will not work properly on this platform. "
 "Use it at your own risk! "
-msgstr ""
+msgstr "Mac OS X не поддерживается и %s не будет работать правильно на этой платформе. Используйте ее на свой страх и риск!"
 
 #: setup/controller.php:142
 msgid ""
 "For the best results, please consider using a GNU/Linux server instead."
-msgstr ""
+msgstr "Для достижения наилучших результатов, пожалуйста, рассмотрите возможность использовать взамен GNU/Linux сервер."
 
 #: strings.php:5
 msgid "Personal"
@@ -686,7 +687,7 @@ msgstr "Создать <strong>учётную запись администра
 
 #: templates/installation.php:70
 msgid "Storage & database"
-msgstr ""
+msgstr "Система хранения данных & база данных"
 
 #: templates/installation.php:77
 msgid "Data folder"
@@ -787,7 +788,7 @@ msgstr "Альтернативные имена пользователя"
 msgid ""
 "Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> "
 "with you.<br><a href=\"%s\">View it!</a><br><br>"
-msgstr ""
+msgstr "Здравствуйте,<br><br>просто даём вам знать, что %s открыл доступ к %s для вас.<br><a href=\"%s\">Посмотреть!</a><br><br>"
 
 #: templates/singleuser.user.php:3
 msgid "This ownCloud instance is currently in single user mode."
diff --git a/l10n/ru/files.po b/l10n/ru/files.po
index 8e80384b7c89ce7e8e75b8e81dfe2f8bc38ac05c..4b5c985dfc97a347bc6ea3b0647737be5ca0b35a 100644
--- a/l10n/ru/files.po
+++ b/l10n/ru/files.po
@@ -8,6 +8,7 @@
 # jekader <jekader@gmail.com>, 2013
 # mogarych <mogarych@mail.ru>, 2014
 # eurekafag <rkfg@rkfg.me>, 2013
+# Swab <swab@i.ua>, 2014
 # Victor Bravo <>, 2013
 # vsapronov <vladimir.sapronov@gmail.com>, 2013
 # not_your_conscience <hex.void@gmail.com>, 2013
@@ -18,9 +19,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 06:01+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 14:22+0000\n"
+"Last-Translator: Swab <swab@i.ua>\n"
 "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -45,7 +46,7 @@ msgstr "Имя файла не может быть пустым."
 #: ajax/newfile.php:63
 #, php-format
 msgid "\"%s\" is an invalid file name."
-msgstr ""
+msgstr "\"%s\" это не правильное имя файла."
 
 #: ajax/newfile.php:69 ajax/newfolder.php:28 js/files.js:105
 msgid ""
@@ -56,7 +57,7 @@ msgstr "Неправильное имя: символы '\\', '/', '<', '>', ':'
 #: ajax/newfile.php:76 ajax/newfolder.php:35 ajax/upload.php:141
 #: lib/app.php:65
 msgid "The target folder has been moved or deleted."
-msgstr ""
+msgstr "Целевой каталог был перемещен или удален."
 
 #: ajax/newfile.php:88 ajax/newfolder.php:47 lib/app.php:74
 #, php-format
@@ -160,12 +161,12 @@ msgstr "Невозможно загрузить {filename}, так как это
 
 #: js/file-upload.js:258
 msgid "Total file size {size1} exceeds upload limit {size2}"
-msgstr ""
+msgstr "Полный размер файла {size1} превышает лимит по загрузке {size2}"
 
 #: js/file-upload.js:268
 msgid ""
 "Not enough free space, you are uploading {size1} but only {size2} is left"
-msgstr ""
+msgstr "Не достаточно свободного места, Вы загружаете {size1} но осталось только {size2}"
 
 #: js/file-upload.js:340
 msgid "Upload cancelled."
@@ -263,7 +264,7 @@ msgstr[2] "Закачка %n файлов"
 
 #: js/files.js:96
 msgid "\"{name}\" is an invalid file name."
-msgstr ""
+msgstr "\"{name}\" это не правильное имя файла."
 
 #: js/files.js:117
 msgid "Your storage is full, files can not be updated or synced anymore!"
diff --git a/l10n/ru/files_encryption.po b/l10n/ru/files_encryption.po
index 07f348b79def6269aba866b7ac2988f3bde0add4..d0f028c8df8e63dfc2a2accd90adc7e8500986a6 100644
--- a/l10n/ru/files_encryption.po
+++ b/l10n/ru/files_encryption.po
@@ -8,15 +8,16 @@
 # lord93 <lordakryl@gmail.com>, 2013
 # jekader <jekader@gmail.com>, 2013
 # eurekafag <rkfg@rkfg.me>, 2013
+# Swab <swab@i.ua>, 2014
 # Victor Bravo <>, 2013
 # vsapronov <vladimir.sapronov@gmail.com>, 2013
 msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-11 01:54-0400\n"
-"PO-Revision-Date: 2014-03-11 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 14:31+0000\n"
+"Last-Translator: Swab <swab@i.ua>\n"
 "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -108,7 +109,7 @@ msgstr "Начато начальное шифрование... Это може
 
 #: js/detect-migration.js:25
 msgid "Initial encryption running... Please try again later."
-msgstr ""
+msgstr "Работает первоначальное шифрование... Пожалуйста, повторите попытку позже."
 
 #: templates/invalid_private_key.php:8
 msgid "Go directly to your "
diff --git a/l10n/ru/files_external.po b/l10n/ru/files_external.po
index 6af3711cc643a10f7cb9d32d6d192f0fb9119d92..74a21556d84d73e0137ae37092924a4b5450ef3a 100644
--- a/l10n/ru/files_external.po
+++ b/l10n/ru/files_external.po
@@ -3,13 +3,14 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
+# Swab <swab@i.ua>, 2014
 msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-11 01:54-0400\n"
-"PO-Revision-Date: 2014-03-11 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 14:41+0000\n"
+"Last-Translator: Swab <swab@i.ua>\n"
 "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -39,22 +40,22 @@ msgstr "Ошибка при настройке хранилища Google Drive"
 
 #: js/settings.js:313 js/settings.js:320
 msgid "Saved"
-msgstr ""
+msgstr "Сохранено"
 
-#: lib/config.php:512
+#: lib/config.php:654
 msgid ""
 "<b>Warning:</b> \"smbclient\" is not installed. Mounting of CIFS/SMB shares "
 "is not possible. Please ask your system administrator to install it."
 msgstr "<b>Внимание:</b> \"smbclient\" не установлен. Подключение по CIFS/SMB невозможно. Пожалуйста, обратитесь к системному администратору, чтобы установить его."
 
-#: lib/config.php:516
+#: lib/config.php:658
 msgid ""
 "<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting"
 " of FTP shares is not possible. Please ask your system administrator to "
 "install it."
 msgstr "<b>Внимание:</b> Поддержка FTP не включена в PHP. Подключение по FTP невозможно. Пожалуйста, обратитесь к системному администратору, чтобы включить."
 
-#: lib/config.php:519
+#: lib/config.php:661
 msgid ""
 "<b>Warning:</b> The Curl support in PHP is not enabled or installed. "
 "Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask "
@@ -116,7 +117,7 @@ msgstr "Включить пользовательские внешние нос
 
 #: templates/settings.php:130
 msgid "Allow users to mount the following external storage"
-msgstr ""
+msgstr "Разрешить пользователям монтировать следующую внешнюю систему хранения данных"
 
 #: templates/settings.php:147
 msgid "SSL root certificates"
diff --git a/l10n/ru/settings.po b/l10n/ru/settings.po
index 5ee5f5e35c3e766624a2ba74726e482935b73a1b..5654edd1a8241e2ac2ead6ad91fc734de281c60d 100644
--- a/l10n/ru/settings.po
+++ b/l10n/ru/settings.po
@@ -22,8 +22,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-26 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 05:55+0000\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 14:41+0000\n"
 "Last-Translator: I Robot\n"
 "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n"
 "MIME-Version: 1.0\n"
@@ -39,7 +39,7 @@ msgstr ""
 
 #: admin/controller.php:73
 msgid "Saved"
-msgstr ""
+msgstr "Сохранено"
 
 #: admin/controller.php:90
 msgid "test email settings"
@@ -232,23 +232,23 @@ msgstr "Выберите картинку профиля"
 
 #: js/personal.js:277
 msgid "Very weak password"
-msgstr ""
+msgstr "Очень слабый пароль"
 
 #: js/personal.js:278
 msgid "Weak password"
-msgstr ""
+msgstr "Слабый пароль"
 
 #: js/personal.js:279
 msgid "So-so password"
-msgstr ""
+msgstr "Так себе пароль"
 
 #: js/personal.js:280
 msgid "Good password"
-msgstr ""
+msgstr "Хороший пароль"
 
 #: js/personal.js:281
 msgid "Strong password"
-msgstr ""
+msgstr "Устойчивый к взлому пароль"
 
 #: js/personal.js:316
 msgid "Decrypting files... Please wait, this can take some time."
diff --git a/l10n/sl/core.po b/l10n/sl/core.po
index ddd78cae32fcc6b679698125f4ca41bd8b3c9bd4..e3285d025c880bb5f58d61f720f244c9ff5d9b05 100644
--- a/l10n/sl/core.po
+++ b/l10n/sl/core.po
@@ -9,9 +9,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-22 01:55-0400\n"
-"PO-Revision-Date: 2014-03-22 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-30 01:55-0400\n"
+"PO-Revision-Date: 2014-03-29 20:30+0000\n"
+"Last-Translator: mateju <>\n"
 "Language-Team: Slovenian (http://www.transifex.com/projects/p/owncloud/language/sl/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -19,24 +19,24 @@ msgstr ""
 "Language: sl\n"
 "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
 
-#: ajax/share.php:88
+#: ajax/share.php:87
 msgid "Expiration date is in the past."
 msgstr "Datum preteka je v preteklosti."
 
-#: ajax/share.php:120 ajax/share.php:162
+#: ajax/share.php:119 ajax/share.php:161
 #, php-format
 msgid "Couldn't send mail to following users: %s "
 msgstr "Ni mogoče poslati sporočila za: %s"
 
-#: ajax/update.php:11
+#: ajax/update.php:10
 msgid "Turned on maintenance mode"
 msgstr "Vzdrževalni način je omogočen"
 
-#: ajax/update.php:14
+#: ajax/update.php:13
 msgid "Turned off maintenance mode"
 msgstr "Vzdrževalni način je onemogočen"
 
-#: ajax/update.php:17
+#: ajax/update.php:16
 msgid "Updated database"
 msgstr "Posodobljena podatkovna zbirka"
 
@@ -140,15 +140,15 @@ msgstr "december"
 msgid "Settings"
 msgstr "Nastavitve"
 
-#: js/js.js:496
+#: js/js.js:543
 msgid "Saving..."
 msgstr "Poteka shranjevanje ..."
 
-#: js/js.js:995
+#: js/js.js:1103
 msgid "seconds ago"
 msgstr "pred nekaj sekundami"
 
-#: js/js.js:996
+#: js/js.js:1104
 msgid "%n minute ago"
 msgid_plural "%n minutes ago"
 msgstr[0] "pred %n minuto"
@@ -156,7 +156,7 @@ msgstr[1] "pred %n minutama"
 msgstr[2] "pred %n minutami"
 msgstr[3] "pred %n minutami"
 
-#: js/js.js:997
+#: js/js.js:1105
 msgid "%n hour ago"
 msgid_plural "%n hours ago"
 msgstr[0] "pred %n uro"
@@ -164,15 +164,15 @@ msgstr[1] "pred %n urama"
 msgstr[2] "pred %n urami"
 msgstr[3] "pred %n urami"
 
-#: js/js.js:998
+#: js/js.js:1106
 msgid "today"
 msgstr "danes"
 
-#: js/js.js:999
+#: js/js.js:1107
 msgid "yesterday"
 msgstr "včeraj"
 
-#: js/js.js:1000
+#: js/js.js:1108
 msgid "%n day ago"
 msgid_plural "%n days ago"
 msgstr[0] "pred %n dnevom"
@@ -180,11 +180,11 @@ msgstr[1] "pred %n dnevoma"
 msgstr[2] "pred %n dnevi"
 msgstr[3] "pred %n dnevi"
 
-#: js/js.js:1001
+#: js/js.js:1109
 msgid "last month"
 msgstr "zadnji mesec"
 
-#: js/js.js:1002
+#: js/js.js:1110
 msgid "%n month ago"
 msgid_plural "%n months ago"
 msgstr[0] "pred %n mesecem"
@@ -192,15 +192,15 @@ msgstr[1] "pred %n mesecema"
 msgstr[2] "pred %n meseci"
 msgstr[3] "pred %n meseci"
 
-#: js/js.js:1003
+#: js/js.js:1111
 msgid "months ago"
 msgstr "mesecev nazaj"
 
-#: js/js.js:1004
+#: js/js.js:1112
 msgid "last year"
 msgstr "lansko leto"
 
-#: js/js.js:1005
+#: js/js.js:1113
 msgid "years ago"
 msgstr "let nazaj"
 
@@ -545,17 +545,17 @@ msgstr "Novo geslo"
 msgid "Reset password"
 msgstr "Ponastavi geslo"
 
-#: setup/controller.php:138
+#: setup/controller.php:140
 #, php-format
 msgid ""
 "Mac OS X is not supported and %s will not work properly on this platform. "
 "Use it at your own risk! "
-msgstr ""
+msgstr "Sistem Mac OS X ni podprt, zato %s ne bo deloval zanesljivo v tem okolju. Program uporabljate na lastno odgovornost! "
 
-#: setup/controller.php:142
+#: setup/controller.php:144
 msgid ""
 "For the best results, please consider using a GNU/Linux server instead."
-msgstr ""
+msgstr "Za najbolj še rezultate je priporočljivo uporabljati strežnik GNU/Linux."
 
 #: strings.php:5
 msgid "Personal"
diff --git a/l10n/sl/settings.po b/l10n/sl/settings.po
index 91e310d8f24f9abcfd65623cb7b9fd8933d0cdaf..dbde28d85dd9c000f420371f76cdaf8a5991ae3f 100644
--- a/l10n/sl/settings.po
+++ b/l10n/sl/settings.po
@@ -9,9 +9,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-26 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-30 01:55-0400\n"
+"PO-Revision-Date: 2014-03-29 20:50+0000\n"
+"Last-Translator: mateju <>\n"
 "Language-Team: Slovenian (http://www.transifex.com/projects/p/owncloud/language/sl/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -22,7 +22,7 @@ msgstr ""
 #: admin/controller.php:66
 #, php-format
 msgid "Invalid value supplied for %s"
-msgstr ""
+msgstr "Navedena je napačna vrednost za %s"
 
 #: admin/controller.php:73
 msgid "Saved"
@@ -66,7 +66,7 @@ msgid "Unable to load list from App Store"
 msgstr "Ni mogoče naložiti seznama iz programskega središča"
 
 #: ajax/changedisplayname.php:25 ajax/removeuser.php:15 ajax/setquota.php:17
-#: ajax/togglegroups.php:20 changepassword/controller.php:55
+#: ajax/togglegroups.php:20 changepassword/controller.php:49
 msgid "Authentication error"
 msgstr "Napaka med overjanjem"
 
@@ -128,32 +128,32 @@ msgstr "Uporabnika ni mogoče odstraniti iz skupine %s"
 msgid "Couldn't update app."
 msgstr "Programa ni mogoče posodobiti."
 
-#: changepassword/controller.php:20
+#: changepassword/controller.php:17
 msgid "Wrong password"
 msgstr "Napačno geslo"
 
-#: changepassword/controller.php:42
+#: changepassword/controller.php:36
 msgid "No user supplied"
 msgstr "Ni navedenega uporabnika"
 
-#: changepassword/controller.php:74
+#: changepassword/controller.php:68
 msgid ""
 "Please provide an admin recovery password, otherwise all user data will be "
 "lost"
 msgstr "Podati je treba skrbniško obnovitveno geslo, sicer bodo vsi uporabniški podatki izgubljeni."
 
-#: changepassword/controller.php:79
+#: changepassword/controller.php:73
 msgid ""
 "Wrong admin recovery password. Please check the password and try again."
 msgstr "Napačno navedeno skrbniško obnovitveno geslo. Preverite geslo in poskusite znova."
 
-#: changepassword/controller.php:87
+#: changepassword/controller.php:81
 msgid ""
 "Back-end doesn't support password change, but the users encryption key was "
 "successfully updated."
 msgstr "Hrbtišče programa ne podpira spreminjanja gesla, je pa uspešno posodobljeno uporabniško šifriranje."
 
-#: changepassword/controller.php:92 changepassword/controller.php:103
+#: changepassword/controller.php:86 changepassword/controller.php:97
 msgid "Unable to change password"
 msgstr "Ni mogoče spremeniti gesla"
 
@@ -286,7 +286,7 @@ msgstr "Navedeno mora biti veljavno geslo"
 msgid "Warning: Home directory for user \"{user}\" already exists"
 msgstr "Opozorilo: osebna mapa uporabnika \"{user}\" že obstaja"
 
-#: personal.php:49 personal.php:50
+#: personal.php:48 personal.php:49
 msgid "__language_name__"
 msgstr "Slovenščina"
 
diff --git a/l10n/sl/user_ldap.po b/l10n/sl/user_ldap.po
index 5a24ba9ffa7072d057e8ea5a4f71eba845c92cfb..222415e4d01680a720b6e65ca4ed6c98512a1f21 100644
--- a/l10n/sl/user_ldap.po
+++ b/l10n/sl/user_ldap.po
@@ -4,14 +4,14 @@
 # 
 # Translators:
 # barbarak <barbarak@arnes.si>, 2013
-# mateju <>, 2013
+# mateju <>, 2013-2014
 msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 06:01+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-30 01:55-0400\n"
+"PO-Revision-Date: 2014-03-29 20:50+0000\n"
+"Last-Translator: mateju <>\n"
 "Language-Team: Slovenian (http://www.transifex.com/projects/p/owncloud/language/sl/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -417,7 +417,7 @@ msgstr "Povezava član-skupina"
 
 #: templates/settings.php:39
 msgid "Nested Groups"
-msgstr ""
+msgstr "Gnezdene skupine"
 
 #: templates/settings.php:39
 msgid ""
diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot
index 8f14123eedf85b0e8343724304eb20cc54dc4bb9..eacfde04d8dd886e55482580190572a1100f6abe 100644
--- a/l10n/templates/core.pot
+++ b/l10n/templates/core.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,24 +18,24 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
-#: ajax/share.php:88
+#: ajax/share.php:87
 msgid "Expiration date is in the past."
 msgstr ""
 
-#: ajax/share.php:120 ajax/share.php:162
+#: ajax/share.php:119 ajax/share.php:161
 #, php-format
 msgid "Couldn't send mail to following users: %s "
 msgstr ""
 
-#: ajax/update.php:11
+#: ajax/update.php:10
 msgid "Turned on maintenance mode"
 msgstr ""
 
-#: ajax/update.php:14
+#: ajax/update.php:13
 msgid "Turned off maintenance mode"
 msgstr ""
 
-#: ajax/update.php:17
+#: ajax/update.php:16
 msgid "Updated database"
 msgstr ""
 
@@ -139,59 +139,59 @@ msgstr ""
 msgid "Settings"
 msgstr ""
 
-#: js/js.js:496
+#: js/js.js:543
 msgid "Saving..."
 msgstr ""
 
-#: js/js.js:995
+#: js/js.js:1103
 msgid "seconds ago"
 msgstr ""
 
-#: js/js.js:996
+#: js/js.js:1104
 msgid "%n minute ago"
 msgid_plural "%n minutes ago"
 msgstr[0] ""
 msgstr[1] ""
 
-#: js/js.js:997
+#: js/js.js:1105
 msgid "%n hour ago"
 msgid_plural "%n hours ago"
 msgstr[0] ""
 msgstr[1] ""
 
-#: js/js.js:998
+#: js/js.js:1106
 msgid "today"
 msgstr ""
 
-#: js/js.js:999
+#: js/js.js:1107
 msgid "yesterday"
 msgstr ""
 
-#: js/js.js:1000
+#: js/js.js:1108
 msgid "%n day ago"
 msgid_plural "%n days ago"
 msgstr[0] ""
 msgstr[1] ""
 
-#: js/js.js:1001
+#: js/js.js:1109
 msgid "last month"
 msgstr ""
 
-#: js/js.js:1002
+#: js/js.js:1110
 msgid "%n month ago"
 msgid_plural "%n months ago"
 msgstr[0] ""
 msgstr[1] ""
 
-#: js/js.js:1003
+#: js/js.js:1111
 msgid "months ago"
 msgstr ""
 
-#: js/js.js:1004
+#: js/js.js:1112
 msgid "last year"
 msgstr ""
 
-#: js/js.js:1005
+#: js/js.js:1113
 msgid "years ago"
 msgstr ""
 
@@ -534,14 +534,14 @@ msgstr ""
 msgid "Reset password"
 msgstr ""
 
-#: setup/controller.php:138
+#: setup/controller.php:140
 #, php-format
 msgid ""
 "Mac OS X is not supported and %s will not work properly on this platform. "
 "Use it at your own risk! "
 msgstr ""
 
-#: setup/controller.php:142
+#: setup/controller.php:144
 msgid "For the best results, please consider using a GNU/Linux server instead."
 msgstr ""
 
diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot
index f2639f9303089cdad47d200fd910764c51613eb8..bc931be91d8f1191c7a8bf5300563ce60c1ae24e 100644
--- a/l10n/templates/files.pot
+++ b/l10n/templates/files.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -193,15 +193,15 @@ msgstr ""
 msgid "Error fetching URL"
 msgstr ""
 
-#: js/fileactions.js:149
+#: js/fileactions.js:164
 msgid "Share"
 msgstr ""
 
-#: js/fileactions.js:162
+#: js/fileactions.js:177
 msgid "Delete permanently"
 msgstr ""
 
-#: js/fileactions.js:223
+#: js/fileactions.js:238
 msgid "Rename"
 msgstr ""
 
@@ -225,13 +225,13 @@ msgstr ""
 msgid "Error deleting file."
 msgstr ""
 
-#: js/filelist.js:687 js/filelist.js:761 js/files.js:691
+#: js/filelist.js:687 js/filelist.js:761 js/files.js:694
 msgid "%n folder"
 msgid_plural "%n folders"
 msgstr[0] ""
 msgstr[1] ""
 
-#: js/filelist.js:688 js/filelist.js:762 js/files.js:697
+#: js/filelist.js:688 js/filelist.js:762 js/files.js:700
 msgid "%n file"
 msgid_plural "%n files"
 msgstr[0] ""
@@ -277,29 +277,29 @@ msgid ""
 "your personal settings to decrypt your files."
 msgstr ""
 
-#: js/files.js:379
+#: js/files.js:382
 msgid ""
 "Your download is being prepared. This might take some time if the files are "
 "big."
 msgstr ""
 
-#: js/files.js:610 js/files.js:654
+#: js/files.js:613 js/files.js:657
 msgid "Error moving file"
 msgstr ""
 
-#: js/files.js:610 js/files.js:654
+#: js/files.js:613 js/files.js:657
 msgid "Error"
 msgstr ""
 
-#: js/files.js:672 templates/index.php:68
+#: js/files.js:675 templates/index.php:68
 msgid "Name"
 msgstr ""
 
-#: js/files.js:673 templates/index.php:80
+#: js/files.js:676 templates/index.php:80
 msgid "Size"
 msgstr ""
 
-#: js/files.js:674 templates/index.php:82
+#: js/files.js:677 templates/index.php:82
 msgid "Modified"
 msgstr ""
 
diff --git a/l10n/templates/files_encryption.pot b/l10n/templates/files_encryption.pot
index 1ef7c2cab99e50b91b05871e2f6e3c19f5bbf438..99f9cf030b692ae06bb36c3ddc37fa1477f5d541 100644
--- a/l10n/templates/files_encryption.pot
+++ b/l10n/templates/files_encryption.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/l10n/templates/files_external.pot b/l10n/templates/files_external.pot
index 965c851209060f540b07f7d60d492849f814ef65..6334e403e412098bc801255c5edc71584b007f15 100644
--- a/l10n/templates/files_external.pot
+++ b/l10n/templates/files_external.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -37,24 +37,24 @@ msgstr ""
 msgid "Error configuring Google Drive storage"
 msgstr ""
 
-#: js/settings.js:313 js/settings.js:320
+#: js/settings.js:318 js/settings.js:325
 msgid "Saved"
 msgstr ""
 
-#: lib/config.php:646
+#: lib/config.php:654
 msgid ""
 "<b>Warning:</b> \"smbclient\" is not installed. Mounting of CIFS/SMB shares "
 "is not possible. Please ask your system administrator to install it."
 msgstr ""
 
-#: lib/config.php:650
+#: lib/config.php:658
 msgid ""
 "<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting "
 "of FTP shares is not possible. Please ask your system administrator to "
 "install it."
 msgstr ""
 
-#: lib/config.php:653
+#: lib/config.php:661
 msgid ""
 "<b>Warning:</b> The Curl support in PHP is not enabled or installed. "
 "Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask "
@@ -89,39 +89,39 @@ msgstr ""
 msgid "Add storage"
 msgstr ""
 
-#: templates/settings.php:90
+#: templates/settings.php:93
 msgid "None set"
 msgstr ""
 
-#: templates/settings.php:91
+#: templates/settings.php:94
 msgid "All Users"
 msgstr ""
 
-#: templates/settings.php:92
+#: templates/settings.php:95
 msgid "Groups"
 msgstr ""
 
-#: templates/settings.php:100
+#: templates/settings.php:103
 msgid "Users"
 msgstr ""
 
-#: templates/settings.php:113 templates/settings.php:114
-#: templates/settings.php:155 templates/settings.php:156
+#: templates/settings.php:116 templates/settings.php:117
+#: templates/settings.php:158 templates/settings.php:159
 msgid "Delete"
 msgstr ""
 
-#: templates/settings.php:127
+#: templates/settings.php:130
 msgid "Enable User External Storage"
 msgstr ""
 
-#: templates/settings.php:130
+#: templates/settings.php:133
 msgid "Allow users to mount the following external storage"
 msgstr ""
 
-#: templates/settings.php:147
+#: templates/settings.php:150
 msgid "SSL root certificates"
 msgstr ""
 
-#: templates/settings.php:165
+#: templates/settings.php:168
 msgid "Import Root Certificate"
 msgstr ""
diff --git a/l10n/templates/files_sharing.pot b/l10n/templates/files_sharing.pot
index 2f8678ef6e2a07d4ee2ec7bce38491e6627284a9..8fbff462614e0e8cf3cb60c0ccb16992f950aace 100644
--- a/l10n/templates/files_sharing.pot
+++ b/l10n/templates/files_sharing.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/l10n/templates/files_trashbin.pot b/l10n/templates/files_trashbin.pot
index d4dcc61a85522cb9ee25e458b4c47e8db59f1b3f..f9b4401c785d047d7a6afc09a25115c1f2bb2ec4 100644
--- a/l10n/templates/files_trashbin.pot
+++ b/l10n/templates/files_trashbin.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -31,7 +31,7 @@ msgstr ""
 msgid "Deleted files"
 msgstr ""
 
-#: js/trash.js:16 js/trash.js:103 js/trash.js:152
+#: js/trash.js:16 js/trash.js:108 js/trash.js:157
 msgid "Error"
 msgstr ""
 
diff --git a/l10n/templates/files_versions.pot b/l10n/templates/files_versions.pot
index 5bae82bfe6995dc40da0ae624cabdf0c5f4ad492..3381aea0a7d6c50936b639bc573cd8efded0f703 100644
--- a/l10n/templates/files_versions.pot
+++ b/l10n/templates/files_versions.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -22,22 +22,22 @@ msgstr ""
 msgid "Could not revert: %s"
 msgstr ""
 
-#: js/versions.js:14
+#: js/versions.js:39
 msgid "Versions"
 msgstr ""
 
-#: js/versions.js:60
+#: js/versions.js:61
 msgid "Failed to revert {file} to revision {timestamp}."
 msgstr ""
 
-#: js/versions.js:87
+#: js/versions.js:88
 msgid "More versions..."
 msgstr ""
 
-#: js/versions.js:125
+#: js/versions.js:126
 msgid "No other versions available"
 msgstr ""
 
-#: js/versions.js:155
+#: js/versions.js:156
 msgid "Restore"
 msgstr ""
diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot
index 90e076435a35bfb75653ffa755b1bc994599c91a..10017472d1b75c6b4a8438109ea6eb0cdeab871e 100644
--- a/l10n/templates/lib.pot
+++ b/l10n/templates/lib.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -66,23 +66,23 @@ msgstr ""
 msgid "web services under your control"
 msgstr ""
 
-#: private/files.php:231
+#: private/files.php:232
 msgid "ZIP download is turned off."
 msgstr ""
 
-#: private/files.php:232
+#: private/files.php:233
 msgid "Files need to be downloaded one by one."
 msgstr ""
 
-#: private/files.php:233 private/files.php:261
+#: private/files.php:234 private/files.php:262
 msgid "Back to Files"
 msgstr ""
 
-#: private/files.php:258
+#: private/files.php:259
 msgid "Selected files too large to generate zip file."
 msgstr ""
 
-#: private/files.php:259
+#: private/files.php:260
 msgid ""
 "Please download the files separately in smaller chunks or kindly ask your "
 "administrator."
diff --git a/l10n/templates/private.pot b/l10n/templates/private.pot
index 2925d3cdfdd7ccafe0393546a935539d2b228efb..12fa6ad93081ef2b6bb955a151d7a30daa1acc23 100644
--- a/l10n/templates/private.pot
+++ b/l10n/templates/private.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -66,23 +66,23 @@ msgstr ""
 msgid "web services under your control"
 msgstr ""
 
-#: files.php:231
+#: files.php:232
 msgid "ZIP download is turned off."
 msgstr ""
 
-#: files.php:232
+#: files.php:233
 msgid "Files need to be downloaded one by one."
 msgstr ""
 
-#: files.php:233 files.php:261
+#: files.php:234 files.php:262
 msgid "Back to Files"
 msgstr ""
 
-#: files.php:258
+#: files.php:259
 msgid "Selected files too large to generate zip file."
 msgstr ""
 
-#: files.php:259
+#: files.php:260
 msgid ""
 "Please download the files separately in smaller chunks or kindly ask your "
 "administrator."
diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot
index 2c810d328e0f543c1119cfbfeedf89c4c5fccf94..892d64a2733cdbdfc127312a0bd0eca6442ebabf 100644
--- a/l10n/templates/settings.pot
+++ b/l10n/templates/settings.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -64,7 +64,7 @@ msgid "Unable to load list from App Store"
 msgstr ""
 
 #: ajax/changedisplayname.php:25 ajax/removeuser.php:15 ajax/setquota.php:17
-#: ajax/togglegroups.php:20 changepassword/controller.php:55
+#: ajax/togglegroups.php:20 changepassword/controller.php:49
 msgid "Authentication error"
 msgstr ""
 
@@ -126,31 +126,31 @@ msgstr ""
 msgid "Couldn't update app."
 msgstr ""
 
-#: changepassword/controller.php:20
+#: changepassword/controller.php:17
 msgid "Wrong password"
 msgstr ""
 
-#: changepassword/controller.php:42
+#: changepassword/controller.php:36
 msgid "No user supplied"
 msgstr ""
 
-#: changepassword/controller.php:74
+#: changepassword/controller.php:68
 msgid ""
 "Please provide an admin recovery password, otherwise all user data will be "
 "lost"
 msgstr ""
 
-#: changepassword/controller.php:79
+#: changepassword/controller.php:73
 msgid "Wrong admin recovery password. Please check the password and try again."
 msgstr ""
 
-#: changepassword/controller.php:87
+#: changepassword/controller.php:81
 msgid ""
 "Back-end doesn't support password change, but the users encryption key was "
 "successfully updated."
 msgstr ""
 
-#: changepassword/controller.php:92 changepassword/controller.php:103
+#: changepassword/controller.php:86 changepassword/controller.php:97
 msgid "Unable to change password"
 msgstr ""
 
@@ -283,7 +283,7 @@ msgstr ""
 msgid "Warning: Home directory for user \"{user}\" already exists"
 msgstr ""
 
-#: personal.php:49 personal.php:50
+#: personal.php:48 personal.php:49
 msgid "__language_name__"
 msgstr ""
 
diff --git a/l10n/templates/user_ldap.pot b/l10n/templates/user_ldap.pot
index 73d07c3e4d25a8e2a10ae60e6429c052a2ab7da4..d16fe0386eb0c13cf7c775b3b89a4246a32e1a24 100644
--- a/l10n/templates/user_ldap.pot
+++ b/l10n/templates/user_ldap.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/l10n/templates/user_webdavauth.pot b/l10n/templates/user_webdavauth.pot
index a01f6858bc6f45a1003d3fafdf7e5a714cd6e9ab..d2e917267ce154db840cf72e6821bc25d0c08328 100644
--- a/l10n/templates/user_webdavauth.pot
+++ b/l10n/templates/user_webdavauth.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud Core 6.0.0\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-27 01:55-0400\n"
+"POT-Creation-Date: 2014-03-31 01:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/l10n/tr/core.po b/l10n/tr/core.po
index 177ac786519540450da8df9a8ccf0e4941a1010d..09a1e3d278e863c0487d8aaba6e550a28f626b76 100644
--- a/l10n/tr/core.po
+++ b/l10n/tr/core.po
@@ -11,8 +11,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-24 01:55-0400\n"
-"PO-Revision-Date: 2014-03-23 13:20+0000\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 19:31+0000\n"
 "Last-Translator: volkangezer <volkangezer@gmail.com>\n"
 "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n"
 "MIME-Version: 1.0\n"
@@ -490,7 +490,7 @@ msgid ""
 "The link to reset your password has been sent to your email.<br>If you do "
 "not receive it within a reasonable amount of time, check your spam/junk "
 "folders.<br>If it is not there ask your local administrator ."
-msgstr "Parolanızı değiştirme bağlantısı e-posta adresinize gönderildi.<br>Eğer makül bir süre içerisinde mesajı almadıysanız spam/junk dizinini kontrol ediniz.<br> Eğer orada da bulamazsanız sistem yöneticinize sorunuz."
+msgstr "Parolanızı değiştirme bağlantısı e-posta adresinize gönderildi.<br>Eğer makül bir süre içerisinde mesajı almadıysanız spam/junk/gereksiz dizinini kontrol ediniz.<br> Eğer yine bulamazsanız sistem yöneticinize sorunuz."
 
 #: lostpassword/templates/lostpassword.php:15
 msgid "Request failed!<br>Did you make sure your email/username was right?"
diff --git a/l10n/tr/settings.po b/l10n/tr/settings.po
index 9cf4c3306ca11749d0bd9e5a1b329f5f00db26bc..cb9da3017de72c5a90b082e768b47d3bb2ae2acd 100644
--- a/l10n/tr/settings.po
+++ b/l10n/tr/settings.po
@@ -11,9 +11,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ownCloud\n"
 "Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-03-26 01:55-0400\n"
-"PO-Revision-Date: 2014-03-26 05:55+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-03-28 01:55-0400\n"
+"PO-Revision-Date: 2014-03-27 19:31+0000\n"
+"Last-Translator: volkangezer <volkangezer@gmail.com>\n"
 "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -433,18 +433,18 @@ msgstr "Cron"
 #: templates/admin.php:167
 #, php-format
 msgid "Last cron was executed at %s."
-msgstr ""
+msgstr "Son cron %s zamanında çalıştırıldı."
 
 #: templates/admin.php:170
 #, php-format
 msgid ""
 "Last cron was executed at %s. This is more than an hour ago, something seems"
 " wrong."
-msgstr ""
+msgstr "Son cron %s zamanında çalıştırıldı. Bu bir saatten daha uzun bir süre, bir şeyler yanlış gibi görünüyor."
 
 #: templates/admin.php:174
 msgid "Cron was not executed yet!"
-msgstr ""
+msgstr "Cron henüz çalıştırılmadı!"
 
 #: templates/admin.php:184
 msgid "Execute one task with each page loaded"
diff --git a/lib/base.php b/lib/base.php
index 2515b9657cbc8e5b5af626340ea238c83bbc42ac..15a3ec8bc8aca22dce7af30dca55b9bf60989c06 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -549,16 +549,10 @@ class OC {
 			OC_User::logout();
 		}
 
-		// Load Apps
-		// This includes plugins for users and filesystems as well
-		global $RUNTIME_NOAPPS;
-		global $RUNTIME_APPTYPES;
-		if (!$RUNTIME_NOAPPS && !self::checkUpgrade(false)) {
-			if ($RUNTIME_APPTYPES) {
-				OC_App::loadApps($RUNTIME_APPTYPES);
-			} else {
-				OC_App::loadApps();
-			}
+		// Load minimum set of apps - which is filesystem, authentication and logging
+		if (!self::checkUpgrade(false)) {
+			OC_App::loadApps(array('authentication'));
+			OC_App::loadApps(array('filesystem', 'logging'));
 		}
 
 		//setup extra user backends
@@ -659,10 +653,10 @@ class OC {
 	 */
 	public static function registerShareHooks() {
 		if (\OC_Config::getValue('installed')) {
-			OC_Hook::connect('OC_User', 'post_deleteUser', 'OCP\Share', 'post_deleteUser');
-			OC_Hook::connect('OC_User', 'post_addToGroup', 'OCP\Share', 'post_addToGroup');
-			OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OCP\Share', 'post_removeFromGroup');
-			OC_Hook::connect('OC_User', 'post_deleteGroup', 'OCP\Share', 'post_deleteGroup');
+			OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Share\Hooks', 'post_deleteUser');
+			OC_Hook::connect('OC_User', 'post_addToGroup', 'OC\Share\Hooks', 'post_addToGroup');
+			OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC\Share\Hooks', 'post_removeFromGroup');
+			OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC\Share\Hooks', 'post_deleteGroup');
 		}
 	}
 
@@ -851,7 +845,7 @@ class OC {
 		) {
 			return false;
 		}
-		OC_App::loadApps(array('authentication'));
+
 		if (defined("DEBUG") && DEBUG) {
 			OC_Log::write('core', 'Trying to login from cookie', OC_Log::DEBUG);
 		}
@@ -923,7 +917,7 @@ class OC {
 		) {
 			return false;
 		}
-		OC_App::loadApps(array('authentication'));
+
 		if (OC_User::login($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"])) {
 			//OC_Log::write('core',"Logged in with HTTP Authentication", OC_Log::DEBUG);
 			OC_User::unsetMagicInCookie();
@@ -934,11 +928,6 @@ class OC {
 
 }
 
-// define runtime variables - unless this already has been done
-if (!isset($RUNTIME_NOAPPS)) {
-	$RUNTIME_NOAPPS = false;
-}
-
 if (!function_exists('get_temp_dir')) {
 	function get_temp_dir() {
 		if ($temp = ini_get('upload_tmp_dir')) return $temp;
@@ -957,4 +946,3 @@ if (!function_exists('get_temp_dir')) {
 }
 
 OC::init();
-
diff --git a/lib/private/cache/file.php b/lib/private/cache/file.php
index 8a6ef39f61bb8061e51184ee06916781ebe5257c..be6805a9a57aea7e95419e38382e1f498f7b1fbc 100644
--- a/lib/private/cache/file.php
+++ b/lib/private/cache/file.php
@@ -1,6 +1,7 @@
 <?php
 /**
  * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
@@ -10,22 +11,22 @@ namespace OC\Cache;
 
 class File {
 	protected $storage;
+
+	/**
+	 * Returns the cache storage for the logged in user
+	 * @return cache storage
+	 */
 	protected function getStorage() {
 		if (isset($this->storage)) {
 			return $this->storage;
 		}
 		if(\OC_User::isLoggedIn()) {
 			\OC\Files\Filesystem::initMountPoints(\OC_User::getUser());
-			$subdir = 'cache';
-			$view = new \OC\Files\View('/' . \OC_User::getUser());
-			if(!$view->file_exists($subdir)) {
-				$view->mkdir($subdir);
-			}
-			$this->storage = new \OC\Files\View('/' . \OC_User::getUser().'/'.$subdir);
+			$this->storage = new \OC\Files\View('/' . \OC_User::getUser() . '/cache');
 			return $this->storage;
 		}else{
 			\OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR);
-			return false;
+			throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in');
 		}
 	}
 
diff --git a/lib/private/db/statementwrapper.php b/lib/private/db/statementwrapper.php
index eaf215c72313be1a4cbc9f9457a8036209cc9384..492209b883bd94134cacd548dcb308ef0937c730 100644
--- a/lib/private/db/statementwrapper.php
+++ b/lib/private/db/statementwrapper.php
@@ -8,6 +8,11 @@
 
 /**
  * small wrapper around \Doctrine\DBAL\Driver\Statement to make it behave, more like an MDB2 Statement
+ *
+ * @method boolean bindValue(mixed $param, mixed $value, integer $type = null);
+ * @method string errorCode();
+ * @method array errorInfo();
+ * @method integer rowCount();
  */
 class OC_DB_StatementWrapper {
 	/**
@@ -161,6 +166,8 @@ class OC_DB_StatementWrapper {
     
 	/**
 	 * provide an alias for fetch
+	 *
+	 * @return mixed
 	 */
 	public function fetchRow() {
 		return $this->statement->fetch();
@@ -168,12 +175,13 @@ class OC_DB_StatementWrapper {
 
 	/**
 	 * Provide a simple fetchOne.
+	 *
 	 * fetch single column from the next row
-	 * @param int $colnum the column number to fetch
+	 * @param int $column the column number to fetch
 	 * @return string
 	 */
-	public function fetchOne($colnum = 0) {
-		return $this->statement->fetchColumn($colnum);
+	public function fetchOne($column = 0) {
+		return $this->statement->fetchColumn($column);
 	}
 
 	/**
diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php
index c31e0c381805812332bfaa6b9d5acf01a226c7fb..7e27650c5574d80bb57ac9b38d47afbe032e05ff 100644
--- a/lib/private/files/filesystem.php
+++ b/lib/private/files/filesystem.php
@@ -321,10 +321,35 @@ class Filesystem {
 			self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user);
 		}
 
+		self::mountCacheDir($user);
+
 		// Chance to mount for other storages
 		\OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root));
 	}
 
+	/**
+	 * Mounts the cache directory
+	 * @param string $user user name
+	 */
+	private static function mountCacheDir($user) {
+		$cacheBaseDir = \OC_Config::getValue('cache_path', '');
+		if ($cacheBaseDir === '') {
+			// use local cache dir relative to the user's home
+			$subdir = 'cache';
+			$view = new \OC\Files\View('/' . $user);
+			if(!$view->file_exists($subdir)) {
+				$view->mkdir($subdir);
+			}
+		} else {
+			$cacheDir = rtrim($cacheBaseDir, '/') . '/' . $user;
+			if (!file_exists($cacheDir)) {
+				mkdir($cacheDir, 0770, true);
+			}
+			// mount external cache dir to "/$user/cache" mount point
+			self::mount('\OC\Files\Storage\Local', array('datadir' => $cacheDir), '/' . $user . '/cache');
+		}
+	}
+
 	/**
 	 * get the default filesystem view
 	 *
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index 3c078d7b1b4b8f9a6f5924d3cf5855b7df06d11b..2b697141515655801dae3b75fcd2aa583952156e 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -160,8 +160,7 @@ abstract class Common implements \OC\Files\Storage\Storage {
 
 	public function hash($type, $path, $raw = false) {
 		$tmpFile = $this->getLocalFile($path);
-		$hash = hash($type, $tmpFile, $raw);
-		unlink($tmpFile);
+		$hash = hash_file($type, $tmpFile, $raw);
 		return $hash;
 	}
 
diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php
index 0f906ec55b4e1be61db6df16e9baf7255ca698bd..571bf7f97c1af3deead5280dc167abd66c4a039f 100644
--- a/lib/private/files/storage/local.php
+++ b/lib/private/files/storage/local.php
@@ -256,7 +256,7 @@ if (\OC_Util::runningOnWindows()) {
 			return 0;
 		}
 
-		public function hash($path, $type, $raw = false) {
+		public function hash($type, $path, $raw = false) {
 			return hash_file($type, $this->datadir . $path, $raw);
 		}
 
diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php
index 026f6ec895ed7f68eddc4704bd1a86b8244d3276..94ee28ca763c2c5340811cf92a498728ea060c36 100644
--- a/lib/private/files/storage/mappedlocal.php
+++ b/lib/private/files/storage/mappedlocal.php
@@ -276,7 +276,7 @@ class MappedLocal extends \OC\Files\Storage\Common{
 		return 0;
 	}
 
-	public function hash($path, $type, $raw=false) {
+	public function hash($type, $path, $raw=false) {
 		return hash_file($type, $this->buildPath($path), $raw);
 	}
 
diff --git a/lib/private/forbiddenexception.php b/lib/private/forbiddenexception.php
new file mode 100644
index 0000000000000000000000000000000000000000..14a4cd14984cd83020061e6014c822e8f808411a
--- /dev/null
+++ b/lib/private/forbiddenexception.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC;
+
+/**
+ * Exception thrown whenever access to a resource has
+ * been forbidden or whenever a user isn't authenticated.
+ */
+class ForbiddenException extends \Exception {
+}
diff --git a/lib/private/helper.php b/lib/private/helper.php
index 98a86388d2088d71d6b691f9d5b8434c7dda3155..d7ac0b5f4fa64846adad31d58c9c6ed960a3653d 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -78,8 +78,7 @@ class OC_Helper {
 	 * Returns a absolute url to the given app and file.
 	 */
 	public static function linkToAbsolute($app, $file, $args = array()) {
-		$urlLinkTo = self::linkTo($app, $file, $args);
-		return self::makeURLAbsolute($urlLinkTo);
+		return self::linkTo($app, $file, $args);
 	}
 
 	/**
diff --git a/lib/private/share/constants.php b/lib/private/share/constants.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e4223d10fae18c5a7b9e27097e6aee6c0d4c315
--- /dev/null
+++ b/lib/private/share/constants.php
@@ -0,0 +1,44 @@
+<?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/>.
+ */
+
+namespace OC\Share;
+
+class Constants {
+
+	const SHARE_TYPE_USER = 0;
+	const SHARE_TYPE_GROUP = 1;
+	const SHARE_TYPE_LINK = 3;
+	const SHARE_TYPE_EMAIL = 4;
+	const SHARE_TYPE_CONTACT = 5;
+	const SHARE_TYPE_REMOTE = 6;
+
+	const FORMAT_NONE = -1;
+	const FORMAT_STATUSES = -2;
+	const FORMAT_SOURCES = -3;
+
+	const TOKEN_LENGTH = 32; // see db_structure.xml
+
+	protected static $shareTypeUserAndGroups = -1;
+	protected static $shareTypeGroupUserUnique = 2;
+	protected static $backends = array();
+	protected static $backendTypes = array();
+	protected static $isResharingAllowed;
+}
diff --git a/lib/private/share/helper.php b/lib/private/share/helper.php
new file mode 100644
index 0000000000000000000000000000000000000000..fde55667281214a39e49454931362a2bf0c646d9
--- /dev/null
+++ b/lib/private/share/helper.php
@@ -0,0 +1,202 @@
+<?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/>.
+ */
+
+namespace OC\Share;
+
+class Helper extends \OC\Share\Constants {
+
+	/**
+	 * Generate a unique target for the item
+	 * @param string Item type
+	 * @param string Item source
+	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @param string User or group the item is being shared with
+	 * @param string User that is the owner of shared item
+	 * @param string The suggested target originating from a reshare (optional)
+	 * @param int The id of the parent group share (optional)
+	 * @return string Item target
+	 */
+	public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
+		$suggestedTarget = null, $groupParent = null) {
+		$backend = \OC\Share\Share::getBackend($itemType);
+		if ($shareType == self::SHARE_TYPE_LINK) {
+			if (isset($suggestedTarget)) {
+				return $suggestedTarget;
+			}
+			return $backend->generateTarget($itemSource, false);
+		} else {
+			if ($itemType == 'file' || $itemType == 'folder') {
+				$column = 'file_target';
+				$columnSource = 'file_source';
+			} else {
+				$column = 'item_target';
+				$columnSource = 'item_source';
+			}
+			if ($shareType == self::SHARE_TYPE_USER) {
+				// Share with is a user, so set share type to user and groups
+				$shareType = self::$shareTypeUserAndGroups;
+				$userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith));
+			} else {
+				$userAndGroups = false;
+			}
+			$exclude = null;
+			// Backend has 3 opportunities to generate a unique target
+			for ($i = 0; $i < 2; $i++) {
+				// Check if suggested target exists first
+				if ($i == 0 && isset($suggestedTarget)) {
+					$target = $suggestedTarget;
+				} else {
+					if ($shareType == self::SHARE_TYPE_GROUP) {
+						$target = $backend->generateTarget($itemSource, false, $exclude);
+					} else {
+						$target = $backend->generateTarget($itemSource, $shareWith, $exclude);
+					}
+					if (is_array($exclude) && in_array($target, $exclude)) {
+						break;
+					}
+				}
+				// Check if target already exists
+				$checkTarget = \OC\Share\Share::getItems($itemType, $target, $shareType, $shareWith);
+				if (!empty($checkTarget)) {
+					foreach ($checkTarget as $item) {
+						// Skip item if it is the group parent row
+						if (isset($groupParent) && $item['id'] == $groupParent) {
+							if (count($checkTarget) == 1) {
+								return $target;
+							} else {
+								continue;
+							}
+						}
+						if ($item['uid_owner'] == $uidOwner) {
+							if ($itemType == 'file' || $itemType == 'folder') {
+								$meta = \OC\Files\Filesystem::getFileInfo($itemSource);
+								if ($item['file_source'] == $meta['fileid']) {
+									return $target;
+								}
+							} else if ($item['item_source'] == $itemSource) {
+								return $target;
+							}
+						}
+					}
+					if (!isset($exclude)) {
+						$exclude = array();
+					}
+					// Find similar targets to improve backend's chances to generate a unqiue target
+					if ($userAndGroups) {
+						if ($column == 'file_target') {
+							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
+								.' WHERE `item_type` IN (\'file\', \'folder\')'
+								.' AND `share_type` IN (?,?,?)'
+								.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
+							$result = $checkTargets->execute(array(self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP,
+								self::$shareTypeGroupUserUnique));
+						} else {
+							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
+								.' WHERE `item_type` = ? AND `share_type` IN (?,?,?)'
+								.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
+							$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_USER,
+								self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique));
+						}
+					} else {
+						if ($column == 'file_target') {
+							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
+								.' WHERE `item_type` IN (\'file\', \'folder\')'
+								.' AND `share_type` = ? AND `share_with` = ?');
+							$result = $checkTargets->execute(array(self::SHARE_TYPE_GROUP, $shareWith));
+						} else {
+							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
+								.' WHERE `item_type` = ? AND `share_type` = ? AND `share_with` = ?');
+							$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_GROUP, $shareWith));
+						}
+					}
+					while ($row = $result->fetchRow()) {
+						$exclude[] = $row[$column];
+					}
+				} else {
+					return $target;
+				}
+			}
+		}
+		$message = 'Sharing backend registered for '.$itemType.' did not generate a unique target for '.$itemSource;
+		\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+		throw new \Exception($message);
+	}
+
+	/**
+	 * Delete all reshares of an item
+	 * @param int Id of item to delete
+	 * @param bool If true, exclude the parent from the delete (optional)
+	 * @param string The user that the parent was shared with (optinal)
+	 */
+	public static function delete($parent, $excludeParent = false, $uidOwner = null) {
+		$ids = array($parent);
+		$parents = array($parent);
+		while (!empty($parents)) {
+			$parents = "'".implode("','", $parents)."'";
+			// Check the owner on the first search of reshares, useful for
+			// finding and deleting the reshares by a single user of a group share
+			if (count($ids) == 1 && isset($uidOwner)) {
+				$query = \OC_DB::prepare('SELECT `id`, `uid_owner`, `item_type`, `item_target`, `parent`'
+					.' FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') AND `uid_owner` = ?');
+				$result = $query->execute(array($uidOwner));
+			} else {
+				$query = \OC_DB::prepare('SELECT `id`, `item_type`, `item_target`, `parent`, `uid_owner`'
+					.' FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.')');
+				$result = $query->execute();
+			}
+			// Reset parents array, only go through loop again if items are found
+			$parents = array();
+			while ($item = $result->fetchRow()) {
+				// Search for a duplicate parent share, this occurs when an
+				// item is shared to the same user through a group and user or the
+				// same item is shared by different users
+				$userAndGroups = array_merge(array($item['uid_owner']), \OC_Group::getUserGroups($item['uid_owner']));
+				$query = \OC_DB::prepare('SELECT `id`, `permissions` FROM `*PREFIX*share`'
+					.' WHERE `item_type` = ?'
+					.' AND `item_target` = ?'
+					.' AND `share_type` IN (?,?,?)'
+					.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')'
+					.' AND `uid_owner` != ? AND `id` != ?');
+				$duplicateParent = $query->execute(array($item['item_type'], $item['item_target'],
+					self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique,
+					$item['uid_owner'], $item['parent']))->fetchRow();
+				if ($duplicateParent) {
+					// Change the parent to the other item id if share permission is granted
+					if ($duplicateParent['permissions'] & \OCP\PERMISSION_SHARE) {
+						$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` = ?');
+						$query->execute(array($duplicateParent['id'], $item['id']));
+						continue;
+					}
+				}
+				$ids[] = $item['id'];
+				$parents[] = $item['id'];
+			}
+		}
+		if ($excludeParent) {
+			unset($ids[0]);
+		}
+		if (!empty($ids)) {
+			$ids = "'".implode("','", $ids)."'";
+			$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$ids.')');
+			$query->execute();
+		}
+	}
+}
diff --git a/lib/private/share/hooks.php b/lib/private/share/hooks.php
new file mode 100644
index 0000000000000000000000000000000000000000..a33c71eedd2f80baf04a6907166a54b2a8b00a0a
--- /dev/null
+++ b/lib/private/share/hooks.php
@@ -0,0 +1,108 @@
+<?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/>.
+ */
+
+namespace OC\Share;
+
+class Hooks extends \OC\Share\Constants {
+		/**
+	 * Function that is called after a user is deleted. Cleans up the shares of that user.
+	 * @param array arguments
+	 */
+	public static function post_deleteUser($arguments) {
+		// Delete any items shared with the deleted user
+		$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'
+			.' WHERE `share_with` = ? AND `share_type` = ? OR `share_type` = ?');
+		$result = $query->execute(array($arguments['uid'], self::SHARE_TYPE_USER, self::$shareTypeGroupUserUnique));
+		// Delete any items the deleted user shared
+		$query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `uid_owner` = ?');
+		$result = $query->execute(array($arguments['uid']));
+		while ($item = $result->fetchRow()) {
+			Helper::delete($item['id']);
+		}
+	}
+
+	/**
+	 * Function that is called after a user is added to a group.
+	 * TODO what does it do?
+	 * @param array arguments
+	 */
+	public static function post_addToGroup($arguments) {
+		// Find the group shares and check if the user needs a unique target
+		$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?');
+		$result = $query->execute(array(self::SHARE_TYPE_GROUP, $arguments['gid']));
+		$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`,'
+			.' `item_target`, `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`,'
+			.' `stime`, `file_source`, `file_target`) VALUES (?,?,?,?,?,?,?,?,?,?,?)');
+		while ($item = $result->fetchRow()) {
+			if ($item['item_type'] == 'file' || $item['item_type'] == 'file') {
+				$itemTarget = null;
+			} else {
+				$itemTarget = Helper::generateTarget($item['item_type'], $item['item_source'], self::SHARE_TYPE_USER,
+						$arguments['uid'], $item['uid_owner'], $item['item_target'], $item['id']);
+			}
+			if (isset($item['file_source'])) {
+				$fileTarget = Helper::generateTarget($item['item_type'], $item['item_source'], self::SHARE_TYPE_USER,
+					$arguments['uid'], $item['uid_owner'], $item['file_target'], $item['id']);
+			} else {
+				$fileTarget = null;
+			}
+			// Insert an extra row for the group share if the item or file target is unique for this user
+			if ($itemTarget != $item['item_target'] || $fileTarget != $item['file_target']) {
+				$query->execute(array($item['item_type'], $item['item_source'], $itemTarget, $item['id'],
+					self::$shareTypeGroupUserUnique, $arguments['uid'], $item['uid_owner'], $item['permissions'],
+					$item['stime'], $item['file_source'], $fileTarget));
+				\OC_DB::insertid('*PREFIX*share');
+			}
+		}
+	}
+
+	/**
+	 * Function that is called after a user is removed from a group. Shares are cleaned up.
+	 * @param array arguments
+	 */
+	public static function post_removeFromGroup($arguments) {
+		$sql = 'SELECT `id`, `share_type` FROM `*PREFIX*share`'
+			.' WHERE (`share_type` = ? AND `share_with` = ?) OR (`share_type` = ? AND `share_with` = ?)';
+		$result = \OC_DB::executeAudited($sql, array(self::SHARE_TYPE_GROUP, $arguments['gid'],
+			self::$shareTypeGroupUserUnique, $arguments['uid']));
+		while ($item = $result->fetchRow()) {
+			if ($item['share_type'] == self::SHARE_TYPE_GROUP) {
+				// Delete all reshares by this user of the group share
+				Helper::delete($item['id'], true, $arguments['uid']);
+			} else {
+				Helper::delete($item['id']);
+			}
+		}
+	}
+
+	/**
+	 * Function that is called after a group is removed. Cleans up the shares to that group.
+	 * @param array arguments
+	 */
+	public static function post_deleteGroup($arguments) {
+		$sql = 'SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?';
+		$result = \OC_DB::executeAudited($sql, array(self::SHARE_TYPE_GROUP, $arguments['gid']));
+		while ($item = $result->fetchRow()) {
+			Helper::delete($item['id']);
+		}
+	}
+
+}
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
new file mode 100644
index 0000000000000000000000000000000000000000..8238797600ead3b19868395dac53f4b42a45916b
--- /dev/null
+++ b/lib/private/share/share.php
@@ -0,0 +1,1619 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Bjoern Schiessle, Michael Gapczynski
+ * @copyright 2012 Michael Gapczynski <mtgap@owncloud.com>
+ *            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/>.
+ */
+
+namespace OC\Share;
+
+/**
+ * This class provides the ability for apps to share their content between users.
+ * Apps must create a backend class that implements OCP\Share_Backend and register it with this class.
+ *
+ * It provides the following hooks:
+ *  - post_shared
+ */
+class Share extends \OC\Share\Constants {
+
+	/** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask
+	 * Construct permissions for share() and setPermissions with Or (|) e.g.
+	 * Give user read and update permissions: PERMISSION_READ | PERMISSION_UPDATE
+	 *
+	 * Check if permission is granted with And (&) e.g. Check if delete is
+	 * granted: if ($permissions & PERMISSION_DELETE)
+	 *
+	 * Remove permissions with And (&) and Not (~) e.g. Remove the update
+	 * permission: $permissions &= ~PERMISSION_UPDATE
+	 *
+	 * Apps are required to handle permissions on their own, this class only
+	 * stores and manages the permissions of shares
+	 * @see lib/public/constants.php
+	 */
+
+	/**
+	 * Register a sharing backend class that implements OCP\Share_Backend for an item type
+	 * @param string Item type
+	 * @param string Backend class
+	 * @param string (optional) Depends on item type
+	 * @param array (optional) List of supported file extensions if this item type depends on files
+	 * @return Returns true if backend is registered or false if error
+	 */
+	public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) {
+		if (self::isEnabled()) {
+			if (!isset(self::$backendTypes[$itemType])) {
+				self::$backendTypes[$itemType] = array(
+					'class' => $class,
+					'collectionOf' => $collectionOf,
+					'supportedFileExtensions' => $supportedFileExtensions
+				);
+				if(count(self::$backendTypes) === 1) {
+					\OC_Util::addScript('core', 'share');
+					\OC_Util::addStyle('core', 'share');
+				}
+				return true;
+			}
+			\OC_Log::write('OCP\Share',
+				'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class']
+				.' is already registered for '.$itemType,
+				\OC_Log::WARN);
+		}
+		return false;
+	}
+
+	/**
+	 * Check if the Share API is enabled
+	 * @return Returns true if enabled or false
+	 *
+	 * The Share API is enabled by default if not configured
+	 */
+	public static function isEnabled() {
+		if (\OC_Appconfig::getValue('core', 'shareapi_enabled', 'yes') == 'yes') {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Find which users can access a shared item
+	 * @param $path to the file
+	 * @param $user owner of the file
+	 * @param include owner to the list of users with access to the file
+	 * @return array
+	 * @note $path needs to be relative to user data dir, e.g. 'file.txt'
+	 *       not '/admin/data/file.txt'
+	 */
+	public static function getUsersSharingFile($path, $user, $includeOwner = false) {
+
+		$shares = array();
+		$publicShare = false;
+		$source = -1;
+		$cache = false;
+
+		$view = new \OC\Files\View('/' . $user . '/files');
+		if ($view->file_exists($path)) {
+			$meta = $view->getFileInfo($path);
+		} else {
+			// if the file doesn't exists yet we start with the parent folder
+			$meta = $view->getFileInfo(dirname($path));
+		}
+
+		if($meta !== false) {
+			$source = $meta['fileid'];
+			$cache = new \OC\Files\Cache\Cache($meta['storage']);
+		}
+
+		while ($source !== -1) {
+
+			// Fetch all shares with another user
+			$query = \OC_DB::prepare(
+				'SELECT `share_with`
+				FROM
+				`*PREFIX*share`
+				WHERE
+				`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
+			);
+
+			$result = $query->execute(array($source, self::SHARE_TYPE_USER));
+
+			if (\OCP\DB::isError($result)) {
+				\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
+			} else {
+				while ($row = $result->fetchRow()) {
+					$shares[] = $row['share_with'];
+				}
+			}
+			// We also need to take group shares into account
+
+			$query = \OC_DB::prepare(
+				'SELECT `share_with`
+				FROM
+				`*PREFIX*share`
+				WHERE
+				`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
+			);
+
+			$result = $query->execute(array($source, self::SHARE_TYPE_GROUP));
+
+			if (\OCP\DB::isError($result)) {
+				\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
+			} else {
+				while ($row = $result->fetchRow()) {
+					$usersInGroup = \OC_Group::usersInGroup($row['share_with']);
+					$shares = array_merge($shares, $usersInGroup);
+				}
+			}
+
+			//check for public link shares
+			if (!$publicShare) {
+				$query = \OC_DB::prepare(
+					'SELECT `share_with`
+					FROM
+					`*PREFIX*share`
+					WHERE
+					`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
+				);
+
+				$result = $query->execute(array($source, self::SHARE_TYPE_LINK));
+
+				if (\OCP\DB::isError($result)) {
+					\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
+				} else {
+					if ($result->fetchRow()) {
+						$publicShare = true;
+					}
+				}
+			}
+
+			// let's get the parent for the next round
+			$meta = $cache->get((int)$source);
+			if($meta !== false) {
+				$source = (int)$meta['parent'];
+			} else {
+				$source = -1;
+			}
+		}
+		// Include owner in list of users, if requested
+		if ($includeOwner) {
+			$shares[] = $user;
+		}
+
+		return array("users" => array_unique($shares), "public" => $publicShare);
+	}
+
+	/**
+	 * Get the items of item type shared with the current user
+	 * @param string Item type
+	 * @param int Format (optional) Format type must be defined by the backend
+	 * @param mixed Parameters (optional)
+	 * @param int Number of items to return (optional) Returns all by default
+	 * @param bool include collections (optional)
+	 * @return Return depends on format
+	 */
+	public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE,
+		$parameters = null, $limit = -1, $includeCollections = false) {
+		return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
+			$parameters, $limit, $includeCollections);
+	}
+
+	/**
+	 * Get the item of item type shared with the current user
+	 * @param string $itemType
+	 * @param string $itemTarget
+	 * @param int $format (optional) Format type must be defined by the backend
+	 * @param mixed Parameters (optional)
+	 * @param bool include collections (optional)
+	 * @return Return depends on format
+	 */
+	public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE,
+		$parameters = null, $includeCollections = false) {
+		return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
+			$parameters, 1, $includeCollections);
+	}
+
+	/**
+	 * Get the item of item type shared with a given user by source
+	 * @param string $itemType
+	 * @param string $itemSource
+	 * @param string $user User user to whom the item was shared
+	 * @return array Return list of items with file_target, permissions and expiration
+	 */
+	public static function getItemSharedWithUser($itemType, $itemSource, $user) {
+
+		$shares = array();
+
+		// first check if there is a db entry for the specific user
+		$query = \OC_DB::prepare(
+				'SELECT `file_target`, `permissions`, `expiration`
+					FROM
+					`*PREFIX*share`
+					WHERE
+					`item_source` = ? AND `item_type` = ? AND `share_with` = ?'
+				);
+
+		$result = \OC_DB::executeAudited($query, array($itemSource, $itemType, $user));
+
+		while ($row = $result->fetchRow()) {
+			$shares[] = $row;
+		}
+
+		//if didn't found a result than let's look for a group share.
+		if(empty($shares)) {
+			$groups = \OC_Group::getUserGroups($user);
+
+			$query = \OC_DB::prepare(
+					'SELECT `file_target`, `permissions`, `expiration`
+						FROM
+						`*PREFIX*share`
+						WHERE
+						`item_source` = ? AND `item_type` = ? AND `share_with` in (?)'
+					);
+
+			$result = \OC_DB::executeAudited($query, array($itemSource, $itemType, implode(',', $groups)));
+
+			while ($row = $result->fetchRow()) {
+				$shares[] = $row;
+			}
+		}
+
+		return $shares;
+
+	}
+
+	/**
+	 * Get the item of item type shared with the current user by source
+	 * @param string Item type
+	 * @param string Item source
+	 * @param int Format (optional) Format type must be defined by the backend
+	 * @param mixed Parameters
+	 * @param bool include collections
+	 * @return Return depends on format
+	 */
+	public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
+		$parameters = null, $includeCollections = false) {
+		return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
+			$parameters, 1, $includeCollections, true);
+	}
+
+	/**
+	 * Get the item of item type shared by a link
+	 * @param string Item type
+	 * @param string Item source
+	 * @param string Owner of link
+	 * @return Item
+	 */
+	public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) {
+		return self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE,
+			null, 1);
+	}
+
+	/**
+	 * Based on the given token the share information will be returned - password protected shares will be verified
+	 * @param string $token
+	 * @return array | bool false will be returned in case the token is unknown or unauthorized
+	 */
+	public static function getShareByToken($token, $checkPasswordProtection = true) {
+		$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1);
+		$result = $query->execute(array($token));
+		if (\OC_DB::isError($result)) {
+			\OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', token=' . $token, \OC_Log::ERROR);
+		}
+		$row = $result->fetchRow();
+		if ($row === false) {
+			return false;
+		}
+		if (is_array($row) and self::expireItem($row)) {
+			return false;
+		}
+
+		// password protected shares need to be authenticated
+		if ($checkPasswordProtection && !\OCP\Share::checkPasswordProtectedShare($row)) {
+			return false;
+		}
+
+		return $row;
+	}
+
+	/**
+	 * resolves reshares down to the last real share
+	 * @param $linkItem
+	 * @return $fileOwner
+	 */
+	public static function resolveReShare($linkItem)
+	{
+		if (isset($linkItem['parent'])) {
+			$parent = $linkItem['parent'];
+			while (isset($parent)) {
+				$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `id` = ?', 1);
+				$item = $query->execute(array($parent))->fetchRow();
+				if (isset($item['parent'])) {
+					$parent = $item['parent'];
+				} else {
+					return $item;
+				}
+			}
+		}
+		return $linkItem;
+	}
+
+
+	/**
+	 * Get the shared items of item type owned by the current user
+	 * @param string Item type
+	 * @param int Format (optional) Format type must be defined by the backend
+	 * @param mixed Parameters
+	 * @param int Number of items to return (optional) Returns all by default
+	 * @param bool include collections
+	 * @return Return depends on format
+	 */
+	public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null,
+		$limit = -1, $includeCollections = false) {
+		return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format,
+			$parameters, $limit, $includeCollections);
+	}
+
+	/**
+	 * Get the shared item of item type owned by the current user
+	 * @param string Item type
+	 * @param string Item source
+	 * @param int Format (optional) Format type must be defined by the backend
+	 * @param mixed Parameters
+	 * @param bool include collections
+	 * @return Return depends on format
+	 */
+	public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE,
+	                                     $parameters = null, $includeCollections = false) {
+		return self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(), $format,
+			$parameters, -1, $includeCollections);
+	}
+
+	/**
+	 * Get all users an item is shared with
+	 * @param string Item type
+	 * @param string Item source
+	 * @param string Owner
+	 * @param bool Include collections
+	 * @praram bool check expire date
+	 * @return Return array of users
+	 */
+	public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false, $checkExpireDate = true) {
+
+		$users = array();
+		$items = self::getItems($itemType, $itemSource, null, null, $uidOwner, self::FORMAT_NONE, null, -1, $includeCollections, false, $checkExpireDate);
+		if ($items) {
+			foreach ($items as $item) {
+				if ((int)$item['share_type'] === self::SHARE_TYPE_USER) {
+					$users[] = $item['share_with'];
+				} else if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
+					$users = array_merge($users, \OC_Group::usersInGroup($item['share_with']));
+				}
+			}
+		}
+		return $users;
+	}
+
+	/**
+	 * Share an item with a user, group, or via private link
+	 * @param string $itemType
+	 * @param string $itemSource
+	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @param string $shareWith User or group the item is being shared with
+	 * @param int $permissions CRUDS
+	 * @param null $itemSourceName
+	 * @throws \Exception
+	 * @internal param \OCP\Item $string type
+	 * @internal param \OCP\Item $string source
+	 * @internal param \OCP\SHARE_TYPE_USER $int , SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @internal param \OCP\User $string or group the item is being shared with
+	 * @internal param \OCP\CRUDS $int permissions
+	 * @return bool|string Returns true on success or false on failure, Returns token on success for links
+	 */
+	public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null) {
+		$uidOwner = \OC_User::getUser();
+		$sharingPolicy = \OC_Appconfig::getValue('core', 'shareapi_share_policy', 'global');
+
+		if (is_null($itemSourceName)) {
+			$itemSourceName = $itemSource;
+		}
+
+		// Verify share type and sharing conditions are met
+		if ($shareType === self::SHARE_TYPE_USER) {
+			if ($shareWith == $uidOwner) {
+				$message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' is the item owner';
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+			if (!\OC_User::userExists($shareWith)) {
+				$message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' does not exist';
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+			if ($sharingPolicy == 'groups_only') {
+				$inGroup = array_intersect(\OC_Group::getUserGroups($uidOwner), \OC_Group::getUserGroups($shareWith));
+				if (empty($inGroup)) {
+					$message = 'Sharing '.$itemSourceName.' failed, because the user '
+						.$shareWith.' is not a member of any groups that '.$uidOwner.' is a member of';
+					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+					throw new \Exception($message);
+				}
+			}
+			// Check if the item source is already shared with the user, either from the same owner or a different user
+			if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups,
+				$shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
+				// Only allow the same share to occur again if it is the same
+				// owner and is not a user share, this use case is for increasing
+				// permissions for a specific user
+				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
+					$message = 'Sharing '.$itemSourceName.' failed, because this item is already shared with '.$shareWith;
+					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+					throw new \Exception($message);
+				}
+			}
+		} else if ($shareType === self::SHARE_TYPE_GROUP) {
+			if (!\OC_Group::groupExists($shareWith)) {
+				$message = 'Sharing '.$itemSourceName.' failed, because the group '.$shareWith.' does not exist';
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+			if ($sharingPolicy == 'groups_only' && !\OC_Group::inGroup($uidOwner, $shareWith)) {
+				$message = 'Sharing '.$itemSourceName.' failed, because '
+					.$uidOwner.' is not a member of the group '.$shareWith;
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+			// Check if the item source is already shared with the group, either from the same owner or a different user
+			// The check for each user in the group is done inside the put() function
+			if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_GROUP, $shareWith,
+				null, self::FORMAT_NONE, null, 1, true, true)) {
+				// Only allow the same share to occur again if it is the same
+				// owner and is not a group share, this use case is for increasing
+				// permissions for a specific user
+				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
+					$message = 'Sharing '.$itemSourceName.' failed, because this item is already shared with '.$shareWith;
+					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+					throw new \Exception($message);
+				}
+			}
+			// Convert share with into an array with the keys group and users
+			$group = $shareWith;
+			$shareWith = array();
+			$shareWith['group'] = $group;
+			$shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
+		} else if ($shareType === self::SHARE_TYPE_LINK) {
+			if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') == 'yes') {
+				// when updating a link share
+				if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null,
+					$uidOwner, self::FORMAT_NONE, null, 1)) {
+					// remember old token
+					$oldToken = $checkExists['token'];
+					$oldPermissions = $checkExists['permissions'];
+					//delete the old share
+					Helper::delete($checkExists['id']);
+				}
+
+				// Generate hash of password - same method as user passwords
+				if (isset($shareWith)) {
+					$forcePortable = (CRYPT_BLOWFISH != 1);
+					$hasher = new \PasswordHash(8, $forcePortable);
+					$shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', ''));
+				} else {
+					// reuse the already set password, but only if we change permissions
+					// otherwise the user disabled the password protection
+					if ($checkExists && (int)$permissions !== (int)$oldPermissions) {
+						$shareWith = $checkExists['share_with'];
+					}
+				}
+
+				// Generate token
+				if (isset($oldToken)) {
+					$token = $oldToken;
+				} else {
+					$token = \OC_Util::generateRandomBytes(self::TOKEN_LENGTH);
+				}
+				$result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions,
+					null, $token, $itemSourceName);
+				if ($result) {
+					return $token;
+				} else {
+					return false;
+				}
+			}
+			$message = 'Sharing '.$itemSourceName.' failed, because sharing with links is not allowed';
+			\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+			throw new \Exception($message);
+			return false;
+		} else {
+			// Future share types need to include their own conditions
+			$message = 'Share type '.$shareType.' is not valid for '.$itemSource;
+			\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+			throw new \Exception($message);
+		}
+			// Put the item into the database
+			return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName);
+	}
+
+	/**
+	 * Unshare an item from a user, group, or delete a private link
+	 * @param string Item type
+	 * @param string Item source
+	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @param string User or group the item is being shared with
+	 * @return Returns true on success or false on failure
+	 */
+	public static function unshare($itemType, $itemSource, $shareType, $shareWith) {
+		$item = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(),self::FORMAT_NONE, null, 1);
+		if (!empty($item)) {
+			self::unshareItem($item);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Unshare an item from all users, groups, and remove all links
+	 * @param string Item type
+	 * @param string Item source
+	 * @return Returns true on success or false on failure
+	 */
+	public static function unshareAll($itemType, $itemSource) {
+		// Get all of the owners of shares of this item.
+		$query = \OC_DB::prepare( 'SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?' );
+		$result = $query->execute(array($itemType, $itemSource));
+		$shares = array();
+		// Add each owner's shares to the array of all shares for this item.
+		while ($row = $result->fetchRow()) {
+			$shares = array_merge($shares, self::getItems($itemType, $itemSource, null, null, $row['uid_owner']));
+		}
+		if (!empty($shares)) {
+			// Pass all the vars we have for now, they may be useful
+			$hookParams = array(
+				'itemType' => $itemType,
+				'itemSource' => $itemSource,
+				'shares' => $shares,
+			);
+			\OC_Hook::emit('OCP\Share', 'pre_unshareAll', $hookParams);
+			foreach ($shares as $share) {
+				self::unshareItem($share);
+			}
+			\OC_Hook::emit('OCP\Share', 'post_unshareAll', $hookParams);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Unshare an item shared with the current user
+	 * @param string Item type
+	 * @param string Item target
+	 * @return Returns true on success or false on failure
+	 *
+	 * Unsharing from self is not allowed for items inside collections
+	 */
+	public static function unshareFromSelf($itemType, $itemTarget) {
+		$item = self::getItemSharedWith($itemType, $itemTarget);
+		if (!empty($item)) {
+			if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
+				// Insert an extra row for the group share and set permission
+				// to 0 to prevent it from showing up for the user
+				$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share`'
+					.' (`item_type`, `item_source`, `item_target`, `parent`, `share_type`,'
+					.' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`)'
+					.' VALUES (?,?,?,?,?,?,?,?,?,?,?)');
+				$query->execute(array($item['item_type'], $item['item_source'], $item['item_target'],
+					$item['id'], self::$shareTypeGroupUserUnique,
+					\OC_User::getUser(), $item['uid_owner'], 0, $item['stime'], $item['file_source'],
+					$item['file_target']));
+				\OC_DB::insertid('*PREFIX*share');
+				// Delete all reshares by this user of the group share
+				Helper::delete($item['id'], true, \OC_User::getUser());
+			} else if ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
+				// Set permission to 0 to prevent it from showing up for the user
+				$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?');
+				$query->execute(array(0, $item['id']));
+				Helper::delete($item['id'], true);
+			} else {
+				Helper::delete($item['id']);
+			}
+			return true;
+		}
+		return false;
+	}
+	/**
+	 * sent status if users got informed by mail about share
+	 * @param string $itemType
+	 * @param string $itemSource
+	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @param bool $status
+	 */
+	public static function setSendMailStatus($itemType, $itemSource, $shareType, $status) {
+		$status = $status ? 1 : 0;
+
+		$query = \OC_DB::prepare(
+				'UPDATE `*PREFIX*share`
+					SET `mail_send` = ?
+					WHERE `item_type` = ? AND `item_source` = ? AND `share_type` = ?');
+
+		$result = $query->execute(array($status, $itemType, $itemSource, $shareType));
+
+		if($result === false) {
+			\OC_Log::write('OCP\Share', 'Couldn\'t set send mail status', \OC_Log::ERROR);
+		}
+	}
+
+	/**
+	 * Set the permissions of an item for a specific user or group
+	 * @param string Item type
+	 * @param string Item source
+	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @param string User or group the item is being shared with
+	 * @param int CRUDS permissions
+	 * @return Returns true on success or false on failure
+	 */
+	public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) {
+		if ($item = self::getItems($itemType, $itemSource, $shareType, $shareWith,
+			\OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) {
+			// Check if this item is a reshare and verify that the permissions
+			// granted don't exceed the parent shared item
+			if (isset($item['parent'])) {
+				$query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*share` WHERE `id` = ?', 1);
+				$result = $query->execute(array($item['parent']))->fetchRow();
+				if (~(int)$result['permissions'] & $permissions) {
+					$message = 'Setting permissions for '.$itemSource.' failed,'
+						.' because the permissions exceed permissions granted to '.\OC_User::getUser();
+					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+					throw new \Exception($message);
+				}
+			}
+			$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?');
+			$query->execute(array($permissions, $item['id']));
+			if ($itemType === 'file' || $itemType === 'folder') {
+				\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
+					'itemType' => $itemType,
+					'itemSource' => $itemSource,
+					'shareType' => $shareType,
+					'shareWith' => $shareWith,
+					'uidOwner' => \OC_User::getUser(),
+					'permissions' => $permissions,
+					'path' => $item['path'],
+				));
+			}
+			// Check if permissions were removed
+			if ($item['permissions'] & ~$permissions) {
+				// If share permission is removed all reshares must be deleted
+				if (($item['permissions'] & \OCP\PERMISSION_SHARE) && (~$permissions & \OCP\PERMISSION_SHARE)) {
+					Helper::delete($item['id'], true);
+				} else {
+					$ids = array();
+					$parents = array($item['id']);
+					while (!empty($parents)) {
+						$parents = "'".implode("','", $parents)."'";
+						$query = \OC_DB::prepare('SELECT `id`, `permissions` FROM `*PREFIX*share`'
+							.' WHERE `parent` IN ('.$parents.')');
+						$result = $query->execute();
+						// Reset parents array, only go through loop again if
+						// items are found that need permissions removed
+						$parents = array();
+						while ($item = $result->fetchRow()) {
+							// Check if permissions need to be removed
+							if ($item['permissions'] & ~$permissions) {
+								// Add to list of items that need permissions removed
+								$ids[] = $item['id'];
+								$parents[] = $item['id'];
+							}
+						}
+					}
+					// Remove the permissions for all reshares of this item
+					if (!empty($ids)) {
+						$ids = "'".implode("','", $ids)."'";
+						// TODO this should be done with Doctrine platform objects
+						if (\OC_Config::getValue( "dbtype") === 'oci') {
+							$andOp = 'BITAND(`permissions`, ?)';
+						} else {
+							$andOp = '`permissions` & ?';
+						}
+						$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp
+							.' WHERE `id` IN ('.$ids.')');
+						$query->execute(array($permissions));
+					}
+				}
+			}
+			return true;
+		}
+		$message = 'Setting permissions for '.$itemSource.' failed, because the item was not found';
+		\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+		throw new \Exception($message);
+	}
+
+	/**
+	 * Set expiration date for a share
+	 * @param string $itemType
+	 * @param string $itemSource
+	 * @param string $date expiration date
+	 * @return \OCP\Share_Backend
+	 */
+	public static function setExpirationDate($itemType, $itemSource, $date) {
+		$user = \OC_User::getUser();
+		$items = self::getItems($itemType, $itemSource, null, null, $user, self::FORMAT_NONE, null, -1, false);
+		if (!empty($items)) {
+			if ($date == '') {
+				$date = null;
+			} else {
+				$date = new \DateTime($date);
+			}
+			$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `id` = ?');
+			$query->bindValue(1, $date, 'datetime');
+			foreach ($items as $item) {
+				$query->bindValue(2, (int) $item['id']);
+				$query->execute();
+				\OC_Hook::emit('OCP\Share', 'post_set_expiration_date', array(
+					'itemType' => $itemType,
+					'itemSource' => $itemSource,
+					'date' => $date,
+					'uidOwner' => $user
+				));
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether a share has expired, calls unshareItem() if yes.
+	 * @param array $item Share data (usually database row)
+	 * @return bool True if item was expired, false otherwise.
+	 */
+	protected static function expireItem(array $item) {
+		if (!empty($item['expiration'])) {
+			$now = new \DateTime();
+			$expires = new \DateTime($item['expiration']);
+			if ($now > $expires) {
+				self::unshareItem($item);
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Unshares a share given a share data array
+	 * @param array $item Share data (usually database row)
+	 * @return null
+	 */
+	protected static function unshareItem(array $item) {
+		// Pass all the vars we have for now, they may be useful
+		$hookParams = array(
+			'itemType'      => $item['item_type'],
+			'itemSource'    => $item['item_source'],
+			'shareType'     => $item['share_type'],
+			'shareWith'     => $item['share_with'],
+			'itemParent'    => $item['parent'],
+			'uidOwner'      => $item['uid_owner'],
+		);
+
+		\OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams + array(
+			'fileSource'	=> $item['file_source'],
+		));
+		Helper::delete($item['id']);
+		\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
+	}
+
+	/**
+	 * Get the backend class for the specified item type
+	 * @param string $itemType
+	 * @return \OCP\Share_Backend
+	 */
+	public static function getBackend($itemType) {
+		if (isset(self::$backends[$itemType])) {
+			return self::$backends[$itemType];
+		} else if (isset(self::$backendTypes[$itemType]['class'])) {
+			$class = self::$backendTypes[$itemType]['class'];
+			if (class_exists($class)) {
+				self::$backends[$itemType] = new $class;
+				if (!(self::$backends[$itemType] instanceof \OCP\Share_Backend)) {
+					$message = 'Sharing backend '.$class.' must implement the interface OCP\Share_Backend';
+					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+					throw new \Exception($message);
+				}
+				return self::$backends[$itemType];
+			} else {
+				$message = 'Sharing backend '.$class.' not found';
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+		}
+		$message = 'Sharing backend for '.$itemType.' not found';
+		\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+		throw new \Exception($message);
+	}
+
+	/**
+	 * Check if resharing is allowed
+	 * @return Returns true if allowed or false
+	 *
+	 * Resharing is allowed by default if not configured
+	 */
+	private static function isResharingAllowed() {
+		if (!isset(self::$isResharingAllowed)) {
+			if (\OC_Appconfig::getValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') {
+				self::$isResharingAllowed = true;
+			} else {
+				self::$isResharingAllowed = false;
+			}
+		}
+		return self::$isResharingAllowed;
+	}
+
+	/**
+	 * Get a list of collection item types for the specified item type
+	 * @param string Item type
+	 * @return array
+	 */
+	private static function getCollectionItemTypes($itemType) {
+		$collectionTypes = array($itemType);
+		foreach (self::$backendTypes as $type => $backend) {
+			if (in_array($backend['collectionOf'], $collectionTypes)) {
+				$collectionTypes[] = $type;
+			}
+		}
+		// TODO Add option for collections to be collection of themselves, only 'folder' does it now...
+		if (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection || $itemType != 'folder') {
+			unset($collectionTypes[0]);
+		}
+		// Return array if collections were found or the item type is a
+		// collection itself - collections can be inside collections
+		if (count($collectionTypes) > 0) {
+			return $collectionTypes;
+		}
+		return false;
+	}
+
+	/**
+	 * Get shared items from the database
+	 * @param string Item type
+	 * @param string Item source or target (optional)
+	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
+	 * @param string User or group the item is being shared with
+	 * @param string User that is the owner of shared items (optional)
+	 * @param int Format to convert items to with formatItems()
+	 * @param mixed Parameters to pass to formatItems()
+	 * @param int Number of items to return, -1 to return all matches (optional)
+	 * @param bool Include collection item types (optional)
+	 * @param bool TODO (optional)
+	 * @prams bool check expire date
+	 * @return array
+	 *
+	 * See public functions getItem(s)... for parameter usage
+	 *
+	 */
+	public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null,
+		$uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1,
+		$includeCollections = false, $itemShareWithBySource = false, $checkExpireDate  = true) {
+		if (!self::isEnabled()) {
+			return array();
+		}
+		$backend = self::getBackend($itemType);
+		$collectionTypes = false;
+		// Get filesystem root to add it to the file target and remove from the
+		// file source, match file_source with the file cache
+		if ($itemType == 'file' || $itemType == 'folder') {
+			if(!is_null($uidOwner)) {
+				$root = \OC\Files\Filesystem::getRoot();
+			} else {
+				$root = '';
+			}
+			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`';
+			if (!isset($item)) {
+				$where .= ' WHERE `file_target` IS NOT NULL';
+			}
+			$fileDependent = true;
+			$queryArgs = array();
+		} else {
+			$fileDependent = false;
+			$root = '';
+			$collectionTypes = self::getCollectionItemTypes($itemType);
+			if ($includeCollections && !isset($item) && $collectionTypes) {
+				// If includeCollections is true, find collections of this item type, e.g. a music album contains songs
+				if (!in_array($itemType, $collectionTypes)) {
+					$itemTypes = array_merge(array($itemType), $collectionTypes);
+				} else {
+					$itemTypes = $collectionTypes;
+				}
+				$placeholders = join(',', array_fill(0, count($itemTypes), '?'));
+				$where = ' WHERE `item_type` IN ('.$placeholders.'))';
+				$queryArgs = $itemTypes;
+			} else {
+				$where = ' WHERE `item_type` = ?';
+				$queryArgs = array($itemType);
+			}
+		}
+		if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
+			$where .= ' AND `share_type` != ?';
+			$queryArgs[] = self::SHARE_TYPE_LINK;
+		}
+		if (isset($shareType)) {
+			// Include all user and group items
+			if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
+				$where .= ' AND `share_type` IN (?,?,?)';
+				$queryArgs[] = self::SHARE_TYPE_USER;
+				$queryArgs[] = self::SHARE_TYPE_GROUP;
+				$queryArgs[] = self::$shareTypeGroupUserUnique;
+				$userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith));
+				$placeholders = join(',', array_fill(0, count($userAndGroups), '?'));
+				$where .= ' AND `share_with` IN ('.$placeholders.')';
+				$queryArgs = array_merge($queryArgs, $userAndGroups);
+				// Don't include own group shares
+				$where .= ' AND `uid_owner` != ?';
+				$queryArgs[] = $shareWith;
+			} else {
+				$where .= ' AND `share_type` = ?';
+				$queryArgs[] = $shareType;
+				if (isset($shareWith)) {
+					$where .= ' AND `share_with` = ?';
+					$queryArgs[] = $shareWith;
+				}
+			}
+		}
+		if (isset($uidOwner)) {
+			$where .= ' AND `uid_owner` = ?';
+			$queryArgs[] = $uidOwner;
+			if (!isset($shareType)) {
+				// Prevent unique user targets for group shares from being selected
+				$where .= ' AND `share_type` != ?';
+				$queryArgs[] = self::$shareTypeGroupUserUnique;
+			}
+			if ($fileDependent) {
+				$column = 'file_source';
+			} else {
+				$column = 'item_source';
+			}
+		} else {
+			if ($fileDependent) {
+				$column = 'file_target';
+			} else {
+				$column = 'item_target';
+			}
+		}
+		if (isset($item)) {
+			$collectionTypes = self::getCollectionItemTypes($itemType);
+			if ($includeCollections && $collectionTypes) {
+				$where .= ' AND (';
+			} else {
+				$where .= ' AND';
+			}
+			// If looking for own shared items, check item_source else check item_target
+			if (isset($uidOwner) || $itemShareWithBySource) {
+				// If item type is a file, file source needs to be checked in case the item was converted
+				if ($fileDependent) {
+					$where .= ' `file_source` = ?';
+					$column = 'file_source';
+				} else {
+					$where .= ' `item_source` = ?';
+					$column = 'item_source';
+				}
+			} else {
+				if ($fileDependent) {
+					$where .= ' `file_target` = ?';
+					$item = \OC\Files\Filesystem::normalizePath($item);
+				} else {
+					$where .= ' `item_target` = ?';
+				}
+			}
+			$queryArgs[] = $item;
+			if ($includeCollections && $collectionTypes) {
+				$placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
+				$where .= ' OR `item_type` IN ('.$placeholders.'))';
+				$queryArgs = array_merge($queryArgs, $collectionTypes);
+			}
+		}
+		if ($limit != -1 && !$includeCollections) {
+			if ($shareType == self::$shareTypeUserAndGroups) {
+				// Make sure the unique user target is returned if it exists,
+				// unique targets should follow the group share in the database
+				// If the limit is not 1, the filtering can be done later
+				$where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
+			}
+			// The limit must be at least 3, because filtering needs to be done
+			if ($limit < 3) {
+				$queryLimit = 3;
+			} else {
+				$queryLimit = $limit;
+			}
+		} else {
+			$queryLimit = null;
+		}
+		$select = self::createSelectStatement($format, $fileDependent, $uidOwner);
+		$root = strlen($root);
+		$query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit);
+		$result = $query->execute($queryArgs);
+		if (\OC_DB::isError($result)) {
+			\OC_Log::write('OCP\Share',
+				\OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where,
+				\OC_Log::ERROR);
+		}
+		$items = array();
+		$targets = array();
+		$switchedItems = array();
+		$mounts = array();
+		while ($row = $result->fetchRow()) {
+			self::transformDBResults($row);
+			// Filter out duplicate group shares for users with unique targets
+			if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
+				$row['share_type'] = self::SHARE_TYPE_GROUP;
+				$row['share_with'] = $items[$row['parent']]['share_with'];
+				// Remove the parent group share
+				unset($items[$row['parent']]);
+				if ($row['permissions'] == 0) {
+					continue;
+				}
+			} else if (!isset($uidOwner)) {
+				// Check if the same target already exists
+				if (isset($targets[$row[$column]])) {
+					// Check if the same owner shared with the user twice
+					// through a group and user share - this is allowed
+					$id = $targets[$row[$column]];
+					if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
+						// Switch to group share type to ensure resharing conditions aren't bypassed
+						if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
+							$items[$id]['share_type'] = self::SHARE_TYPE_GROUP;
+							$items[$id]['share_with'] = $row['share_with'];
+						}
+						// Switch ids if sharing permission is granted on only
+						// one share to ensure correct parent is used if resharing
+						if (~(int)$items[$id]['permissions'] & \OCP\PERMISSION_SHARE
+							&& (int)$row['permissions'] & \OCP\PERMISSION_SHARE) {
+							$items[$row['id']] = $items[$id];
+							$switchedItems[$id] = $row['id'];
+							unset($items[$id]);
+							$id = $row['id'];
+						}
+						// Combine the permissions for the item
+						$items[$id]['permissions'] |= (int)$row['permissions'];
+						continue;
+					}
+				} else {
+					$targets[$row[$column]] = $row['id'];
+				}
+			}
+			// Remove root from file source paths if retrieving own shared items
+			if (isset($uidOwner) && isset($row['path'])) {
+				if (isset($row['parent'])) {
+					// FIXME: Doesn't always construct the correct path, example:
+					// Folder '/a/b', share '/a' and '/a/b' to user2
+					// user2 reshares /Shared/b and ask for share status of /Shared/a/b
+					// expected result: path=/Shared/a/b; actual result /Shared/b because of the parent
+					$query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
+					$parentResult = $query->execute(array($row['parent']));
+					if (\OC_DB::isError($result)) {
+						\OC_Log::write('OCP\Share', 'Can\'t select parent: ' .
+								\OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where,
+								\OC_Log::ERROR);
+					} else {
+						$parentRow = $parentResult->fetchRow();
+						$tmpPath = '/Shared' . $parentRow['file_target'];
+						// find the right position where the row path continues from the target path
+						$pos = strrpos($row['path'], $parentRow['file_target']);
+						$subPath = substr($row['path'], $pos);
+						$splitPath = explode('/', $subPath);
+						foreach (array_slice($splitPath, 2) as $pathPart) {
+							$tmpPath = $tmpPath . '/' . $pathPart;
+						}
+						$row['path'] = $tmpPath;
+					}
+				} else {
+					if (!isset($mounts[$row['storage']])) {
+						$mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
+						if (is_array($mountPoints)) {
+							$mounts[$row['storage']] = current($mountPoints);
+						}
+					}
+					if ($mounts[$row['storage']]) {
+						$path = $mounts[$row['storage']]->getMountPoint().$row['path'];
+						$row['path'] = substr($path, $root);
+					}
+				}
+			}
+			if($checkExpireDate) {
+				if (self::expireItem($row)) {
+					continue;
+				}
+			}
+			// Check if resharing is allowed, if not remove share permission
+			if (isset($row['permissions']) && !self::isResharingAllowed()) {
+				$row['permissions'] &= ~\OCP\PERMISSION_SHARE;
+			}
+			// Add display names to result
+			if ( isset($row['share_with']) && $row['share_with'] != '') {
+				$row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']);
+			}
+			if ( isset($row['uid_owner']) && $row['uid_owner'] != '') {
+				$row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
+			}
+
+			$items[$row['id']] = $row;
+		}
+		if (!empty($items)) {
+			$collectionItems = array();
+			foreach ($items as &$row) {
+				// Return only the item instead of a 2-dimensional array
+				if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
+					if ($format == self::FORMAT_NONE) {
+						return $row;
+					} else {
+						break;
+					}
+				}
+				// Check if this is a collection of the requested item type
+				if ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
+					if (($collectionBackend = self::getBackend($row['item_type']))
+						&& $collectionBackend instanceof \OCP\Share_Backend_Collection) {
+						// Collections can be inside collections, check if the item is a collection
+						if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
+							$collectionItems[] = $row;
+						} else {
+							$collection = array();
+							$collection['item_type'] = $row['item_type'];
+							if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
+								$collection['path'] = basename($row['path']);
+							}
+							$row['collection'] = $collection;
+							// Fetch all of the children sources
+							$children = $collectionBackend->getChildren($row[$column]);
+							foreach ($children as $child) {
+								$childItem = $row;
+								$childItem['item_type'] = $itemType;
+								if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
+									$childItem['item_source'] = $child['source'];
+									$childItem['item_target'] = $child['target'];
+								}
+								if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
+									if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
+										$childItem['file_source'] = $child['source'];
+									} else { // TODO is this really needed if we already know that we use the file backend?
+										$meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
+										$childItem['file_source'] = $meta['fileid'];
+									}
+									$childItem['file_target'] =
+										\OC\Files\Filesystem::normalizePath($child['file_path']);
+								}
+								if (isset($item)) {
+									if ($childItem[$column] == $item) {
+										// Return only the item instead of a 2-dimensional array
+										if ($limit == 1) {
+											if ($format == self::FORMAT_NONE) {
+												return $childItem;
+											} else {
+												// Unset the items array and break out of both loops
+												$items = array();
+												$items[] = $childItem;
+												break 2;
+											}
+										} else {
+											$collectionItems[] = $childItem;
+										}
+									}
+								} else {
+									$collectionItems[] = $childItem;
+								}
+							}
+						}
+					}
+					// Remove collection item
+					$toRemove = $row['id'];
+					if (array_key_exists($toRemove, $switchedItems)) {
+						$toRemove = $switchedItems[$toRemove];
+					}
+					unset($items[$toRemove]);
+				}
+			}
+			if (!empty($collectionItems)) {
+				$items = array_merge($items, $collectionItems);
+			}
+
+			return self::formatResult($items, $column, $backend, $format, $parameters);
+		}
+
+		return array();
+	}
+
+	/**
+	 * Put shared item into the database
+	 * @param string Item type
+	 * @param string Item source
+	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @param string User or group the item is being shared with
+	 * @param string User that is the owner of shared item
+	 * @param int CRUDS permissions
+	 * @param bool|array Parent folder target (optional)
+	 * @param string token (optional)
+	 * @param string name of the source item (optional)
+	 * @return bool Returns true on success or false on failure
+	 */
+	private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
+		$permissions, $parentFolder = null, $token = null, $itemSourceName = null) {
+		$backend = self::getBackend($itemType);
+
+		// Check if this is a reshare
+		if ($checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true)) {
+
+			// Check if attempting to share back to owner
+			if ($checkReshare['uid_owner'] == $shareWith && $shareType == self::SHARE_TYPE_USER) {
+				$message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' is the original sharer';
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+			// Check if share permissions is granted
+			if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\PERMISSION_SHARE) {
+				if (~(int)$checkReshare['permissions'] & $permissions) {
+					$message = 'Sharing '.$itemSourceName
+						.' failed, because the permissions exceed permissions granted to '.$uidOwner;
+					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+					throw new \Exception($message);
+				} else {
+					// TODO Don't check if inside folder
+					$parent = $checkReshare['id'];
+					$itemSource = $checkReshare['item_source'];
+					$fileSource = $checkReshare['file_source'];
+					$suggestedItemTarget = $checkReshare['item_target'];
+					$suggestedFileTarget = $checkReshare['file_target'];
+					$filePath = $checkReshare['file_target'];
+				}
+			} else {
+				$message = 'Sharing '.$itemSourceName.' failed, because resharing is not allowed';
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+		} else {
+			$parent = null;
+			$suggestedItemTarget = null;
+			$suggestedFileTarget = null;
+			if (!$backend->isValidSource($itemSource, $uidOwner)) {
+				$message = 'Sharing '.$itemSource.' failed, because the sharing backend for '
+					.$itemType.' could not find its source';
+				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+				throw new \Exception($message);
+			}
+			if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
+				$filePath = $backend->getFilePath($itemSource, $uidOwner);
+				if ($itemType == 'file' || $itemType == 'folder') {
+					$fileSource = $itemSource;
+				} else {
+					$meta = \OC\Files\Filesystem::getFileInfo($filePath);
+					$fileSource = $meta['fileid'];
+				}
+				if ($fileSource == -1) {
+					$message = 'Sharing '.$itemSource.' failed, because the file could not be found in the file cache';
+					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+					throw new \Exception($message);
+				}
+			} else {
+				$filePath = null;
+				$fileSource = null;
+			}
+		}
+		$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,'
+			.' `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
+			.' `file_target`, `token`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
+		// Share with a group
+		if ($shareType == self::SHARE_TYPE_GROUP) {
+			$groupItemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith['group'],
+				$uidOwner, $suggestedItemTarget);
+			$run = true;
+			$error = '';
+			\OC_Hook::emit('OCP\Share', 'pre_shared', array(
+				'itemType' => $itemType,
+				'itemSource' => $itemSource,
+				'itemTarget' => $groupItemTarget,
+				'shareType' => $shareType,
+				'shareWith' => $shareWith['group'],
+				'uidOwner' => $uidOwner,
+				'permissions' => $permissions,
+				'fileSource' => $fileSource,
+				'token' => $token,
+				'run' => &$run,
+				'error' => &$error
+			));
+
+			if ($run === false) {
+				throw new \Exception($error);
+			}
+
+			if (isset($fileSource)) {
+				if ($parentFolder) {
+					if ($parentFolder === true) {
+						$groupFileTarget = Helper::generateTarget('file', $filePath, $shareType,
+							$shareWith['group'], $uidOwner, $suggestedFileTarget);
+						// Set group default file target for future use
+						$parentFolders[0]['folder'] = $groupFileTarget;
+					} else {
+						// Get group default file target
+						$groupFileTarget = $parentFolder[0]['folder'].$itemSource;
+						$parent = $parentFolder[0]['id'];
+					}
+				} else {
+					$groupFileTarget = Helper::generateTarget('file', $filePath, $shareType, $shareWith['group'],
+						$uidOwner, $suggestedFileTarget);
+				}
+			} else {
+				$groupFileTarget = null;
+			}
+			$query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType,
+				$shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token));
+			// Save this id, any extra rows for this group share will need to reference it
+			$parent = \OC_DB::insertid('*PREFIX*share');
+			// Loop through all users of this group in case we need to add an extra row
+			foreach ($shareWith['users'] as $uid) {
+				$itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid,
+					$uidOwner, $suggestedItemTarget, $parent);
+				if (isset($fileSource)) {
+					if ($parentFolder) {
+						if ($parentFolder === true) {
+							$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $uid,
+								$uidOwner, $suggestedFileTarget, $parent);
+							if ($fileTarget != $groupFileTarget) {
+								$parentFolders[$uid]['folder'] = $fileTarget;
+							}
+						} else if (isset($parentFolder[$uid])) {
+							$fileTarget = $parentFolder[$uid]['folder'].$itemSource;
+							$parent = $parentFolder[$uid]['id'];
+						}
+					} else {
+						$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER,
+							$uid, $uidOwner, $suggestedFileTarget, $parent);
+					}
+				} else {
+					$fileTarget = null;
+				}
+				// Insert an extra row for the group share if the item or file target is unique for this user
+				if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) {
+					$query->execute(array($itemType, $itemSource, $itemTarget, $parent,
+						self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(),
+							$fileSource, $fileTarget, $token));
+					$id = \OC_DB::insertid('*PREFIX*share');
+				}
+			}
+			\OC_Hook::emit('OCP\Share', 'post_shared', array(
+				'itemType' => $itemType,
+				'itemSource' => $itemSource,
+				'itemTarget' => $groupItemTarget,
+				'parent' => $parent,
+				'shareType' => $shareType,
+				'shareWith' => $shareWith['group'],
+				'uidOwner' => $uidOwner,
+				'permissions' => $permissions,
+				'fileSource' => $fileSource,
+				'fileTarget' => $groupFileTarget,
+				'id' => $parent,
+				'token' => $token
+			));
+
+			if ($parentFolder === true) {
+				// Return parent folders to preserve file target paths for potential children
+				return $parentFolders;
+			}
+		} else {
+			$itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
+				$suggestedItemTarget);
+			$run = true;
+			$error = '';
+			\OC_Hook::emit('OCP\Share', 'pre_shared', array(
+				'itemType' => $itemType,
+				'itemSource' => $itemSource,
+				'itemTarget' => $itemTarget,
+				'shareType' => $shareType,
+				'shareWith' => $shareWith,
+				'uidOwner' => $uidOwner,
+				'permissions' => $permissions,
+				'fileSource' => $fileSource,
+				'token' => $token,
+				'run' => &$run,
+				'error' => &$error
+			));
+
+			if ($run === false) {
+				throw new \Exception($error);
+			}
+
+			if (isset($fileSource)) {
+				if ($parentFolder) {
+					if ($parentFolder === true) {
+						$fileTarget = Helper::generateTarget('file', $filePath, $shareType, $shareWith,
+							$uidOwner, $suggestedFileTarget);
+						$parentFolders['folder'] = $fileTarget;
+					} else {
+						$fileTarget = $parentFolder['folder'].$itemSource;
+						$parent = $parentFolder['id'];
+					}
+				} else {
+					$fileTarget = Helper::generateTarget('file', $filePath, $shareType, $shareWith, $uidOwner,
+						$suggestedFileTarget);
+				}
+			} else {
+				$fileTarget = null;
+			}
+			$query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner,
+				$permissions, time(), $fileSource, $fileTarget, $token));
+			$id = \OC_DB::insertid('*PREFIX*share');
+			\OC_Hook::emit('OCP\Share', 'post_shared', array(
+				'itemType' => $itemType,
+				'itemSource' => $itemSource,
+				'itemTarget' => $itemTarget,
+				'parent' => $parent,
+				'shareType' => $shareType,
+				'shareWith' => $shareWith,
+				'uidOwner' => $uidOwner,
+				'permissions' => $permissions,
+				'fileSource' => $fileSource,
+				'fileTarget' => $fileTarget,
+				'id' => $id,
+				'token' => $token
+			));
+			if ($parentFolder === true) {
+				$parentFolders['id'] = $id;
+				// Return parent folder to preserve file target paths for potential children
+				return $parentFolders;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Delete all shares with type SHARE_TYPE_LINK
+	 */
+	public static function removeAllLinkShares() {
+		// Delete any link shares
+		$query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ?');
+		$result = $query->execute(array(self::SHARE_TYPE_LINK));
+		while ($item = $result->fetchRow()) {
+			Helper::delete($item['id']);
+		}
+	}
+
+	/**
+	 * In case a password protected link is not yet authenticated this function will return false
+	 *
+	 * @param array $linkItem
+	 * @return bool
+	 */
+	public static function checkPasswordProtectedShare(array $linkItem) {
+		if (!isset($linkItem['share_with'])) {
+			return true;
+		}
+		if (!isset($linkItem['share_type'])) {
+			return true;
+		}
+		if (!isset($linkItem['id'])) {
+			return true;
+		}
+
+		if ($linkItem['share_type'] != \OCP\Share::SHARE_TYPE_LINK) {
+			return true;
+		}
+
+		if ( \OC::$session->exists('public_link_authenticated')
+			&& \OC::$session->get('public_link_authenticated') === $linkItem['id'] ) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * @breif construct select statement
+	 * @param int $format
+	 * @param bool $fileDependent ist it a file/folder share or a generla share
+	 * @param string $uidOwner
+	 * @return string select statement
+	 */
+	private static function createSelectStatement($format, $fileDependent, $uidOwner = null) {
+		$select = '*';
+		if ($format == self::FORMAT_STATUSES) {
+			if ($fileDependent) {
+				$select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `share_with`, `uid_owner`';
+			} else {
+				$select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`';
+			}
+		} else {
+			if (isset($uidOwner)) {
+				if ($fileDependent) {
+					$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
+							. ' `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`,'
+							. ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`';
+				} else {
+					$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`,'
+							. ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`';
+				}
+			} else {
+				if ($fileDependent) {
+					if ($format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) {
+						$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`, `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`,
+							`file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`';
+					}
+				}
+			}
+		}
+		return $select;
+	}
+
+
+	/**
+	 * @brief transform db results
+	 * @param array $row result
+	 */
+	private static function transformDBResults(&$row) {
+		if (isset($row['id'])) {
+			$row['id'] = (int) $row['id'];
+		}
+		if (isset($row['share_type'])) {
+			$row['share_type'] = (int) $row['share_type'];
+		}
+		if (isset($row['parent'])) {
+			$row['parent'] = (int) $row['parent'];
+		}
+		if (isset($row['file_parent'])) {
+			$row['file_parent'] = (int) $row['file_parent'];
+		}
+		if (isset($row['file_source'])) {
+			$row['file_source'] = (int) $row['file_source'];
+		}
+		if (isset($row['permissions'])) {
+			$row['permissions'] = (int) $row['permissions'];
+		}
+		if (isset($row['storage'])) {
+			$row['storage'] = (int) $row['storage'];
+		}
+		if (isset($row['stime'])) {
+			$row['stime'] = (int) $row['stime'];
+		}
+	}
+
+	/**
+	 * @brief format result
+	 * @param array $items result
+	 * @prams string $column is it a file share or a general share ('file_target' or 'item_target')
+	 * @params \OCP\Share_Backend $backend sharing backend
+	 * @param int $format
+	 * @param array additional format parameters
+	 * @return array formate result
+	 */
+	private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) {
+		if ($format === self::FORMAT_NONE) {
+			return $items;
+		} else if ($format === self::FORMAT_STATUSES) {
+			$statuses = array();
+			foreach ($items as $item) {
+				if ($item['share_type'] === self::SHARE_TYPE_LINK) {
+					$statuses[$item[$column]]['link'] = true;
+				} else if (!isset($statuses[$item[$column]])) {
+					$statuses[$item[$column]]['link'] = false;
+				}
+				if ('file_target') {
+					$statuses[$item[$column]]['path'] = $item['path'];
+				}
+			}
+			return $statuses;
+		} else {
+			return $backend->formatItems($items, $format, $parameters);
+		}
+	}
+}
diff --git a/lib/private/urlgenerator.php b/lib/private/urlgenerator.php
index b7ae8dd0f60d4d984e1da4fc430d3bf532800e1b..0d238737dde4e9af37fba54232a060025b8691fb 100644
--- a/lib/private/urlgenerator.php
+++ b/lib/private/urlgenerator.php
@@ -148,6 +148,7 @@ class URLGenerator implements IURLGenerator {
 	 */
 	public function getAbsoluteURL($url) {
 		$separator = $url[0] === '/' ? '' : '/';
-		return \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost() . $separator . $url;
+
+		return \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost(). \OC::$WEBROOT . $separator . $url;
 	}
 }
diff --git a/lib/private/user.php b/lib/private/user.php
index a89b7286c1009e48525cf039ccd4ac41228a9fe4..dc4c7ec3b611fb7cc278080a8dab615bb4b4f697 100644
--- a/lib/private/user.php
+++ b/lib/private/user.php
@@ -321,8 +321,6 @@ class OC_User {
 	 */
 	public static function isLoggedIn() {
 		if (\OC::$session->get('user_id') && self::$incognitoMode === false) {
-			OC_App::loadApps(array('authentication'));
-			self::setupBackends();
 			return self::userExists(\OC::$session->get('user_id'));
 		}
 		return false;
diff --git a/lib/private/util.php b/lib/private/util.php
index 87e173fa765da6af5e10580ef03251fccc91370f..731b7c975038f9e8dac48e71cc714be67bf459f0 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -30,9 +30,7 @@ class OC_Util {
 		}
 
 		// load all filesystem apps before, so no setup-hook gets lost
-		if(!isset($RUNTIME_NOAPPS) || !$RUNTIME_NOAPPS) {
-			OC_App::loadApps(array('filesystem'));
-		}
+		OC_App::loadApps(array('filesystem'));
 
 		// the filesystem will finish when $user is not empty,
 		// mark fs setup here to avoid doing the setup from loading
@@ -703,17 +701,18 @@ class OC_Util {
 	 * @return void
 	 */
 	public static function redirectToDefaultPage() {
+		$urlGenerator = \OC::$server->getURLGenerator();
 		if(isset($_REQUEST['redirect_url'])) {
-			$location = OC_Helper::makeURLAbsolute(urldecode($_REQUEST['redirect_url']));
+			$location = urldecode($_REQUEST['redirect_url']);
 		}
 		else if (isset(OC::$REQUESTEDAPP) && !empty(OC::$REQUESTEDAPP)) {
-			$location = OC_Helper::linkToAbsolute( OC::$REQUESTEDAPP, 'index.php' );
+			$location = $urlGenerator->getAbsoluteURL('/index.php/apps/'.OC::$REQUESTEDAPP.'/index.php');
 		} else {
 			$defaultPage = OC_Appconfig::getValue('core', 'defaultpage');
 			if ($defaultPage) {
-				$location = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/'.$defaultPage);
+				$location = $urlGenerator->getAbsoluteURL($defaultPage);
 			} else {
-				$location = OC_Helper::linkToAbsolute( 'files', 'index.php' );
+				$location = $urlGenerator->getAbsoluteURL('/index.php/files/index.php');
 			}
 		}
 		OC_Log::write('core', 'redirectToDefaultPage: '.$location, OC_Log::DEBUG);
@@ -1074,13 +1073,13 @@ class OC_Util {
 	public static function getUrlContent($url) {
 		if (function_exists('curl_init')) {
 			$curl = curl_init();
+			$max_redirects = 10;
 
 			curl_setopt($curl, CURLOPT_HEADER, 0);
 			curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 			curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
 			curl_setopt($curl, CURLOPT_URL, $url);
-			curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
-			curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
+			
 
 			curl_setopt($curl, CURLOPT_USERAGENT, "ownCloud Server Crawler");
 			if(OC_Config::getValue('proxy', '') != '') {
@@ -1089,9 +1088,50 @@ class OC_Util {
 			if(OC_Config::getValue('proxyuserpwd', '') != '') {
 				curl_setopt($curl, CURLOPT_PROXYUSERPWD, OC_Config::getValue('proxyuserpwd'));
 			}
-			$data = curl_exec($curl);
+			
+			if (ini_get('open_basedir') === '' && ini_get('safe_mode' === 'Off')) { 
+				curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+				curl_setopt($curl, CURLOPT_MAXREDIRS, $max_redirects);
+				$data = curl_exec($curl);
+			} else {
+				curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
+				$mr = $max_redirects;
+				if ($mr > 0) { 
+					$newurl = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
+					
+					$rcurl = curl_copy_handle($curl);
+					curl_setopt($rcurl, CURLOPT_HEADER, true);
+					curl_setopt($rcurl, CURLOPT_NOBODY, true);
+					curl_setopt($rcurl, CURLOPT_FORBID_REUSE, false);
+					curl_setopt($rcurl, CURLOPT_RETURNTRANSFER, true);
+					do {
+						curl_setopt($rcurl, CURLOPT_URL, $newurl);
+						$header = curl_exec($rcurl);
+						if (curl_errno($rcurl)) {
+							$code = 0;
+						} else {
+							$code = curl_getinfo($rcurl, CURLINFO_HTTP_CODE);
+							if ($code == 301 || $code == 302) {
+								preg_match('/Location:(.*?)\n/', $header, $matches);
+								$newurl = trim(array_pop($matches));
+							} else {
+								$code = 0;
+							}
+						}
+					} while ($code && --$mr);
+					curl_close($rcurl);
+					if ($mr > 0) {
+						curl_setopt($curl, CURLOPT_URL, $newurl);
+					} 
+				}
+				
+				if($mr == 0 && $max_redirects > 0) {
+					$data = false;
+				} else {
+					$data = curl_exec($curl);
+				}
+			}
 			curl_close($curl);
-
 		} else {
 			$contextArray = null;
 
diff --git a/lib/public/share.php b/lib/public/share.php
index 5066d40354d21b699da27da04a00857383e47445..a08134b3837789e9a7fc614b7909a366179e601c 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -2,8 +2,9 @@
 /**
  * ownCloud
  *
- * @author Michael Gapczynski
- * @copyright 2012 Michael Gapczynski mtgap@owncloud.com
+ * @author Bjoern Schiessle, Michael Gapczynski
+ * @copyright 2012 Michael Gapczynski <mtgap@owncloud.com>
+ *            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
@@ -36,41 +37,7 @@ namespace OCP;
  * It provides the following hooks:
  *  - post_shared
  */
-class Share {
-
-	const SHARE_TYPE_USER = 0;
-	const SHARE_TYPE_GROUP = 1;
-	const SHARE_TYPE_LINK = 3;
-	const SHARE_TYPE_EMAIL = 4;
-	const SHARE_TYPE_CONTACT = 5;
-	const SHARE_TYPE_REMOTE = 6;
-
-	/** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask
-	 * Construct permissions for share() and setPermissions with Or (|) e.g.
-	 * Give user read and update permissions: PERMISSION_READ | PERMISSION_UPDATE
-	 *
-	 * Check if permission is granted with And (&) e.g. Check if delete is
-	 * granted: if ($permissions & PERMISSION_DELETE)
-	 *
-	 * Remove permissions with And (&) and Not (~) e.g. Remove the update
-	 * permission: $permissions &= ~PERMISSION_UPDATE
-	 *
-	 * Apps are required to handle permissions on their own, this class only
-	 * stores and manages the permissions of shares
-	 * @see lib/public/constants.php
-	 */
-
-	const FORMAT_NONE = -1;
-	const FORMAT_STATUSES = -2;
-	const FORMAT_SOURCES = -3;
-
-	const TOKEN_LENGTH = 32; // see db_structure.xml
-
-	private static $shareTypeUserAndGroups = -1;
-	private static $shareTypeGroupUserUnique = 2;
-	private static $backends = array();
-	private static $backendTypes = array();
-	private static $isResharingAllowed;
+class Share extends \OC\Share\Constants {
 
 	/**
 	 * Register a sharing backend class that implements OCP\Share_Backend for an item type
@@ -78,67 +45,25 @@ class Share {
 	 * @param string Backend class
 	 * @param string (optional) Depends on item type
 	 * @param array (optional) List of supported file extensions if this item type depends on files
-	 * @param string $itemType
-	 * @param string $class
-	 * @param string $collectionOf
-	 * @return boolean true if backend is registered or false if error
+	 * @return Returns true if backend is registered or false if error
 	 */
 	public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) {
-		if (self::isEnabled()) {
-			if (!isset(self::$backendTypes[$itemType])) {
-				self::$backendTypes[$itemType] = array(
-					'class' => $class,
-					'collectionOf' => $collectionOf,
-					'supportedFileExtensions' => $supportedFileExtensions
-				);
-				if(count(self::$backendTypes) === 1) {
-					\OC_Util::addScript('core', 'share');
-					\OC_Util::addStyle('core', 'share');
-				}
-				return true;
-			}
-			\OC_Log::write('OCP\Share',
-				'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class']
-				.' is already registered for '.$itemType,
-				\OC_Log::WARN);
-		}
-		return false;
+		return \OC\Share\Share::registerBackend($itemType, $class, $collectionOf, $supportedFileExtensions);
 	}
 
 	/**
 	 * Check if the Share API is enabled
-	 * @return boolean true if enabled or false
+	 * @return Returns true if enabled or false
 	 *
 	 * The Share API is enabled by default if not configured
 	 */
 	public static function isEnabled() {
-		if (\OC_Appconfig::getValue('core', 'shareapi_enabled', 'yes') == 'yes') {
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Prepare a path to be passed to DB as file_target
-	 * @param string $path path
-	 * @return string Prepared path
-	 */
-	public static function prepFileTarget( $path ) {
-
-		// Paths in DB are stored with leading slashes, so add one if necessary
-		if ( substr( $path, 0, 1 ) !== '/' ) {
-
-			$path = '/' . $path;
-
-		}
-
-		return $path;
-
+		return \OC\Share\Share::isEnabled();
 	}
 
 	/**
 	 * Find which users can access a shared item
-	 * @param string $path to the file
+	 * @param $path to the file
 	 * @param $user owner of the file
 	 * @param include owner to the list of users with access to the file
 	 * @return array
@@ -146,101 +71,7 @@ class Share {
 	 *       not '/admin/data/file.txt'
 	 */
 	public static function getUsersSharingFile($path, $user, $includeOwner = false) {
-
-		$shares = array();
-		$publicShare = false;
-		$source = -1;
-		$cache = false;
-
-		$view = new \OC\Files\View('/' . $user . '/files');
-		if ($view->file_exists($path)) {
-			$meta = $view->getFileInfo($path);
-		} else {
-			// if the file doesn't exists yet we start with the parent folder
-			$meta = $view->getFileInfo(dirname($path));
-		}
-
-		if($meta !== false) {
-			$source = $meta['fileid'];
-			$cache = new \OC\Files\Cache\Cache($meta['storage']);
-		}
-
-		while ($source !== -1) {
-
-			// Fetch all shares with another user
-			$query = \OC_DB::prepare(
-				'SELECT `share_with`
-				FROM
-				`*PREFIX*share`
-				WHERE
-				`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
-			);
-
-			$result = $query->execute(array($source, self::SHARE_TYPE_USER));
-
-			if (\OCP\DB::isError($result)) {
-				\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
-			} else {
-				while ($row = $result->fetchRow()) {
-					$shares[] = $row['share_with'];
-				}
-			}
-			// We also need to take group shares into account
-
-			$query = \OC_DB::prepare(
-				'SELECT `share_with`
-				FROM
-				`*PREFIX*share`
-				WHERE
-				`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
-			);
-
-			$result = $query->execute(array($source, self::SHARE_TYPE_GROUP));
-
-			if (\OCP\DB::isError($result)) {
-				\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
-			} else {
-				while ($row = $result->fetchRow()) {
-					$usersInGroup = \OC_Group::usersInGroup($row['share_with']);
-					$shares = array_merge($shares, $usersInGroup);
-				}
-			}
-
-			//check for public link shares
-			if (!$publicShare) {
-				$query = \OC_DB::prepare(
-					'SELECT `share_with`
-					FROM
-					`*PREFIX*share`
-					WHERE
-					`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
-				);
-
-				$result = $query->execute(array($source, self::SHARE_TYPE_LINK));
-
-				if (\OCP\DB::isError($result)) {
-					\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
-				} else {
-					if ($result->fetchRow()) {
-						$publicShare = true;
-					}
-				}
-			}
-
-			// let's get the parent for the next round
-			$meta = $cache->get((int)$source);
-			if($meta !== false) {
-				$source = (int)$meta['parent'];
-			} else {
-				$source = -1;
-			}
-		}
-		// Include owner in list of users, if requested
-		if ($includeOwner) {
-			$shares[] = $user;
-		}
-
-		return array("users" => array_unique($shares), "public" => $publicShare);
+		return \OC\Share\Share::getUsersSharingFile($path, $user, $includeOwner);
 	}
 
 	/**
@@ -250,13 +81,12 @@ class Share {
 	 * @param mixed Parameters (optional)
 	 * @param int Number of items to return (optional) Returns all by default
 	 * @param bool include collections (optional)
-	 * @param string $itemType
 	 * @return Return depends on format
 	 */
 	public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE,
 		$parameters = null, $limit = -1, $includeCollections = false) {
-		return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
-			$parameters, $limit, $includeCollections);
+
+		return \OC\Share\Share::getItemsSharedWith($itemType, $format, $parameters, $limit, $includeCollections);
 	}
 
 	/**
@@ -266,12 +96,12 @@ class Share {
 	 * @param int $format (optional) Format type must be defined by the backend
 	 * @param mixed Parameters (optional)
 	 * @param bool include collections (optional)
-	 * @return string depends on format
+	 * @return Return depends on format
 	 */
 	public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE,
 		$parameters = null, $includeCollections = false) {
-		return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
-			$parameters, 1, $includeCollections);
+
+		return \OC\Share\Share::getItemSharedWith($itemType, $itemTarget, $format, $parameters, $includeCollections);
 	}
 
 	/**
@@ -282,45 +112,7 @@ class Share {
 	 * @return array Return list of items with file_target, permissions and expiration
 	 */
 	public static function getItemSharedWithUser($itemType, $itemSource, $user) {
-
-		$shares = array();
-
-		// first check if there is a db entry for the specific user
-		$query = \OC_DB::prepare(
-				'SELECT `file_target`, `permissions`, `expiration`
-					FROM
-					`*PREFIX*share`
-					WHERE
-					`item_source` = ? AND `item_type` = ? AND `share_with` = ?'
-				);
-
-		$result = \OC_DB::executeAudited($query, array($itemSource, $itemType, $user));
-
-		while ($row = $result->fetchRow()) {
-			$shares[] = $row;
-		}
-
-		//if didn't found a result than let's look for a group share.
-		if(empty($shares)) {
-			$groups = \OC_Group::getUserGroups($user);
-
-			$query = \OC_DB::prepare(
-					'SELECT `file_target`, `permissions`, `expiration`
-						FROM
-						`*PREFIX*share`
-						WHERE
-						`item_source` = ? AND `item_type` = ? AND `share_with` in (?)'
-					);
-
-			$result = \OC_DB::executeAudited($query, array($itemSource, $itemType, implode(',', $groups)));
-
-			while ($row = $result->fetchRow()) {
-				$shares[] = $row;
-			}
-		}
-
-		return $shares;
-
+		return \OC\Share\Share::getItemSharedWithUser($itemType, $itemSource, $user);
 	}
 
 	/**
@@ -334,8 +126,7 @@ class Share {
 	 */
 	public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
 		$parameters = null, $includeCollections = false) {
-		return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
-			$parameters, 1, $includeCollections, true);
+		return \OC\Share\Share::getItemSharedWithBySource($itemType, $itemSource, $format, $parameters, $includeCollections);
 	}
 
 	/**
@@ -346,8 +137,7 @@ class Share {
 	 * @return Item
 	 */
 	public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) {
-		return self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE,
-			null, 1);
+		return \OC\Share\Share::getItemSharedWithByLink($itemType, $itemSource, $uidOwner);
 	}
 
 	/**
@@ -356,25 +146,7 @@ class Share {
 	 * @return array | bool false will be returned in case the token is unknown or unauthorized
 	 */
 	public static function getShareByToken($token, $checkPasswordProtection = true) {
-		$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1);
-		$result = $query->execute(array($token));
-		if (\OC_DB::isError($result)) {
-			\OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', token=' . $token, \OC_Log::ERROR);
-		}
-		$row = $result->fetchRow();
-		if ($row === false) {
-			return false;
-		}
-		if (is_array($row) and self::expireItem($row)) {
-			return false;
-		}
-
-		// password protected shares need to be authenticated
-		if ($checkPasswordProtection && !\OCP\Share::checkPasswordProtectedShare($row)) {
-			return false;
-		}
-
-		return $row;
+		return \OC\Share\Share::getShareByToken($token, $checkPasswordProtection);
 	}
 
 	/**
@@ -382,21 +154,8 @@ class Share {
 	 * @param $linkItem
 	 * @return $fileOwner
 	 */
-	public static function resolveReShare($linkItem)
-	{
-		if (isset($linkItem['parent'])) {
-			$parent = $linkItem['parent'];
-			while (isset($parent)) {
-				$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `id` = ?', 1);
-				$item = $query->execute(array($parent))->fetchRow();
-				if (isset($item['parent'])) {
-					$parent = $item['parent'];
-				} else {
-					return $item;
-				}
-			}
-		}
-		return $linkItem;
+	public static function resolveReShare($linkItem) {
+		return \OC\Share\Share::resolveReShare($linkItem);
 	}
 
 
@@ -407,13 +166,12 @@ class Share {
 	 * @param mixed Parameters
 	 * @param int Number of items to return (optional) Returns all by default
 	 * @param bool include collections
-	 * @param string $itemType
 	 * @return Return depends on format
 	 */
 	public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null,
 		$limit = -1, $includeCollections = false) {
-		return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format,
-			$parameters, $limit, $includeCollections);
+
+		return \OC\Share\Share::getItemsShared($itemType, $format, $parameters, $limit, $includeCollections);
 	}
 
 	/**
@@ -427,8 +185,8 @@ class Share {
 	 */
 	public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE,
 	                                     $parameters = null, $includeCollections = false) {
-		return self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(), $format,
-			$parameters, -1, $includeCollections);
+
+		return \OC\Share\Share::getItemShared($itemType, $itemSource, $format, $parameters, $includeCollections);
 	}
 
 	/**
@@ -441,19 +199,7 @@ class Share {
 	 * @return Return array of users
 	 */
 	public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false, $checkExpireDate = true) {
-
-		$users = array();
-		$items = self::getItems($itemType, $itemSource, null, null, $uidOwner, self::FORMAT_NONE, null, -1, $includeCollections, false, $checkExpireDate);
-		if ($items) {
-			foreach ($items as $item) {
-				if ((int)$item['share_type'] === self::SHARE_TYPE_USER) {
-					$users[] = $item['share_with'];
-				} else if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
-					$users = array_merge($users, \OC_Group::usersInGroup($item['share_with']));
-				}
-			}
-		}
-		return $users;
+		return \OC\Share\Share::getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections, $checkExpireDate);
 	}
 
 	/**
@@ -473,176 +219,7 @@ class Share {
 	 * @return bool|string Returns true on success or false on failure, Returns token on success for links
 	 */
 	public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null) {
-		$uidOwner = \OC_User::getUser();
-		$sharingPolicy = \OC_Appconfig::getValue('core', 'shareapi_share_policy', 'global');
-
-		if (is_null($itemSourceName)) {
-			$itemSourceName = $itemSource;
-		}
-
-		// Verify share type and sharing conditions are met
-		if ($shareType === self::SHARE_TYPE_USER) {
-			if ($shareWith == $uidOwner) {
-				$message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' is the item owner';
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-			if (!\OC_User::userExists($shareWith)) {
-				$message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' does not exist';
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-			if ($sharingPolicy == 'groups_only') {
-				$inGroup = array_intersect(\OC_Group::getUserGroups($uidOwner), \OC_Group::getUserGroups($shareWith));
-				if (empty($inGroup)) {
-					$message = 'Sharing '.$itemSourceName.' failed, because the user '
-						.$shareWith.' is not a member of any groups that '.$uidOwner.' is a member of';
-					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-					throw new \Exception($message);
-				}
-			}
-			// Check if the item source is already shared with the user, either from the same owner or a different user
-			if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups,
-				$shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
-				// Only allow the same share to occur again if it is the same
-				// owner and is not a user share, this use case is for increasing
-				// permissions for a specific user
-				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
-					$message = 'Sharing '.$itemSourceName.' failed, because this item is already shared with '.$shareWith;
-					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-					throw new \Exception($message);
-				}
-			}
-		} else if ($shareType === self::SHARE_TYPE_GROUP) {
-			if (!\OC_Group::groupExists($shareWith)) {
-				$message = 'Sharing '.$itemSourceName.' failed, because the group '.$shareWith.' does not exist';
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-			if ($sharingPolicy == 'groups_only' && !\OC_Group::inGroup($uidOwner, $shareWith)) {
-				$message = 'Sharing '.$itemSourceName.' failed, because '
-					.$uidOwner.' is not a member of the group '.$shareWith;
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-			// Check if the item source is already shared with the group, either from the same owner or a different user
-			// The check for each user in the group is done inside the put() function
-			if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_GROUP, $shareWith,
-				null, self::FORMAT_NONE, null, 1, true, true)) {
-				// Only allow the same share to occur again if it is the same
-				// owner and is not a group share, this use case is for increasing
-				// permissions for a specific user
-				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
-					$message = 'Sharing '.$itemSourceName.' failed, because this item is already shared with '.$shareWith;
-					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-					throw new \Exception($message);
-				}
-			}
-			// Convert share with into an array with the keys group and users
-			$group = $shareWith;
-			$shareWith = array();
-			$shareWith['group'] = $group;
-			$shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
-		} else if ($shareType === self::SHARE_TYPE_LINK) {
-			if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') == 'yes') {
-				// when updating a link share
-				if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null,
-					$uidOwner, self::FORMAT_NONE, null, 1)) {
-					// remember old token
-					$oldToken = $checkExists['token'];
-					$oldPermissions = $checkExists['permissions'];
-					//delete the old share
-					self::delete($checkExists['id']);
-				}
-
-				// Generate hash of password - same method as user passwords
-				if (isset($shareWith)) {
-					$forcePortable = (CRYPT_BLOWFISH != 1);
-					$hasher = new \PasswordHash(8, $forcePortable);
-					$shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', ''));
-				} else {
-					// reuse the already set password, but only if we change permissions
-					// otherwise the user disabled the password protection
-					if ($checkExists && (int)$permissions !== (int)$oldPermissions) {
-						$shareWith = $checkExists['share_with'];
-					}
-				}
-
-				// Generate token
-				if (isset($oldToken)) {
-					$token = $oldToken;
-				} else {
-					$token = \OC_Util::generateRandomBytes(self::TOKEN_LENGTH);
-				}
-				$result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions,
-					null, $token, $itemSourceName);
-				if ($result) {
-					return $token;
-				} else {
-					return false;
-				}
-			}
-			$message = 'Sharing '.$itemSourceName.' failed, because sharing with links is not allowed';
-			\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-			throw new \Exception($message);
-			return false;
-// 		} else if ($shareType === self::SHARE_TYPE_CONTACT) {
-// 			if (!\OC_App::isEnabled('contacts')) {
-// 				$message = 'Sharing '.$itemSource.' failed, because the contacts app is not enabled';
-// 				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-// 				return false;
-// 			}
-// 			$vcard = \OC_Contacts_App::getContactVCard($shareWith);
-// 			if (!isset($vcard)) {
-// 				$message = 'Sharing '.$itemSource.' failed, because the contact does not exist';
-// 				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-// 				throw new \Exception($message);
-// 			}
-// 			$details = \OC_Contacts_VCard::structureContact($vcard);
-// 			// TODO Add ownCloud user to contacts vcard
-// 			if (!isset($details['EMAIL'])) {
-// 				$message = 'Sharing '.$itemSource.' failed, because no email address is associated with the contact';
-// 				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-// 				throw new \Exception($message);
-// 			}
-// 			return self::shareItem($itemType, $itemSource, self::SHARE_TYPE_EMAIL, $details['EMAIL'], $permissions);
-		} else {
-			// Future share types need to include their own conditions
-			$message = 'Share type '.$shareType.' is not valid for '.$itemSource;
-			\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-			throw new \Exception($message);
-		}
-		// If the item is a folder, scan through the folder looking for equivalent item types
-// 		if ($itemType == 'folder') {
-// 			$parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true);
-// 			if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) {
-// 				for ($i = 0; $i < count($files); $i++) {
-// 					$name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource));
-// 					if ($files[$i]['mimetype'] == 'httpd/unix-directory'
-// 						&& $children = \OC\Files\Filesystem::getDirectoryContent($name, '/')
-// 					) {
-// 						// Continue scanning into child folders
-// 						array_push($files, $children);
-// 					} else {
-// 						// Check file extension for an equivalent item type to convert to
-// 						$extension = strtolower(substr($itemSource, strrpos($itemSource, '.') + 1));
-// 						foreach (self::$backends as $type => $backend) {
-// 							if (isset($backend->dependsOn) && $backend->dependsOn == 'file' && isset($backend->supportedFileExtensions) && in_array($extension, $backend->supportedFileExtensions)) {
-// 								$itemType = $type;
-// 								break;
-// 							}
-// 						}
-// 						// Pass on to put() to check if this item should be converted, the item won't be inserted into the database unless it can be converted
-// 						self::put($itemType, $name, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder);
-// 					}
-// 				}
-// 				return true;
-// 			}
-// 			return false;
-// 		} else {
-			// Put the item into the database
-			return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName);
-// 		}
+		return \OC\Share\Share::shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName);
 	}
 
 	/**
@@ -651,88 +228,32 @@ class Share {
 	 * @param string Item source
 	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
 	 * @param string User or group the item is being shared with
-	 * @return boolean true on success or false on failure
+	 * @return Returns true on success or false on failure
 	 */
 	public static function unshare($itemType, $itemSource, $shareType, $shareWith) {
-		if ($item = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(),
-			self::FORMAT_NONE, null, 1)) {
-			self::unshareItem($item);
-			return true;
-		}
-		return false;
+		return \OC\Share\Share::unshare($itemType, $itemSource, $shareType, $shareWith);
 	}
 
 	/**
 	 * Unshare an item from all users, groups, and remove all links
 	 * @param string Item type
 	 * @param string Item source
-	 * @param string $itemType
-	 * @param string $itemSource
-	 * @return boolean true on success or false on failure
+	 * @return Returns true on success or false on failure
 	 */
 	public static function unshareAll($itemType, $itemSource) {
-		// Get all of the owners of shares of this item.
-		$query = \OC_DB::prepare( 'SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?' );
-		$result = $query->execute(array($itemType, $itemSource));
-		$shares = array();
-		// Add each owner's shares to the array of all shares for this item.
-		while ($row = $result->fetchRow()) {
-			$shares = array_merge($shares, self::getItems($itemType, $itemSource, null, null, $row['uid_owner']));
-		}
-		if (!empty($shares)) {
-			// Pass all the vars we have for now, they may be useful
-			$hookParams = array(
-				'itemType' => $itemType,
-				'itemSource' => $itemSource,
-				'shares' => $shares,
-			);
-			\OC_Hook::emit('OCP\Share', 'pre_unshareAll', $hookParams);
-			foreach ($shares as $share) {
-				self::unshareItem($share);
-			}
-			\OC_Hook::emit('OCP\Share', 'post_unshareAll', $hookParams);
-			return true;
-		}
-		return false;
+		return \OC\Share\Share::unshareAll($itemType, $itemSource);
 	}
 
 	/**
 	 * Unshare an item shared with the current user
 	 * @param string Item type
 	 * @param string Item target
-	 * @param string $itemType
-	 * @param string $itemTarget
-	 * @return boolean true on success or false on failure
+	 * @return Returns true on success or false on failure
 	 *
 	 * Unsharing from self is not allowed for items inside collections
 	 */
 	public static function unshareFromSelf($itemType, $itemTarget) {
-		if ($item = self::getItemSharedWith($itemType, $itemTarget)) {
-			if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
-				// Insert an extra row for the group share and set permission
-				// to 0 to prevent it from showing up for the user
-				$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share`'
-					.' (`item_type`, `item_source`, `item_target`, `parent`, `share_type`,'
-					.' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`)'
-					.' VALUES (?,?,?,?,?,?,?,?,?,?,?)');
-				$query->execute(array($item['item_type'], $item['item_source'], $item['item_target'],
-					$item['id'], self::$shareTypeGroupUserUnique,
-					\OC_User::getUser(), $item['uid_owner'], 0, $item['stime'], $item['file_source'],
-					$item['file_target']));
-				\OC_DB::insertid('*PREFIX*share');
-				// Delete all reshares by this user of the group share
-				self::delete($item['id'], true, \OC_User::getUser());
-			} else if ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
-				// Set permission to 0 to prevent it from showing up for the user
-				$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?');
-				$query->execute(array(0, $item['id']));
-				self::delete($item['id'], true);
-			} else {
-				self::delete($item['id']);
-			}
-			return true;
-		}
-		return false;
+		return \OC\Share\Share::unshareFromSelf($itemType, $itemTarget);
 	}
 	/**
 	 * sent status if users got informed by mail about share
@@ -742,102 +263,20 @@ class Share {
 	 * @param bool $status
 	 */
 	public static function setSendMailStatus($itemType, $itemSource, $shareType, $status) {
-		$status = $status ? 1 : 0;
-
-		$query = \OC_DB::prepare(
-				'UPDATE `*PREFIX*share`
-					SET `mail_send` = ?
-					WHERE `item_type` = ? AND `item_source` = ? AND `share_type` = ?');
-
-		$result = $query->execute(array($status, $itemType, $itemSource, $shareType));
-
-		if($result === false) {
-			\OC_Log::write('OCP\Share', 'Couldn\'t set send mail status', \OC_Log::ERROR);
-		}
+		return \OC\Share\Share::setSendMailStatus($itemType, $itemSource, $shareType, $status);
 	}
 
 	/**
 	 * Set the permissions of an item for a specific user or group
-	 * @param string $itemType Item type
-	 * @param string $itemSource Item source
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
-	 * @param string $shareWith User or group the item is being shared with
-	 * @param integer|null $permissions CRUDS
-	 * @return boolean true on success or false on failure
+	 * @param string Item type
+	 * @param string Item source
+	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
+	 * @param string User or group the item is being shared with
+	 * @param int CRUDS permissions
+	 * @return Returns true on success or false on failure
 	 */
 	public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) {
-		if ($item = self::getItems($itemType, $itemSource, $shareType, $shareWith,
-			\OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) {
-			// Check if this item is a reshare and verify that the permissions
-			// granted don't exceed the parent shared item
-			if (isset($item['parent'])) {
-				$query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*share` WHERE `id` = ?', 1);
-				$result = $query->execute(array($item['parent']))->fetchRow();
-				if (~(int)$result['permissions'] & $permissions) {
-					$message = 'Setting permissions for '.$itemSource.' failed,'
-						.' because the permissions exceed permissions granted to '.\OC_User::getUser();
-					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-					throw new \Exception($message);
-				}
-			}
-			$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?');
-			$query->execute(array($permissions, $item['id']));
-			if ($itemType === 'file' || $itemType === 'folder') {
-				\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
-					'itemType' => $itemType,
-					'itemSource' => $itemSource,
-					'shareType' => $shareType,
-					'shareWith' => $shareWith,
-					'uidOwner' => \OC_User::getUser(),
-					'permissions' => $permissions,
-					'path' => $item['path'],
-				));
-			}
-			// Check if permissions were removed
-			if ($item['permissions'] & ~$permissions) {
-				// If share permission is removed all reshares must be deleted
-				if (($item['permissions'] & PERMISSION_SHARE) && (~$permissions & PERMISSION_SHARE)) {
-					self::delete($item['id'], true);
-				} else {
-					$ids = array();
-					$parents = array($item['id']);
-					while (!empty($parents)) {
-						$parents = "'".implode("','", $parents)."'";
-						$query = \OC_DB::prepare('SELECT `id`, `permissions` FROM `*PREFIX*share`'
-							.' WHERE `parent` IN ('.$parents.')');
-						$result = $query->execute();
-						// Reset parents array, only go through loop again if
-						// items are found that need permissions removed
-						$parents = array();
-						while ($item = $result->fetchRow()) {
-							// Check if permissions need to be removed
-							if ($item['permissions'] & ~$permissions) {
-								// Add to list of items that need permissions removed
-								$ids[] = $item['id'];
-								$parents[] = $item['id'];
-							}
-						}
-					}
-					// Remove the permissions for all reshares of this item
-					if (!empty($ids)) {
-						$ids = "'".implode("','", $ids)."'";
-						// TODO this should be done with Doctrine platform objects
-						if (\OC_Config::getValue( "dbtype") === 'oci') {
-							$andOp = 'BITAND(`permissions`, ?)';
-						} else {
-							$andOp = '`permissions` & ?';
-						}
-						$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp
-							.' WHERE `id` IN ('.$ids.')');
-						$query->execute(array($permissions));
-					}
-				}
-			}
-			return true;
-		}
-		$message = 'Setting permissions for '.$itemSource.' failed, because the item was not found';
-		\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-		throw new \Exception($message);
+		return \OC\Share\Share::setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions);
 	}
 
 	/**
@@ -845,67 +284,10 @@ class Share {
 	 * @param string $itemType
 	 * @param string $itemSource
 	 * @param string $date expiration date
-	 * @return boolean
+	 * @return Share_Backend
 	 */
 	public static function setExpirationDate($itemType, $itemSource, $date) {
-		if ($items = self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(),
-			self::FORMAT_NONE, null, -1, false)) {
-			if (!empty($items)) {
-				if ($date == '') {
-					$date = null;
-				} else {
-					$date = new \DateTime($date);
-				}
-				$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `id` = ?');
-				$query->bindValue(1, $date, 'datetime');
-				foreach ($items as $item) {
-					$query->bindValue(2, (int) $item['id']);
-					$query->execute();
-				}
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Checks whether a share has expired, calls unshareItem() if yes.
-	 * @param array $item Share data (usually database row)
-	 * @return bool True if item was expired, false otherwise.
-	 */
-	protected static function expireItem(array $item) {
-		if (!empty($item['expiration'])) {
-			$now = new \DateTime();
-			$expires = new \DateTime($item['expiration']);
-			if ($now > $expires) {
-				self::unshareItem($item);
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Unshares a share given a share data array
-	 * @param array $item Share data (usually database row)
-	 * @return null
-	 */
-	protected static function unshareItem(array $item) {
-		// Pass all the vars we have for now, they may be useful
-		$hookParams = array(
-			'itemType'      => $item['item_type'],
-			'itemSource'    => $item['item_source'],
-			'shareType'     => $item['share_type'],
-			'shareWith'     => $item['share_with'],
-			'itemParent'    => $item['parent'],
-			'uidOwner'      => $item['uid_owner'],
-		);
-
-		\OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams + array(
-			'fileSource'	=> $item['file_source'],
-		));
-		self::delete($item['id']);
-		\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
+		return \OC\Share\Share::setExpirationDate($itemType, $itemSource, $date);
 	}
 
 	/**
@@ -914,1018 +296,14 @@ class Share {
 	 * @return Share_Backend
 	 */
 	public static function getBackend($itemType) {
-		if (isset(self::$backends[$itemType])) {
-			return self::$backends[$itemType];
-		} else if (isset(self::$backendTypes[$itemType]['class'])) {
-			$class = self::$backendTypes[$itemType]['class'];
-			if (class_exists($class)) {
-				self::$backends[$itemType] = new $class;
-				if (!(self::$backends[$itemType] instanceof Share_Backend)) {
-					$message = 'Sharing backend '.$class.' must implement the interface OCP\Share_Backend';
-					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-					throw new \Exception($message);
-				}
-				return self::$backends[$itemType];
-			} else {
-				$message = 'Sharing backend '.$class.' not found';
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-		}
-		$message = 'Sharing backend for '.$itemType.' not found';
-		\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-		throw new \Exception($message);
-	}
-
-	/**
-	 * Check if resharing is allowed
-	 * @return boolean true if allowed or false
-	 *
-	 * Resharing is allowed by default if not configured
-	 */
-	private static function isResharingAllowed() {
-		if (!isset(self::$isResharingAllowed)) {
-			if (\OC_Appconfig::getValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') {
-				self::$isResharingAllowed = true;
-			} else {
-				self::$isResharingAllowed = false;
-			}
-		}
-		return self::$isResharingAllowed;
-	}
-
-	/**
-	 * Get a list of collection item types for the specified item type
-	 * @param string Item type
-	 * @return array
-	 */
-	private static function getCollectionItemTypes($itemType) {
-		$collectionTypes = array($itemType);
-		foreach (self::$backendTypes as $type => $backend) {
-			if (in_array($backend['collectionOf'], $collectionTypes)) {
-				$collectionTypes[] = $type;
-			}
-		}
-		// TODO Add option for collections to be collection of themselves, only 'folder' does it now...
-		if (!self::getBackend($itemType) instanceof Share_Backend_Collection || $itemType != 'folder') {
-			unset($collectionTypes[0]);
-		}
-		// Return array if collections were found or the item type is a
-		// collection itself - collections can be inside collections
-		if (count($collectionTypes) > 0) {
-			return $collectionTypes;
-		}
-		return false;
-	}
-
-	/**
-	 * Get shared items from the database
-	 * @param string Item type
-	 * @param string Item source or target (optional)
-	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
-	 * @param string User or group the item is being shared with
-	 * @param string User that is the owner of shared items (optional)
-	 * @param int Format to convert items to with formatItems()
-	 * @param mixed Parameters to pass to formatItems()
-	 * @param int Number of items to return, -1 to return all matches (optional)
-	 * @param bool Include collection item types (optional)
-	 * @param bool TODO (optional)
-	 * @prams bool check expire date
-	 * @return mixed
-	 *
-	 * See public functions getItem(s)... for parameter usage
-	 *
-	 */
-	private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null,
-		$uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1,
-		$includeCollections = false, $itemShareWithBySource = false, $checkExpireDate  = true) {
-		if (!self::isEnabled()) {
-			if ($limit == 1 || (isset($uidOwner) && isset($item))) {
-				return false;
-			} else {
-				return array();
-			}
-		}
-		$backend = self::getBackend($itemType);
-		$collectionTypes = false;
-		// Get filesystem root to add it to the file target and remove from the
-		// file source, match file_source with the file cache
-		if ($itemType == 'file' || $itemType == 'folder') {
-			if(!is_null($uidOwner)) {
-				$root = \OC\Files\Filesystem::getRoot();
-			} else {
-				$root = '';
-			}
-			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`';
-			if (!isset($item)) {
-				$where .= ' WHERE `file_target` IS NOT NULL';
-			}
-			$fileDependent = true;
-			$queryArgs = array();
-		} else {
-			$fileDependent = false;
-			$root = '';
-			if ($includeCollections && !isset($item) && ($collectionTypes = self::getCollectionItemTypes($itemType))) {
-				// If includeCollections is true, find collections of this item type, e.g. a music album contains songs
-				if (!in_array($itemType, $collectionTypes)) {
-					$itemTypes = array_merge(array($itemType), $collectionTypes);
-				} else {
-					$itemTypes = $collectionTypes;
-				}
-				$placeholders = join(',', array_fill(0, count($itemTypes), '?'));
-				$where = ' WHERE `item_type` IN ('.$placeholders.'))';
-				$queryArgs = $itemTypes;
-			} else {
-				$where = ' WHERE `item_type` = ?';
-				$queryArgs = array($itemType);
-			}
-		}
-		if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
-			$where .= ' AND `share_type` != ?';
-			$queryArgs[] = self::SHARE_TYPE_LINK;
-		}
-		if (isset($shareType)) {
-			// Include all user and group items
-			if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
-				$where .= ' AND `share_type` IN (?,?,?)';
-				$queryArgs[] = self::SHARE_TYPE_USER;
-				$queryArgs[] = self::SHARE_TYPE_GROUP;
-				$queryArgs[] = self::$shareTypeGroupUserUnique;
-				$userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith));
-				$placeholders = join(',', array_fill(0, count($userAndGroups), '?'));
-				$where .= ' AND `share_with` IN ('.$placeholders.')';
-				$queryArgs = array_merge($queryArgs, $userAndGroups);
-				// Don't include own group shares
-				$where .= ' AND `uid_owner` != ?';
-				$queryArgs[] = $shareWith;
-			} else {
-				$where .= ' AND `share_type` = ?';
-				$queryArgs[] = $shareType;
-				if (isset($shareWith)) {
-					$where .= ' AND `share_with` = ?';
-					$queryArgs[] = $shareWith;
-				}
-			}
-		}
-		if (isset($uidOwner)) {
-			$where .= ' AND `uid_owner` = ?';
-			$queryArgs[] = $uidOwner;
-			if (!isset($shareType)) {
-				// Prevent unique user targets for group shares from being selected
-				$where .= ' AND `share_type` != ?';
-				$queryArgs[] = self::$shareTypeGroupUserUnique;
-			}
-			if ($itemType == 'file' || $itemType == 'folder') {
-				$column = 'file_source';
-			} else {
-				$column = 'item_source';
-			}
-		} else {
-			if ($itemType == 'file' || $itemType == 'folder') {
-				$column = 'file_target';
-			} else {
-				$column = 'item_target';
-			}
-		}
-		if (isset($item)) {
-			if ($includeCollections && $collectionTypes = self::getCollectionItemTypes($itemType)) {
-				$where .= ' AND (';
-			} else {
-				$where .= ' AND';
-			}
-			// If looking for own shared items, check item_source else check item_target
-			if (isset($uidOwner) || $itemShareWithBySource) {
-				// If item type is a file, file source needs to be checked in case the item was converted
-				if ($itemType == 'file' || $itemType == 'folder') {
-					$where .= ' `file_source` = ?';
-					$column = 'file_source';
-				} else {
-					$where .= ' `item_source` = ?';
-					$column = 'item_source';
-				}
-			} else {
-				if ($itemType == 'file' || $itemType == 'folder') {
-					$where .= ' `file_target` = ?';
-					$item = \OC\Files\Filesystem::normalizePath($item);
-				} else {
-					$where .= ' `item_target` = ?';
-				}
-			}
-			$queryArgs[] = $item;
-			if ($includeCollections && $collectionTypes) {
-				$placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
-				$where .= ' OR `item_type` IN ('.$placeholders.'))';
-				$queryArgs = array_merge($queryArgs, $collectionTypes);
-			}
-		}
-		if ($limit != -1 && !$includeCollections) {
-			if ($shareType == self::$shareTypeUserAndGroups) {
-				// Make sure the unique user target is returned if it exists,
-				// unique targets should follow the group share in the database
-				// If the limit is not 1, the filtering can be done later
-				$where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
-			}
-			// The limit must be at least 3, because filtering needs to be done
-			if ($limit < 3) {
-				$queryLimit = 3;
-			} else {
-				$queryLimit = $limit;
-			}
-		} else {
-			$queryLimit = null;
-		}
-		// TODO Optimize selects
-		if ($format == self::FORMAT_STATUSES) {
-			if ($itemType == 'file' || $itemType == 'folder') {
-				$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
-					.' `share_type`, `file_source`, `path`, `expiration`, `storage`, `share_with`, `mail_send`, `uid_owner`';
-			} else {
-				$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `expiration`, `mail_send`, `uid_owner`';
-			}
-		} else {
-			if (isset($uidOwner)) {
-				if ($itemType == 'file' || $itemType == 'folder') {
-					$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
-						.' `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`,'
-						.' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`';
-				} else {
-					$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`,'
-						.' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`';
-				}
-			} else {
-				if ($fileDependent) {
-					if (($itemType == 'file' || $itemType == 'folder')
-						&& $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS
-						|| $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT
-					) {
-						$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`, `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`,
-							`file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`';
-					}
-				} else {
-					$select = '*';
-				}
-			}
-		}
-		$root = strlen($root);
-		$query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit);
-		$result = $query->execute($queryArgs);
-		if (\OC_DB::isError($result)) {
-			\OC_Log::write('OCP\Share',
-				\OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where,
-				\OC_Log::ERROR);
-		}
-		$items = array();
-		$targets = array();
-		$switchedItems = array();
-		$mounts = array();
-		while ($row = $result->fetchRow()) {
-			if (isset($row['id'])) {
-				$row['id']=(int)$row['id'];
-			}
-			if (isset($row['share_type'])) {
-				$row['share_type']=(int)$row['share_type'];
-			}
-			if (isset($row['parent'])) {
-				$row['parent']=(int)$row['parent'];
-			}
-			if (isset($row['file_parent'])) {
-				$row['file_parent']=(int)$row['file_parent'];
-			}
-			if (isset($row['file_source'])) {
-				$row['file_source']=(int)$row['file_source'];
-			}
-			if (isset($row['permissions'])) {
-				$row['permissions']=(int)$row['permissions'];
-			}
-			if (isset($row['storage'])) {
-				$row['storage']=(int)$row['storage'];
-			}
-			if (isset($row['stime'])) {
-				$row['stime']=(int)$row['stime'];
-			}
-			// Filter out duplicate group shares for users with unique targets
-			if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
-				$row['share_type'] = self::SHARE_TYPE_GROUP;
-				$row['share_with'] = $items[$row['parent']]['share_with'];
-				// Remove the parent group share
-				unset($items[$row['parent']]);
-				if ($row['permissions'] == 0) {
-					continue;
-				}
-			} else if (!isset($uidOwner)) {
-				// Check if the same target already exists
-				if (isset($targets[$row[$column]])) {
-					// Check if the same owner shared with the user twice
-					// through a group and user share - this is allowed
-					$id = $targets[$row[$column]];
-					if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
-						// Switch to group share type to ensure resharing conditions aren't bypassed
-						if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
-							$items[$id]['share_type'] = self::SHARE_TYPE_GROUP;
-							$items[$id]['share_with'] = $row['share_with'];
-						}
-						// Switch ids if sharing permission is granted on only
-						// one share to ensure correct parent is used if resharing
-						if (~(int)$items[$id]['permissions'] & PERMISSION_SHARE
-							&& (int)$row['permissions'] & PERMISSION_SHARE) {
-							$items[$row['id']] = $items[$id];
-							$switchedItems[$id] = $row['id'];
-							unset($items[$id]);
-							$id = $row['id'];
-						}
-						// Combine the permissions for the item
-						$items[$id]['permissions'] |= (int)$row['permissions'];
-						continue;
-					}
-				} else {
-					$targets[$row[$column]] = $row['id'];
-				}
-			}
-			// Remove root from file source paths if retrieving own shared items
-			if (isset($uidOwner) && isset($row['path'])) {
-				if (isset($row['parent'])) {
-					// FIXME: Doesn't always construct the correct path, example:
-					// Folder '/a/b', share '/a' and '/a/b' to user2
-					// user2 reshares /Shared/b and ask for share status of /Shared/a/b
-					// expected result: path=/Shared/a/b; actual result /Shared/b because of the parent
-					$query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
-					$parentResult = $query->execute(array($row['parent']));
-					if (\OC_DB::isError($result)) {
-						\OC_Log::write('OCP\Share', 'Can\'t select parent: ' .
-								\OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where,
-								\OC_Log::ERROR);
-					} else {
-						$parentRow = $parentResult->fetchRow();
-						$tmpPath = '/Shared' . $parentRow['file_target'];
-						// find the right position where the row path continues from the target path
-						$pos = strrpos($row['path'], $parentRow['file_target']);
-						$subPath = substr($row['path'], $pos);
-						$splitPath = explode('/', $subPath);
-						foreach (array_slice($splitPath, 2) as $pathPart) {
-							$tmpPath = $tmpPath . '/' . $pathPart;
-						}
-						$row['path'] = $tmpPath;
-					}
-				} else {
-					if (!isset($mounts[$row['storage']])) {
-						$mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
-						if (is_array($mountPoints)) {
-							$mounts[$row['storage']] = current($mountPoints);
-						}
-					}
-					if ($mounts[$row['storage']]) {
-						$path = $mounts[$row['storage']]->getMountPoint().$row['path'];
-						$row['path'] = substr($path, $root);
-					}
-				}
-			}
-			if($checkExpireDate) {
-				if (self::expireItem($row)) {
-					continue;
-				}
-			}
-			// Check if resharing is allowed, if not remove share permission
-			if (isset($row['permissions']) && !self::isResharingAllowed()) {
-				$row['permissions'] &= ~PERMISSION_SHARE;
-			}
-			// Add display names to result
-			if ( isset($row['share_with']) && $row['share_with'] != '') {
-				$row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']);
-			}
-			if ( isset($row['uid_owner']) && $row['uid_owner'] != '') {
-				$row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
-			}
-
-			$items[$row['id']] = $row;
-		}
-		if (!empty($items)) {
-			$collectionItems = array();
-			foreach ($items as &$row) {
-				// Return only the item instead of a 2-dimensional array
-				if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
-					if ($format == self::FORMAT_NONE) {
-						return $row;
-					} else {
-						break;
-					}
-				}
-				// Check if this is a collection of the requested item type
-				if ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
-					if (($collectionBackend = self::getBackend($row['item_type']))
-						&& $collectionBackend instanceof Share_Backend_Collection) {
-						// Collections can be inside collections, check if the item is a collection
-						if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
-							$collectionItems[] = $row;
-						} else {
-							$collection = array();
-							$collection['item_type'] = $row['item_type'];
-							if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
-								$collection['path'] = basename($row['path']);
-							}
-							$row['collection'] = $collection;
-							// Fetch all of the children sources
-							$children = $collectionBackend->getChildren($row[$column]);
-							foreach ($children as $child) {
-								$childItem = $row;
-								$childItem['item_type'] = $itemType;
-								if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
-									$childItem['item_source'] = $child['source'];
-									$childItem['item_target'] = $child['target'];
-								}
-								if ($backend instanceof Share_Backend_File_Dependent) {
-									if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
-										$childItem['file_source'] = $child['source'];
-									} else {
-										$meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
-										$childItem['file_source'] = $meta['fileid'];
-									}
-									$childItem['file_target'] =
-										\OC\Files\Filesystem::normalizePath($child['file_path']);
-								}
-								if (isset($item)) {
-									if ($childItem[$column] == $item) {
-										// Return only the item instead of a 2-dimensional array
-										if ($limit == 1) {
-											if ($format == self::FORMAT_NONE) {
-												return $childItem;
-											} else {
-												// Unset the items array and break out of both loops
-												$items = array();
-												$items[] = $childItem;
-												break 2;
-											}
-										} else {
-											$collectionItems[] = $childItem;
-										}
-									}
-								} else {
-									$collectionItems[] = $childItem;
-								}
-							}
-						}
-					}
-					// Remove collection item
-					$toRemove = $row['id'];
-					if (array_key_exists($toRemove, $switchedItems)) {
-						$toRemove = $switchedItems[$toRemove];
-					}
-					unset($items[$toRemove]);
-				}
-			}
-			if (!empty($collectionItems)) {
-				$items = array_merge($items, $collectionItems);
-			}
-			if (empty($items) && $limit == 1) {
-				return false;
-			}
-			if ($format == self::FORMAT_NONE) {
-				return $items;
-			} else if ($format == self::FORMAT_STATUSES) {
-				$statuses = array();
-				foreach ($items as $item) {
-					if ($item['share_type'] == self::SHARE_TYPE_LINK) {
-						$statuses[$item[$column]]['link'] = true;
-					} else if (!isset($statuses[$item[$column]])) {
-						$statuses[$item[$column]]['link'] = false;
-					}
-					if ($itemType == 'file' || $itemType == 'folder') {
-						$statuses[$item[$column]]['path'] = $item['path'];
-					}
-				}
-				return $statuses;
-			} else {
-				return $backend->formatItems($items, $format, $parameters);
-			}
-		} else if ($limit == 1 || (isset($uidOwner) && isset($item))) {
-			return false;
-		}
-		return array();
-	}
-
-	/**
-	 * Put shared item into the database
-	 * @param string $itemType Item type
-	 * @param string $itemSource Item source
-	 * @param integer $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
-	 * @param string $shareWith User or group the item is being shared with
-	 * @param string $uidOwner User that is the owner of shared item
-	 * @param int $permissions CRUDS permissions
-	 * @param bool|array, $parentFolder Parent folder target (optional)
-	 * @param string $token (optional)
-	 * @param string $itemSourceName name of the source item (optional)
-	 * @return bool Returns true on success or false on failure
-	 */
-	private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
-		$permissions, $parentFolder = null, $token = null, $itemSourceName = null) {
-		$backend = self::getBackend($itemType);
-
-		// Check if this is a reshare
-		if ($checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true)) {
-
-			// Check if attempting to share back to owner
-			if ($checkReshare['uid_owner'] == $shareWith && $shareType == self::SHARE_TYPE_USER) {
-				$message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' is the original sharer';
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-			// Check if share permissions is granted
-			if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & PERMISSION_SHARE) {
-				if (~(int)$checkReshare['permissions'] & $permissions) {
-					$message = 'Sharing '.$itemSourceName
-						.' failed, because the permissions exceed permissions granted to '.$uidOwner;
-					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-					throw new \Exception($message);
-				} else {
-					// TODO Don't check if inside folder
-					$parent = $checkReshare['id'];
-					$itemSource = $checkReshare['item_source'];
-					$fileSource = $checkReshare['file_source'];
-					$suggestedItemTarget = $checkReshare['item_target'];
-					$suggestedFileTarget = $checkReshare['file_target'];
-					$filePath = $checkReshare['file_target'];
-				}
-			} else {
-				$message = 'Sharing '.$itemSourceName.' failed, because resharing is not allowed';
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-		} else {
-			$parent = null;
-			$suggestedItemTarget = null;
-			$suggestedFileTarget = null;
-			if (!$backend->isValidSource($itemSource, $uidOwner)) {
-				$message = 'Sharing '.$itemSource.' failed, because the sharing backend for '
-					.$itemType.' could not find its source';
-				\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-				throw new \Exception($message);
-			}
-			$parent = null;
-			if ($backend instanceof Share_Backend_File_Dependent) {
-				$filePath = $backend->getFilePath($itemSource, $uidOwner);
-				if ($itemType == 'file' || $itemType == 'folder') {
-					$fileSource = $itemSource;
-				} else {
-					$meta = \OC\Files\Filesystem::getFileInfo($filePath);
-					$fileSource = $meta['fileid'];
-				}
-				if ($fileSource == -1) {
-					$message = 'Sharing '.$itemSource.' failed, because the file could not be found in the file cache';
-					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-					throw new \Exception($message);
-				}
-			} else {
-				$filePath = null;
-				$fileSource = null;
-			}
-		}
-		$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,'
-			.' `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
-			.' `file_target`, `token`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
-		// Share with a group
-		if ($shareType == self::SHARE_TYPE_GROUP) {
-			$groupItemTarget = self::generateTarget($itemType, $itemSource, $shareType, $shareWith['group'],
-				$uidOwner, $suggestedItemTarget);
-			$run = true;
-			$error = '';
-			\OC_Hook::emit('OCP\Share', 'pre_shared', array(
-				'itemType' => $itemType,
-				'itemSource' => $itemSource,
-				'itemTarget' => $groupItemTarget,
-				'shareType' => $shareType,
-				'shareWith' => $shareWith['group'],
-				'uidOwner' => $uidOwner,
-				'permissions' => $permissions,
-				'fileSource' => $fileSource,
-				'token' => $token,
-				'run' => &$run,
-				'error' => &$error
-			));
-
-			if ($run === false) {
-				throw new \Exception($error);
-			}
-
-			if (isset($fileSource)) {
-				if ($parentFolder) {
-					if ($parentFolder === true) {
-						$groupFileTarget = self::generateTarget('file', $filePath, $shareType,
-							$shareWith['group'], $uidOwner, $suggestedFileTarget);
-						// Set group default file target for future use
-						$parentFolders[0]['folder'] = $groupFileTarget;
-					} else {
-						// Get group default file target
-						$groupFileTarget = $parentFolder[0]['folder'].$itemSource;
-						$parent = $parentFolder[0]['id'];
-					}
-				} else {
-					$groupFileTarget = self::generateTarget('file', $filePath, $shareType, $shareWith['group'],
-						$uidOwner, $suggestedFileTarget);
-				}
-			} else {
-				$groupFileTarget = null;
-			}
-			$query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType,
-				$shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token));
-			// Save this id, any extra rows for this group share will need to reference it
-			$parent = \OC_DB::insertid('*PREFIX*share');
-			// Loop through all users of this group in case we need to add an extra row
-			foreach ($shareWith['users'] as $uid) {
-				$itemTarget = self::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid,
-					$uidOwner, $suggestedItemTarget, $parent);
-				if (isset($fileSource)) {
-					if ($parentFolder) {
-						if ($parentFolder === true) {
-							$fileTarget = self::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $uid,
-								$uidOwner, $suggestedFileTarget, $parent);
-							if ($fileTarget != $groupFileTarget) {
-								$parentFolders[$uid]['folder'] = $fileTarget;
-							}
-						} else if (isset($parentFolder[$uid])) {
-							$fileTarget = $parentFolder[$uid]['folder'].$itemSource;
-							$parent = $parentFolder[$uid]['id'];
-						}
-					} else {
-						$fileTarget = self::generateTarget('file', $filePath, self::SHARE_TYPE_USER,
-							$uid, $uidOwner, $suggestedFileTarget, $parent);
-					}
-				} else {
-					$fileTarget = null;
-				}
-				// Insert an extra row for the group share if the item or file target is unique for this user
-				if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) {
-					$query->execute(array($itemType, $itemSource, $itemTarget, $parent,
-						self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(),
-							$fileSource, $fileTarget, $token));
-					$id = \OC_DB::insertid('*PREFIX*share');
-				}
-			}
-			\OC_Hook::emit('OCP\Share', 'post_shared', array(
-				'itemType' => $itemType,
-				'itemSource' => $itemSource,
-				'itemTarget' => $groupItemTarget,
-				'parent' => $parent,
-				'shareType' => $shareType,
-				'shareWith' => $shareWith['group'],
-				'uidOwner' => $uidOwner,
-				'permissions' => $permissions,
-				'fileSource' => $fileSource,
-				'fileTarget' => $groupFileTarget,
-				'id' => $parent,
-				'token' => $token
-			));
-
-			if ($parentFolder === true) {
-				// Return parent folders to preserve file target paths for potential children
-				return $parentFolders;
-			}
-		} else {
-			$itemTarget = self::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
-				$suggestedItemTarget);
-			$run = true;
-			$error = '';
-			\OC_Hook::emit('OCP\Share', 'pre_shared', array(
-				'itemType' => $itemType,
-				'itemSource' => $itemSource,
-				'itemTarget' => $itemTarget,
-				'shareType' => $shareType,
-				'shareWith' => $shareWith,
-				'uidOwner' => $uidOwner,
-				'permissions' => $permissions,
-				'fileSource' => $fileSource,
-				'token' => $token,
-				'run' => &$run,
-				'error' => &$error
-			));
-
-			if ($run === false) {
-				throw new \Exception($error);
-			}
-
-			if (isset($fileSource)) {
-				if ($parentFolder) {
-					if ($parentFolder === true) {
-						$fileTarget = self::generateTarget('file', $filePath, $shareType, $shareWith,
-							$uidOwner, $suggestedFileTarget);
-						$parentFolders['folder'] = $fileTarget;
-					} else {
-						$fileTarget = $parentFolder['folder'].$itemSource;
-						$parent = $parentFolder['id'];
-					}
-				} else {
-					$fileTarget = self::generateTarget('file', $filePath, $shareType, $shareWith, $uidOwner,
-						$suggestedFileTarget);
-				}
-			} else {
-				$fileTarget = null;
-			}
-			$query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner,
-				$permissions, time(), $fileSource, $fileTarget, $token));
-			$id = \OC_DB::insertid('*PREFIX*share');
-			\OC_Hook::emit('OCP\Share', 'post_shared', array(
-				'itemType' => $itemType,
-				'itemSource' => $itemSource,
-				'itemTarget' => $itemTarget,
-				'parent' => $parent,
-				'shareType' => $shareType,
-				'shareWith' => $shareWith,
-				'uidOwner' => $uidOwner,
-				'permissions' => $permissions,
-				'fileSource' => $fileSource,
-				'fileTarget' => $fileTarget,
-				'id' => $id,
-				'token' => $token
-			));
-			if ($parentFolder === true) {
-				$parentFolders['id'] = $id;
-				// Return parent folder to preserve file target paths for potential children
-				return $parentFolders;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Generate a unique target for the item
-	 * @param string Item type
-	 * @param string Item source
-	 * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
-	 * @param string User or group the item is being shared with
-	 * @param string User that is the owner of shared item
-	 * @param string The suggested target originating from a reshare (optional)
-	 * @param int The id of the parent group share (optional)
-	 * @param integer $shareType
-	 * @return string Item target
-	 */
-	private static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
-		$suggestedTarget = null, $groupParent = null) {
-		$backend = self::getBackend($itemType);
-		if ($shareType == self::SHARE_TYPE_LINK) {
-			if (isset($suggestedTarget)) {
-				return $suggestedTarget;
-			}
-			return $backend->generateTarget($itemSource, false);
-		} else {
-			if ($itemType == 'file' || $itemType == 'folder') {
-				$column = 'file_target';
-				$columnSource = 'file_source';
-			} else {
-				$column = 'item_target';
-				$columnSource = 'item_source';
-			}
-			if ($shareType == self::SHARE_TYPE_USER) {
-				// Share with is a user, so set share type to user and groups
-				$shareType = self::$shareTypeUserAndGroups;
-				$userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith));
-			} else {
-				$userAndGroups = false;
-			}
-			$exclude = null;
-			// Backend has 3 opportunities to generate a unique target
-			for ($i = 0; $i < 2; $i++) {
-				// Check if suggested target exists first
-				if ($i == 0 && isset($suggestedTarget)) {
-					$target = $suggestedTarget;
-				} else {
-					if ($shareType == self::SHARE_TYPE_GROUP) {
-						$target = $backend->generateTarget($itemSource, false, $exclude);
-					} else {
-						$target = $backend->generateTarget($itemSource, $shareWith, $exclude);
-					}
-					if (is_array($exclude) && in_array($target, $exclude)) {
-						break;
-					}
-				}
-				// Check if target already exists
-				$checkTarget = self::getItems($itemType, $target, $shareType, $shareWith);
-				if (!empty($checkTarget)) {
-					foreach ($checkTarget as $item) {
-						// Skip item if it is the group parent row
-						if (isset($groupParent) && $item['id'] == $groupParent) {
-							if (count($checkTarget) == 1) {
-								return $target;
-							} else {
-								continue;
-							}
-						}
-						if ($item['uid_owner'] == $uidOwner) {
-							if ($itemType == 'file' || $itemType == 'folder') {
-								$meta = \OC\Files\Filesystem::getFileInfo($itemSource);
-								if ($item['file_source'] == $meta['fileid']) {
-									return $target;
-								}
-							} else if ($item['item_source'] == $itemSource) {
-								return $target;
-							}
-						}
-					}
-					if (!isset($exclude)) {
-						$exclude = array();
-					}
-					// Find similar targets to improve backend's chances to generate a unqiue target
-					if ($userAndGroups) {
-						if ($column == 'file_target') {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` IN (\'file\', \'folder\')'
-								.' AND `share_type` IN (?,?,?)'
-								.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
-							$result = $checkTargets->execute(array(self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP,
-								self::$shareTypeGroupUserUnique));
-						} else {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` = ? AND `share_type` IN (?,?,?)'
-								.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
-							$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_USER,
-								self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique));
-						}
-					} else {
-						if ($column == 'file_target') {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` IN (\'file\', \'folder\')'
-								.' AND `share_type` = ? AND `share_with` = ?');
-							$result = $checkTargets->execute(array(self::SHARE_TYPE_GROUP, $shareWith));
-						} else {
-							$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
-								.' WHERE `item_type` = ? AND `share_type` = ? AND `share_with` = ?');
-							$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_GROUP, $shareWith));
-						}
-					}
-					while ($row = $result->fetchRow()) {
-						$exclude[] = $row[$column];
-					}
-				} else {
-					return $target;
-				}
-			}
-		}
-		$message = 'Sharing backend registered for '.$itemType.' did not generate a unique target for '.$itemSource;
-		\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
-		throw new \Exception($message);
-	}
-
-	/**
-	 * Delete all reshares of an item
-	 * @param int Id of item to delete
-	 * @param bool If true, exclude the parent from the delete (optional)
-	 * @param string The user that the parent was shared with (optinal)
-	 */
-	private static function delete($parent, $excludeParent = false, $uidOwner = null) {
-		$ids = array($parent);
-		$parents = array($parent);
-		while (!empty($parents)) {
-			$parents = "'".implode("','", $parents)."'";
-			// Check the owner on the first search of reshares, useful for
-			// finding and deleting the reshares by a single user of a group share
-			if (count($ids) == 1 && isset($uidOwner)) {
-				$query = \OC_DB::prepare('SELECT `id`, `uid_owner`, `item_type`, `item_target`, `parent`'
-					.' FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') AND `uid_owner` = ?');
-				$result = $query->execute(array($uidOwner));
-			} else {
-				$query = \OC_DB::prepare('SELECT `id`, `item_type`, `item_target`, `parent`, `uid_owner`'
-					.' FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.')');
-				$result = $query->execute();
-			}
-			// Reset parents array, only go through loop again if items are found
-			$parents = array();
-			while ($item = $result->fetchRow()) {
-				// Search for a duplicate parent share, this occurs when an
-				// item is shared to the same user through a group and user or the
-				// same item is shared by different users
-				$userAndGroups = array_merge(array($item['uid_owner']), \OC_Group::getUserGroups($item['uid_owner']));
-				$query = \OC_DB::prepare('SELECT `id`, `permissions` FROM `*PREFIX*share`'
-					.' WHERE `item_type` = ?'
-					.' AND `item_target` = ?'
-					.' AND `share_type` IN (?,?,?)'
-					.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')'
-					.' AND `uid_owner` != ? AND `id` != ?');
-				$duplicateParent = $query->execute(array($item['item_type'], $item['item_target'],
-					self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique,
-					$item['uid_owner'], $item['parent']))->fetchRow();
-				if ($duplicateParent) {
-					// Change the parent to the other item id if share permission is granted
-					if ($duplicateParent['permissions'] & PERMISSION_SHARE) {
-						$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` = ?');
-						$query->execute(array($duplicateParent['id'], $item['id']));
-						continue;
-					}
-				}
-				$ids[] = $item['id'];
-				$parents[] = $item['id'];
-			}
-		}
-		if ($excludeParent) {
-			unset($ids[0]);
-		}
-		if (!empty($ids)) {
-			$ids = "'".implode("','", $ids)."'";
-			$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$ids.')');
-			$query->execute();
-		}
+		return \OC\Share\Share::getBackend($itemType);
 	}
 
 	/**
 	 * Delete all shares with type SHARE_TYPE_LINK
 	 */
 	public static function removeAllLinkShares() {
-		// Delete any link shares
-		$query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ?');
-		$result = $query->execute(array(self::SHARE_TYPE_LINK));
-		while ($item = $result->fetchRow()) {
-			self::delete($item['id']);
-		}
-	}
-
-	/**
-	 * Hook Listeners
-	 */
-
-	/**
-	 * Function that is called after a user is deleted. Cleans up the shares of that user.
-	 * @param array arguments
-	 */
-	public static function post_deleteUser($arguments) {
-		// Delete any items shared with the deleted user
-		$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'
-			.' WHERE `share_with` = ? AND `share_type` = ? OR `share_type` = ?');
-		$result = $query->execute(array($arguments['uid'], self::SHARE_TYPE_USER, self::$shareTypeGroupUserUnique));
-		// Delete any items the deleted user shared
-		$query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `uid_owner` = ?');
-		$result = $query->execute(array($arguments['uid']));
-		while ($item = $result->fetchRow()) {
-			self::delete($item['id']);
-		}
-	}
-
-	/**
-	 * Function that is called after a user is added to a group.
-	 * TODO what does it do?
-	 * @param array arguments
-	 */
-	public static function post_addToGroup($arguments) {
-		// Find the group shares and check if the user needs a unique target
-		$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?');
-		$result = $query->execute(array(self::SHARE_TYPE_GROUP, $arguments['gid']));
-		$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`,'
-			.' `item_target`, `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`,'
-			.' `stime`, `file_source`, `file_target`) VALUES (?,?,?,?,?,?,?,?,?,?,?)');
-		while ($item = $result->fetchRow()) {
-			if ($item['item_type'] == 'file' || $item['item_type'] == 'file') {
-				$itemTarget = null;
-			} else {
-				$itemTarget = self::generateTarget($item['item_type'], $item['item_source'], self::SHARE_TYPE_USER,
-					$arguments['uid'], $item['uid_owner'], $item['item_target'], $item['id']);
-			}
-			if (isset($item['file_source'])) {
-				$fileTarget = self::generateTarget($item['item_type'], $item['item_source'], self::SHARE_TYPE_USER,
-					$arguments['uid'], $item['uid_owner'], $item['file_target'], $item['id']);
-			} else {
-				$fileTarget = null;
-			}
-			// Insert an extra row for the group share if the item or file target is unique for this user
-			if ($itemTarget != $item['item_target'] || $fileTarget != $item['file_target']) {
-				$query->execute(array($item['item_type'], $item['item_source'], $itemTarget, $item['id'],
-					self::$shareTypeGroupUserUnique, $arguments['uid'], $item['uid_owner'], $item['permissions'],
-					$item['stime'], $item['file_source'], $fileTarget));
-				\OC_DB::insertid('*PREFIX*share');
-			}
-		}
-	}
-
-	/**
-	 * Function that is called after a user is removed from a group. Shares are cleaned up.
-	 * @param array arguments
-	 */
-	public static function post_removeFromGroup($arguments) {
-		// TODO Don't call if user deleted?
-		$sql = 'SELECT `id`, `share_type` FROM `*PREFIX*share`'
-			.' WHERE (`share_type` = ? AND `share_with` = ?) OR (`share_type` = ? AND `share_with` = ?)';
-		$result = \OC_DB::executeAudited($sql, array(self::SHARE_TYPE_GROUP, $arguments['gid'],
-			self::$shareTypeGroupUserUnique, $arguments['uid']));
-		while ($item = $result->fetchRow()) {
-			if ($item['share_type'] == self::SHARE_TYPE_GROUP) {
-				// Delete all reshares by this user of the group share
-				self::delete($item['id'], true, $arguments['uid']);
-			} else {
-				self::delete($item['id']);
-			}
-		}
-	}
-
-	/**
-	 * Function that is called after a group is removed. Cleans up the shares to that group.
-	 * @param array arguments
-	 */
-	public static function post_deleteGroup($arguments) {
-		$sql = 'SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?';
-		$result = \OC_DB::executeAudited($sql, array(self::SHARE_TYPE_GROUP, $arguments['gid']));
-		while ($item = $result->fetchRow()) {
-			self::delete($item['id']);
-		}
+		return \OC\Share\Share::removeAllLinkShares();
 	}
 
 	/**
@@ -1935,26 +313,7 @@ class Share {
 	 * @return bool
 	 */
 	public static function checkPasswordProtectedShare(array $linkItem) {
-		if (!isset($linkItem['share_with'])) {
-			return true;
-		}
-		if (!isset($linkItem['share_type'])) {
-			return true;
-		}
-		if (!isset($linkItem['id'])) {
-			return true;
-		}
-
-		if ($linkItem['share_type'] != \OCP\Share::SHARE_TYPE_LINK) {
-			return true;
-		}
-
-		if ( \OC::$session->exists('public_link_authenticated')
-			&& \OC::$session->get('public_link_authenticated') === $linkItem['id'] ) {
-			return true;
-		}
-
-		return false;
+		return \OC\Share\Share::checkPasswordProtectedShare($linkItem);
 	}
 }
 
@@ -1967,9 +326,7 @@ interface Share_Backend {
 	 * Get the source of the item to be stored in the database
 	 * @param string Item source
 	 * @param string Owner of the item
-	 * @param string $itemSource
-	 * @param string $uidOwner
-	 * @return boolean Source
+	 * @return mixed|array|false Source
 	 *
 	 * Return an array if the item is file dependent, the array needs two keys: 'item' and 'file'
 	 * Return false if the item does not exist for the user
@@ -1992,8 +349,8 @@ interface Share_Backend {
 
 	/**
 	 * Converts the shared item sources back into the item in the specified format
-	 * @param array $items Shared items
-	 * @param integer $format
+	 * @param array Shared items
+	 * @param int Format
 	 * @return TODO
 	 *
 	 * The items array is a 3-dimensional array with the item_source as the
@@ -2025,9 +382,6 @@ interface Share_Backend_File_Dependent extends Share_Backend {
 	 * Get the file path of the item
 	 * @param string Item source
 	 * @param string User that is the owner of shared item
-	 * @param string $itemSource
-	 * @param string $uidOwner
-	 * @return boolean
 	 */
 	public function getFilePath($itemSource, $uidOwner);
 
diff --git a/ocs/v1.php b/ocs/v1.php
index 5d360c530a9d35faa9f407decbac89f643f7b2b1..62a3511e611b6a40bb8d20f4295899a420b385db 100644
--- a/ocs/v1.php
+++ b/ocs/v1.php
@@ -21,11 +21,15 @@
 *
 */
 
-require_once('../lib/base.php');
+require_once '../lib/base.php';
+
 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
 
 try {
+	// load all apps to get all api routes properly setup
+	OC_App::loadApps();
+
 	OC::$server->getRouter()->match('/ocs'.OC_Request::getRawPathInfo());
 } catch (ResourceNotFoundException $e) {
 	OC_API::setContentType();
diff --git a/public.php b/public.php
index 767295b98db100476f1119488443df88191a3835..e072db93d29dc7b0daf6c896269ec17b3cc39168 100644
--- a/public.php
+++ b/public.php
@@ -1,5 +1,4 @@
 <?php
-$RUNTIME_NOAPPS = true;
 
 try {
 
diff --git a/remote.php b/remote.php
index 9e18c8f80a9dd207d001f7c2912b2e4b38fb9690..15dfa8256ff3c2e93158d4d484320995b711c550 100644
--- a/remote.php
+++ b/remote.php
@@ -1,5 +1,4 @@
 <?php
-$RUNTIME_NOAPPS = true;
 
 try {
 
diff --git a/search/ajax/search.php b/search/ajax/search.php
index f0ca5752b9a731a91a5ed6102c5d3b67c2259966..0cc1f9d30cd21c7b10c74d85e6c0fae25eefc67e 100644
--- a/search/ajax/search.php
+++ b/search/ajax/search.php
@@ -23,7 +23,6 @@
 
 // Check if we are a user
 OC_JSON::checkLoggedIn();
-OC_App::loadApps();
 
 $query=(isset($_GET['query']))?$_GET['query']:'';
 if($query) {
diff --git a/settings/admin.php b/settings/admin.php
index 23b3a2d5a0e765dab5f1fc86b1a2394d0b7e506c..ea8aa7af5d0a4bab2f895d9df6806409ae193018 100755
--- a/settings/admin.php
+++ b/settings/admin.php
@@ -6,7 +6,6 @@
  */
 
 OC_Util::checkAdminUser();
-OC_App::loadApps();
 
 OC_Util::addStyle( "settings", "settings" );
 OC_Util::addScript( "settings", "admin" );
diff --git a/settings/apps.php b/settings/apps.php
index 96b6d21b50214d717423a27aa32d1a894543778d..6fd2efc2018020397daa17099692afa76a608e5c 100644
--- a/settings/apps.php
+++ b/settings/apps.php
@@ -22,7 +22,6 @@
 */
 
 OC_Util::checkAdminUser();
-OC_App::loadApps();
 
 // Load the files we need
 OC_Util::addStyle( "settings", "settings" );
diff --git a/settings/changepassword/controller.php b/settings/changepassword/controller.php
index e8c2a1943f3b0e28d156b7410c2662a83cd5fe07..9f1e732996412455e0dc9b5bb41a0815915ddf5b 100644
--- a/settings/changepassword/controller.php
+++ b/settings/changepassword/controller.php
@@ -8,9 +8,6 @@ class Controller {
 		\OC_JSON::callCheck();
 		\OC_JSON::checkLoggedIn();
 
-		// Manually load apps to ensure hooks work correctly (workaround for issue 1503)
-		\OC_App::loadApps();
-
 		$username = \OC_User::getUser();
 		$password = isset($_POST['personal-password']) ? $_POST['personal-password'] : null;
 		$oldPassword = isset($_POST['oldpassword']) ? $_POST['oldpassword'] : '';
@@ -32,9 +29,6 @@ class Controller {
 		\OC_JSON::callCheck();
 		\OC_JSON::checkLoggedIn();
 
-		// Manually load apps to ensure hooks work correctly (workaround for issue 1503)
-		\OC_App::loadApps();
-
 		if (isset($_POST['username'])) {
 			$username = $_POST['username'];
 		} else {
diff --git a/settings/help.php b/settings/help.php
index 88693939b848375bea86c54265f797487f36de78..301f50592aed4396552774862b5479d0641f9025 100644
--- a/settings/help.php
+++ b/settings/help.php
@@ -6,7 +6,6 @@
  */
 
 OC_Util::checkLoggedIn();
-OC_App::loadApps();
 
 // Load the files we need
 OC_Util::addStyle( "settings", "settings" );
diff --git a/settings/l10n/cs_CZ.php b/settings/l10n/cs_CZ.php
index 09bfe89d8af01c117373c21f235998b109d5648a..960938b1c6847364ccbc54cf835b57a52c200cdc 100644
--- a/settings/l10n/cs_CZ.php
+++ b/settings/l10n/cs_CZ.php
@@ -93,6 +93,9 @@ $TRANSLATIONS = array(
 "Internet connection not working" => "Připojení k internetu nefunguje",
 "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." => "Server nemá funkční připojení k internetu. Některé moduly jako např. externí úložiště, oznámení o dostupných aktualizacích nebo instalace aplikací třetích stran nebudou fungovat. Přístup k souborům z jiných míst a odesílání oznamovacích e-mailů také nemusí fungovat. Pokud si přejete využívat všech vlastností ownCloud, doporučujeme povolit připojení k internetu tomuto serveru.",
 "Cron" => "Cron",
+"Last cron was executed at %s." => "Poslední cron byl spuštěn v %s.",
+"Last cron was executed at %s. This is more than an hour ago, something seems wrong." => "Poslední cron byl spuštěn v  %s. To se stalo před více než hodinu. Vypadá to, že není něco v pořádku.",
+"Cron was not executed yet!" => "Cron ještě nebyl spuštěn!",
 "Execute one task with each page loaded" => "Spustit jednu úlohu s každým načtením stránky",
 "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." => "cron.php je registrován u služby webcron, aby volal cron.php jednou za 15 minut přes http.",
 "Use systems cron service to call the cron.php file every 15 minutes." => "Použít systémovou službu cron pro volání cron.php každých 15 minut.",
diff --git a/settings/l10n/gl.php b/settings/l10n/gl.php
index d98d812d9445415e26d1c7f3ba3148226beba6d7..2d23efd96a3c08d4f66e74075b042b5c70c76afe 100644
--- a/settings/l10n/gl.php
+++ b/settings/l10n/gl.php
@@ -93,6 +93,9 @@ $TRANSLATIONS = array(
 "Internet connection not working" => "A conexión á Internet non funciona",
 "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." => "Este servidor non ten conexión a Internet. Isto significa que algunhas das funcionalidades como a montaxe de almacenamento externo, as notificacións sobre actualizacións ou instalación de aplicativos de terceiros non funcionan. O acceso aos ficheiros de forma remota e o envío de mensaxes de notificación poderían non funcionar. Suxerímoslle que active a conexión a Internet deste servidor se quere dispor de todas as funcionalidades.",
 "Cron" => "Cron",
+"Last cron was executed at %s." => "O último «cron» executouse ás %s.",
+"Last cron was executed at %s. This is more than an hour ago, something seems wrong." => "O último «cron» executouse ás %s. Isto supón que pasou máis dunha hora. polo que semella que algo vai mal.",
+"Cron was not executed yet!" => "«Cron» aínda non foi executado!",
 "Execute one task with each page loaded" => "Executar unha tarefa con cada páxina cargada",
 "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." => "cron.php está rexistrado nun servizo de WebCron para chamar a cron.php cada 15 minutos a través de HTTP.",
 "Use systems cron service to call the cron.php file every 15 minutes." => "Use o servizo de sistema cron para chamar ao ficheiro cron.php cada 15 minutos.",
diff --git a/settings/l10n/pt_BR.php b/settings/l10n/pt_BR.php
index 4a7554499d5ecf432be2b639f847b80259a1b93d..dad6773d6afd5e0d9ba3773c4f71d8c3e4921ddb 100644
--- a/settings/l10n/pt_BR.php
+++ b/settings/l10n/pt_BR.php
@@ -93,6 +93,9 @@ $TRANSLATIONS = array(
 "Internet connection not working" => "Sem conexão com a internet",
 "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." => "Este servidor não tem conexão com a internet. Isso significa que algumas das características como a montagem de armazenamento externo, notificações sobre atualizações ou instalação de aplicativos de 3ºs terceiros não funcionam. Acessar arquivos remotamente e envio de e-mails de notificação também não podem funcionar. Sugerimos permitir conexão com a internet para esse servidor, se você deseja ter todas as funcionalidades.",
 "Cron" => "Cron",
+"Last cron was executed at %s." => "Último cron foi executado em %s.",
+"Last cron was executed at %s. This is more than an hour ago, something seems wrong." => "Última cron foi executado em %s. Isso é, mais do que uma hora atrás, algo parece errado.",
+"Cron was not executed yet!" => "Cron não foi executado ainda!",
 "Execute one task with each page loaded" => "Execute uma tarefa com cada página carregada",
 "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." => "cron.php está registrado no serviço webcron para chamar cron.php a cada 15 minutos sobre http.",
 "Use systems cron service to call the cron.php file every 15 minutes." => "Use o sistema de serviço cron para chamar o arquivo cron.php a cada 15 minutos.",
diff --git a/settings/l10n/ru.php b/settings/l10n/ru.php
index 49f3aeeb65d969c6333782edb23f4678a3fde1f8..9cbdeee2c23b35bc95fca77a9b2474805751bef2 100644
--- a/settings/l10n/ru.php
+++ b/settings/l10n/ru.php
@@ -1,5 +1,6 @@
 <?php
 $TRANSLATIONS = array(
+"Saved" => "Сохранено",
 "Email sent" => "Письмо отправлено",
 "Encryption" => "Шифрование",
 "Unable to load list from App Store" => "Не удалось загрузить список из App Store",
@@ -37,6 +38,11 @@ $TRANSLATIONS = array(
 "Update" => "Обновить",
 "Updated" => "Обновлено",
 "Select a profile picture" => "Выберите картинку профиля",
+"Very weak password" => "Очень слабый пароль",
+"Weak password" => "Слабый пароль",
+"So-so password" => "Так себе пароль",
+"Good password" => "Хороший пароль",
+"Strong password" => "Устойчивый к взлому пароль",
 "Decrypting files... Please wait, this can take some time." => "Расшифровка файлов... Пожалуйста, подождите, это может занять некоторое время.",
 "deleted" => "удален",
 "undo" => "отмена",
diff --git a/settings/l10n/sl.php b/settings/l10n/sl.php
index fea2d4cc3ad3e40e0f2a6c239997a92191d706cb..414f46712e388ec44d4b94cc89f51cf60be4da37 100644
--- a/settings/l10n/sl.php
+++ b/settings/l10n/sl.php
@@ -1,5 +1,6 @@
 <?php
 $TRANSLATIONS = array(
+"Invalid value supplied for %s" => "Navedena je napačna vrednost za %s",
 "Saved" => "Shranjeno",
 "Email sent" => "Elektronska pošta je poslana",
 "Send mode" => "Način pošiljanja",
diff --git a/settings/l10n/tr.php b/settings/l10n/tr.php
index e02c6701a9816d810a09ed3a3dcf6e5261611990..68b464a5cc2c66cd458268921ad3f5336febdcaa 100644
--- a/settings/l10n/tr.php
+++ b/settings/l10n/tr.php
@@ -93,6 +93,9 @@ $TRANSLATIONS = array(
 "Internet connection not working" => "İnternet bağlantısı çalışmıyor",
 "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." => "Bu sunucunun çalışan bir internet bağlantısı yok. Bu, harici depolama alanı bağlama, güncelleştirme bildirimleri veya 3. parti uygulama kurma gibi bazı özellikler çalışmayacak demektir. Uzak dosyalara erişim ve e-posta ile bildirim gönderme de çalışmayacaktır. Eğer bu özelliklerin tamamını kullanmak istiyorsanız, sunucu için internet bağlantısını etkinleştirmenizi öneriyoruz.",
 "Cron" => "Cron",
+"Last cron was executed at %s." => "Son cron %s zamanında çalıştırıldı.",
+"Last cron was executed at %s. This is more than an hour ago, something seems wrong." => "Son cron %s zamanında çalıştırıldı. Bu bir saatten daha uzun bir süre, bir şeyler yanlış gibi görünüyor.",
+"Cron was not executed yet!" => "Cron henüz çalıştırılmadı!",
 "Execute one task with each page loaded" => "Yüklenen her sayfa ile bir görev çalıştır",
 "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." => "cron.php, http üzerinden her 15 dakikada bir çağrılması için webcron hizmetine kaydedilir.",
 "Use systems cron service to call the cron.php file every 15 minutes." => "Cron.php dosyasını her 15 dakikada bir çağırmak için sistem cron hizmetini kullan.",
diff --git a/settings/personal.php b/settings/personal.php
index cf1a496bdf018ef7b7ff8d59d71540b82563aa32..be1aa6400bf63457f1d60201481bd6f6bb731352 100644
--- a/settings/personal.php
+++ b/settings/personal.php
@@ -6,7 +6,6 @@
  */
 
 OC_Util::checkLoggedIn();
-OC_App::loadApps();
 
 $defaults = new OC_Defaults(); // initialize themable default strings and urls
 
diff --git a/settings/settings.php b/settings/settings.php
index 1e05452ec4d1b612e43720f9006f17275c97477c..c08732fcf66203aa6c647bc4ab8552725314d292 100644
--- a/settings/settings.php
+++ b/settings/settings.php
@@ -6,7 +6,6 @@
  */
 
 OC_Util::checkLoggedIn();
-OC_App::loadApps();
 
 OC_Util::addStyle( 'settings', 'settings' );
 OC_App::setActiveNavigationEntry( 'settings' );
diff --git a/settings/users.php b/settings/users.php
index 2f1c63a0b59856900109f277c0ff93e5aa3366bd..f09d0e90d3c6bde5265a085450163153af0db743 100644
--- a/settings/users.php
+++ b/settings/users.php
@@ -6,7 +6,6 @@
  */
 
 OC_Util::checkSubAdminUser();
-OC_App::loadApps();
 
 // We have some javascript foo!
 OC_Util::addScript( 'settings', 'users' );
diff --git a/status.php b/status.php
index 88422100f14cf96afb6b637ecb139520efa8807e..861eaed9cd2638c3fe8ca3099d9f4ae811bb3981 100644
--- a/status.php
+++ b/status.php
@@ -21,8 +21,6 @@
 *
 */
 
-$RUNTIME_NOAPPS = true; //no apps, yet
-
 try {
 
 	require_once 'lib/base.php';
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 70de7cd1c44a20112d5769f763f54251f97b8cb9..99374d68a5c59971215144727ddb9fe65c55c2b0 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -16,3 +16,4 @@ if (!class_exists('PHPUnit_Framework_TestCase')) {
 
 OC_Hook::clear();
 OC_Log::$enabled = false;
+OC_FileProxy::clearProxies();
diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php
index 90f1dfe581b12674d3169c6fa66242e54ae876ac..53f528af793db009a4b1bfc5b4ecbd543c974fde 100644
--- a/tests/lib/files/filesystem.php
+++ b/tests/lib/files/filesystem.php
@@ -226,4 +226,55 @@ class Filesystem extends \PHPUnit_Framework_TestCase {
 		$path = $arguments['path'];
 		$this->assertEquals($path, \OC\Files\Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized
 	}
+
+	/**
+	 * Test that the default cache dir is part of the user's home
+	 */
+	public function testMountDefaultCacheDir() {
+		$userId = uniqid('user_');
+		$oldCachePath = \OC_Config::getValue('cache_path', '');
+		// no cache path configured
+		\OC_Config::setValue('cache_path', '');
+
+		\OC_User::createUser($userId, $userId);
+		\OC\Files\Filesystem::initMountPoints($userId);
+
+		$this->assertEquals(
+			'/' . $userId . '/',
+			\OC\Files\Filesystem::getMountPoint('/' . $userId . '/cache')
+		);
+		list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/cache');
+		$this->assertInstanceOf('\OC\Files\Storage\Home', $storage);
+		$this->assertEquals('cache', $internalPath);
+		\OC_User::deleteUser($userId);
+
+		\OC_Config::setValue('cache_path', $oldCachePath);
+	}
+
+	/**
+	 * Test that an external cache is mounted into
+	 * the user's home
+	 */
+	public function testMountExternalCacheDir() {
+		$userId = uniqid('user_');
+
+		$oldCachePath = \OC_Config::getValue('cache_path', '');
+		// set cache path to temp dir
+		$cachePath = \OC_Helper::tmpFolder() . '/extcache';
+		\OC_Config::setValue('cache_path', $cachePath);
+
+		\OC_User::createUser($userId, $userId);
+		\OC\Files\Filesystem::initMountPoints($userId);
+
+		$this->assertEquals(
+			'/' . $userId . '/cache/',
+			\OC\Files\Filesystem::getMountPoint('/' . $userId . '/cache')
+		);
+		list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/cache');
+		$this->assertInstanceOf('\OC\Files\Storage\Local', $storage);
+		$this->assertEquals('', $internalPath);
+		\OC_User::deleteUser($userId);
+
+		\OC_Config::setValue('cache_path', $oldCachePath);
+	}
 }
diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php
index f9291758606dc3cb327ac459ef264c9f1ca822d5..f3bfba3feb8e64171464b315ab283904d16dbf94 100644
--- a/tests/lib/files/storage/storage.php
+++ b/tests/lib/files/storage/storage.php
@@ -64,17 +64,17 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
 	 * @dataProvider directoryProvider
 	 */
 	public function testDirectories($directory) {
-		$this->assertFalse($this->instance->file_exists('/'.$directory));
+		$this->assertFalse($this->instance->file_exists('/' . $directory));
 
-		$this->assertTrue($this->instance->mkdir('/'.$directory));
+		$this->assertTrue($this->instance->mkdir('/' . $directory));
 
-		$this->assertTrue($this->instance->file_exists('/'.$directory));
-		$this->assertTrue($this->instance->is_dir('/'.$directory));
-		$this->assertFalse($this->instance->is_file('/'.$directory));
-		$this->assertEquals('dir', $this->instance->filetype('/'.$directory));
-		$this->assertEquals(0, $this->instance->filesize('/'.$directory));
-		$this->assertTrue($this->instance->isReadable('/'.$directory));
-		$this->assertTrue($this->instance->isUpdatable('/'.$directory));
+		$this->assertTrue($this->instance->file_exists('/' . $directory));
+		$this->assertTrue($this->instance->is_dir('/' . $directory));
+		$this->assertFalse($this->instance->is_file('/' . $directory));
+		$this->assertEquals('dir', $this->instance->filetype('/' . $directory));
+		$this->assertEquals(0, $this->instance->filesize('/' . $directory));
+		$this->assertTrue($this->instance->isReadable('/' . $directory));
+		$this->assertTrue($this->instance->isUpdatable('/' . $directory));
 
 		$dh = $this->instance->opendir('/');
 		$content = array();
@@ -85,13 +85,13 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
 		}
 		$this->assertEquals(array($directory), $content);
 
-		$this->assertFalse($this->instance->mkdir('/'.$directory)); //cant create existing folders
-		$this->assertTrue($this->instance->rmdir('/'.$directory));
+		$this->assertFalse($this->instance->mkdir('/' . $directory)); //cant create existing folders
+		$this->assertTrue($this->instance->rmdir('/' . $directory));
 
 		$this->wait();
-		$this->assertFalse($this->instance->file_exists('/'.$directory));
+		$this->assertFalse($this->instance->file_exists('/' . $directory));
 
-		$this->assertFalse($this->instance->rmdir('/'.$directory)); //cant remove non existing folders
+		$this->assertFalse($this->instance->rmdir('/' . $directory)); //cant remove non existing folders
 
 		$dh = $this->instance->opendir('/');
 		$content = array();
@@ -103,8 +103,7 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
 		$this->assertEquals(array(), $content);
 	}
 
-	public function directoryProvider()
-	{
+	public function directoryProvider() {
 		return array(
 			array('folder'),
 			array(' folder'),
@@ -113,6 +112,7 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
 			array('spéciäl földer'),
 		);
 	}
+
 	/**
 	 * test the various uses of file_get_contents and file_put_contents
 	 */
@@ -298,4 +298,21 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
 		$this->assertFalse($this->instance->file_exists('folder/bar'));
 		$this->assertFalse($this->instance->file_exists('folder'));
 	}
+
+	public function hashProvider(){
+		return array(
+			array('Foobar', 'md5'),
+			array('Foobar', 'sha1'),
+			array('Foobar', 'sha256'),
+		);
+	}
+
+	/**
+	 * @dataProvider hashProvider
+	 */
+	public function testHash($data, $type) {
+		$this->instance->file_put_contents('hash.txt', $data);
+		$this->assertEquals(hash($type, $data), $this->instance->hash($type, 'hash.txt'));
+		$this->assertEquals(hash($type, $data, true), $this->instance->hash($type, 'hash.txt', true));
+	}
 }
diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php
index b5cba9430aac998bb547f03de03525fcc4847a1a..aae91fa1087e6c576bae24ea9e4b748dd4938658 100644
--- a/tests/lib/share/share.php
+++ b/tests/lib/share/share.php
@@ -282,7 +282,7 @@ class Test_Share extends PHPUnit_Framework_TestCase {
 		OC_User::setUserId($this->user2);
 		$this->assertEquals(array(OCP\PERMISSION_READ), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_PERMISSIONS));
 		OC_User::setUserId($this->user3);
-		$this->assertFalse(OCP\Share::getItemSharedWith('test', 'test.txt'));
+		$this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt'));
 
 		// Reshare again, and then have owner unshare
 		OC_User::setUserId($this->user1);
@@ -292,9 +292,9 @@ class Test_Share extends PHPUnit_Framework_TestCase {
 		OC_User::setUserId($this->user1);
 		$this->assertTrue(OCP\Share::unshare('test', 'test.txt', OCP\Share::SHARE_TYPE_USER, $this->user2));
 		OC_User::setUserId($this->user2);
-		$this->assertFalse(OCP\Share::getItemSharedWith('test', 'test.txt'));
+		$this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt'));
 		OC_User::setUserId($this->user3);
-		$this->assertFalse(OCP\Share::getItemSharedWith('test', 'test.txt'));
+		$this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt'));
 
 		// Attempt target conflict
 		OC_User::setUserId($this->user1);
@@ -325,7 +325,7 @@ class Test_Share extends PHPUnit_Framework_TestCase {
 		);
 
 		OC_User::setUserId($this->user2);
-		$this->assertFalse(
+		$this->assertSame(array(),
 			OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE),
 			'Failed asserting that user 2 no longer has access to test.txt after expiration.'
 		);
@@ -526,13 +526,13 @@ class Test_Share extends PHPUnit_Framework_TestCase {
 		);
 
 		OC_User::setUserId($this->user2);
-		$this->assertFalse(
+		$this->assertSame(array(),
 			OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE),
 			'Failed asserting that user 2 no longer has access to test.txt after expiration.'
 		);
 
 		OC_User::setUserId($this->user3);
-		$this->assertFalse(
+		$this->assertSame(array(),
 			OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE),
 			'Failed asserting that user 3 no longer has access to test.txt after expiration.'
 		);
diff --git a/tests/lib/urlgenerator.php b/tests/lib/urlgenerator.php
index 875a7f06580bb87ebe5292f3e781ed7b4a0f0f6f..8e605d88f32f26b13f275ca1dbe39d95e709a23c 100644
--- a/tests/lib/urlgenerator.php
+++ b/tests/lib/urlgenerator.php
@@ -12,17 +12,32 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase {
 	/**
 	 * @small
 	 * @brief test absolute URL construction
-	 * @dataProvider provideURLs
+	 * @dataProvider provideDocRootURLs
 	 */
-	function testGetAbsoluteURL($url, $expectedResult) {
+	function testGetAbsoluteURLDocRoot($url, $expectedResult) {
 
+		\OC::$WEBROOT = '';
 		$urlGenerator = new \OC\URLGenerator(null);
 		$result = $urlGenerator->getAbsoluteURL($url);
 
 		$this->assertEquals($expectedResult, $result);
 	}
 
-	public function provideURLs() {
+	/**
+	 * @small
+	 * @brief test absolute URL construction
+	 * @dataProvider provideSubDirURLs
+	 */
+	function testGetAbsoluteURLSubDir($url, $expectedResult) {
+
+		\OC::$WEBROOT = '/owncloud';
+		$urlGenerator = new \OC\URLGenerator(null);
+		$result = $urlGenerator->getAbsoluteURL($url);
+
+		$this->assertEquals($expectedResult, $result);
+	}
+
+	public function provideDocRootURLs() {
 		return array(
 			array("index.php", "http://localhost/index.php"),
 			array("/index.php", "http://localhost/index.php"),
@@ -30,5 +45,14 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase {
 			array("apps/index.php", "http://localhost/apps/index.php"),
 			);
 	}
+
+	public function provideSubDirURLs() {
+		return array(
+			array("index.php", "http://localhost/owncloud/index.php"),
+			array("/index.php", "http://localhost/owncloud/index.php"),
+			array("/apps/index.php", "http://localhost/owncloud/apps/index.php"),
+			array("apps/index.php", "http://localhost/owncloud/apps/index.php"),
+			);
+	}
 }