diff --git a/apps/dav/lib/connector/sabre/serverfactory.php b/apps/dav/lib/connector/sabre/serverfactory.php
index 6ccec0bc0e83aa0954c1844db3dc75e299202a0a..080f889ae71cdfe95e9e5d64c9548e9d6209b3f2 100644
--- a/apps/dav/lib/connector/sabre/serverfactory.php
+++ b/apps/dav/lib/connector/sabre/serverfactory.php
@@ -137,6 +137,12 @@ class ServerFactory {
 
 			if($this->userSession->isLoggedIn()) {
 				$server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
+				$server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin(
+					$objectTree,
+					$this->userSession,
+					$userFolder,
+					\OC::$server->getShareManager()
+				));
 				$server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession));
 				$server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin(
 					$objectTree,
diff --git a/apps/dav/lib/connector/sabre/sharesplugin.php b/apps/dav/lib/connector/sabre/sharesplugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..f75c137871804f899b7b776ef9e710239b1ac43e
--- /dev/null
+++ b/apps/dav/lib/connector/sabre/sharesplugin.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCA\DAV\Connector\Sabre;
+
+use \Sabre\DAV\PropFind;
+use \Sabre\DAV\PropPatch;
+use OCP\IUserSession;
+use OCP\Share\IShare;
+use OCA\DAV\Connector\Sabre\ShareTypeList;
+
+/**
+ * Sabre Plugin to provide share-related properties
+ */
+class SharesPlugin extends \Sabre\DAV\ServerPlugin {
+
+	const NS_OWNCLOUD = 'http://owncloud.org/ns';
+	const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types';
+
+	/**
+	 * Reference to main server object
+	 *
+	 * @var \Sabre\DAV\Server
+	 */
+	private $server;
+
+	/**
+	 * @var \OCP\Share\IManager
+	 */
+	private $shareManager;
+
+	/**
+	 * @var \Sabre\DAV\Tree
+	 */
+	private $tree;
+
+	/**
+	 * @var string
+	 */
+	private $userId;
+
+	/**
+	 * @var \OCP\Files\Folder
+	 */
+	private $userFolder;
+
+	/**
+	 * @var IShare[]
+	 */
+	private $cachedShareTypes;
+
+	/**
+	 * @param \Sabre\DAV\Tree $tree tree
+	 * @param IUserSession $userSession user session
+	 * @param \OCP\Files\Folder $userFolder user home folder
+	 * @param \OCP\Share\IManager $shareManager share manager
+	 */
+	public function __construct(
+		\Sabre\DAV\Tree $tree,
+		IUserSession $userSession,
+		\OCP\Files\Folder $userFolder,
+		\OCP\Share\IManager $shareManager
+	) {
+		$this->tree = $tree;
+		$this->shareManager = $shareManager;
+		$this->userFolder = $userFolder;
+		$this->userId = $userSession->getUser()->getUID();
+		$this->cachedShareTypes = [];
+	}
+
+	/**
+	 * This initializes the plugin.
+	 *
+	 * This function is called by \Sabre\DAV\Server, after
+	 * addPlugin is called.
+	 *
+	 * This method should set up the required event subscriptions.
+	 *
+	 * @param \Sabre\DAV\Server $server
+	 */
+	public function initialize(\Sabre\DAV\Server $server) {
+		$server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc';
+		$server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = 'OCA\\DAV\\Connector\\Sabre\\ShareTypeList';
+		$server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME;
+
+		$this->server = $server;
+		$this->server->on('propFind', array($this, 'handleGetProperties'));
+	}
+
+	/**
+	 * Return a list of share types for outgoing shares
+	 *
+	 * @param \OCP\Files\Node $node file node
+	 *
+	 * @return int[] array of share types
+	 */
+	private function getShareTypes(\OCP\Files\Node $node) {
+		$shareTypes = [];
+		$requestedShareTypes = [
+			\OCP\Share::SHARE_TYPE_USER,
+			\OCP\Share::SHARE_TYPE_GROUP,
+			\OCP\Share::SHARE_TYPE_LINK
+		];
+		foreach ($requestedShareTypes as $requestedShareType) {
+			// one of each type is enough to find out about the types
+			$shares = $this->shareManager->getSharesBy(
+				$this->userId,
+				$requestedShareType,
+				$node,
+				false,
+				1
+			);
+			if (!empty($shares)) {
+				$shareTypes[] = $requestedShareType;
+			}
+		}
+		return $shareTypes;
+	}
+
+	/**
+	 * Adds shares to propfind response
+	 *
+	 * @param PropFind $propFind propfind object
+	 * @param \Sabre\DAV\INode $sabreNode sabre node
+	 */
+	public function handleGetProperties(
+		PropFind $propFind,
+		\Sabre\DAV\INode $sabreNode
+	) {
+		if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) {
+			return;
+		}
+
+		// need prefetch ?
+		if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory
+			&& $propFind->getDepth() !== 0
+			&& !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME))
+		) {
+			$folderNode = $this->userFolder->get($propFind->getPath());
+			$children = $folderNode->getDirectoryListing();
+
+			$this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode);
+			foreach ($children as $childNode) {
+				$this->cachedShareTypes[$childNode->getId()] = $this->getShareTypes($childNode);
+			}
+		}
+
+		$propFind->handle(self::SHARETYPES_PROPERTYNAME, function() use ($sabreNode) {
+			if (isset($this->cachedShareTypes[$sabreNode->getId()])) {
+				$shareTypes = $this->cachedShareTypes[$sabreNode->getId()];
+			} else {
+				$node = $this->userFolder->get($sabreNode->getPath());
+				$shareTypes = $this->getShareTypes($node);
+			}
+
+			return new ShareTypeList($shareTypes);
+		});
+	}
+}
diff --git a/apps/dav/lib/connector/sabre/sharetypelist.php b/apps/dav/lib/connector/sabre/sharetypelist.php
new file mode 100644
index 0000000000000000000000000000000000000000..763586412ad7abceb000c5f4c8a4a0db2a7d296e
--- /dev/null
+++ b/apps/dav/lib/connector/sabre/sharetypelist.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\Connector\Sabre;
+
+use Sabre\Xml\Element;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Writer;
+
+/**
+ * ShareTypeList property
+ *
+ * This property contains multiple "share-type" elements, each containing a share type.
+ */
+class ShareTypeList implements Element {
+	const NS_OWNCLOUD = 'http://owncloud.org/ns';
+
+	/**
+	 * Share types
+	 *
+	 * @var int[]
+	 */
+	private $shareTypes;
+
+	/**
+	 * @param int[] $shareTypes
+	 */
+	public function __construct($shareTypes) {
+		$this->shareTypes = $shareTypes;
+	}
+
+	/**
+	 * Returns the share types
+	 *
+	 * @return int[]
+	 */
+	public function getShareTypes() {
+		return $this->shareTypes;
+	}
+
+	/**
+	 * The deserialize method is called during xml parsing.
+	 *
+	 * @param Reader $reader
+	 * @return mixed
+	 */
+	static function xmlDeserialize(Reader $reader) {
+		$shareTypes = [];
+
+		foreach ($reader->parseInnerTree() as $elem) {
+			if ($elem['name'] === '{' . self::NS_OWNCLOUD . '}share-type') {
+				$shareTypes[] = (int)$elem['value'];
+			}
+		}
+		return new self($shareTypes);
+	}
+
+	/**
+	 * The xmlSerialize metod is called during xml writing.
+	 *
+	 * @param Writer $writer
+	 * @return void
+	 */
+	function xmlSerialize(Writer $writer) {
+		foreach ($this->shareTypes as $shareType) {
+			$writer->writeElement('{' . self::NS_OWNCLOUD . '}share-type', $shareType);
+		}
+	}
+}
diff --git a/apps/dav/tests/unit/connector/sabre/sharesplugin.php b/apps/dav/tests/unit/connector/sabre/sharesplugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a1c6eec50751ea40fc190951c5140105fb0937f
--- /dev/null
+++ b/apps/dav/tests/unit/connector/sabre/sharesplugin.php
@@ -0,0 +1,257 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCA\DAV\Tests\Unit\Connector\Sabre;
+
+class SharesPlugin extends \Test\TestCase {
+
+	const SHARETYPES_PROPERTYNAME = \OCA\DAV\Connector\Sabre\SharesPlugin::SHARETYPES_PROPERTYNAME;
+
+	/**
+	 * @var \Sabre\DAV\Server
+	 */
+	private $server;
+
+	/**
+	 * @var \Sabre\DAV\Tree
+	 */
+	private $tree;
+
+	/**
+	 * @var \OCP\Share\IManager
+	 */
+	private $shareManager;
+
+	/**
+	 * @var \OCP\Files\Folder
+	 */
+	private $userFolder;
+
+	/**
+	 * @var \OCA\DAV\Connector\Sabre\SharesPlugin
+	 */
+	private $plugin;
+
+	public function setUp() {
+		parent::setUp();
+		$this->server = new \Sabre\DAV\Server();
+		$this->tree = $this->getMockBuilder('\Sabre\DAV\Tree')
+			->disableOriginalConstructor()
+			->getMock();
+		$this->shareManager = $this->getMock('\OCP\Share\IManager');
+		$user = $this->getMock('\OCP\IUser');
+		$user->expects($this->once())
+			->method('getUID')
+			->will($this->returnValue('user1'));
+		$userSession = $this->getMock('\OCP\IUserSession');
+		$userSession->expects($this->once())
+			->method('getUser')
+			->will($this->returnValue($user));
+
+		$this->userFolder = $this->getMock('\OCP\Files\Folder');
+
+		$this->plugin = new \OCA\DAV\Connector\Sabre\SharesPlugin(
+			$this->tree,
+			$userSession,
+			$this->userFolder,
+			$this->shareManager
+		);
+		$this->plugin->initialize($this->server);
+	}
+
+	/**
+	 * @dataProvider sharesGetPropertiesDataProvider
+	 */
+	public function testGetProperties($shareTypes) {
+		$sabreNode = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Node')
+			->disableOriginalConstructor()
+			->getMock();
+		$sabreNode->expects($this->any())
+			->method('getId')
+			->will($this->returnValue(123));
+		$sabreNode->expects($this->once())
+			->method('getPath')
+			->will($this->returnValue('/subdir'));
+
+		// node API nodes
+		$node = $this->getMock('\OCP\Files\Folder');
+
+		$this->userFolder->expects($this->once())
+			->method('get')
+			->with('/subdir')
+			->will($this->returnValue($node));
+
+		$this->shareManager->expects($this->any())
+			->method('getSharesBy')
+			->with(
+				$this->equalTo('user1'),
+				$this->anything(),
+				$this->anything(),
+				$this->equalTo(false),
+				$this->equalTo(1)
+			)
+			->will($this->returnCallback(function($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes){
+				if (in_array($requestedShareType, $shareTypes)) {
+					return ['dummyshare'];
+				}
+				return [];
+			}));
+
+		$propFind = new \Sabre\DAV\PropFind(
+			'/dummyPath',
+			[self::SHARETYPES_PROPERTYNAME],
+			0
+		);
+
+		$this->plugin->handleGetProperties(
+			$propFind,
+			$sabreNode
+		);
+
+		$result = $propFind->getResultForMultiStatus();
+
+		$this->assertEmpty($result[404]);
+		unset($result[404]);
+		$this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes());
+	}
+
+	/**
+	 * @dataProvider sharesGetPropertiesDataProvider
+	 */
+	public function testPreloadThenGetProperties($shareTypes) {
+		$sabreNode1 = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\File')
+			->disableOriginalConstructor()
+			->getMock();
+		$sabreNode1->expects($this->any())
+			->method('getId')
+			->will($this->returnValue(111));
+		$sabreNode1->expects($this->never())
+			->method('getPath');
+		$sabreNode2 = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\File')
+			->disableOriginalConstructor()
+			->getMock();
+		$sabreNode2->expects($this->any())
+			->method('getId')
+			->will($this->returnValue(222));
+		$sabreNode2->expects($this->never())
+			->method('getPath');
+
+		$sabreNode = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Directory')
+			->disableOriginalConstructor()
+			->getMock();
+		$sabreNode->expects($this->any())
+			->method('getId')
+			->will($this->returnValue(123));
+		// never, because we use getDirectoryListing from the Node API instead
+		$sabreNode->expects($this->never())
+			->method('getChildren');
+		$sabreNode->expects($this->any())
+			->method('getPath')
+			->will($this->returnValue('/subdir'));
+
+		// node API nodes
+		$node = $this->getMock('\OCP\Files\Folder');
+		$node->expects($this->any())
+			->method('getId')
+			->will($this->returnValue(123));
+		$node1 = $this->getMock('\OCP\Files\File');
+		$node1->expects($this->any())
+			->method('getId')
+			->will($this->returnValue(111));
+		$node2 = $this->getMock('\OCP\Files\File');
+		$node2->expects($this->any())
+			->method('getId')
+			->will($this->returnValue(222));
+		$node->expects($this->once())
+			->method('getDirectoryListing')
+			->will($this->returnValue([$node1, $node2]));
+
+		$this->userFolder->expects($this->once())
+			->method('get')
+			->with('/subdir')
+			->will($this->returnValue($node));
+
+		$this->shareManager->expects($this->any())
+			->method('getSharesBy')
+			->with(
+				$this->equalTo('user1'),
+				$this->anything(),
+				$this->anything(),
+				$this->equalTo(false),
+				$this->equalTo(1)
+			)
+			->will($this->returnCallback(function($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes){
+				if ($node->getId() === 111 && in_array($requestedShareType, $shareTypes)) {
+					return ['dummyshare'];
+				}
+
+				return [];
+			}));
+
+		// simulate sabre recursive PROPFIND traversal
+		$propFindRoot = new \Sabre\DAV\PropFind(
+			'/subdir',
+			[self::SHARETYPES_PROPERTYNAME],
+			1
+		);
+		$propFind1 = new \Sabre\DAV\PropFind(
+			'/subdir/test.txt',
+			[self::SHARETYPES_PROPERTYNAME],
+			0
+		);
+		$propFind2 = new \Sabre\DAV\PropFind(
+			'/subdir/test2.txt',
+			[self::SHARETYPES_PROPERTYNAME],
+			0
+		);
+
+		$this->plugin->handleGetProperties(
+			$propFindRoot,
+			$sabreNode
+		);
+		$this->plugin->handleGetProperties(
+			$propFind1,
+			$sabreNode1
+		);
+		$this->plugin->handleGetProperties(
+			$propFind2,
+			$sabreNode2
+		);
+
+		$result = $propFind1->getResultForMultiStatus();
+
+		$this->assertEmpty($result[404]);
+		unset($result[404]);
+		$this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes());
+	}
+
+	function sharesGetPropertiesDataProvider() {
+		return [
+			[[]],
+			[[\OCP\Share::SHARE_TYPE_USER]],
+			[[\OCP\Share::SHARE_TYPE_GROUP]],
+			[[\OCP\Share::SHARE_TYPE_LINK]],
+			[[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP]],
+			[[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]],
+			[[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK]],
+			[[\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]],
+		];
+	}
+}
diff --git a/apps/files/appinfo/application.php b/apps/files/appinfo/application.php
index bc6dc9fb9edd9e42a58a20a3ee43dff4a2662e1a..593e0533c8006daab7716d1689fedac87d18b3bf 100644
--- a/apps/files/appinfo/application.php
+++ b/apps/files/appinfo/application.php
@@ -40,8 +40,10 @@ class Application extends App {
 			return new ApiController(
 				$c->query('AppName'),
 				$c->query('Request'),
+				$server->getUserSession(),
 				$c->query('TagService'),
-				$server->getPreviewManager()
+				$server->getPreviewManager(),
+				$server->getShareManager()
 			);
 		});
 
