diff --git a/apps/dav/lib/SystemTag/SystemTagMappingNode.php b/apps/dav/lib/SystemTag/SystemTagMappingNode.php
index b72b1de0183e0b61b354a446b57703b3092f1716..09a3c79c7577bf2b34d897c26651f36523a43271 100644
--- a/apps/dav/lib/SystemTag/SystemTagMappingNode.php
+++ b/apps/dav/lib/SystemTag/SystemTagMappingNode.php
@@ -24,6 +24,7 @@ namespace OCA\DAV\SystemTag;
 
 use Sabre\DAV\Exception\NotFound;
 use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Exception\MethodNotAllowed;
 
 use OCP\SystemTag\ISystemTag;
 use OCP\SystemTag\ISystemTagManager;
@@ -34,12 +35,11 @@ use OCP\IUser;
 /**
  * Mapping node for system tag to object id
  */
-class SystemTagMappingNode extends SystemTagNode {
-
+class SystemTagMappingNode implements \Sabre\DAV\INode {
 	/**
-	 * @var ISystemTagObjectMapper
+	 * @var ISystemTag
 	 */
-	private $tagMapper;
+	protected $tag;
 
 	/**
 	 * @var string
@@ -51,6 +51,23 @@ class SystemTagMappingNode extends SystemTagNode {
 	 */
 	private $objectType;
 
+	/**
+	 * User
+	 *
+	 * @var IUser
+	 */
+	protected $user;
+
+	/**
+	 * @var ISystemTagManager
+	 */
+	protected $tagManager;
+
+	/**
+	 * @var ISystemTagObjectMapper
+	 */
+	private $tagMapper;
+
 	/**
 	 * Sets up the node, expects a full path name
 	 *
@@ -69,10 +86,12 @@ class SystemTagMappingNode extends SystemTagNode {
 		ISystemTagManager $tagManager,
 		ISystemTagObjectMapper $tagMapper
 	) {
+		$this->tag = $tag;
 		$this->objectId = $objectId;
 		$this->objectType = $objectType;
+		$this->user = $user;
+		$this->tagManager = $tagManager;
 		$this->tagMapper = $tagMapper;
-		parent::__construct($tag, $user, $tagManager);
 	}
 
 	/**
@@ -93,6 +112,43 @@ class SystemTagMappingNode extends SystemTagNode {
 		return $this->objectType;
 	}
 
+	/**
+	 * Returns the system tag represented by this node
+	 *
+	 * @return ISystemTag system tag
+	 */
+	public function getSystemTag() {
+		return $this->tag;
+	}
+
+	/**
+	 *  Returns the id of the tag
+	 *
+	 * @return string
+	 */
+	public function getName() {
+		return $this->tag->getId();
+	}
+
+	/**
+	 * Renames the node
+	 *
+	 * @param string $name The new name
+	 *
+	 * @throws MethodNotAllowed not allowed to rename node
+	 */
+	public function setName($name) {
+		throw new MethodNotAllowed();
+	}
+
+	/**
+	 * Returns null, not supported
+	 *
+	 */
+	public function getLastModified() {
+		return null;
+	}
+
 	/**
 	 * Delete tag to object association
 	 */
diff --git a/apps/dav/lib/SystemTag/SystemTagPlugin.php b/apps/dav/lib/SystemTag/SystemTagPlugin.php
index a266b4a1214285d71a520f2543c3daab231ea2bc..0b44287371b7308950e90c82511d31387af94c9d 100644
--- a/apps/dav/lib/SystemTag/SystemTagPlugin.php
+++ b/apps/dav/lib/SystemTag/SystemTagPlugin.php
@@ -36,6 +36,7 @@ use OCP\SystemTag\ISystemTagManager;
 use OCP\SystemTag\TagAlreadyExistsException;
 use Sabre\HTTP\RequestInterface;
 use Sabre\HTTP\ResponseInterface;
+use OCA\DAV\SystemTag\SystemTagMappingNode;
 
 /**
  * Sabre plugin to handle system tags:
diff --git a/apps/dav/tests/unit/systemtag/systemtagmappingnode.php b/apps/dav/tests/unit/systemtag/systemtagmappingnode.php
index 7f2ff7d6616dbf170ead629a84600071355c0828..f0e1c3bc56713d784e6ad037074133b92bd30219 100644
--- a/apps/dav/tests/unit/systemtag/systemtagmappingnode.php
+++ b/apps/dav/tests/unit/systemtag/systemtagmappingnode.php
@@ -24,6 +24,7 @@ namespace OCA\DAV\Tests\Unit\SystemTag;
 use Sabre\DAV\Exception\NotFound;
 use OC\SystemTag\SystemTag;
 use OCP\SystemTag\TagNotFoundException;
+use OCP\SystemTag\ISystemTag;
 
 class SystemTagMappingNode extends \Test\TestCase {
 
@@ -37,14 +38,20 @@ class SystemTagMappingNode extends \Test\TestCase {
 	 */
 	private $tagMapper;
 
+	/**
+	 * @var \OCP\IUser
+	 */
+	private $user;
+
 	protected function setUp() {
 		parent::setUp();
 
 		$this->tagManager = $this->getMock('\OCP\SystemTag\ISystemTagManager');
 		$this->tagMapper = $this->getMock('\OCP\SystemTag\ISystemTagObjectMapper');
+		$this->user = $this->getMock('\OCP\IUser');
 	}
 
-	public function getMappingNode($isAdmin = true, $tag = null) {
+	public function getMappingNode($tag = null) {
 		if ($tag === null) {
 			$tag = new SystemTag(1, 'Test', true, true);
 		}
@@ -52,7 +59,7 @@ class SystemTagMappingNode extends \Test\TestCase {
 			$tag,
 			123,
 			'files',
-			$isAdmin,
+			$this->user,
 			$this->tagManager,
 			$this->tagMapper
 		);
@@ -60,28 +67,30 @@ class SystemTagMappingNode extends \Test\TestCase {
 
 	public function testGetters() {
 		$tag = new SystemTag(1, 'Test', true, false);
-		$node = $this->getMappingNode(true, $tag);
+		$node = $this->getMappingNode($tag);
 		$this->assertEquals('1', $node->getName());
 		$this->assertEquals($tag, $node->getSystemTag());
 		$this->assertEquals(123, $node->getObjectId());
 		$this->assertEquals('files', $node->getObjectType());
 	}
 
-	public function adminFlagProvider() {
-		return [[true], [false]];
-	}
-
-	/**
-	 * @dataProvider adminFlagProvider
-	 */
-	public function testDeleteTag($isAdmin) {
+	public function testDeleteTag() {
+		$node = $this->getMappingNode();
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($node->getSystemTag())
+			->will($this->returnValue(true));
+		$this->tagManager->expects($this->once())
+			->method('canUserAssignTag')
+			->with($node->getSystemTag())
+			->will($this->returnValue(true));
 		$this->tagManager->expects($this->never())
 			->method('deleteTags');
 		$this->tagMapper->expects($this->once())
 			->method('unassignTags')
 			->with(123, 'files', 1);
 
-		$this->getMappingNode($isAdmin)->delete();
+		$node->delete();
 	}
 
 	public function tagNodeDeleteProviderPermissionException() {
@@ -102,7 +111,15 @@ class SystemTagMappingNode extends \Test\TestCase {
 	/**
 	 * @dataProvider tagNodeDeleteProviderPermissionException
 	 */
-	public function testDeleteTagExpectedException($tag, $expectedException) {
+	public function testDeleteTagExpectedException(ISystemTag $tag, $expectedException) {
+		$this->tagManager->expects($this->any())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserVisible()));
+		$this->tagManager->expects($this->any())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserAssignable()));
 		$this->tagManager->expects($this->never())
 			->method('deleteTags');
 		$this->tagMapper->expects($this->never())
@@ -110,7 +127,7 @@ class SystemTagMappingNode extends \Test\TestCase {
 
 		$thrown = null;
 		try {
-			$this->getMappingNode(false, $tag)->delete();
+			$this->getMappingNode($tag)->delete();
 		} catch (\Exception $e) {
 			$thrown = $e;
 		}
@@ -122,11 +139,22 @@ class SystemTagMappingNode extends \Test\TestCase {
 	 * @expectedException Sabre\DAV\Exception\NotFound
 	 */
 	public function testDeleteTagNotFound() {
+		// assuming the tag existed at the time the node was created,
+		// but got deleted concurrently in the database
+		$tag = new SystemTag(1, 'Test', true, true);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserVisible()));
+		$this->tagManager->expects($this->once())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserAssignable()));
 		$this->tagMapper->expects($this->once())
 			->method('unassignTags')
 			->with(123, 'files', 1)
 			->will($this->throwException(new TagNotFoundException()));
 
-		$this->getMappingNode()->delete();
+		$this->getMappingNode($tag)->delete();
 	}
 }
diff --git a/apps/dav/tests/unit/systemtag/systemtagnode.php b/apps/dav/tests/unit/systemtag/systemtagnode.php
index 5184b74e5c87274bd75a7a0751be92ec414a83f2..d9e088a7d9081d19e3435a2c926d967ea18108eb 100644
--- a/apps/dav/tests/unit/systemtag/systemtagnode.php
+++ b/apps/dav/tests/unit/systemtag/systemtagnode.php
@@ -28,6 +28,7 @@ use Sabre\DAV\Exception\Conflict;
 use OC\SystemTag\SystemTag;
 use OCP\SystemTag\TagNotFoundException;
 use OCP\SystemTag\TagAlreadyExistsException;
+use OCP\SystemTag\ISystemTag;
 
 class SystemTagNode extends \Test\TestCase {
 
@@ -36,10 +37,16 @@ class SystemTagNode extends \Test\TestCase {
 	 */
 	private $tagManager;
 
+	/**
+	 * @var \OCP\IUser
+	 */
+	private $user;
+
 	protected function setUp() {
 		parent::setUp();
 
 		$this->tagManager = $this->getMock('\OCP\SystemTag\ISystemTagManager');
+		$this->user = $this->getMock('\OCP\IUser');
 	}
 
 	protected function getTagNode($isAdmin = true, $tag = null) {
@@ -48,6 +55,7 @@ class SystemTagNode extends \Test\TestCase {
 		}
 		return new \OCA\DAV\SystemTag\SystemTagNode(
 			$tag,
+			$this->user,
 			$isAdmin,
 			$this->tagManager
 		);
@@ -101,6 +109,14 @@ class SystemTagNode extends \Test\TestCase {
 	 * @dataProvider tagNodeProvider
 	 */
 	public function testUpdateTag($isAdmin, $originalTag, $changedArgs) {
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($originalTag)
+			->will($this->returnValue($originalTag->isUserVisible() || $isAdmin));
+		$this->tagManager->expects($this->once())
+			->method('canUserAssignTag')
+			->with($originalTag)
+			->will($this->returnValue($originalTag->isUserAssignable() || $isAdmin));
 		$this->tagManager->expects($this->once())
 			->method('updateTag')
 			->with(1, $changedArgs[0], $changedArgs[1], $changedArgs[2]);
@@ -153,6 +169,14 @@ class SystemTagNode extends \Test\TestCase {
 	 * @dataProvider tagNodeProviderPermissionException
 	 */
 	public function testUpdateTagPermissionException($originalTag, $changedArgs, $expectedException = null) {
+		$this->tagManager->expects($this->any())
+			->method('canUserSeeTag')
+			->with($originalTag)
+			->will($this->returnValue($originalTag->isUserVisible()));
+		$this->tagManager->expects($this->any())
+			->method('canUserAssignTag')
+			->with($originalTag)
+			->will($this->returnValue($originalTag->isUserAssignable()));
 		$this->tagManager->expects($this->never())
 			->method('updateTag');
 
@@ -172,32 +196,59 @@ class SystemTagNode extends \Test\TestCase {
 	 * @expectedException Sabre\DAV\Exception\Conflict
 	 */
 	public function testUpdateTagAlreadyExists() {
+		$tag = new SystemTag(1, 'tag1', true, true);
+		$this->tagManager->expects($this->any())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(true));
+		$this->tagManager->expects($this->any())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue(true));
 		$this->tagManager->expects($this->once())
 			->method('updateTag')
-			->with(1, 'Renamed', false, true)
+			->with(1, 'Renamed', true, true)
 			->will($this->throwException(new TagAlreadyExistsException()));
-		$this->getTagNode()->update('Renamed', false, true);
+		$this->getTagNode(false, $tag)->update('Renamed', true, true);
 	}
 
 	/**
 	 * @expectedException Sabre\DAV\Exception\NotFound
 	 */
 	public function testUpdateTagNotFound() {
+		$tag = new SystemTag(1, 'tag1', true, true);
+		$this->tagManager->expects($this->any())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(true));
+		$this->tagManager->expects($this->any())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue(true));
 		$this->tagManager->expects($this->once())
 			->method('updateTag')
-			->with(1, 'Renamed', false, true)
+			->with(1, 'Renamed', true, true)
 			->will($this->throwException(new TagNotFoundException()));
-		$this->getTagNode()->update('Renamed', false, true);
+		$this->getTagNode(false, $tag)->update('Renamed', true, true);
 	}
 
 	/**
 	 * @dataProvider adminFlagProvider
 	 */
 	public function testDeleteTag($isAdmin) {
+		$tag = new SystemTag(1, 'tag1', true, true);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(true));
+		$this->tagManager->expects($this->once())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue(true));
 		$this->tagManager->expects($this->once())
 			->method('deleteTags')
 			->with('1');
-		$this->getTagNode($isAdmin)->delete();
+		$this->getTagNode($isAdmin, $tag)->delete();
 	}
 
 	public function tagNodeDeleteProviderPermissionException() {
@@ -218,7 +269,15 @@ class SystemTagNode extends \Test\TestCase {
 	/**
 	 * @dataProvider tagNodeDeleteProviderPermissionException
 	 */
-	public function testDeleteTagPermissionException($tag, $expectedException) {
+	public function testDeleteTagPermissionException(ISystemTag $tag, $expectedException) {
+		$this->tagManager->expects($this->any())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserVisible()));
+		$this->tagManager->expects($this->any())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserAssignable()));
 		$this->tagManager->expects($this->never())
 			->method('deleteTags');
 
@@ -235,10 +294,19 @@ class SystemTagNode extends \Test\TestCase {
 	 * @expectedException Sabre\DAV\Exception\NotFound
 	 */
 	public function testDeleteTagNotFound() {
+		$tag = new SystemTag(1, 'tag1', true, true);
+		$this->tagManager->expects($this->any())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserVisible()));
+		$this->tagManager->expects($this->any())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue($tag->isUserAssignable()));
 		$this->tagManager->expects($this->once())
 			->method('deleteTags')
 			->with('1')
 			->will($this->throwException(new TagNotFoundException()));
-		$this->getTagNode()->delete();
+		$this->getTagNode(false, $tag)->delete();
 	}
 }
diff --git a/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php b/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php
index a2bf571ab68eee9508625992d01148a0cf91f5ae..5aa28d1a2542c9138c8c0b9fcb643cc270c15cfb 100644
--- a/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php
+++ b/apps/dav/tests/unit/systemtag/systemtagsbyidcollection.php
@@ -32,6 +32,11 @@ class SystemTagsByIdCollection extends \Test\TestCase {
 	 */
 	private $tagManager;
 
+	/**
+	 * @var \OCP\IUser
+	 */
+	private $user;
+
 	protected function setUp() {
 		parent::setUp();
 
@@ -39,14 +44,14 @@ class SystemTagsByIdCollection extends \Test\TestCase {
 	}
 
 	public function getNode($isAdmin = true) {
-		$user = $this->getMock('\OCP\IUser');
-		$user->expects($this->any())
+		$this->user = $this->getMock('\OCP\IUser');
+		$this->user->expects($this->any())
 			->method('getUID')
 			->will($this->returnValue('testuser'));
 		$userSession = $this->getMock('\OCP\IUserSession');
 		$userSession->expects($this->any())
 			->method('getUser')
-			->will($this->returnValue($user));
+			->will($this->returnValue($this->user));
 		$groupManager = $this->getMock('\OCP\IGroupManager');
 		$groupManager->expects($this->any())
 			->method('isAdmin')
@@ -77,35 +82,19 @@ class SystemTagsByIdCollection extends \Test\TestCase {
 		$this->getNode()->createDirectory('789');
 	}
 
-	public function getChildProvider() {
-		return [
-			[
-				true,
-				true,
-			],
-			[
-				true,
-				false,
-			],
-			[
-				false,
-				true,
-			],
-		];
-	}
-
-	/**
-	 * @dataProvider getChildProvider
-	 */
-	public function testGetChild($isAdmin, $userVisible) {
-		$tag = new SystemTag(123, 'Test', $userVisible, false);
+	public function testGetChild() {
+		$tag = new SystemTag(123, 'Test', true, false);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(true));
 
 		$this->tagManager->expects($this->once())
 			->method('getTagsByIds')
 			->with(['123'])
 			->will($this->returnValue([$tag]));
 
-		$childNode = $this->getNode($isAdmin)->getChild('123');
+		$childNode = $this->getNode()->getChild('123');
 
 		$this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagNode', $childNode);
 		$this->assertEquals('123', $childNode->getName());
@@ -198,27 +187,27 @@ class SystemTagsByIdCollection extends \Test\TestCase {
 
 	public function childExistsProvider() {
 		return [
-			// admins, always visible
-			[true, true, true],
-			[true, false, true],
-			// non-admins, depends on flag
-			[false, true, true],
-			[false, false, false],
+			[true, true],
+			[false, false],
 		];
 	}
 
 	/**
 	 * @dataProvider childExistsProvider
 	 */
-	public function testChildExists($isAdmin, $userVisible, $expectedResult) {
+	public function testChildExists($userVisible, $expectedResult) {
 		$tag = new SystemTag(123, 'One', $userVisible, false);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue($userVisible));
 
 		$this->tagManager->expects($this->once())
 			->method('getTagsByIds')
 			->with(['123'])
 			->will($this->returnValue([$tag]));
 
-		$this->assertEquals($expectedResult, $this->getNode($isAdmin)->childExists('123'));
+		$this->assertEquals($expectedResult, $this->getNode()->childExists('123'));
 	}
 
 	public function testChildExistsNotFound() {
diff --git a/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php b/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php
index df97acd846b8ff8381eeb06d191e8f82143dd5c4..9adc5b88c418809f94b62b8909ce73b6aa253f57 100644
--- a/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php
+++ b/apps/dav/tests/unit/systemtag/systemtagsobjectmappingcollection.php
@@ -37,45 +37,50 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 	 */
 	private $tagMapper;
 
+	/**
+	 * @var \OCP\IUser
+	 */
+	private $user;
+
 	protected function setUp() {
 		parent::setUp();
 
 		$this->tagManager = $this->getMock('\OCP\SystemTag\ISystemTagManager');
 		$this->tagMapper = $this->getMock('\OCP\SystemTag\ISystemTagObjectMapper');
+
+		$this->user = $this->getMock('\OCP\IUser');
 	}
 
-	public function getNode($isAdmin = true) {
+	public function getNode() {
 		return new \OCA\DAV\SystemTag\SystemTagsObjectMappingCollection (
 			111,
 			'files',
-			$isAdmin,
+			$this->user,
 			$this->tagManager,
 			$this->tagMapper
 		);
 	}
 
-	public function testAssignTagAsAdmin() {
-		$this->tagManager->expects($this->never())
-			->method('getTagsByIds');
-		$this->tagMapper->expects($this->once())
-			->method('assignTags')
-			->with(111, 'files', '555');
-
-		$this->getNode(true)->createFile('555');
-	}
-
-	public function testAssignTagAsUser() {
+	public function testAssignTag() {
 		$tag = new SystemTag('1', 'Test', true, true);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(true));
+		$this->tagManager->expects($this->once())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue(true));
 
 		$this->tagManager->expects($this->once())
 			->method('getTagsByIds')
-			->with('555')
+			->with(['555'])
 			->will($this->returnValue([$tag]));
 		$this->tagMapper->expects($this->once())
 			->method('assignTags')
 			->with(111, 'files', '555');
 
-		$this->getNode(false)->createFile('555');
+		$this->getNode()->createFile('555');
 	}
 
 	public function permissionsProvider() {
@@ -90,19 +95,27 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 	/**
 	 * @dataProvider permissionsProvider
 	 */
-	public function testAssignTagAsUserNoPermission($userVisible, $userAssignable, $expectedException) {
+	public function testAssignTagNoPermission($userVisible, $userAssignable, $expectedException) {
 		$tag = new SystemTag('1', 'Test', $userVisible, $userAssignable);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue($userVisible));
+		$this->tagManager->expects($this->any())
+			->method('canUserAssignTag')
+			->with($tag)
+			->will($this->returnValue($userAssignable));
 
 		$this->tagManager->expects($this->once())
 			->method('getTagsByIds')
-			->with('555')
+			->with(['555'])
 			->will($this->returnValue([$tag]));
 		$this->tagMapper->expects($this->never())
 			->method('assignTags');
 
 		$thrown = null;
 		try {
-			$this->getNode(false)->createFile('555');
+			$this->getNode()->createFile('555');
 		} catch (\Exception $e) {
 			$thrown = $e;
 		}
@@ -114,9 +127,9 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 	 * @expectedException Sabre\DAV\Exception\PreconditionFailed
 	 */
 	public function testAssignTagNotFound() {
-		$this->tagMapper->expects($this->once())
-			->method('assignTags')
-			->with(111, 'files', '555')
+		$this->tagManager->expects($this->once())
+			->method('getTagsByIds')
+			->with(['555'])
 			->will($this->throwException(new TagNotFoundException()));
 
 		$this->getNode()->createFile('555');
@@ -129,28 +142,12 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 		$this->getNode()->createDirectory('789');
 	}
 
-	public function getChildProvider() {
-		return [
-			[
-				true,
-				true,
-			],
-			[
-				true,
-				false,
-			],
-			[
-				false,
-				true,
-			],
-		];
-	}
-
-	/**
-	 * @dataProvider getChildProvider
-	 */
-	public function testGetChild($isAdmin, $userVisible) {
-		$tag = new SystemTag(555, 'TheTag', $userVisible, false);
+	public function testGetChild() {
+		$tag = new SystemTag(555, 'TheTag', true, false);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(true));
 
 		$this->tagMapper->expects($this->once())
 			->method('haveTag')
@@ -162,17 +159,21 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 			->with(['555'])
 			->will($this->returnValue(['555' => $tag]));
 
-		$childNode = $this->getNode($isAdmin)->getChild('555');
+		$childNode = $this->getNode()->getChild('555');
 
-		$this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagNode', $childNode);
+		$this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $childNode);
 		$this->assertEquals('555', $childNode->getName());
 	}
 
 	/**
 	 * @expectedException \Sabre\DAV\Exception\NotFound
 	 */
-	public function testGetChildUserNonVisible() {
+	public function testGetChildNonVisible() {
 		$tag = new SystemTag(555, 'TheTag', false, false);
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(false));
 
 		$this->tagMapper->expects($this->once())
 			->method('haveTag')
@@ -184,7 +185,7 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 			->with(['555'])
 			->will($this->returnValue(['555' => $tag]));
 
-		$this->getNode(false)->getChild('555');
+		$this->getNode()->getChild('555');
 	}
 
 	/**
@@ -223,7 +224,7 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 		$this->getNode()->getChild('777');
 	}
 
-	public function testGetChildrenAsAdmin() {
+	public function testGetChildren() {
 		$tag1 = new SystemTag(555, 'TagOne', true, false);
 		$tag2 = new SystemTag(556, 'TagTwo', true, true);
 		$tag3 = new SystemTag(557, 'InvisibleTag', false, true);
@@ -238,43 +239,13 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 			->with(['555', '556', '557'])
 			->will($this->returnValue(['555' => $tag1, '556' => $tag2, '557' => $tag3]));
 
-		$children = $this->getNode(true)->getChildren();
-
-		$this->assertCount(3, $children);
-
-		$this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $children[0]);
-		$this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $children[1]);
-		$this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagMappingNode', $children[2]);
-
-		$this->assertEquals(111, $children[0]->getObjectId());
-		$this->assertEquals('files', $children[0]->getObjectType());
-		$this->assertEquals($tag1, $children[0]->getSystemTag());
-
-		$this->assertEquals(111, $children[1]->getObjectId());
-		$this->assertEquals('files', $children[1]->getObjectType());
-		$this->assertEquals($tag2, $children[1]->getSystemTag());
+		$this->tagManager->expects($this->exactly(3))
+			->method('canUserSeeTag')
+			->will($this->returnCallback(function($tag) {
+				return $tag->isUserVisible();
+			}));
 
-		$this->assertEquals(111, $children[2]->getObjectId());
-		$this->assertEquals('files', $children[2]->getObjectType());
-		$this->assertEquals($tag3, $children[2]->getSystemTag());
-	}
-
-	public function testGetChildrenAsUser() {
-		$tag1 = new SystemTag(555, 'TagOne', true, false);
-		$tag2 = new SystemTag(556, 'TagTwo', true, true);
-		$tag3 = new SystemTag(557, 'InvisibleTag', false, true);
-
-		$this->tagMapper->expects($this->once())
-			->method('getTagIdsForObjects')
-			->with([111], 'files')
-			->will($this->returnValue(['111' => ['555', '556', '557']]));
-
-		$this->tagManager->expects($this->once())
-			->method('getTagsByIds')
-			->with(['555', '556', '557'])
-			->will($this->returnValue(['555' => $tag1, '556' => $tag2, '557' => $tag3]));
-
-		$children = $this->getNode(false)->getChildren();
+		$children = $this->getNode()->getChildren();
 
 		$this->assertCount(2, $children);
 
@@ -290,16 +261,7 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 		$this->assertEquals($tag2, $children[1]->getSystemTag());
 	}
 
-	public function testChildExistsAsAdmin() {
-		$this->tagMapper->expects($this->once())
-			->method('haveTag')
-			->with([111], 'files', '555')
-			->will($this->returnValue(true));
-
-		$this->assertTrue($this->getNode(true)->childExists('555'));
-	}
-
-	public function testChildExistsWithVisibleTagAsUser() {
+	public function testChildExistsWithVisibleTag() {
 		$tag = new SystemTag(555, 'TagOne', true, false);
 
 		$this->tagMapper->expects($this->once())
@@ -307,15 +269,20 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 			->with([111], 'files', '555')
 			->will($this->returnValue(true));
 
+		$this->tagManager->expects($this->once())
+			->method('canUserSeeTag')
+			->with($tag)
+			->will($this->returnValue(true));
+
 		$this->tagManager->expects($this->once())
 			->method('getTagsByIds')
-			->with('555')
+			->with(['555'])
 			->will($this->returnValue([$tag]));
 
-		$this->assertTrue($this->getNode(false)->childExists('555'));
+		$this->assertTrue($this->getNode()->childExists('555'));
 	}
 
-	public function testChildExistsWithInvisibleTagAsUser() {
+	public function testChildExistsWithInvisibleTag() {
 		$tag = new SystemTag(555, 'TagOne', false, false);
 
 		$this->tagMapper->expects($this->once())
@@ -325,10 +292,10 @@ class SystemTagsObjectMappingCollection extends \Test\TestCase {
 
 		$this->tagManager->expects($this->once())
 			->method('getTagsByIds')
-			->with('555')
+			->with(['555'])
 			->will($this->returnValue([$tag]));
 
-		$this->assertFalse($this->getNode(false)->childExists('555'));
+		$this->assertFalse($this->getNode()->childExists('555'));
 	}
 
 	public function testChildExistsNotFound() {