diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php
index 92c761838760db9e1b820346e0939c2d6f8650c4..dd5c470431a556498903c3f43241eb6d57fcb335 100644
--- a/apps/files/appinfo/remote.php
+++ b/apps/files/appinfo/remote.php
@@ -49,8 +49,9 @@ $server->subscribeEvent('beforeMethod', function () use ($server, $objectTree) {
 	$rootInfo = $view->getFileInfo('');
 
 	// Create ownCloud Dir
+	$mountManager = \OC\Files\Filesystem::getMountManager();
 	$rootDir = new OC_Connector_Sabre_Directory($view, $rootInfo);
-	$objectTree->init($rootDir, $view);
+	$objectTree->init($rootDir, $view, $mountManager);
 
 	$server->addPlugin(new OC_Connector_Sabre_AbortedUploadDetectionPlugin($view));
 	$server->addPlugin(new OC_Connector_Sabre_QuotaPlugin($view));
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index fd91073b8debf95cc77bc59b0efe2502460af51e..b1af4676852e2de6285adf9a00eb77e7868fe12d 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -41,6 +41,39 @@ class Proxy extends \OC_FileProxy {
 	private static $fopenMode = array(); // remember the fopen mode
 	private static $enableEncryption = false; // Enable encryption for the given path
 
+
+	/**
+	 * check if path is excluded from encryption
+	 *
+	 * @param string $path relative to data/
+	 * @param string $uid user
+	 * @return boolean
+	 */
+	private function isExcludedPath($path, $uid) {
+
+		$view = new \OC\Files\View();
+
+		// files outside of the files-folder are excluded
+		if(strpos($path, '/' . $uid . '/files') !== 0) {
+			return true;
+		}
+
+		if (!$view->file_exists($path)) {
+			$path = dirname($path);
+		}
+
+		// we don't encrypt server-to-server shares
+		list($storage, ) = \OC\Files\Filesystem::resolvePath($path);
+		/**
+		 * @var \OCP\Files\Storage $storage
+		 */
+		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
+			return true;
+		}
+
+		return false;
+	}
+
 	/**
 	 * Check if a file requires encryption
 	 * @param string $path
@@ -50,7 +83,7 @@ class Proxy extends \OC_FileProxy {
 	 * Tests if server side encryption is enabled, and if we should call the
 	 * crypt stream wrapper for the given file
 	 */
-	private static function shouldEncrypt($path, $mode = 'w') {
+	private function shouldEncrypt($path, $mode = 'w') {
 
 		$userId = Helper::getUser($path);
 		$session = new Session(new \OC\Files\View());
@@ -59,7 +92,7 @@ class Proxy extends \OC_FileProxy {
 		if (
 				$session->getInitialized() !== Session::INIT_SUCCESSFUL // encryption successful initialized
 				|| Crypt::mode() !== 'server'   // we are not in server-side-encryption mode
-				|| strpos($path, '/' . $userId . '/files') !== 0 // path is not in files/
+				|| $this->isExcludedPath($path, $userId) // if path is excluded from encryption
 				|| substr($path, 0, 8) === 'crypt://' // we are already in crypt mode
 		) {
 			return false;
@@ -85,7 +118,7 @@ class Proxy extends \OC_FileProxy {
 	 */
 	public function preFile_put_contents($path, &$data) {
 
-		if (self::shouldEncrypt($path)) {
+		if ($this->shouldEncrypt($path)) {
 
 			if (!is_resource($data)) {
 
@@ -219,7 +252,7 @@ class Proxy extends \OC_FileProxy {
 	public function preFopen($path, $mode) {
 
 		self::$fopenMode[$path] = $mode;
-		self::$enableEncryption = self::shouldEncrypt($path, $mode);
+		self::$enableEncryption = $this->shouldEncrypt($path, $mode);
 
 	}
 
diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php
index 93be6691f96bbc0d0e6db2db632f7b8a1357782a..ef18b924dd8175c8279da7074a41f3ab3186a12d 100644
--- a/apps/files_encryption/lib/session.php
+++ b/apps/files_encryption/lib/session.php
@@ -100,6 +100,8 @@ class Session {
 			$privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
 			$this->setPublicSharePrivateKey($privateKey);
 
+			$this->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL);
+
 			\OC_FileProxy::$enabled = $proxyStatus;
 		}
 	}
diff --git a/apps/files_encryption/tests/webdav.php b/apps/files_encryption/tests/webdav.php
index 84db54ff30b208a9e1a7cbb00505c0858cc7f91c..73bc9ce08dea9d0ca7d7647cb5b3fc87f9fac2d6 100755
--- a/apps/files_encryption/tests/webdav.php
+++ b/apps/files_encryption/tests/webdav.php
@@ -235,7 +235,8 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase {
 		$view = new \OC\Files\View($root);
 		$publicDir = new OC_Connector_Sabre_Directory($view, $view->getFileInfo(''));
 		$objectTree = new \OC\Connector\Sabre\ObjectTree();
-		$objectTree->init($publicDir, $view);
+		$mountManager = \OC\Files\Filesystem::getMountManager();
+		$objectTree->init($publicDir, $view, $mountManager);
 
 		// Fire up server
 		$server = new \Sabre\DAV\Server($publicDir);
diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php
index 525f41c127651469e1d1a29b9fcaf0f6a2e598e0..c532c5eaa7d14426752e1521b7a7d767c430a39f 100644
--- a/apps/files_external/lib/webdav.php
+++ b/apps/files_external/lib/webdav.php
@@ -9,13 +9,13 @@
 namespace OC\Files\Storage;
 
 class DAV extends \OC\Files\Storage\Common {
-	private $password;
-	private $user;
-	private $host;
-	private $secure;
-	private $root;
-	private $certPath;
-	private $ready;
+	protected $password;
+	protected $user;
+	protected $host;
+	protected $secure;
+	protected $root;
+	protected $certPath;
+	protected $ready;
 	/**
 	 * @var \Sabre\DAV\Client
 	 */
@@ -355,6 +355,9 @@ class DAV extends \OC\Files\Storage\Common {
 	 * @param string $path
 	 */
 	public function cleanPath($path) {
+		if ($path === "") {
+			return $path;
+		}
 		$path = \OC\Files\Filesystem::normalizePath($path);
 		// remove leading slash
 		return substr($path, 1);
@@ -397,11 +400,27 @@ class DAV extends \OC\Files\Storage\Common {
 		}
 	}
 
+	public function isUpdatable($path) {
+		return (bool)($this->getPermissions($path) & \OCP\PERMISSION_UPDATE);
+	}
+
+	public function isCreatable($path) {
+		return (bool)($this->getPermissions($path) & \OCP\PERMISSION_CREATE);
+	}
+
+	public function isSharable($path) {
+		return (bool)($this->getPermissions($path) & \OCP\PERMISSION_SHARE);
+	}
+
+	public function isDeletable($path) {
+		return (bool)($this->getPermissions($path) & \OCP\PERMISSION_DELETE);
+	}
+
 	public function getPermissions($path) {
 		$this->init();
 		$response = $this->client->propfind($this->encodePath($path), array('{http://owncloud.org/ns}permissions'));
 		if (isset($response['{http://owncloud.org/ns}permissions'])) {
-			$permissions = 0;
+			$permissions = \OCP\PERMISSION_READ;
 			$permissionsString = $response['{http://owncloud.org/ns}permissions'];
 			if (strpos($permissionsString, 'R') !== false) {
 				$permissions |= \OCP\PERMISSION_SHARE;
@@ -416,8 +435,12 @@ class DAV extends \OC\Files\Storage\Common {
 				$permissions |= \OCP\PERMISSION_CREATE;
 			}
 			return $permissions;
+		} else if ($this->is_dir($path)) {
+			return \OCP\PERMISSION_ALL;
+		} else if ($this->file_exists($path)) {
+			return \OCP\PERMISSION_ALL - \OCP\PERMISSION_CREATE;
 		} else {
-			return parent::getPermissions($path);
+			return 0;
 		}
 	}
 }
diff --git a/apps/files_sharing/ajax/external.php b/apps/files_sharing/ajax/external.php
new file mode 100644
index 0000000000000000000000000000000000000000..52c84b7babbc3c1c0e84237e04ceead2e187dd42
--- /dev/null
+++ b/apps/files_sharing/ajax/external.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+OCP\JSON::callCheck();
+OCP\JSON::checkLoggedIn();
+OCP\JSON::checkAppEnabled('files_sharing');
+
+$l = OC_L10N::get('files_sharing');
+
+// check if server admin allows to mount public links from other servers
+// check if files_external is enabled
+// FIXME file_external check no longer needed if we use the webdav implementation from core
+if (OCA\Files_Sharing\Helper::isIncomingServer2serverShareEnabled() === false ||
+		\OC_App::isEnabled('files_external') === false) {
+	\OCP\JSON::error(array('data' => array('message' => $l->t('Server to server sharing is not enabled on this server'))));
+	exit();
+}
+
+$token = $_POST['token'];
+$remote = $_POST['remote'];
+$owner = $_POST['owner'];
+$name = $_POST['name'];
+$password = $_POST['password'];
+
+$externalManager = new \OCA\Files_Sharing\External\Manager(
+	\OC::$server->getDatabaseConnection(),
+	\OC\Files\Filesystem::getMountManager(),
+	\OC\Files\Filesystem::getLoader(),
+	\OC::$server->getUserSession()
+);
+
+$name = OCP\Files::buildNotExistingFileName('/', $name);
+
+$mount = $externalManager->addShare($remote, $token, $password, $name, $owner);
+/**
+ * @var \OCA\Files_Sharing\External\Storage $storage
+ */
+$storage = $mount->getStorage();
+$result = $storage->file_exists('');
+if($result){
+	$storage->getScanner()->scanAll();
+	\OCP\JSON::success();
+} else {
+	$externalManager->removeShare($mount->getMountPoint());
+	\OCP\JSON::error(array('data' => array('message' => $l->t("Couldn't add remote share"))));
+}
diff --git a/apps/files_sharing/ajax/shareinfo.php b/apps/files_sharing/ajax/shareinfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..e87b0779e8d653d47800eaba070d14c8e4ea9246
--- /dev/null
+++ b/apps/files_sharing/ajax/shareinfo.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+OCP\JSON::checkAppEnabled('files_sharing');
+
+if (!isset($_GET['t'])) {
+	\OC_Response::setStatus(400); //400 Bad Request
+	exit;
+}
+
+$token = $_GET['t'];
+
+$password = null;
+if (isset($_POST['password'])) {
+	$password = $_POST['password'];
+}
+
+$relativePath = null;
+if (isset($_GET['dir'])) {
+	$relativePath = $_GET['dir'];
+}
+
+$data = \OCA\Files_Sharing\Helper::setupFromToken($token, $relativePath, $password);
+
+$linkItem = $data['linkItem'];
+// Load the files
+$path = $data['realPath'];
+
+$isWritable = $linkItem['permissions'] & (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_CREATE);
+if (!$isWritable) {
+	\OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, $storage) {
+		return new \OCA\Files_Sharing\ReadOnlyWrapper(array('storage' => $storage));
+	});
+}
+
+$rootInfo = \OC\Files\Filesystem::getFileInfo($path);
+$rootView = new \OC\Files\View('');
+
+/**
+ * @param \OCP\Files\FileInfo $dir
+ * @param \OC\Files\View $view
+ * @return array
+ */
+function getChildInfo($dir, $view) {
+	$children = $view->getDirectoryContent($dir->getPath());
+	$result = array();
+	foreach ($children as $child) {
+		$formated = \OCA\Files\Helper::formatFileInfo($child);
+		if ($child->getType() === 'dir') {
+			$formated['children'] = getChildInfo($child, $view);
+		}
+		$formated['mtime'] = $formated['mtime'] / 1000;
+		$result[] = $formated;
+	}
+	return $result;
+}
+
+$result = \OCA\Files\Helper::formatFileInfo($rootInfo);
+$result['mtime'] = $result['mtime'] / 1000;
+if ($rootInfo->getType() === 'dir') {
+	$result['children'] = getChildInfo($rootInfo, $rootView);
+}
+
+OCP\JSON::success(array('data' => $result));
diff --git a/apps/files_sharing/ajax/testremote.php b/apps/files_sharing/ajax/testremote.php
new file mode 100644
index 0000000000000000000000000000000000000000..89581794698a4e1d56fa942f0fea06c0615a24d0
--- /dev/null
+++ b/apps/files_sharing/ajax/testremote.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+OCP\JSON::checkAppEnabled('files_sharing');
+
+$remote = $_GET['remote'];
+
+function testUrl($url) {
+	try {
+		$result = file_get_contents($url);
+		$data = json_decode($result);
+		return is_object($data) and !empty($data->version);
+	} catch (Exception $e) {
+		return false;
+	}
+}
+
+if (testUrl('https://' . $remote . '/status.php')) {
+	echo 'https';
+} elseif (testUrl('http://' . $remote . '/status.php')) {
+	echo 'http';
+} else {
+	echo 'false';
+}
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 6b40ba921ccc4211889b524a69a6f7279633a78d..a9f4ff5089b5da195438a7f1ee91cabaa54caa16 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -11,10 +11,24 @@ OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'files_sharing/lib/watcher.php
 OC::$CLASSPATH['OCA\Files\Share\Api'] = 'files_sharing/lib/api.php';
 OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php';
 OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php';
+
+\OCP\App::registerAdmin('files_sharing', 'settings-admin');
+
+$externalManager = new \OCA\Files_Sharing\External\Manager(
+	\OC::$server->getDatabaseConnection(),
+	\OC\Files\Filesystem::getMountManager(),
+	\OC\Files\Filesystem::getLoader(),
+	\OC::$server->getUserSession()
+);
+$externalManager->setup();
+
 OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
 OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
 OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
+
 OCP\Util::addScript('files_sharing', 'share');
+OCP\Util::addScript('files_sharing', 'external');
+
 \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook');
 \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Shared_Updater', 'postDeleteHook');
 \OC_Hook::connect('OC_Filesystem', 'delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook');
diff --git a/apps/files_sharing/appinfo/database.xml b/apps/files_sharing/appinfo/database.xml
new file mode 100644
index 0000000000000000000000000000000000000000..73d64c527b7a381e6cd5144dcbf942d10fd79a0a
--- /dev/null
+++ b/apps/files_sharing/appinfo/database.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<database>
+	<name>*dbname*</name>
+	<create>true</create>
+	<overwrite>false</overwrite>
+	<charset>utf8</charset>
+	<table>
+		<name>*dbprefix*share_external</name>
+		<declaration>
+			<field>
+				<name>id</name>
+				<type>integer</type>
+				<default>0</default>
+				<notnull>true</notnull>
+				<autoincrement>1</autoincrement>
+				<length>4</length>
+			</field>
+			<field>
+				<name>remote</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>512</length>
+				<comments>Url of the remove owncloud instance</comments>
+			</field>
+			<field>
+				<name>share_token</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+				<comments>Public share token</comments>
+			</field>
+			<field>
+				<name>password</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+				<comments>Optional password for the public share</comments>
+			</field>
+			<field>
+				<name>name</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+				<comments>Original name on the remote server</comments>
+			</field>
+			<field>
+				<name>owner</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+				<comments>User that owns the public share on the remote server</comments>
+			</field>
+			<field>
+				<name>user</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+				<comments>Local user which added the external share</comments>
+			</field>
+			<field>
+				<name>mountpoint</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>4000</length>
+				<comments>Full path where the share is mounted</comments>
+			</field>
+			<field>
+				<name>mountpoint_hash</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>32</length>
+				<comments>md5 hash of the mountpoint</comments>
+			</field>
+			<index>
+				<name>sh_external_user</name>
+				<field>
+					<name>user</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+			<index>
+				<name>sh_external_mp</name>
+				<unique>true</unique>
+				<field>
+					<name>user</name>
+					<sorting>ascending</sorting>
+				</field>
+				<field>
+					<name>mountpoint_hash</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+		</declaration>
+	</table>
+</database>
diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php
index 7c2834dc9c2b008f02fef4ea6c2e4876699fbac7..e68b953fc05951db3558d5cf1fa8134df4feb3c0 100644
--- a/apps/files_sharing/appinfo/routes.php
+++ b/apps/files_sharing/appinfo/routes.php
@@ -5,6 +5,10 @@ $this->create('core_ajax_public_preview', '/publicpreview')->action(
 		require_once __DIR__ . '/../ajax/publicpreview.php';
 	});
 
+$this->create('sharing_external_shareinfo', '/shareinfo')->actionInclude('files_sharing/ajax/shareinfo.php');
+$this->create('sharing_external_add', '/external')->actionInclude('files_sharing/ajax/external.php');
+$this->create('sharing_external_test_remote', '/testremote')->actionInclude('files_sharing/ajax/testremote.php');
+
 // OCS API
 
 //TODO: SET: mail notification, waiting for PR #4689 to be accepted
diff --git a/apps/files_sharing/appinfo/version b/apps/files_sharing/appinfo/version
index 2eb3c4fe4eebcdea3da0790cc0ba74cb286ec4f4..cb0c939a936f142669d38cf1ece330266d730965 100644
--- a/apps/files_sharing/appinfo/version
+++ b/apps/files_sharing/appinfo/version
@@ -1 +1 @@
-0.5
+0.5.2
diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css
index 1bafb7807441cc96713ff3f97f35e1ab12ec93e3..31c3bca874868795b990efc6c2fa32dc9115b7a8 100644
--- a/apps/files_sharing/css/public.css
+++ b/apps/files_sharing/css/public.css
@@ -87,3 +87,38 @@ thead {
 	width: 300px;
 	max-width: 90%;
 }
+
+.header-right {
+	transition: opacity 500ms ease 0s;
+	-moz-transition: opacity 500ms ease 0s;
+	-ms-transition: opacity 500ms ease 0s;
+	-o-transition: opacity 500ms ease 0s;
+	-webkit-transition: opacity 500ms ease 0s;
+}
+
+.header-right:hover, .header-right.active {
+	opacity: 1;
+	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
+	filter: alpha(opacity=100);
+}
+
+/* within #save */
+#remote_address {
+	margin: 0;
+	height: 14px;
+	line-height: 16px;
+	padding: 6px;
+}
+
+#save button {
+	margin: 0 5px;
+	height: 28px;
+	padding-bottom: 4px;
+	line-height: 14px;
+}
+
+#save .save-form [type="submit"] {
+	margin: 0 5px;
+	height: 28px;
+	padding-bottom: 4px;
+}
diff --git a/apps/files_sharing/js/external.js b/apps/files_sharing/js/external.js
new file mode 100644
index 0000000000000000000000000000000000000000..5c476b2d43d25fa007732e9d81b005ab40d30646
--- /dev/null
+++ b/apps/files_sharing/js/external.js
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+(function () {
+	var getParameterByName = function (query, name) {
+		name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+		var regex = new RegExp("[\\#&]" + name + "=([^&#]*)"),
+			results = regex.exec(query);
+		return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+	};
+
+	var addExternalShare = function (remote, token, owner, name, password) {
+		return $.post(OC.generateUrl('apps/files_sharing/external'), {
+			remote: remote,
+			token: token,
+			owner: owner,
+			name: name,
+			password: password
+		});
+	};
+
+	var showAddExternalDialog = function (remote, token, owner, name, passwordProtected) {
+		var remoteClean = (remote.substr(0, 8) === 'https://') ? remote.substr(8) : remote.substr(7);
+		var callback = function (add, password) {
+			password = password || '';
+			if (add) {
+				addExternalShare(remote, token, owner, name, password).then(function (result) {
+					if (result.status === 'error') {
+						OC.Notification.show(result.data.message);
+					} else {
+						FileList.reload();
+					}
+				});
+			}
+		};
+		if (!passwordProtected) {
+			OC.dialogs.confirm(t('files_sharing', 'Add {name} from {owner}@{remote}', {name: name, owner: owner, remote: remoteClean})
+				, 'Add Share', callback, true);
+		} else {
+			OC.dialogs.prompt(t('files_sharing', 'Add {name} from {owner}@{remote}', {name: name, owner: owner, remote: remoteClean})
+				, 'Add Share', callback, true, 'Password', true);
+		}
+	};
+
+	OCA.Sharing.showAddExternalDialog = function (hash) {
+		var remote = getParameterByName(hash, 'remote');
+		var owner = getParameterByName(hash, 'owner');
+		var name = getParameterByName(hash, 'name');
+		var token = getParameterByName(hash, 'token');
+		var passwordProtected = parseInt(getParameterByName(hash, 'protected'), 10);
+
+		if (remote && token && owner && name) {
+			showAddExternalDialog(remote, token, owner, name, passwordProtected);
+		}
+	};
+})();
+
+$(document).ready(function () {
+	// FIXME: HACK: do not init when running unit tests, need a better way
+	if (!window.TESTING && OCA.Files) {// only run in the files app
+		var hash = location.hash;
+		location.hash = '';
+		OCA.Sharing.showAddExternalDialog(hash);
+	}
+});
diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js
index a2248405d22297bb81a90265f5c61de9dbd07f84..80631908d24df715e6b145162d3c8c139e7f1fc9 100644
--- a/apps/files_sharing/js/public.js
+++ b/apps/files_sharing/js/public.js
@@ -19,7 +19,7 @@ if (!OCA.Files) {
 OCA.Sharing.PublicApp = {
 	_initialized: false,
 
-	initialize: function($el) {
+	initialize: function ($el) {
 		var self = this;
 		var fileActions;
 		if (this._initialized) {
@@ -65,7 +65,7 @@ OCA.Sharing.PublicApp = {
 		}
 
 		// dynamically load image previews
-		if (mimetype.substr(0, mimetype.indexOf('/')) === 'image' ) {
+		if (mimetype.substr(0, mimetype.indexOf('/')) === 'image') {
 
 			var params = {
 				x: $(document).width() * window.devicePixelRatio,
@@ -82,7 +82,7 @@ OCA.Sharing.PublicApp = {
 
 		if (this.fileList) {
 			// TODO: move this to a separate PublicFileList class that extends OCA.Files.FileList (+ unit tests)
-			this.fileList.getDownloadUrl = function(filename, dir) {
+			this.fileList.getDownloadUrl = function (filename, dir) {
 				if ($.isArray(filename)) {
 					filename = JSON.stringify(filename);
 				}
@@ -97,13 +97,13 @@ OCA.Sharing.PublicApp = {
 				return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params);
 			};
 
-			this.fileList.getAjaxUrl = function(action, params) {
+			this.fileList.getAjaxUrl = function (action, params) {
 				params = params || {};
 				params.t = $('#sharingToken').val();
 				return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params);
 			};
 
-			this.fileList.linkTo = function(dir) {
+			this.fileList.linkTo = function (dir) {
 				var params = {
 					service: 'files',
 					t: $('#sharingToken').val(),
@@ -112,15 +112,15 @@ OCA.Sharing.PublicApp = {
 				return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params);
 			};
 
-			this.fileList.generatePreviewUrl = function(urlSpec) {
+			this.fileList.generatePreviewUrl = function (urlSpec) {
 				urlSpec.t = $('#dirToken').val();
 				return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec);
 			};
 
 			var file_upload_start = $('#file_upload_start');
-			file_upload_start.on('fileuploadadd', function(e, data) {
+			file_upload_start.on('fileuploadadd', function (e, data) {
 				var fileDirectory = '';
-				if(typeof data.files[0].relativePath !== 'undefined') {
+				if (typeof data.files[0].relativePath !== 'undefined') {
 					fileDirectory = data.files[0].relativePath;
 				}
 
@@ -143,16 +143,34 @@ OCA.Sharing.PublicApp = {
 			OC.Util.History.addOnPopStateHandler(_.bind(this._onUrlChanged, this));
 		}
 
-		$(document).on('click', '#directLink', function() {
+		$(document).on('click', '#directLink', function () {
 			$(this).focus();
 			$(this).select();
 		});
 
+		$('.save-form').submit(function (event) {
+			event.preventDefault();
+
+			var remote = $(this).find('input[type="text"]').val();
+			var token = $('#sharingToken').val();
+			var owner = $('#save').data('owner');
+			var name = $('#save').data('name');
+			var isProtected = $('#save').data('protected') ? 1 : 0;
+			OCA.Sharing.PublicApp._saveToOwnCloud(remote, token, owner, name, isProtected);
+		});
+
+		$('#save > button').click(function () {
+			$(this).hide();
+			$('.header-right').addClass('active');
+			$('.save-form').css('display', 'inline');
+			$('#remote_address').focus();
+		});
+
 		// legacy
 		window.FileList = this.fileList;
 	},
 
-	_onDirectoryChanged: function(e) {
+	_onDirectoryChanged: function (e) {
 		OC.Util.History.pushState({
 			service: 'files',
 			t: $('#sharingToken').val(),
@@ -161,21 +179,44 @@ OCA.Sharing.PublicApp = {
 		});
 	},
 
-	_onUrlChanged: function(params) {
+	_onUrlChanged: function (params) {
 		this.fileList.changeDirectory(params.path || params.dir, false, true);
+	},
+
+	_saveToOwnCloud: function(remote, token, owner, name, isProtected) {
+		var location = window.location.protocol + '//' + window.location.host + OC.webroot;
+
+		var url = remote + '/index.php/apps/files#' + 'remote=' + encodeURIComponent(location) // our location is the remote for the other server
+			+ "&token=" + encodeURIComponent(token) + "&owner=" + encodeURIComponent(owner) + "&name=" + encodeURIComponent(name) + "&protected=" + isProtected;
+
+
+		if (remote.indexOf('://') > 0) {
+			OC.redirect(url);
+		} else {
+			// if no protocol is specified, we automatically detect it by testing https and http
+			// this check needs to happen on the server due to the Content Security Policy directive
+			$.get(OC.generateUrl('apps/files_sharing/testremote'), {remote: remote}).then(function (protocol) {
+				if (protocol !== 'http' && protocol !== 'https') {
+					OC.dialogs.alert(t('files_sharing', 'No ownCloud installation found at {remote}', {remote: remote}),
+						t('files_sharing', 'Invalid ownCloud url'));
+				} else {
+					OC.redirect(protocol + '://' + url);
+				}
+			});
+		}
 	}
 };
 
-$(document).ready(function() {
+$(document).ready(function () {
 	var App = OCA.Sharing.PublicApp;
 	// defer app init, to give a chance to plugins to register file actions
-	_.defer(function() {
+	_.defer(function () {
 		App.initialize($('#preview'));
 	});
 
 	if (window.Files) {
 		// HACK: for oc-dialogs previews that depends on Files:
-		Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
+		Files.lazyLoadPreview = function (path, mime, ready, width, height, etag) {
 			return App.fileList.lazyLoadPreview({
 				path: path,
 				mime: mime,
diff --git a/apps/files_sharing/js/settings-admin.js b/apps/files_sharing/js/settings-admin.js
new file mode 100644
index 0000000000000000000000000000000000000000..257c864b04f7d84db0543513b5d63cefbb4b05b9
--- /dev/null
+++ b/apps/files_sharing/js/settings-admin.js
@@ -0,0 +1,11 @@
+$(document).ready(function() {
+
+	$('#fileSharingSettings input').change(function() {
+		var value = 'no';
+		if (this.checked) {
+			value = 'yes';
+		}
+		OC.AppConfig.setValue('files_sharing', $(this).attr('name'), value);
+	});
+
+});
diff --git a/apps/files_sharing/lib/connector/publicauth.php b/apps/files_sharing/lib/connector/publicauth.php
index ec7b68ba69ce2eddebbd6c5afcad0b30cf388540..c9d545180b31c239501d377c9eba0c51370ab18c 100644
--- a/apps/files_sharing/lib/connector/publicauth.php
+++ b/apps/files_sharing/lib/connector/publicauth.php
@@ -38,6 +38,7 @@ class PublicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
 	 */
 	protected function validateUserPass($username, $password) {
 		$linkItem = \OCP\Share::getShareByToken($username, false);
+		\OC_User::setIncognitoMode(true);
 		$this->share = $linkItem;
 		if (!$linkItem) {
 			return false;
diff --git a/apps/files_sharing/lib/external/cache.php b/apps/files_sharing/lib/external/cache.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd06bfb12724ca3dd3098a0281ada1707cd123d7
--- /dev/null
+++ b/apps/files_sharing/lib/external/cache.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\External;
+
+class Cache extends \OC\Files\Cache\Cache {
+	private $remote;
+	private $remoteUser;
+	private $storage;
+
+	/**
+	 * @param \OCA\Files_Sharing\External\Storage $storage
+	 * @param string $remote
+	 * @param string $remoteUser
+	 */
+	public function __construct($storage, $remote, $remoteUser) {
+		$this->storage = $storage;
+		list(, $remote) = explode('://', $remote, 2);
+		$this->remote = $remote;
+		$this->remoteUser = $remoteUser;
+		parent::__construct($storage);
+	}
+
+	public function get($file) {
+		$result = parent::get($file);
+		$result['displayname_owner'] = $this->remoteUser . '@' . $this->remote;
+		if (!$file || $file === '') {
+			$result['is_share_mount_point'] = true;
+			$mountPoint = rtrim($this->storage->getMountPoint());
+			$result['name'] = basename($mountPoint);
+		}
+		return $result;
+	}
+
+	public function getFolderContentsById($id) {
+		$results = parent::getFolderContentsById($id);
+		foreach ($results as &$file) {
+			$file['displayname_owner'] = $this->remoteUser . '@' . $this->remote;
+		}
+		return $results;
+	}
+}
diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php
new file mode 100644
index 0000000000000000000000000000000000000000..70a0e98ebd57b54043f5bbba662d240d541f41e4
--- /dev/null
+++ b/apps/files_sharing/lib/external/manager.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\External;
+
+use OC\Files\Filesystem;
+
+class Manager {
+	const STORAGE = '\OCA\Files_Sharing\External\Storage';
+
+	/**
+	 * @var \OCP\IDBConnection
+	 */
+	private $connection;
+
+	/**
+	 * @var \OC\Files\Mount\Manager
+	 */
+	private $mountManager;
+
+	/**
+	 * @var \OC\Files\Storage\Loader
+	 */
+	private $storageLoader;
+
+	/**
+	 * @var \OC\User\Session
+	 */
+	private $userSession;
+
+	/**
+	 * @param \OCP\IDBConnection $connection
+	 * @param \OC\Files\Mount\Manager $mountManager
+	 * @param \OC\User\Session $userSession
+	 * @param \OC\Files\Storage\Loader $storageLoader
+	 */
+	public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager,
+								\OC\Files\Storage\Loader $storageLoader, \OC\User\Session $userSession) {
+		$this->connection = $connection;
+		$this->mountManager = $mountManager;
+		$this->userSession = $userSession;
+		$this->storageLoader = $storageLoader;
+	}
+
+	public function addShare($remote, $token, $password, $name, $owner) {
+		$user = $this->userSession->getUser();
+		if ($user) {
+			$query = $this->connection->prepare('INSERT INTO *PREFIX*share_external(`remote`, `share_token`, `password`,
+				`name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`) VALUES(?, ?, ?, ?, ?, ?, ?, ?)');
+			$mountPoint = Filesystem::normalizePath('/' . $name);
+			$hash = md5($mountPoint);
+			$query->execute(array($remote, $token, $password, $name, $owner, $user->getUID(), $mountPoint, $hash));
+
+			$options = array(
+				'remote' => $remote,
+				'token' => $token,
+				'password' => $password,
+				'mountpoint' => $mountPoint,
+				'owner' => $owner
+			);
+			return $this->mountShare($options);
+		}
+	}
+
+	public function setup() {
+		// don't setup server-to-server shares if the file_external app is disabled
+		// FIXME no longer needed if we use the webdav implementation from  core
+		if (\OC_App::isEnabled('files_external') === false) {
+			return false;
+		}
+
+		$user = $this->userSession->getUser();
+		if ($user) {
+			$query = $this->connection->prepare('SELECT `remote`, `share_token`, `password`, `mountpoint`, `owner`
+			FROM *PREFIX*share_external WHERE `user` = ?');
+			$query->execute(array($user->getUID()));
+
+			while ($row = $query->fetch()) {
+				$row['manager'] = $this;
+				$row['token'] = $row['share_token'];
+				$this->mountShare($row);
+			}
+		}
+	}
+
+	protected function stripPath($path) {
+		$prefix = '/' . $this->userSession->getUser()->getUID() . '/files';
+		return rtrim(substr($path, strlen($prefix)), '/');
+	}
+
+	/**
+	 * @param array $data
+	 * @return Mount
+	 */
+	protected function mountShare($data) {
+		$mountPoint = '/' . $this->userSession->getUser()->getUID() . '/files' . $data['mountpoint'];
+		$mount = new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader);
+		$this->mountManager->addMount($mount);
+		return $mount;
+	}
+
+	/**
+	 * @return \OC\Files\Mount\Manager
+	 */
+	public function getMountManager() {
+		return $this->mountManager;
+	}
+
+	/**
+	 * @param string $source
+	 * @param string $target
+	 * @return bool
+	 */
+	public function setMountPoint($source, $target) {
+		$user = $this->userSession->getUser();
+		$source = $this->stripPath($source);
+		$target = $this->stripPath($target);
+		$sourceHash = md5($source);
+		$targetHash = md5($target);
+
+		$query = $this->connection->prepare('UPDATE *PREFIX*share_external SET
+			`mountpoint` = ?, `mountpoint_hash` = ? WHERE `mountpoint_hash` = ? AND `user` = ?');
+		$result = (bool)$query->execute(array($target, $targetHash, $sourceHash, $user->getUID()));
+
+		return $result;
+	}
+
+	public function removeShare($mountPoint) {
+		$user = $this->userSession->getUser();
+		$mountPoint = $this->stripPath($mountPoint);
+		$hash = md5($mountPoint);
+		$query = $this->connection->prepare('DELETE FROM *PREFIX*share_external WHERE `mountpoint_hash` = ? AND `user` = ?');
+		return (bool)$query->execute(array($hash, $user->getUID()));
+	}
+}
diff --git a/apps/files_sharing/lib/external/mount.php b/apps/files_sharing/lib/external/mount.php
new file mode 100644
index 0000000000000000000000000000000000000000..a42a12f9b9a4dbe2b216ac636552046d293207ce
--- /dev/null
+++ b/apps/files_sharing/lib/external/mount.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\External;
+
+use OC\Files\Mount\MoveableMount;
+
+class Mount extends \OC\Files\Mount\Mount implements MoveableMount {
+
+	/**
+	 * @var \OCA\Files_Sharing\External\Manager
+	 */
+	protected $manager;
+
+	/**
+	 * @param string|\OC\Files\Storage\Storage $storage
+	 * @param string $mountpoint
+	 * @param array $options
+	 * @param \OCA\Files_Sharing\External\Manager $manager
+	 * @param \OC\Files\Storage\Loader $loader
+	 */
+	public function __construct($storage, $mountpoint, $options, $manager, $loader = null) {
+		parent::__construct($storage, $mountpoint, $options, $loader);
+		$this->manager = $manager;
+	}
+
+	/**
+	 * Move the mount point to $target
+	 *
+	 * @param string $target the target mount point
+	 * @return bool
+	 */
+	public function moveMount($target) {
+		$result = $this->manager->setMountPoint($this->mountPoint, $target);
+		$this->setMountPoint($target);
+		return $result;
+	}
+
+	/**
+	 * Remove the mount points
+	 *
+	 * @return mixed
+	 * @return bool
+	 */
+	public function removeMount() {
+		return $this->manager->removeShare($this->mountPoint);
+	}
+}
diff --git a/apps/files_sharing/lib/external/scanner.php b/apps/files_sharing/lib/external/scanner.php
new file mode 100644
index 0000000000000000000000000000000000000000..8921dd1a4c0b5fb8d7439698aa14a30b8a278b76
--- /dev/null
+++ b/apps/files_sharing/lib/external/scanner.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\External;
+
+class Scanner extends \OC\Files\Cache\Scanner {
+	/**
+	 * @var \OCA\Files_Sharing\External\Storage
+	 */
+	protected $storage;
+
+	public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) {
+		$this->scanAll();
+	}
+
+	public function scanAll() {
+		$remote = $this->storage->getRemote();
+		$token = $this->storage->getToken();
+		$password = $this->storage->getPassword();
+		$url = $remote . '/index.php/apps/files_sharing/shareinfo?t=' . $token;
+
+		$ch = curl_init();
+
+		curl_setopt($ch, CURLOPT_URL, $url);
+		curl_setopt($ch, CURLOPT_POST, 1);
+		curl_setopt($ch, CURLOPT_POSTFIELDS,
+			http_build_query(array('password' => $password)));
+		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+		$result = curl_exec($ch);
+		curl_close($ch);
+
+		$data = json_decode($result, true);
+		if ($data['status'] === 'success') {
+			$this->addResult($data['data'], '');
+		} else {
+			throw new \Exception('Error while scanning remote share');
+		}
+	}
+
+	private function addResult($data, $path) {
+		$this->cache->put($path, $data);
+		if (isset($data['children'])) {
+			foreach ($data['children'] as $child) {
+				$this->addResult($child, ltrim($path . '/' . $child['name'], '/'));
+			}
+		}
+	}
+}
diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd04841bb09761d182f48a512ff179cde2ace27f
--- /dev/null
+++ b/apps/files_sharing/lib/external/storage.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\External;
+
+use OC\Files\Filesystem;
+use OC\Files\Storage\DAV;
+use OCA\Files_Sharing\ISharedStorage;
+
+class Storage extends DAV implements ISharedStorage {
+	/**
+	 * @var string
+	 */
+	private $remoteUser;
+
+	/**
+	 * @var string
+	 */
+	private $remote;
+
+	/**
+	 * @var string
+	 */
+	private $mountPoint;
+
+	/**
+	 * @var string
+	 */
+	private $token;
+
+	public function __construct($options) {
+		$this->remote = $options['remote'];
+		$this->remoteUser = $options['owner'];
+		list($protocol, $remote) = explode('://', $this->remote);
+		list($host, $root) = explode('/', $remote);
+		$secure = $protocol === 'https';
+		$root .= '/public.php/webdav';
+		$this->mountPoint = $options['mountpoint'];
+		$this->token = $options['token'];
+		parent::__construct(array(
+			'secure' => $secure,
+			'host' => $host,
+			'root' => $root,
+			'user' => $options['token'],
+			'password' => $options['password']
+		));
+	}
+
+	public function getRemoteUser() {
+		return $this->remoteUser;
+	}
+
+	public function getRemote() {
+		return $this->remote;
+	}
+
+	public function getMountPoint() {
+		return $this->mountPoint;
+	}
+
+	public function getToken() {
+		return $this->token;
+	}
+
+	public function getPassword() {
+		return $this->password;
+	}
+
+	/**
+	 * @brief get id of the mount point
+	 * @return string
+	 */
+	public function getId() {
+		return 'shared::' . md5($this->token . '@' . $this->remote);
+	}
+
+	public function getCache($path = '', $storage = null) {
+		if (!$storage) {
+			$this->cache = new Cache($this, $this->remote, $this->remoteUser);
+		}
+		return $this->cache;
+	}
+
+	/**
+	 * @param string $path
+	 * @param \OC\Files\Storage\Storage $storage
+	 * @return \OCA\Files_Sharing\External\Scanner
+	 */
+	public function getScanner($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		if (!isset($this->scanner)) {
+			$this->scanner = new Scanner($storage);
+		}
+		return $this->scanner;
+	}
+}
diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php
index 49546f012a63e87b7535ca8d4017cd6c3efd8cee..34de3a915aba9774700ad4c51086d2df2e4a2e15 100644
--- a/apps/files_sharing/lib/helper.php
+++ b/apps/files_sharing/lib/helper.php
@@ -16,7 +16,7 @@ class Helper {
 	public static function setupFromToken($token, $relativePath = null, $password = null) {
 		\OC_User::setIncognitoMode(true);
 
-		$linkItem = \OCP\Share::getShareByToken($token);
+		$linkItem = \OCP\Share::getShareByToken($token, !$password);
 		if($linkItem === false || ($linkItem['item_type'] !== 'file' && $linkItem['item_type'] !== 'folder')) {
 			\OC_Response::setStatus(404);
 			\OC_Log::write('core-preview', 'Passed token parameter is not valid', \OC_Log::DEBUG);
@@ -202,4 +202,24 @@ class Helper {
 
 		return $path;
 	}
+
+	/**
+	 * allow users from other ownCloud instances to mount public links share by this instance
+	 * @return bool
+	 */
+	public static function isOutgoingServer2serverShareEnabled() {
+		$appConfig = \OC::$server->getAppConfig();
+		$result = $appConfig->getValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes');
+		return ($result === 'yes') ? true : false;
+	}
+
+	/**
+	 * allow user to mount public links from onther ownClouds
+	 * @return bool
+	 */
+	public static function isIncomingServer2serverShareEnabled() {
+		$appConfig = \OC::$server->getAppConfig();
+		$result = $appConfig->getValue('files_sharing', 'incoming_server2server_share_enabled', 'yes');
+		return ($result === 'yes') ? true : false;
+	}
 }
diff --git a/apps/files_sharing/lib/isharedstorage.php b/apps/files_sharing/lib/isharedstorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..75e0afef39482ce0dd21db4b759e4493e865b821
--- /dev/null
+++ b/apps/files_sharing/lib/isharedstorage.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing;
+
+interface ISharedStorage{
+
+}
diff --git a/apps/files_sharing/lib/readonlycache.php b/apps/files_sharing/lib/readonlycache.php
new file mode 100644
index 0000000000000000000000000000000000000000..f129ca49433e4ecb3769d6ecc0146e6083f7e0ab
--- /dev/null
+++ b/apps/files_sharing/lib/readonlycache.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing;
+
+use OC\Files\Cache\Cache;
+
+class ReadOnlyCache extends Cache {
+	public function get($path) {
+		$data = parent::get($path);
+		$data['permissions'] &= (\OCP\PERMISSION_READ | \OCP\PERMISSION_SHARE);
+		return $data;
+	}
+
+	public function getFolderContents($path) {
+		$content = parent::getFolderContents($path);
+		foreach ($content as &$data) {
+			$data['permissions'] &= (\OCP\PERMISSION_READ | \OCP\PERMISSION_SHARE);
+		}
+		return $content;
+	}
+}
diff --git a/apps/files_sharing/lib/readonlywrapper.php b/apps/files_sharing/lib/readonlywrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..45ed3fd68bb72f7a36b2753e6f2c77a8f3307ca9
--- /dev/null
+++ b/apps/files_sharing/lib/readonlywrapper.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing;
+
+use OC\Files\Storage\Wrapper\Wrapper;
+
+class ReadOnlyWrapper extends Wrapper {
+	public function isUpdatable($path) {
+		return false;
+	}
+
+	public function isCreatable($path) {
+		return false;
+	}
+
+	public function isDeletable($path) {
+		return false;
+	}
+
+	public function getPermissions($path) {
+		return $this->storage->getPermissions($path) & (\OCP\PERMISSION_READ | \OCP\PERMISSION_SHARE);
+	}
+
+	public function rename($path1, $path2) {
+		return false;
+	}
+
+	public function touch($path, $mtime = null) {
+		return false;
+	}
+
+	public function mkdir($path) {
+		return false;
+	}
+
+	public function rmdir($path) {
+		return false;
+	}
+
+	public function unlink($path) {
+		return false;
+	}
+
+	public function getCache($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return new ReadOnlyCache($storage);
+	}
+}
diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php
index 59de2dfa4c474c56c5c9e333a7f51ab9e2126180..8d5b22dc2834b469a5ded592db59cdca906c4667 100644
--- a/apps/files_sharing/lib/sharedstorage.php
+++ b/apps/files_sharing/lib/sharedstorage.php
@@ -23,12 +23,13 @@
 
 namespace OC\Files\Storage;
 use OC\Files\Filesystem;
+use OCA\Files_Sharing\ISharedStorage;
 use OCA\Files_Sharing\SharedMount;
 
 /**
  * Convert target path to source path and pass the function call to the correct storage provider
  */
-class Shared extends \OC\Files\Storage\Common {
+class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	private $share;   // the shared resource
 	private $files = array();
@@ -488,16 +489,25 @@ class Shared extends \OC\Files\Storage\Common {
 		return $this->filemtime($path) > $time;
 	}
 
-	public function getCache($path = '') {
-		return new \OC\Files\Cache\Shared_Cache($this);
+	public function getCache($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return new \OC\Files\Cache\Shared_Cache($storage);
 	}
 
-	public function getScanner($path = '') {
-		return new \OC\Files\Cache\Scanner($this);
+	public function getScanner($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return new \OC\Files\Cache\Scanner($storage);
 	}
 
-	public function getWatcher($path = '') {
-		return new \OC\Files\Cache\Shared_Watcher($this);
+	public function getWatcher($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return new \OC\Files\Cache\Shared_Watcher($storage);
 	}
 
 	public function getOwner($path) {
diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php
index 4782c4dbe324f1b135d43d7d5aea22b1e051dfbf..ec7c80f3316391317d99214279c2e6bd15ba66ab 100644
--- a/apps/files_sharing/public.php
+++ b/apps/files_sharing/public.php
@@ -128,6 +128,7 @@ if (isset($path)) {
 		$tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path));
 		$tmpl->assign('dirToken', $linkItem['token']);
 		$tmpl->assign('sharingToken', $token);
+		$tmpl->assign('protected', isset($linkItem['share_with']) ? 'true' : 'false');
 
 		$urlLinkIdentifiers= (isset($token)?'&t='.$token:'')
 							.(isset($_GET['dir'])?'&dir='.$_GET['dir']:'')
diff --git a/apps/files_sharing/publicwebdav.php b/apps/files_sharing/publicwebdav.php
index df2c04cf45c60df6e77240ad573cd84c0a98da43..684edd976705b0165d363528fd8c7aa87be4e20b 100644
--- a/apps/files_sharing/publicwebdav.php
+++ b/apps/files_sharing/publicwebdav.php
@@ -6,6 +6,10 @@
  * See the COPYING-README file.
  */
 
+if (OCA\Files_Sharing\Helper::isOutgoingServer2serverShareEnabled() === false) {
+	return false;
+}
+
 // load needed apps
 $RUNTIME_APPTYPES = array('filesystem', 'authentication', 'logging');
 
@@ -37,7 +41,15 @@ $server->addPlugin(new OC_Connector_Sabre_ExceptionLoggerPlugin('webdav'));
 $server->subscribeEvent('beforeMethod', function () use ($server, $objectTree, $authBackend) {
 	$share = $authBackend->getShare();
 	$owner = $share['uid_owner'];
+	$isWritable = $share['permissions'] & (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_CREATE);
 	$fileId = $share['file_source'];
+
+	if (!$isWritable) {
+		\OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, $storage) {
+			return new \OCA\Files_Sharing\ReadOnlyWrapper(array('storage' => $storage));
+		});
+	}
+
 	OC_Util::setupFS($owner);
 	$ownerView = \OC\Files\Filesystem::getView();
 	$path = $ownerView->getPath($fileId);
@@ -47,8 +59,13 @@ $server->subscribeEvent('beforeMethod', function () use ($server, $objectTree, $
 	$rootInfo = $view->getFileInfo('');
 
 	// Create ownCloud Dir
-	$rootDir = new OC_Connector_Sabre_Directory($view, $rootInfo);
-	$objectTree->init($rootDir, $view);
+	if ($rootInfo->getType() === 'dir') {
+		$root = new OC_Connector_Sabre_Directory($view, $rootInfo);
+	} else {
+		$root = new OC_Connector_Sabre_File($view, $rootInfo);
+	}
+	$mountManager = \OC\Files\Filesystem::getMountManager();
+	$objectTree->init($root, $view, $mountManager);
 
 	$server->addPlugin(new OC_Connector_Sabre_AbortedUploadDetectionPlugin($view));
 	$server->addPlugin(new OC_Connector_Sabre_QuotaPlugin($view));
diff --git a/apps/files_sharing/settings-admin.php b/apps/files_sharing/settings-admin.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c630b6a911b45dcd43528c424b21dc81f0049c6
--- /dev/null
+++ b/apps/files_sharing/settings-admin.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright (c) 2011 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+\OC_Util::checkAdminUser();
+
+\OCP\Util::addScript('files_sharing', 'settings-admin');
+
+$tmpl = new OCP\Template('files_sharing', 'settings-admin');
+$tmpl->assign('outgoingServer2serverShareEnabled', OCA\Files_Sharing\Helper::isOutgoingServer2serverShareEnabled());
+$tmpl->assign('incomingServer2serverShareEnabled', OCA\Files_Sharing\Helper::isIncomingServer2serverShareEnabled());
+
+return $tmpl->fetchPage();
diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php
index 7b5f603a1053387a2c3b11a325874c498c028712..c053aaabecef0d44cab9b83afec8b2486d9f79a9 100644
--- a/apps/files_sharing/templates/public.php
+++ b/apps/files_sharing/templates/public.php
@@ -15,10 +15,19 @@
 		                                                                                          src="<?php print_unescaped(image_path('', 'logo-wide.svg')); ?>" alt="<?php p($theme->getName()); ?>" /></a>
 		<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
 		<div class="header-right">
-			<a href="<?php p($_['downloadURL']); ?>" id="download" class="button">
-				<img class="svg" alt="" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>"/>
-				<?php p($l->t('Download'))?>
-			</a>
+			<span id="details">
+				<span id="save" data-protected="<?php p($_['protected'])?>" data-owner="<?php p($_['displayName'])?>" data-name="<?php p($_['filename'])?>">
+					<button><?php p($l->t('Save to ownCloud')) ?></button>
+					<form class="save-form hidden" action="#">
+						<input type="text" id="remote_address" placeholder="<?php p($l->t('example.com/owncloud')) ?>"/>
+						<input type="submit" value="<?php p($l->t('Save')) ?>"/>
+					</form>
+				</span>
+				<a href="<?php p($_['downloadURL']); ?>" id="download" class="button">
+					<img class="svg" alt="" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>"/>
+					<?php p($l->t('Download'))?>
+				</a>
+			</span>
 		</div>
 </div></header>
 <div id="content">
diff --git a/apps/files_sharing/templates/settings-admin.php b/apps/files_sharing/templates/settings-admin.php
new file mode 100644
index 0000000000000000000000000000000000000000..18cf22767019b3d1e93fa63f1cb6846eff86d003
--- /dev/null
+++ b/apps/files_sharing/templates/settings-admin.php
@@ -0,0 +1,13 @@
+<div class="section" id="fileSharingSettings" >
+
+	<h2><?php p($l->t('File Sharing'));?></h2>
+
+	<input type="checkbox" name="outgoing_server2server_share_enabled" id="outgoingServer2serverShareEnabled"
+		   value="1" <?php if ($_['outgoingServer2serverShareEnabled']) print_unescaped('checked="checked"'); ?> />
+	<label for="outgoingServer2serverShareEnabled"><?php p($l->t('Allow other instances to mount public links shared from this server'));?></label><br/>
+
+	<input type="checkbox" name="incoming_server2server_share_enabled" id="incomingServer2serverShareEnabled"
+		   value="1" <?php if ($_['incomingServer2serverShareEnabled']) print_unescaped('checked="checked"'); ?> />
+	<label for="incomingServer2serverShareEnabled"><?php p($l->t('Allow users to mount public link shares'));?></label><br/>
+
+</div>
diff --git a/config/.htaccess b/config/.htaccess
old mode 100644
new mode 100755
diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index aa467cec535d1c01673a3d9502fcb5b5aa48f49d..9904c3525c4058d94c52642db0858550ee3f2085 100644
--- a/lib/private/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -202,7 +202,8 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node
 	 * @return array
 	 */
 	public function getQuotaInfo() {
-		$storageInfo = OC_Helper::getStorageInfo($this->path);
+		$path = \OC\Files\Filesystem::getView()->getRelativePath($this->info->getPath());
+		$storageInfo = OC_Helper::getStorageInfo($path);
 		return array(
 			$storageInfo['used'],
 			$storageInfo['free']
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 4e90d46ad41f2af4655505ffffa8a8a2f572fa38..7591cc5c0669416bdb748b430cac24ec35235c95 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -140,7 +140,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
 		if (\OC_Util::encryptedFiles()) {
 			throw new \Sabre\DAV\Exception\ServiceUnavailable();
 		} else {
-			return $this->fileView->fopen($this->path, 'rb');
+			return $this->fileView->fopen(ltrim($this->path, '/'), 'rb');
 		}
 
 	}
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index c55a392bca0c31f7b86cd9942f2bd0bad0c5102a..f2578e3c097ac5d55c261243a7fbd26e619a4eeb 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -10,6 +10,7 @@ namespace OC\Connector\Sabre;
 
 use OC\Files\FileInfo;
 use OC\Files\Filesystem;
+use OC\Files\Mount\MoveableMount;
 
 class ObjectTree extends \Sabre\DAV\ObjectTree {
 
@@ -18,6 +19,11 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
 	 */
 	protected $fileView;
 
+	/**
+	 * @var \OC\Files\Mount\Manager
+	 */
+	protected $mountManager;
+
 	/**
 	 * Creates the object
 	 *
@@ -29,10 +35,12 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
 	/**
 	 * @param \Sabre\DAV\ICollection $rootNode
 	 * @param \OC\Files\View $view
+	 * @param \OC\Files\Mount\Manager $mountManager
 	 */
-	public function init(\Sabre\DAV\ICollection $rootNode, \OC\Files\View $view) {
+	public function init(\Sabre\DAV\ICollection $rootNode, \OC\Files\View $view, \OC\Files\Mount\Manager $mountManager) {
 		$this->rootNode = $rootNode;
 		$this->fileView = $view;
+		$this->mountManager = $mountManager;
 	}
 
 	/**
@@ -115,14 +123,15 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
 		list($sourceDir,) = \Sabre\DAV\URLUtil::splitPath($sourcePath);
 		list($destinationDir,) = \Sabre\DAV\URLUtil::splitPath($destinationPath);
 
-		$isShareMountPoint = false;
-		list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath( '/' . \OCP\User::getUser() . '/files/' . $sourcePath);
-		if ($storage instanceof \OC\Files\Storage\Shared && !$internalPath) {
-			$isShareMountPoint = true;
+		$isMovableMount = false;
+		$sourceMount = $this->mountManager->find($this->fileView->getAbsolutePath($sourcePath));
+		$internalPath = $sourceMount->getInternalPath($this->fileView->getAbsolutePath($sourcePath));
+		if ($sourceMount instanceof MoveableMount && $internalPath === '') {
+			$isMovableMount = true;
 		}
 
 		// check update privileges
-		if (!$this->fileView->isUpdatable($sourcePath) && !$isShareMountPoint) {
+		if (!$this->fileView->isUpdatable($sourcePath) && !$isMovableMount) {
 			throw new \Sabre\DAV\Exception\Forbidden();
 		}
 		if ($sourceDir !== $destinationDir) {
@@ -132,7 +141,7 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
 			if (!$this->fileView->isUpdatable($destinationDir)) {
 				throw new \Sabre\DAV\Exception\Forbidden();
 			}
-			if (!$this->fileView->isDeletable($sourcePath)) {
+			if (!$this->fileView->isDeletable($sourcePath) && !$isMovableMount) {
 				throw new \Sabre\DAV\Exception\Forbidden();
 			}
 		}
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php
index bfd280a91a16af79817b82cf7e8b83bc28ea5640..48c57e2e439dd7e59c5968f8938d735866e01acf 100644
--- a/lib/private/files/cache/cache.php
+++ b/lib/private/files/cache/cache.php
@@ -22,20 +22,20 @@ class Cache {
 	/**
 	 * @var array partial data for the cache
 	 */
-	private $partial = array();
+	protected $partial = array();
 
 	/**
 	 * @var string
 	 */
-	private $storageId;
+	protected $storageId;
 
 	/**
 	 * @var Storage $storageCache
 	 */
-	private $storageCache;
+	protected $storageCache;
 
-	private static $mimetypeIds = array();
-	private static $mimetypes = array();
+	protected static $mimetypeIds = array();
+	protected static $mimetypes = array();
 
 	/**
 	 * @param \OC\Files\Storage\Storage|string $storage
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index 4d5a2078ef7809d9ebd24eab0f973edbcfaeb61c..ecc75298b66f79555c49bb7a76b0289536058c3b 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -287,31 +287,43 @@ abstract class Common implements \OC\Files\Storage\Storage {
 		return $this->filemtime($path) > $time;
 	}
 
-	public function getCache($path = '') {
+	public function getCache($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
 		if (!isset($this->cache)) {
-			$this->cache = new \OC\Files\Cache\Cache($this);
+			$this->cache = new \OC\Files\Cache\Cache($storage);
 		}
 		return $this->cache;
 	}
 
-	public function getScanner($path = '') {
+	public function getScanner($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
 		if (!isset($this->scanner)) {
-			$this->scanner = new \OC\Files\Cache\Scanner($this);
+			$this->scanner = new \OC\Files\Cache\Scanner($storage);
 		}
 		return $this->scanner;
 	}
 
-	public function getWatcher($path = '') {
+	public function getWatcher($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
 		if (!isset($this->watcher)) {
-			$this->watcher = new \OC\Files\Cache\Watcher($this);
+			$this->watcher = new \OC\Files\Cache\Watcher($storage);
 			$this->watcher->setPolicy(\OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_ONCE));
 		}
 		return $this->watcher;
 	}
 
-	public function getStorageCache() {
+	public function getStorageCache($storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
 		if (!isset($this->storageCache)) {
-			$this->storageCache = new \OC\Files\Cache\Storage($this);
+			$this->storageCache = new \OC\Files\Cache\Storage($storage);
 		}
 		return $this->storageCache;
 	}
diff --git a/lib/private/files/storage/home.php b/lib/private/files/storage/home.php
index f66096f6d9c1660900788afa2433bae3274d7219..214deede620482df85bdea349d2753edb7f6ec3f 100644
--- a/lib/private/files/storage/home.php
+++ b/lib/private/files/storage/home.php
@@ -49,9 +49,12 @@ class Home extends Local {
 	/**
 	 * @return \OC\Files\Cache\HomeCache
 	 */
-	public function getCache($path = '') {
+	public function getCache($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
 		if (!isset($this->cache)) {
-			$this->cache = new \OC\Files\Cache\HomeCache($this);
+			$this->cache = new \OC\Files\Cache\HomeCache($storage);
 		}
 		return $this->cache;
 	}
diff --git a/lib/private/files/storage/storage.php b/lib/private/files/storage/storage.php
index f085a0590b47d1968dfa813f3080f40793748d8f..2139f464821d349ff2a7bd778dece7f1b0ddfe0a 100644
--- a/lib/private/files/storage/storage.php
+++ b/lib/private/files/storage/storage.php
@@ -19,17 +19,19 @@ interface Storage extends \OCP\Files\Storage {
 	 * get a cache instance for the storage
 	 *
 	 * @param string $path
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
 	 * @return \OC\Files\Cache\Cache
 	 */
-	public function getCache($path = '');
+	public function getCache($path = '', $storage = null);
 
 	/**
 	 * get a scanner instance for the storage
 	 *
 	 * @param string $path
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
 	 * @return \OC\Files\Cache\Scanner
 	 */
-	public function getScanner($path = '');
+	public function getScanner($path = '', $storage = null);
 
 
 	/**
@@ -44,9 +46,10 @@ interface Storage extends \OCP\Files\Storage {
 	 * get a watcher instance for the cache
 	 *
 	 * @param string $path
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
 	 * @return \OC\Files\Cache\Watcher
 	 */
-	public function getWatcher($path = '');
+	public function getWatcher($path = '', $storage = null);
 
 	/**
 	 * @return \OC\Files\Cache\Storage
diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
index 057c31c3cd84b386692ef0e61201e395717c32fb..d899c88363f20bd387cd171903b3b6aa48d55041 100644
--- a/lib/private/files/storage/wrapper/wrapper.php
+++ b/lib/private/files/storage/wrapper/wrapper.php
@@ -361,20 +361,28 @@ class Wrapper implements \OC\Files\Storage\Storage {
 	 * get a cache instance for the storage
 	 *
 	 * @param string $path
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
 	 * @return \OC\Files\Cache\Cache
 	 */
-	public function getCache($path = '') {
-		return $this->storage->getCache($path);
+	public function getCache($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return $this->storage->getCache($path, $storage);
 	}
 
 	/**
 	 * get a scanner instance for the storage
 	 *
 	 * @param string $path
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
 	 * @return \OC\Files\Cache\Scanner
 	 */
-	public function getScanner($path = '') {
-		return $this->storage->getScanner($path);
+	public function getScanner($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return $this->storage->getScanner($path, $storage);
 	}
 
 
@@ -392,10 +400,14 @@ class Wrapper implements \OC\Files\Storage\Storage {
 	 * get a watcher instance for the cache
 	 *
 	 * @param string $path
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
 	 * @return \OC\Files\Cache\Watcher
 	 */
-	public function getWatcher($path = '') {
-		return $this->storage->getWatcher($path);
+	public function getWatcher($path = '', $storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return $this->storage->getWatcher($path, $storage);
 	}
 
 	/**
@@ -417,6 +429,7 @@ class Wrapper implements \OC\Files\Storage\Storage {
 
 	/**
 	 * Returns true
+	 *
 	 * @return true
 	 */
 	public function test() {
@@ -425,6 +438,7 @@ class Wrapper implements \OC\Files\Storage\Storage {
 
 	/**
 	 * Returns the wrapped storage's value for isLocal()
+	 *
 	 * @return bool wrapped storage's isLocal() value
 	 */
 	public function isLocal() {
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index afccdf9f733de00864b881f4e4f6f176dcd1662f..91d7ea260d3a5fd5b4a4d9e7ca00c3df1ef93e01 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -161,7 +161,34 @@ class View {
 		return $this->basicOperation('mkdir', $path, array('create', 'write'));
 	}
 
+	protected function removeMount($mount, $path){
+		if ($mount instanceof MoveableMount) {
+			\OC_Hook::emit(
+				Filesystem::CLASSNAME, "umount",
+				array(Filesystem::signal_param_path => $path)
+			);
+			$result = $mount->removeMount();
+			if ($result) {
+				\OC_Hook::emit(
+					Filesystem::CLASSNAME, "post_umount",
+					array(Filesystem::signal_param_path => $path)
+				);
+			}
+			return $result;
+		} else {
+			// do not allow deleting the storage's root / the mount point
+			// because for some storages it might delete the whole contents
+			// but isn't supposed to work that way
+			return false;
+		}
+	}
+
 	public function rmdir($path) {
+		$absolutePath= $this->getAbsolutePath($path);
+		$mount = Filesystem::getMountManager()->find($absolutePath);
+		if ($mount->getInternalPath($absolutePath) === '') {
+			return $this->removeMount($mount, $path);
+		}
 		if ($this->is_dir($path)) {
 			return $this->basicOperation('rmdir', $path, array('delete'));
 		} else {
@@ -360,25 +387,7 @@ class View {
 		$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
 		$mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
 		if ($mount->getInternalPath($absolutePath) === '') {
-			if ($mount instanceof MoveableMount) {
-				\OC_Hook::emit(
-						Filesystem::CLASSNAME, "umount",
-						array(Filesystem::signal_param_path => $path)
-						);
-				$result = $mount->removeMount();
-				if ($result) {
-					\OC_Hook::emit(
-							Filesystem::CLASSNAME, "post_umount",
-							array(Filesystem::signal_param_path => $path)
-							);
-				}
-				return $result;
-			} else {
-				// do not allow deleting the storage's root / the mount point
-				// because for some storages it might delete the whole contents
-				// but isn't supposed to work that way
-				return false;
-			}
+			return $this->removeMount($mount, $path);
 		}
 		return $this->basicOperation('unlink', $path, array('delete'));
 	}
@@ -836,11 +845,10 @@ class View {
 			return $data;
 		}
 		$path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
-		/**
-		 * @var \OC\Files\Storage\Storage $storage
-		 * @var string $internalPath
-		 */
-		list($storage, $internalPath) = Filesystem::resolvePath($path);
+
+		$mount = Filesystem::getMountManager()->find($path);
+		$storage = $mount->getStorage();
+		$internalPath = $mount->getInternalPath($path);
 		$data = null;
 		if ($storage) {
 			$cache = $storage->getCache($internalPath);
@@ -888,6 +896,10 @@ class View {
 			return false;
 		}
 
+		if ($mount instanceof MoveableMount) {
+			$data['permissions'] |= \OCP\PERMISSION_DELETE | \OCP\PERMISSION_UPDATE;
+		}
+
 		$data = \OC_FileProxy::runPostProxies('getFileInfo', $path, $data);
 
 		return new FileInfo($path, $storage, $internalPath, $data);
diff --git a/lib/private/helper.php b/lib/private/helper.php
index 3e2c1db79da47cbe9559695c4dd38e2b800e9afe..243baa46948d24ae29afc687f727e5ebcbd1528f 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -940,7 +940,7 @@ class OC_Helper {
 		// return storage info without adding mount points
 		$includeExtStorage = \OC_Config::getValue('quota_include_external_storage', false);
 
-		if (is_null($rootInfo)) {
+		if (!$rootInfo) {
 			$rootInfo = \OC\Files\Filesystem::getFileInfo($path, false);
 		}
 		$used = $rootInfo->getSize();
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index a3de8ebc0efa4646daf5cbfaefd31f165ee79154..26108a937cec6aeaf8103bf0bba99f00b024647a 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -508,9 +508,9 @@ class Share extends \OC\Share\Constants {
 		if ($itemType === 'folder') {
 			$path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/';
 			$mountManager = \OC\Files\Filesystem::getMountManager();
-			$mounts = $mountManager->getAll();
-			foreach ($mounts as $mountPoint => $mount) {
-				if ($mount->getStorage() instanceof \OC\Files\Storage\Shared && strpos($mountPoint, $path) === 0) {
+			$mounts = $mountManager->findIn($path);
+			foreach ($mounts as $mount) {
+				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
 					$message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!';
 					\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
 					throw new \Exception($message);
diff --git a/tests/lib/connector/sabre/objecttree.php b/tests/lib/connector/sabre/objecttree.php
index 0075b7832b8e17316a2ce31d135acf45a1591172..a88e23bbe2ff24132f881955ef5972677f94f4af 100644
--- a/tests/lib/connector/sabre/objecttree.php
+++ b/tests/lib/connector/sabre/objecttree.php
@@ -110,7 +110,8 @@ class ObjectTree extends PHPUnit_Framework_TestCase {
 			->will($this->returnValue(false));
 
 		/** @var $objectTree \OC\Connector\Sabre\ObjectTree */
-		$objectTree->init($rootDir, $view);
+		$mountManager = \OC\Files\Filesystem::getMountManager();
+		$objectTree->init($rootDir, $view, $mountManager);
 		$objectTree->move($source, $dest);
 	}