diff --git a/apps/files/controller/apicontroller.php b/apps/files/controller/apicontroller.php
index c96d92a046b0a2c7eb9f0bc836717aa73e6fe3ed..43abf2ff4589982569592f0c9d6733e862a34867 100644
--- a/apps/files/controller/apicontroller.php
+++ b/apps/files/controller/apicontroller.php
@@ -34,6 +34,10 @@ use OCP\AppFramework\Http\DataResponse;
 use OCP\AppFramework\Http\DataDisplayResponse;
 use OCA\Files\Service\TagService;
 use OCP\IPreview;
+use OCP\Share\IManager;
+use OCP\Files\FileInfo;
+use OCP\Files\Node;
+use OCP\IUserSession;
 
 /**
  * Class ApiController
@@ -43,8 +47,12 @@ use OCP\IPreview;
 class ApiController extends Controller {
 	/** @var TagService */
 	private $tagService;
+	/** @var IManager **/
+	private $shareManager;
 	/** @var IPreview */
 	private $previewManager;
+	/** IUserSession */
+	private $userSession;
 
 	/**
 	 * @param string $appName
@@ -54,11 +62,15 @@ class ApiController extends Controller {
 	 */
 	public function __construct($appName,
 								IRequest $request,
+								IUserSession $userSession,
 								TagService $tagService,
-								IPreview $previewManager){
+								IPreview $previewManager,
+								IManager $shareManager) {
 		parent::__construct($appName, $request);
+		$this->userSession = $userSession;
 		$this->tagService = $tagService;
 		$this->previewManager = $previewManager;
+		$this->shareManager = $shareManager;
 	}
 
 	/**
@@ -132,8 +144,10 @@ class ApiController extends Controller {
 	 */
 	public function getFilesByTag($tagName) {
 		$files = array();
-		$fileInfos = $this->tagService->getFilesByTag($tagName);
-		foreach ($fileInfos as &$fileInfo) {
+		$nodes = $this->tagService->getFilesByTag($tagName);
+		foreach ($nodes as &$node) {
+			$shareTypes = $this->getShareTypes($node);
+			$fileInfo = $node->getFileInfo();
 			$file = \OCA\Files\Helper::formatFileInfo($fileInfo);
 			$parts = explode('/', dirname($fileInfo->getPath()), 4);
 			if(isset($parts[3])) {
@@ -142,9 +156,43 @@ class ApiController extends Controller {
 				$file['path'] = '/';
 			}
 			$file['tags'] = [$tagName];
+			if (!empty($shareTypes)) {
+				$file['shareTypes'] = $shareTypes;
+			}
 			$files[] = $file;
 		}
 		return new DataResponse(['files' => $files]);
 	}
 
+	/**
+	 * Return a list of share types for outgoing shares
+	 *
+	 * @param Node $node file node
+	 *
+	 * @return int[] array of share types
+	 */
+	private function getShareTypes(Node $node) {
+		$userId = $this->userSession->getUser()->getUID();
+		$shareTypes = [];
+		$requestedShareTypes = [
+			\OCP\Share::SHARE_TYPE_USER,
+			\OCP\Share::SHARE_TYPE_GROUP,
+			\OCP\Share::SHARE_TYPE_LINK
+		];
+		foreach ($requestedShareTypes as $requestedShareType) {
+			// one of each type is enough to find out about the types
+			$shares = $this->shareManager->getSharesBy(
+				$userId,
+				$requestedShareType,
+				$node,
+				false,
+				1
+			);
+			if (!empty($shares)) {
+				$shareTypes[] = $requestedShareType;
+			}
+		}
+		return $shareTypes;
+	}
+
 }
diff --git a/apps/files/service/tagservice.php b/apps/files/service/tagservice.php
index e1425c466159e9ea7a3aca1b9c6029ca320309ab..57cad43a53942426833a2cb3f84a2043a7e0c235 100644
--- a/apps/files/service/tagservice.php
+++ b/apps/files/service/tagservice.php
@@ -25,6 +25,7 @@
 namespace OCA\Files\Service;
 
 use OC\Files\FileInfo;
+use OCP\Files\Node;
 
 /**
  * Service class to manage tags on files.
@@ -93,7 +94,7 @@ class TagService {
 	 * Get all files for the given tag
 	 *
 	 * @param string $tagName tag name to filter by
-	 * @return FileInfo[] list of matching files
+	 * @return Node[] list of matching files
 	 * @throws \Exception if the tag does not exist
 	 */
 	public function getFilesByTag($tagName) {
@@ -103,15 +104,11 @@ class TagService {
 			return [];
 		}
 
-		$fileInfos = [];
+		$allNodes = [];
 		foreach ($fileIds as $fileId) {
-			$nodes = $this->homeFolder->getById((int) $fileId);
-			foreach ($nodes as $node) {
-				/** @var \OC\Files\Node\Node $node */
-				$fileInfos[] = $node->getFileInfo();
-			}
+			$allNodes = array_merge($allNodes, $this->homeFolder->getById((int) $fileId));
 		}
-		return $fileInfos;
+		return $allNodes;
 	}
 }
 
diff --git a/apps/files/tests/controller/apicontrollertest.php b/apps/files/tests/controller/apicontrollertest.php
index 6fb8340ead8003d0efe538e30887e535a58ceccb..a9b248a36fede01b290389e604a11b047683349d 100644
--- a/apps/files/tests/controller/apicontrollertest.php
+++ b/apps/files/tests/controller/apicontrollertest.php
@@ -51,14 +51,27 @@ class ApiControllerTest extends TestCase {
 	private $preview;
 	/** @var ApiController */
 	private $apiController;
+	/** @var \OCP\Share\IManager */
+	private $shareManager;
 
 	public function setUp() {
 		$this->request = $this->getMockBuilder('\OCP\IRequest')
 			->disableOriginalConstructor()
 			->getMock();
+		$user = $this->getMock('\OCP\IUser');
+		$user->expects($this->any())
+			->method('getUID')
+			->will($this->returnValue('user1'));
+		$userSession = $this->getMock('\OCP\IUserSession');
+		$userSession->expects($this->any())
+			->method('getUser')
+			->will($this->returnValue($user));
 		$this->tagService = $this->getMockBuilder('\OCA\Files\Service\TagService')
 			->disableOriginalConstructor()
 			->getMock();
+		$this->shareManager = $this->getMockBuilder('\OCP\Share\IManager')
+			->disableOriginalConstructor()
+			->getMock();
 		$this->preview = $this->getMockBuilder('\OCP\IPreview')
 			->disableOriginalConstructor()
 			->getMock();
@@ -66,8 +79,10 @@ class ApiControllerTest extends TestCase {
 		$this->apiController = new ApiController(
 			$this->appName,
 			$this->request,
+			$userSession,
 			$this->tagService,
-			$this->preview
+			$this->preview,
+			$this->shareManager
 		);
 	}
 
@@ -101,10 +116,32 @@ class ApiControllerTest extends TestCase {
 				->disableOriginalConstructor()
 				->getMock()
 		);
+		$node = $this->getMockBuilder('\OC\Files\Node\File')
+			->disableOriginalConstructor()
+			->getMock();
+		$node->expects($this->once())
+			->method('getFileInfo')
+			->will($this->returnValue($fileInfo));
 		$this->tagService->expects($this->once())
 			->method('getFilesByTag')
 			->with($this->equalTo([$tagName]))
-			->will($this->returnValue([$fileInfo]));
+			->will($this->returnValue([$node]));
+
+		$this->shareManager->expects($this->any())
+			->method('getSharesBy')
+			->with(
+				$this->equalTo('user1'),
+				$this->anything(),
+				$node,
+				$this->equalTo(false),
+				$this->equalTo(1)
+			)
+			->will($this->returnCallback(function($userId, $shareType) {
+				if ($shareType === \OCP\Share::SHARE_TYPE_USER || $shareType === \OCP\Share::SHARE_TYPE_LINK) {
+					return ['dummy_share'];
+				}
+				return [];
+			}));
 
 		$expected = new DataResponse([
 			'files' => [
@@ -124,6 +161,7 @@ class ApiControllerTest extends TestCase {
 							'MyTagName'
 						]
 					],
+					'shareTypes' => [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK]
 				],
 			],
 		]);
@@ -166,10 +204,22 @@ class ApiControllerTest extends TestCase {
 				->disableOriginalConstructor()
 				->getMock()
 		);
+		$node1 = $this->getMockBuilder('\OC\Files\Node\File')
+			->disableOriginalConstructor()
+			->getMock();
+		$node1->expects($this->once())
+			->method('getFileInfo')
+			->will($this->returnValue($fileInfo1));
+		$node2 = $this->getMockBuilder('\OC\Files\Node\File')
+			->disableOriginalConstructor()
+			->getMock();
+		$node2->expects($this->once())
+			->method('getFileInfo')
+			->will($this->returnValue($fileInfo2));
 		$this->tagService->expects($this->once())
 			->method('getFilesByTag')
 			->with($this->equalTo([$tagName]))
-			->will($this->returnValue([$fileInfo1, $fileInfo2]));
+			->will($this->returnValue([$node1, $node2]));
 
 		$expected = new DataResponse([
 			'files' => [
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 2711b2392e9fa1658d867842153c142bd023d3c5..5ec7824758f4b8605773dccea70babc50a25c341 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -60,6 +60,9 @@
 				if (fileData.recipientsDisplayName) {
 					tr.attr('data-share-recipients', fileData.recipientsDisplayName);
 				}
+				if (fileData.shareTypes) {
+					tr.attr('data-share-types', fileData.shareTypes.join(','));
+				}
 				return tr;
 			};
 
@@ -77,6 +80,7 @@
 			fileList._getWebdavProperties = function() {
 				var props = oldGetWebdavProperties.apply(this, arguments);
 				props.push('{' + NS_OC + '}owner-display-name');
+				props.push('{' + NS_OC + '}share-types');
 				return props;
 			};
 
@@ -88,40 +92,45 @@
 				if (permissionsProp && permissionsProp.indexOf('S') >= 0) {
 					data.shareOwner = props['{' + NS_OC + '}owner-display-name'];
 				}
+
+				var shareTypesProp = props['{' + NS_OC + '}share-types'];
+				if (shareTypesProp) {
+					data.shareTypes = _.chain(shareTypesProp).filter(function(xmlvalue) {
+						return (xmlvalue.namespaceURI === NS_OC && xmlvalue.nodeName.split(':')[1] === 'share-type');
+					}).map(function(xmlvalue) {
+						return parseInt(xmlvalue.textContent || xmlvalue.text, 10);
+					}).value();
+				}
+
 				return data;
 			});
 
 			// use delegate to catch the case with multiple file lists
 			fileList.$el.on('fileActionsReady', function(ev){
-				var fileList = ev.fileList;
 				var $files = ev.$files;
 
-				function updateIcons($files) {
-					if (!$files) {
-						// if none specified, update all
-						$files = fileList.$fileList.find('tr');
+				_.each($files, function(file) {
+					var $tr = $(file);
+					var shareTypes = $tr.attr('data-share-types');
+					if (shareTypes) {
+						var hasLink = false;
+						var hasShares = false;
+						_.each(shareTypes.split(',') || [], function(shareType) {
+							shareType = parseInt(shareType, 10);
+							if (shareType === OC.Share.SHARE_TYPE_LINK) {
+								hasLink = true;
+							} else if (shareType === OC.Share.SHARE_TYPE_USER) {
+								hasShares = true;
+							} else if (shareType === OC.Share.SHARE_TYPE_GROUP) {
+								hasShares = true;
+							}
+						});
+						OCA.Sharing.Util._updateFileActionIcon($tr, hasShares, hasLink);
 					}
-					_.each($files, function(file) {
-						var $tr = $(file);
-						var shareStatus = OC.Share.statuses[$tr.data('id')];
-						OCA.Sharing.Util._updateFileActionIcon($tr, !!shareStatus, shareStatus && shareStatus.link);
-					});
-				}
-
-				if (!OCA.Sharing.sharesLoaded){
-					OC.Share.loadIcons('file', fileList, function() {
-						// since we don't know which files are affected, just refresh them all
-						updateIcons();
-					});
-					// assume that we got all shares, so switching directories
-					// will not invalidate that list
-					OCA.Sharing.sharesLoaded = true;
-				}
-				else{
-					updateIcons($files);
-				}
+				});
 			});
 
+
 			fileList.$el.on('changeDirectory', function() {
 				OCA.Sharing.sharesLoaded = false;
 			});
diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js
index a799d4a94c2a0b437fe4a88311e494cb1b3d32ae..da0f957ed99b86c779014a433872fdfaf8672620 100644
--- a/apps/files_sharing/js/sharedfilelist.js
+++ b/apps/files_sharing/js/sharedfilelist.js
@@ -286,6 +286,8 @@
 						// using a hash to make them unique,
 						// this is only a list to be displayed
 						data.recipients = {};
+						// share types
+						data.shareTypes = {};
 						// counter is cheaper than calling _.keys().length
 						data.recipientsCount = 0;
 						data.mtime = file.share.stime;
@@ -308,6 +310,8 @@
 						data.recipientsCount++;
 					}
 
+					data.shareTypes[file.share.type] = true;
+
 					delete file.share;
 					return memo;
 				}, {})
@@ -324,6 +328,12 @@
 						data.recipientsCount
 					);
 					delete data.recipientsCount;
+					if (self._sharedWithUser) {
+						// only for outgoing shres
+						delete data.shareTypes;
+					} else {
+						data.shareTypes = _.keys(data.shareTypes);
+					}
 				})
 				// Finish the chain by getting the result
 				.value();
diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js
index 7607ada50baf69ca202e262a2ad1ce0e5298232d..c488bd94fab98294a108c8a49e5f4aa6ae2dd019 100644
--- a/apps/files_sharing/tests/js/shareSpec.js
+++ b/apps/files_sharing/tests/js/shareSpec.js
@@ -53,35 +53,21 @@ describe('OCA.Sharing.Util tests', function() {
 			permissions: OC.PERMISSION_ALL,
 			etag: 'abc',
 			shareOwner: 'User One',
-			isShareMountPoint: false
+			isShareMountPoint: false,
+			shareTypes: [OC.Share.SHARE_TYPE_USER]
 		}];
-
-		OCA.Sharing.sharesLoaded = true;
-		OC.Share.statuses = {
-			1: {link: false, path: '/subdir'}
-		};
 	});
 	afterEach(function() {
 		delete OCA.Sharing.sharesLoaded;
 		delete OC.Share.droppedDown;
 		fileList.destroy();
 		fileList = null;
-		OC.Share.statuses = {};
-		OC.Share.currentShares = {};
 	});
 
 	describe('Sharing data in table row', function() {
 		// TODO: test data-permissions, data-share-owner, etc
 	});
 	describe('Share action icon', function() {
-		beforeEach(function() {
-			OC.Share.statuses = {1: {link: false, path: '/subdir'}};
-			OCA.Sharing.sharesLoaded = true;
-		});
-		afterEach(function() {
-			OC.Share.statuses = {};
-			OCA.Sharing.sharesLoaded = false;
-		});
 		it('do not shows share text when not shared', function() {
 			var $action, $tr;
 			OC.Share.statuses = {};
@@ -93,7 +79,8 @@ describe('OCA.Sharing.Util tests', function() {
 				mimetype: 'httpd/unix-directory',
 				size: 12,
 				permissions: OC.PERMISSION_ALL,
-				etag: 'abc'
+				etag: 'abc',
+				shareTypes: []
 			}]);
 			$tr = fileList.$el.find('tbody tr:first');
 			$action = $tr.find('.action-share');
@@ -111,7 +98,8 @@ describe('OCA.Sharing.Util tests', function() {
 				mimetype: 'text/plain',
 				size: 12,
 				permissions: OC.PERMISSION_ALL,
-				etag: 'abc'
+				etag: 'abc',
+				shareTypes: [OC.Share.SHARE_TYPE_USER]
 			}]);
 			$tr = fileList.$el.find('tbody tr:first');
 			$action = $tr.find('.action-share');
@@ -131,7 +119,8 @@ describe('OCA.Sharing.Util tests', function() {
 				mimetype: 'text/plain',
 				size: 12,
 				permissions: OC.PERMISSION_ALL,
-				etag: 'abc'
+				etag: 'abc',
+				shareTypes: [OC.Share.SHARE_TYPE_LINK]
 			}]);
 			$tr = fileList.$el.find('tbody tr:first');
 			$action = $tr.find('.action-share');
@@ -151,7 +140,8 @@ describe('OCA.Sharing.Util tests', function() {
 				size: 12,
 				permissions: OC.PERMISSION_ALL,
 				shareOwner: 'User One',
-				etag: 'abc'
+				etag: 'abc',
+				shareTypes: [OC.Share.SHARE_TYPE_USER]
 			}]);
 			$tr = fileList.$el.find('tbody tr:first');
 			$action = $tr.find('.action-share');
@@ -171,7 +161,8 @@ describe('OCA.Sharing.Util tests', function() {
 				size: 12,
 				permissions: OC.PERMISSION_ALL,
 				recipientsDisplayName: 'User One, User Two',
-				etag: 'abc'
+				etag: 'abc',
+				shareTypes: [OC.Share.SHARE_TYPE_USER]
 			}]);
 			$tr = fileList.$el.find('tbody tr:first');
 			$action = $tr.find('.action-share');
diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php
index 95a05f4ed6f77a7581d99e4f576a2a270c69c27c..b56a1b7d2f6192a1e722d0b5426c1e796397e2dd 100644
--- a/build/integration/features/bootstrap/WebDav.php
+++ b/build/integration/features/bootstrap/WebDav.php
@@ -190,7 +190,7 @@ trait WebDav {
 	 */
 	public function theSingleResponseShouldContainAPropertyWithValue($key, $expectedValue) {
 		$keys = $this->response;
-		if (!isset($keys[$key])) {
+		if (!array_key_exists($key, $keys)) {
 			throw new \Exception("Cannot find property \"$key\" with \"$expectedValue\"");
 		}
 
@@ -200,6 +200,57 @@ trait WebDav {
 		}
 	}
 
+	/**
+	 * @Then the response should contain a share-types property with
+	 */
+	public function theResponseShouldContainAShareTypesPropertyWith($table)
+	{
+		$keys = $this->response;
+		if (!array_key_exists('{http://owncloud.org/ns}share-types', $keys)) {
+			throw new \Exception("Cannot find property \"{http://owncloud.org/ns}share-types\"");
+		}
+
+		$foundTypes = [];
+		$data = $keys['{http://owncloud.org/ns}share-types'];
+		foreach ($data as $item) {
+			if ($item['name'] !== '{http://owncloud.org/ns}share-type') {
+				throw new \Exception('Invalid property found: "' . $item['name'] . '"');
+			}
+
+			$foundTypes[] = $item['value'];
+		}
+
+		foreach ($table->getRows() as $row) {
+			$key = array_search($row[0], $foundTypes);
+			if ($key === false) {
+				throw new \Exception('Expected type ' . $row[0] . ' not found');
+			}
+
+			unset($foundTypes[$key]);
+		}
+
+		if ($foundTypes !== []) {
+			throw new \Exception('Found more share types then specified: ' . $foundTypes);
+		}
+	}
+
+	/**
+	 * @Then the response should contain an empty property :property
+	 * @param string $property
+	 * @throws \Exception
+	 */
+	public function theResponseShouldContainAnEmptyProperty($property) {
+		$properties = $this->response;
+		if (!array_key_exists($property, $properties)) {
+			throw new \Exception("Cannot find property \"$property\"");
+		}
+
+		if ($properties[$property] !== null) {
+			throw new \Exception("Property \"$property\" is not empty");
+		}
+	}
+
+
 	/*Returns the elements of a propfind, $folderDepth requires 1 to see elements without children*/
 	public function listFolder($user, $path, $folderDepth, $properties = null){
 		$fullUrl = substr($this->baseUrl, 0, -4);
diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature
index 019df3436f8a910b3cd9dfc986a845d08543a81a..ee841f9eb5b4e13bb6e54eb797d56cf2671c4ee1 100644
--- a/build/integration/features/webdav-related.feature
+++ b/build/integration/features/webdav-related.feature
@@ -168,3 +168,76 @@ Feature: webdav-related
 		When As an "user0"
 		And Downloading file "/myChunkedFile.txt"
 		Then Downloaded content should be "AAAAABBBBBCCCCC"
+
+	Scenario: A file that is not shared does not have a share-types property
+		Given user "user0" exists
+		And user "user0" created a folder "/test"
+		When as "user0" gets properties of folder "/test" with
+			|{http://owncloud.org/ns}share-types|
+		Then the response should contain an empty property "{http://owncloud.org/ns}share-types"
+
+	Scenario: A file that is shared to a user has a share-types property
+		Given user "user0" exists
+		And user "user1" exists
+		And user "user0" created a folder "/test"
+		And as "user0" creating a share with
+			| path | test |
+			| shareType | 0 |
+			| permissions | 31 |
+			| shareWith | user1 |
+		When as "user0" gets properties of folder "/test" with
+			|{http://owncloud.org/ns}share-types|
+		Then the response should contain a share-types property with
+			| 0 |
+
+	Scenario: A file that is shared to a group has a share-types property
+		Given user "user0" exists
+		And group "group1" exists
+		And user "user0" created a folder "/test"
+		And as "user0" creating a share with
+			| path | test |
+			| shareType | 1 |
+			| permissions | 31 |
+			| shareWith | group1 |
+		When as "user0" gets properties of folder "/test" with
+			|{http://owncloud.org/ns}share-types|
+		Then the response should contain a share-types property with
+			| 1 |
+
+	Scenario: A file that is shared by link has a share-types property
+		Given user "user0" exists
+		And user "user0" created a folder "/test"
+		And as "user0" creating a share with
+			| path | test |
+			| shareType | 3 |
+			| permissions | 31 |
+		When as "user0" gets properties of folder "/test" with
+			|{http://owncloud.org/ns}share-types|
+		Then the response should contain a share-types property with
+			| 3 |
+
+	Scenario: A file that is shared by user,group and link has a share-types property
+		Given user "user0" exists
+		And user "user1" exists
+		And group "group2" exists
+		And user "user0" created a folder "/test"
+		And as "user0" creating a share with
+			| path        | test  |
+			| shareType   | 0     |
+			| permissions | 31    |
+			| shareWith   | user1 |
+		And as "user0" creating a share with
+			| path        | test  |
+			| shareType   | 1     |
+			| permissions | 31    |
+			| shareWith   | group2 |
+		And as "user0" creating a share with
+			| path        | test  |
+			| shareType   | 3     |
+			| permissions | 31    |
+		When as "user0" gets properties of folder "/test" with
+			|{http://owncloud.org/ns}share-types|
+		Then the response should contain a share-types property with
+			| 0 |
+			| 1 |
+			| 3 |