diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
index 4ea7bbd7aa8237dbf5994e7ebb8ecb44f8d1e935..8d15de9e12a32087e9ce247f1a0a324b3bbdf929 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
@@ -97,6 +97,9 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.update.SpaceUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyTermDeletionOptions;
@@ -128,6 +131,7 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IMapMaterialM
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IMapProjectMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IMapSampleMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IMapSpaceMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IMapTagMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IMapVocabularyTermMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IRevertDeletionMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.ISearchCustomASServiceMethodExecutor;
@@ -242,6 +246,9 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @Autowired
     private IMapVocabularyTermMethodExecutor mapVocabularyTermExecutor;
 
+    @Autowired
+    private IMapTagMethodExecutor mapTagExecutor;
+
     @Autowired
     private ISearchSpaceMethodExecutor searchSpaceExecutor;
 
@@ -555,6 +562,14 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
         return mapVocabularyTermExecutor.map(sessionToken, vocabularyTermIds, fetchOptions);
     }
 
+    @Override
+    @Transactional(readOnly = true)
+    @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    public Map<ITagId, Tag> mapTags(String sessionToken, List<? extends ITagId> tagIds, TagFetchOptions fetchOptions)
+    {
+        return mapTagExecutor.map(sessionToken, tagIds, fetchOptions);
+    }
+
     @Override
     @Transactional(readOnly = true)
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
index 3d53dc965415ef56c93b342a5007c765ab66ade3..8b11da128be3a442742b11543e2af15a190b221b 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
@@ -93,6 +93,9 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.update.SpaceUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyTermDeletionOptions;
@@ -284,6 +287,13 @@ public class ApplicationServerApiLogger extends AbstractServerLogger implements
         return null;
     }
 
+    @Override
+    public Map<ITagId, Tag> mapTags(String sessionToken, List<? extends ITagId> tagIds, TagFetchOptions fetchOptions)
+    {
+        logAccess(sessionToken, "map-tags", "TAG_IDS(%s) FETCH_OPTIONS(%s)", abbreviate(tagIds), fetchOptions);
+        return null;
+    }
+
     @Override
     public Map<IDataSetId, DataSet> mapDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetFetchOptions fetchOptions)
     {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IMapTagMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IMapTagMethodExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..786475860a5b56570facd823a9d79b27b04ceb57
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IMapTagMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapTagMethodExecutor extends IMapMethodExecutor<ITagId, Tag, TagFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/MapTagMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/MapTagMethodExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe0e1586655162f2225a5af14a41966863eebb19
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/MapTagMethodExecutor.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.IMapTagByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag.ITagTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapTagMethodExecutor extends AbstractMapMethodExecutor<ITagId, Long, Tag, TagFetchOptions> implements
+        IMapTagMethodExecutor
+{
+
+    @Autowired
+    private IMapTagByIdExecutor mapExecutor;
+
+    @Autowired
+    private ITagTranslator translator;
+
+    @Override
+    protected IMapObjectByIdExecutor<ITagId, Long> getMapExecutor()
+    {
+        return new IMapObjectByIdExecutor<ITagId, Long>()
+            {
+                @Override
+                public Map<ITagId, Long> map(IOperationContext context, Collection<? extends ITagId> ids)
+                {
+                    Map<ITagId, Long> idMap = new LinkedHashMap<ITagId, Long>();
+                    Map<ITagId, MetaprojectPE> peMap = mapExecutor.map(context, ids);
+
+                    for (Map.Entry<ITagId, MetaprojectPE> entry : peMap.entrySet())
+                    {
+                        idMap.put(entry.getKey(), entry.getValue().getId());
+                    }
+
+                    return idMap;
+                }
+            };
+    }
+
+    @Override
+    protected ITranslator<Long, Tag, TagFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/AddTagToEntityExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/AddTagToEntityExecutor.java
index 2ec9b9d81c13db0f89ade38c6ed9ccac126cabe1..954cf099d02a428400411d24049f7265f86e4e31 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/AddTagToEntityExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/AddTagToEntityExecutor.java
@@ -26,6 +26,8 @@ import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.tag.TagAuthorization;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityWithMetaprojects;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
@@ -36,6 +38,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 public class AddTagToEntityExecutor implements IAddTagToEntityExecutor
 {
 
+    @Autowired
+    private IDAOFactory daoFactory;
+
     @Autowired
     private IMapTagByIdExecutor mapTagByIdExecutor;
 
@@ -71,6 +76,7 @@ public class AddTagToEntityExecutor implements IAddTagToEntityExecutor
             }
         }
 
+        TagAuthorization authorization = new TagAuthorization(context, daoFactory);
         Map<ITagId, MetaprojectPE> allTagsMap = mapTagByIdExecutor.map(context, allTagIds);
 
         for (Map.Entry<IEntityWithMetaprojects, Collection<? extends ITagId>> entry : entityToTagIdsMap.entrySet())
@@ -90,6 +96,8 @@ public class AddTagToEntityExecutor implements IAddTagToEntityExecutor
                         allTagsMap.put(tagId, tag);
                     }
 
+                    authorization.checkAccess(tag);
+
                     entity.addMetaproject(tag);
                 }
             }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/CreateTagExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/CreateTagExecutor.java
index 7c0532b548977f3c34c46abb0908ddefea423b4d..40e7727d3c323e2bc4ea0992a394b9e8485a3c7e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/CreateTagExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/CreateTagExecutor.java
@@ -23,7 +23,9 @@ import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.tag.TagAuthorization;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
 /**
@@ -37,27 +39,34 @@ public class CreateTagExecutor implements ICreateTagExecutor
     private IDAOFactory daoFactory;
 
     @Autowired
-    private IGetTagCodeExecutor getTagCodeExecutor;
+    private IGetTagIdentifierExecutor getTagIdentifierExecutor;
 
     @SuppressWarnings("unused")
     private CreateTagExecutor()
     {
     }
 
-    public CreateTagExecutor(IDAOFactory daoFactory, IGetTagCodeExecutor getTagCodeExecutor)
+    public CreateTagExecutor(IDAOFactory daoFactory, IGetTagIdentifierExecutor getTagIdentifierExecutor)
     {
         this.daoFactory = daoFactory;
-        this.getTagCodeExecutor = getTagCodeExecutor;
+        this.getTagIdentifierExecutor = getTagIdentifierExecutor;
     }
 
     @Override
     public MetaprojectPE createTag(IOperationContext context, ITagId tagId)
     {
         MetaprojectPE tag = new MetaprojectPE();
-        tag.setName(getTagCodeExecutor.getTagCode(context, tagId));
+        MetaprojectIdentifier identifier = getTagIdentifierExecutor.getIdentifier(context, tagId);
+
+        tag.setName(identifier.getMetaprojectName());
         tag.setOwner(context.getSession().tryGetPerson());
         tag.setCreationDate(new Date());
+        tag.setPrivate(true);
+
         daoFactory.getMetaprojectDAO().createOrUpdateMetaproject(tag, context.getSession().tryGetPerson());
+
+        new TagAuthorization(context, daoFactory).checkAccess(tag);
+
         return tag;
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagCodeExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagIdentifierExecutor.java
similarity index 70%
rename from openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagCodeExecutor.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagIdentifierExecutor.java
index 2d97f2c956b341434aae88feb5ad2c7a07ee0cbb..eef7588a1913e8e3f0dbe5358dea76d6091129fb 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagCodeExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagIdentifierExecutor.java
@@ -21,7 +21,6 @@ import org.springframework.stereotype.Component;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagCode;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
-import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.UnauthorizedObjectAccessException;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
 import ch.systemsx.cisd.common.exceptions.NotImplementedException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectIdentifier;
@@ -30,33 +29,28 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectIdentifier;
  * @author pkupczyk
  */
 @Component
-public class GetTagCodeExecutor implements IGetTagCodeExecutor
+public class GetTagIdentifierExecutor implements IGetTagIdentifierExecutor
 {
 
-    public GetTagCodeExecutor()
+    public GetTagIdentifierExecutor()
     {
     }
 
     @Override
-    public String getTagCode(IOperationContext context, ITagId tagId)
+    public MetaprojectIdentifier getIdentifier(IOperationContext context, ITagId tagId)
     {
         if (tagId instanceof TagCode)
         {
-            return ((TagCode) tagId).getCode();
+            String code = ((TagCode) tagId).getCode();
+            String owner = context.getSession().tryGetPerson().getUserId();
+            return new MetaprojectIdentifier(owner, code);
         }
         if (tagId instanceof TagPermId)
         {
             TagPermId tagPermId = (TagPermId) tagId;
             MetaprojectIdentifier tagIdentifier =
                     MetaprojectIdentifier.parse(tagPermId.getPermId());
-            String name = tagIdentifier.getMetaprojectName();
-            String ownerId = tagIdentifier.getMetaprojectOwnerId();
-            String userId = context.getSession().tryGetPerson().getUserId();
-            if (ownerId.equals(userId) == false)
-            {
-                throw new UnauthorizedObjectAccessException(tagId);
-            }
-            return name;
+            return tagIdentifier;
         }
         throw new NotImplementedException("Tag id [" + tagId + "] is of unknown type: "
                 + tagId.getClass().getName());
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/IGetTagCodeExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/IGetTagIdentifierExecutor.java
similarity index 79%
rename from openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/IGetTagCodeExecutor.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/IGetTagIdentifierExecutor.java
index bb9f35c662ab2fb93d692f8e89946953ecabc35d..332dada817526cf019792f6216c49f4e686b1d1b 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/IGetTagCodeExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/IGetTagIdentifierExecutor.java
@@ -18,13 +18,14 @@ package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectIdentifier;
 
 /**
  * @author pkupczyk
  */
-public interface IGetTagCodeExecutor
+public interface IGetTagIdentifierExecutor
 {
 
-    public String getTagCode(IOperationContext context, ITagId tagId);
+    public MetaprojectIdentifier getIdentifier(IOperationContext context, ITagId tagId);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutor.java
index 0cd37eea8ec8ca7dd9b05040d35f24394ef2abcf..60cf42772d0f95207eaab186500fdd6d8993752e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutor.java
@@ -17,7 +17,7 @@
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag;
 
 import java.util.Collection;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,6 +26,7 @@ import org.springframework.stereotype.Component;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
 /**
@@ -39,32 +40,32 @@ public class MapTagByIdExecutor implements IMapTagByIdExecutor
     private IDAOFactory daoFactory;
 
     @Autowired
-    private IGetTagCodeExecutor getTagCodeExecutor;
+    private IGetTagIdentifierExecutor getTagIdentifierExecutor;
 
     @SuppressWarnings("unused")
     private MapTagByIdExecutor()
     {
     }
 
-    public MapTagByIdExecutor(IDAOFactory daoFactory, IGetTagCodeExecutor getTagCodeExecutor)
+    public MapTagByIdExecutor(IDAOFactory daoFactory, IGetTagIdentifierExecutor getTagCodeExecutor)
     {
         this.daoFactory = daoFactory;
-        this.getTagCodeExecutor = getTagCodeExecutor;
+        this.getTagIdentifierExecutor = getTagCodeExecutor;
     }
 
     @Override
     public Map<ITagId, MetaprojectPE> map(IOperationContext context, Collection<? extends ITagId> tagIds)
     {
-        Map<ITagId, MetaprojectPE> map = new HashMap<ITagId, MetaprojectPE>();
+        Map<ITagId, MetaprojectPE> map = new LinkedHashMap<ITagId, MetaprojectPE>();
 
         if (tagIds != null)
         {
             for (ITagId tagId : tagIds)
             {
-                String code = getTagCodeExecutor.getTagCode(context, tagId);
+                MetaprojectIdentifier identifier = getTagIdentifierExecutor.getIdentifier(context, tagId);
                 MetaprojectPE tag =
                         daoFactory.getMetaprojectDAO()
-                                .tryFindByOwnerAndName(context.getSession().tryGetPerson().getUserId(), code);
+                                .tryFindByOwnerAndName(identifier.getMetaprojectOwnerId(), identifier.getMetaprojectName());
                 if (tag != null)
                 {
                     map.put(tagId, tag);
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/RemoveTagFromEntityExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/RemoveTagFromEntityExecutor.java
index 3f3b9c44d74a20ac168ac15c38f64fad93c7db0b..734c91062ae1af26296351c535e7ee7b6b3e2ae8 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/RemoveTagFromEntityExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/RemoveTagFromEntityExecutor.java
@@ -24,6 +24,8 @@ import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.tag.TagAuthorization;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityWithMetaprojects;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
@@ -34,6 +36,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 public class RemoveTagFromEntityExecutor implements IRemoveTagFromEntityExecutor
 {
 
+    @Autowired
+    private IDAOFactory daoFactory;
+
     @Autowired
     private IMapTagByIdExecutor mapTagByIdExecutor;
 
@@ -50,10 +55,12 @@ public class RemoveTagFromEntityExecutor implements IRemoveTagFromEntityExecutor
     @Override
     public void removeTag(IOperationContext context, IEntityWithMetaprojects entity, Collection<? extends ITagId> tagIds)
     {
+        TagAuthorization authorization = new TagAuthorization(context, daoFactory);
         Map<ITagId, MetaprojectPE> tagMap = mapTagByIdExecutor.map(context, tagIds);
 
         for (MetaprojectPE tag : tagMap.values())
         {
+            authorization.checkAccess(tag);
             entity.removeMetaproject(tag);
         }
     }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagForEntityExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagForEntityExecutor.java
index af0852035836a92ac3d92267e07d8b40af8d3a3c..b1528e0ae80aa1fb0b6addcaa32102e297102669 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagForEntityExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagForEntityExecutor.java
@@ -26,6 +26,8 @@ import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.tag.TagAuthorization;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityWithMetaprojects;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
@@ -36,6 +38,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 public class SetTagForEntityExecutor implements ISetTagForEntityExecutor
 {
 
+    @Autowired
+    private IDAOFactory daoFactory;
+
     @Autowired
     private IMapTagByIdExecutor mapTagByIdExecutor;
 
@@ -56,12 +61,13 @@ public class SetTagForEntityExecutor implements ISetTagForEntityExecutor
     @Override
     public void setTags(IOperationContext context, IEntityWithMetaprojects entity, Collection<? extends ITagId> tagIds)
     {
+        TagAuthorization authorization = new TagAuthorization(context, daoFactory);
         Map<ITagId, MetaprojectPE> tagMap = mapTagByIdExecutor.map(context, tagIds);
         Set<MetaprojectPE> tags = new HashSet<MetaprojectPE>(tagMap.values());
 
         for (MetaprojectPE existingTag : entity.getMetaprojects())
         {
-            if (false == tags.contains(existingTag))
+            if (false == tags.contains(existingTag) && authorization.canAccess(existingTag))
             {
                 entity.removeMetaproject(existingTag);
             }
@@ -78,6 +84,7 @@ public class SetTagForEntityExecutor implements ISetTagForEntityExecutor
                     tag = createTagExecutor.createTag(context, tagId);
                 }
 
+                authorization.checkAccess(tag);
                 entity.addMetaproject(tag);
             }
         }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/AbstractGenerator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/AbstractGenerator.java
index 9921475c53a2dd7d8278eba5fd95d1de0a4bd5ad..effa1b83cbc753798cef5c4ce5e020c5d0143f3d 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/AbstractGenerator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/AbstractGenerator.java
@@ -10,12 +10,14 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.fetchoptions.Attachme
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IAttachmentsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModificationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModifierHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPermIdHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPropertiesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistrationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistratorHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISampleHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISpaceHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ITagsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
@@ -69,12 +71,12 @@ public class AbstractGenerator
 
     public static void addExperiment(DtoGenerator gen)
     {
-        gen.addFetchedField(Experiment.class, "experiment", "Experiment", ExperimentFetchOptions.class);
+        gen.addFetchedField(Experiment.class, "experiment", "Experiment", ExperimentFetchOptions.class).withInterface(IExperimentHolder.class);
     }
 
     public static void addSample(DtoGenerator gen)
     {
-        gen.addFetchedField(Sample.class, "sample", "Sample", SampleFetchOptions.class);
+        gen.addFetchedField(Sample.class, "sample", "Sample", SampleFetchOptions.class).withInterface(ISampleHolder.class);
     }
 
     public static void addSpace(DtoGenerator gen)
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/Generator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/Generator.java
index 217e8981b95ee50eceddc7b1db932f02c9e67482..5f7797f98c00d30f94b29a0fe33de6c9706474f4 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/Generator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/generators/Generator.java
@@ -9,7 +9,14 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.Attachment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.fetchoptions.AttachmentFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.fetchoptions.EmptyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IDataSetsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IMaterialsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IOwnerHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IParentChildrenHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IProjectHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IProjectsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISamplesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.ArchivingStatus;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.Complete;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
@@ -104,7 +111,8 @@ public class Generator extends AbstractGenerator
                 .withInterfaceReflexive(IParentChildrenHolder.class);
         gen.addFetchedField(Sample.class, "container", "Container sample", SampleFetchOptions.class);
         gen.addPluralFetchedField("List<Sample>", List.class.getName(), "components", "Component samples", SampleFetchOptions.class);
-        gen.addPluralFetchedField("List<DataSet>", List.class.getName(), "dataSets", "Data sets", DataSetFetchOptions.class);
+        gen.addPluralFetchedField("List<DataSet>", List.class.getName(), "dataSets", "Data sets", DataSetFetchOptions.class)
+                .withInterface(IDataSetsHolder.class);
         gen.addClassForImport(DataSet.class);
         gen.addPluralFetchedField("List<HistoryEntry>", List.class.getName(), "history", "History", HistoryEntryFetchOptions.class);
         gen.addClassForImport(HistoryEntry.class);
@@ -182,12 +190,14 @@ public class Generator extends AbstractGenerator
         addModificationDate(gen);
 
         gen.addFetchedField(ExperimentType.class, "type", "Experiment type", ExperimentTypeFetchOptions.class);
-        gen.addFetchedField(Project.class, "project", "Project", ProjectFetchOptions.class);
+        gen.addFetchedField(Project.class, "project", "Project", ProjectFetchOptions.class).withInterface(IProjectHolder.class);
 
-        gen.addPluralFetchedField("List<DataSet>", List.class.getName(), "dataSets", "Data sets", DataSetFetchOptions.class);
+        gen.addPluralFetchedField("List<DataSet>", List.class.getName(), "dataSets", "Data sets", DataSetFetchOptions.class)
+                .withInterface(IDataSetsHolder.class);
         gen.addClassForImport(DataSet.class);
 
-        gen.addPluralFetchedField("List<Sample>", List.class.getName(), "samples", "Samples", SampleFetchOptions.class);
+        gen.addPluralFetchedField("List<Sample>", List.class.getName(), "samples", "Samples", SampleFetchOptions.class)
+                .withInterface(ISamplesHolder.class);
         gen.addClassForImport(Sample.class);
 
         gen.addPluralFetchedField("List<HistoryEntry>", List.class.getName(), "history", "History", HistoryEntryFetchOptions.class);
@@ -431,7 +441,8 @@ public class Generator extends AbstractGenerator
         addRegistrationDate(gen);
         addModificationDate(gen);
 
-        gen.addPluralFetchedField("List<Experiment>", List.class.getName(), "experiments", "Experiments", ExperimentFetchOptions.class);
+        gen.addPluralFetchedField("List<Experiment>", List.class.getName(), "experiments", "Experiments", ExperimentFetchOptions.class)
+                .withInterface(IExperimentsHolder.class);
         gen.addClassForImport(Experiment.class);
         // TODO: project samples
         // gen.addPluralFetchedField("List<Sample>", List.class.getName(), "samples", "Samples", SampleFetchOptions.class);
@@ -461,9 +472,11 @@ public class Generator extends AbstractGenerator
         addRegistrationDate(gen);
         addModificationDate(gen);
         addRegistrator(gen);
-        gen.addPluralFetchedField("List<Sample>", List.class.getName(), "samples", "Samples", SampleFetchOptions.class);
+        gen.addPluralFetchedField("List<Sample>", List.class.getName(), "samples", "Samples", SampleFetchOptions.class)
+                .withInterface(ISamplesHolder.class);
         gen.addClassForImport(Sample.class);
-        gen.addPluralFetchedField("List<Project>", List.class.getName(), "projects", "Projects", ProjectFetchOptions.class);
+        gen.addPluralFetchedField("List<Project>", List.class.getName(), "projects", "Projects", ProjectFetchOptions.class)
+                .withInterface(IProjectsHolder.class);
         gen.addClassForImport(Project.class);
 
         gen.setToStringMethod("\"Space \" + permId");
@@ -479,9 +492,25 @@ public class Generator extends AbstractGenerator
         addCode(gen);
         addDescription(gen);
         gen.addSimpleField(Boolean.class, "private", "isPrivate");
-        addRegistrationDate(gen);
 
-        gen.addFetchedField(Person.class, "owner", "Owner", PersonFetchOptions.class);
+        gen.addPluralFetchedField("List<Experiment>", List.class.getName(), "experiments", "Experiments", ExperimentFetchOptions.class)
+                .withInterface(IExperimentsHolder.class);
+        gen.addClassForImport(Experiment.class);
+
+        gen.addPluralFetchedField("List<Sample>", List.class.getName(), "samples", "Samples", SampleFetchOptions.class)
+                .withInterface(ISamplesHolder.class);
+        gen.addClassForImport(Sample.class);
+
+        gen.addPluralFetchedField("List<DataSet>", List.class.getName(), "dataSets", "Data sets", DataSetFetchOptions.class)
+                .withInterface(IDataSetsHolder.class);
+        gen.addClassForImport(DataSet.class);
+
+        gen.addPluralFetchedField("List<Material>", List.class.getName(), "materials", "Materials", MaterialFetchOptions.class)
+                .withInterface(IMaterialsHolder.class);
+        gen.addClassForImport(Material.class);
+
+        addRegistrationDate(gen);
+        gen.addFetchedField(Person.class, "owner", "Owner", PersonFetchOptions.class).withInterface(IOwnerHolder.class);
 
         gen.setToStringMethod("\"Tag \" + code");
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/tag/TagAuthorization.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/tag/TagAuthorization.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ee88b04f6b1121436c44151da6f69ce81dda503
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/tag/TagAuthorization.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.helper.tag;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.UnauthorizedObjectAccessException;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationServiceUtils;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+public class TagAuthorization
+{
+
+    private AuthorizationServiceUtils service;
+
+    public TagAuthorization(IOperationContext context, IDAOFactory daoFactory)
+    {
+        this.service = new AuthorizationServiceUtils(daoFactory, context.getSession().tryGetPerson());
+    }
+
+    public void checkAccess(MetaprojectPE tag)
+    {
+        try
+        {
+            service.checkAccessMetaproject(tag);
+        } catch (AuthorizationFailureException e)
+        {
+            throw new UnauthorizedObjectAccessException(new TagPermId(tag.getOwner().getUserId(), tag.getName()));
+        }
+    }
+
+    public boolean canAccess(MetaprojectPE tag)
+    {
+        return service.canAccessMetaproject(tag);
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/DataSetHistoryTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/DataSetHistoryTranslator.java
index af941583fc70ebe823f8f2574a4b0d2b318d316a..6d76edb66e99a7f9d6e59e9f6995f9b4c02be75f 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/DataSetHistoryTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/DataSetHistoryTranslator.java
@@ -20,7 +20,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.history.DataSetRelationType;
@@ -33,7 +32,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SamplePermId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.history.HistoryPropertyRecord;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.history.HistoryRelationshipRecord;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.history.HistoryTranslator;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.RelationType;
 
 import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
@@ -46,9 +44,6 @@ import net.lemnik.eodsql.QueryTool;
 public class DataSetHistoryTranslator extends HistoryTranslator implements IDataSetHistoryTranslator
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
-
     @Override
     protected List<HistoryPropertyRecord> loadPropertyHistory(Collection<Long> entityIds)
     {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/ObjectToDataSetsTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/ObjectToDataSetsTranslator.java
index c1ddb1a39cb921e8ca013fe8de417e83958060e4..3b41a2c846f94d83ab800bbcc44c71d47354da95 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/ObjectToDataSetsTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/dataset/ObjectToDataSetsTranslator.java
@@ -26,7 +26,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.TranslationContext;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectToManyRelationTranslator;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 
 /**
  * @author pkupczyk
@@ -35,9 +34,6 @@ public abstract class ObjectToDataSetsTranslator extends ObjectToManyRelationTra
         IObjectToDataSetsTranslator
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
-
     @Autowired
     private IDataSetTranslator dataSetTranslator;
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/experiment/ObjectToExperimentsTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/experiment/ObjectToExperimentsTranslator.java
index b3d2782748a4c01a3b762df1d90acfda53dbf242..07505a606889373efc9f65cf693203358a097c05 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/experiment/ObjectToExperimentsTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/experiment/ObjectToExperimentsTranslator.java
@@ -26,7 +26,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentFetchOptions;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.TranslationContext;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectToManyRelationTranslator;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 
 /**
  * @author pkupczyk
@@ -35,9 +34,6 @@ public abstract class ObjectToExperimentsTranslator extends ObjectToManyRelation
         IObjectToExperimentsTranslator
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
-
     @Autowired
     private IExperimentTranslator experimentTranslator;
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/material/IObjectToMaterialsTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/material/IObjectToMaterialsTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..f97a1d005afaced2aceb344c1c5465328c223e8b
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/material/IObjectToMaterialsTranslator.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.material;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.fetchoptions.MaterialFetchOptions;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.IObjectToManyRelationTranslator;
+
+/**
+ * @author pkupczyk
+ */
+public interface IObjectToMaterialsTranslator extends IObjectToManyRelationTranslator<Material, MaterialFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/material/ObjectToMaterialsTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/material/ObjectToMaterialsTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..62458206cdcb15e00eda17961ded668e37c53f88
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/material/ObjectToMaterialsTranslator.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.material;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.fetchoptions.MaterialFetchOptions;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.TranslationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectToManyRelationTranslator;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class ObjectToMaterialsTranslator extends ObjectToManyRelationTranslator<Material, MaterialFetchOptions> implements
+        IObjectToMaterialsTranslator
+{
+
+    @Autowired
+    private IMaterialTranslator materialTranslator;
+
+    @Override
+    protected Map<Long, Material> translateRelated(TranslationContext context, Collection<Long> relatedIds,
+            MaterialFetchOptions relatedFetchOptions)
+    {
+        return materialTranslator.translate(context, relatedIds, relatedFetchOptions);
+    }
+
+    @Override
+    protected Collection<Material> createCollection()
+    {
+        return new ArrayList<Material>();
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/project/ProjectTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/project/ProjectTranslator.java
index 1940d24762585f5c1992d7580c8a20b7ec9f7d34..a6bf0de5e81f22e6de2eba903242d72c14ae320e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/project/ProjectTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/project/ProjectTranslator.java
@@ -52,8 +52,9 @@ public class ProjectTranslator extends AbstractCachingTranslator<Long, Project,
     @Autowired
     private IProjectExperimentTranslator experimentTranslator;
 
-    @Autowired
-    private IProjectSampleTranslator sampleTranslator;
+    // TODO : project samples
+    // @Autowired
+    // private IProjectSampleTranslator sampleTranslator;
 
     @Autowired
     private IProjectRegistratorTranslator registratorTranslator;
@@ -102,10 +103,10 @@ public class ProjectTranslator extends AbstractCachingTranslator<Long, Project,
         }
 
         // TODO: project samples
-//        if (fetchOptions.hasSamples())
-//        {
-//            relations.put(IProjectSampleTranslator.class, sampleTranslator.translate(context, projectIds, fetchOptions.withSamples()));
-//        }
+        // if (fetchOptions.hasSamples())
+        // {
+        // relations.put(IProjectSampleTranslator.class, sampleTranslator.translate(context, projectIds, fetchOptions.withSamples()));
+        // }
 
         if (fetchOptions.hasRegistrator())
         {
@@ -162,11 +163,11 @@ public class ProjectTranslator extends AbstractCachingTranslator<Long, Project,
         }
 
         // TODO: project samples
-//        if (fetchOptions.hasSamples())
-//        {
-//            result.setSamples((List<Sample>) relations.get(IProjectSampleTranslator.class, projectId));
-//            result.getFetchOptions().withSamplesUsing(fetchOptions.withSamples());
-//        }
+        // if (fetchOptions.hasSamples())
+        // {
+        // result.setSamples((List<Sample>) relations.get(IProjectSampleTranslator.class, projectId));
+        // result.getFetchOptions().withSamplesUsing(fetchOptions.withSamples());
+        // }
 
         if (fetchOptions.hasRegistrator())
         {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/sample/SampleTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/sample/SampleTranslator.java
index 275481480de30b687adf632947a57f4bc322b360..44fe1042bcb82a9a7b2ebaf4936c4abaf6dcfd0c 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/sample/SampleTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/sample/SampleTranslator.java
@@ -53,8 +53,9 @@ public class SampleTranslator extends AbstractCachingTranslator<Long, Sample, Sa
     @Autowired
     private ISampleSpaceTranslator spaceTranslator;
 
-    @Autowired
-    private ISampleProjectTranslator projectTranslator;
+    // TODO: project samples
+    // @Autowired
+    // private ISampleProjectTranslator projectTranslator;
 
     @Autowired
     private ISamplePropertyTranslator propertyTranslator;
@@ -127,10 +128,10 @@ public class SampleTranslator extends AbstractCachingTranslator<Long, Sample, Sa
         }
 
         // TODO: project samples
-//        if (fetchOptions.hasProject())
-//        {
-//            relations.put(ISampleProjectTranslator.class, projectTranslator.translate(context, sampleIds, fetchOptions.withProject()));
-//        }
+        // if (fetchOptions.hasProject())
+        // {
+        // relations.put(ISampleProjectTranslator.class, projectTranslator.translate(context, sampleIds, fetchOptions.withProject()));
+        // }
 
         if (fetchOptions.hasProperties())
         {
@@ -210,9 +211,9 @@ public class SampleTranslator extends AbstractCachingTranslator<Long, Sample, Sa
         result.setPermId(new SamplePermId(baseRecord.permId));
         result.setCode(baseRecord.code);
         // TODO: project samples
-//        result.setIdentifier(new SampleIdentifier(baseRecord.spaceCode, baseRecord.projectCode,
-//                baseRecord.containerCode, baseRecord.code));
-        result.setIdentifier(new SampleIdentifier(baseRecord.spaceCode, 
+        // result.setIdentifier(new SampleIdentifier(baseRecord.spaceCode, baseRecord.projectCode,
+        // baseRecord.containerCode, baseRecord.code));
+        result.setIdentifier(new SampleIdentifier(baseRecord.spaceCode,
                 baseRecord.containerCode, baseRecord.code));
         result.setModificationDate(baseRecord.modificationDate);
         result.setRegistrationDate(baseRecord.registrationDate);
@@ -230,11 +231,11 @@ public class SampleTranslator extends AbstractCachingTranslator<Long, Sample, Sa
         }
 
         // TODO: project samples
-//        if (fetchOptions.hasProject())
-//        {
-//            result.setProject(relations.get(ISampleProjectTranslator.class, sampleId));
-//            result.getFetchOptions().withProjectUsing(fetchOptions.withProject());
-//        }
+        // if (fetchOptions.hasProject())
+        // {
+        // result.setProject(relations.get(ISampleProjectTranslator.class, sampleId));
+        // result.getFetchOptions().withProjectUsing(fetchOptions.withProject());
+        // }
 
         if (fetchOptions.hasProperties())
         {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagAuthorizationValidator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagAuthorizationValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..4cbec5a2ab3db0a07e42d5104d28740010adeed6
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagAuthorizationValidator.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.IObjectAuthorizationValidator;
+
+/**
+ * @author pkupczyk
+ */
+public interface ITagAuthorizationValidator extends IObjectAuthorizationValidator
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagDataSetTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagDataSetTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..603b5e5b91a5b764d2d04e9456d8db0c7de78f1e
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagDataSetTranslator.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.dataset.IObjectToDataSetsTranslator;
+
+/**
+ * @author pkupczyk
+ */
+public interface ITagDataSetTranslator extends IObjectToDataSetsTranslator
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagExperimentTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagExperimentTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce5fba65fc981fc8193fb37715a3f7a44e98d8fc
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagExperimentTranslator.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.experiment.IObjectToExperimentsTranslator;
+
+/**
+ * @author pkupczyk
+ */
+public interface ITagExperimentTranslator extends IObjectToExperimentsTranslator
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagMaterialTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagMaterialTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..959a1a49dbb504f5c3aa16f301548124773b255d
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagMaterialTranslator.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.material.IObjectToMaterialsTranslator;
+
+/**
+ * @author pkupczyk
+ */
+public interface ITagMaterialTranslator extends IObjectToMaterialsTranslator
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagSampleTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagSampleTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c086307960443ca4986233d3b06f1c1eb622b00e
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/ITagSampleTranslator.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.sample.IObjectToSamplesTranslator;
+
+/**
+ * @author pkupczyk
+ */
+public interface ITagSampleTranslator extends IObjectToSamplesTranslator
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagAuthorizationValidator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagAuthorizationValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..488547cf6b61dad53a63ec4651f906edc499c9b6
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagAuthorizationValidator.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.stereotype.Component;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import net.lemnik.eodsql.QueryTool;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class TagAuthorizationValidator implements ITagAuthorizationValidator
+{
+
+    @Override
+    public Set<Long> validate(PersonPE person, Collection<Long> tagIds)
+    {
+        TagQuery query = QueryTool.getManagedQuery(TagQuery.class);
+        List<TagAuthorizationRecord> records = query.getAuthorizations(new LongOpenHashSet(tagIds));
+        Set<Long> result = new HashSet<Long>();
+
+        for (TagAuthorizationRecord record : records)
+        {
+            if (record.isPublic || record.owner.equals(person.getUserId()))
+            {
+                result.add(record.id);
+            }
+        }
+
+        return result;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagDataSetTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagDataSetTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..4462f133658e6e4ca73b0c1341ff22b132cfbe19
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagDataSetTranslator.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import java.util.List;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectRelationRecord;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.dataset.ObjectToDataSetsTranslator;
+
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import net.lemnik.eodsql.QueryTool;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class TagDataSetTranslator extends ObjectToDataSetsTranslator implements ITagDataSetTranslator
+{
+
+    @Override
+    protected List<ObjectRelationRecord> loadRecords(LongOpenHashSet objectIds)
+    {
+        TagQuery query = QueryTool.getManagedQuery(TagQuery.class);
+        return query.getDataSetIds(new LongOpenHashSet(objectIds));
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagExperimentTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagExperimentTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..f38a799685ac65bedd6d73f0c2b4ce3b619ee1f4
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagExperimentTranslator.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+
+import java.util.List;
+
+import net.lemnik.eodsql.QueryTool;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectRelationRecord;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.experiment.ObjectToExperimentsTranslator;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class TagExperimentTranslator extends ObjectToExperimentsTranslator implements ITagExperimentTranslator
+{
+
+    @Override
+    protected List<ObjectRelationRecord> loadRecords(LongOpenHashSet objectIds)
+    {
+        TagQuery query = QueryTool.getManagedQuery(TagQuery.class);
+        return query.getExperimentIds(new LongOpenHashSet(objectIds));
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagMaterialTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagMaterialTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..3125f9ff6c1159fc652844101559e9b5444128ef
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagMaterialTranslator.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import java.util.List;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectRelationRecord;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.material.ObjectToMaterialsTranslator;
+
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import net.lemnik.eodsql.QueryTool;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class TagMaterialTranslator extends ObjectToMaterialsTranslator implements ITagMaterialTranslator
+{
+
+    @Override
+    protected List<ObjectRelationRecord> loadRecords(LongOpenHashSet objectIds)
+    {
+        TagQuery query = QueryTool.getManagedQuery(TagQuery.class);
+        return query.getMaterialIds(new LongOpenHashSet(objectIds));
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagQuery.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagQuery.java
index f3e8eb0425931b2da9428bcb7af1d5841fa9972c..e098467cc2c82bc78041cc4c9e72c7731e62236a 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagQuery.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagQuery.java
@@ -16,17 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
 
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
-import it.unimi.dsi.fastutil.longs.LongSet;
-
 import java.util.List;
 
-import net.lemnik.eodsql.Select;
-
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectQuery;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectRelationRecord;
 import ch.systemsx.cisd.common.db.mapper.LongSetMapper;
 
+import it.unimi.dsi.fastutil.longs.LongSet;
+import net.lemnik.eodsql.Select;
+
 /**
  * @author pkupczyk
  */
@@ -34,14 +32,32 @@ public interface TagQuery extends ObjectQuery
 {
 
     @Select(sql = "select m.id, m.name, m.description, p.user_id as owner, m.private as isPrivate, m.creation_date as registrationDate from "
-            + "metaprojects m, persons p where m.owner = p.id and m.id = any(?{1})", parameterBindings = { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+            + "metaprojects m, persons p where m.owner = p.id and m.id = any(?{1})", parameterBindings = {
+                    LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public List<TagBaseRecord> getTags(LongSet tagIds);
 
     @Select(sql = "select m.id, p.user_id as owner, not m.private as isPublic from metaprojects m, persons p where "
             + "m.owner = p.id and m.id = any(?{1})", parameterBindings = { LongSetMapper.class }, fetchSize = FETCH_SIZE)
-    public List<TagAuthorizationRecord> getAuthorizations(LongOpenHashSet tagIds);
+    public List<TagAuthorizationRecord> getAuthorizations(LongSet tagIds);
+
+    @Select(sql = "select m.id as objectId, m.owner as relatedId from metaprojects m where m.id = any(?{1})", parameterBindings = {
+            LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public List<ObjectRelationRecord> getOwnerIds(LongSet tagIds);
+
+    @Select(sql = "select ma.mepr_id as objectId, ma.expe_id as relatedId from metaproject_assignments ma where ma.mepr_id = any(?{1}) and ma.expe_id is not null", parameterBindings = {
+            LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public List<ObjectRelationRecord> getExperimentIds(LongSet tagIds);
+
+    @Select(sql = "select ma.mepr_id as objectId, ma.samp_id as relatedId from metaproject_assignments ma where ma.mepr_id = any(?{1}) and ma.samp_id is not null", parameterBindings = {
+            LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public List<ObjectRelationRecord> getSampleIds(LongSet tagIds);
+
+    @Select(sql = "select ma.mepr_id as objectId, ma.data_id as relatedId from metaproject_assignments ma where ma.mepr_id = any(?{1}) and ma.data_id is not null", parameterBindings = {
+            LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public List<ObjectRelationRecord> getDataSetIds(LongSet tagIds);
 
-    @Select(sql = "select m.id as objectId, m.owner as relatedId from metaprojects m where m.id = any(?{1})", parameterBindings = { LongSetMapper.class }, fetchSize = FETCH_SIZE)
-    public List<ObjectRelationRecord> getOwnerIds(LongOpenHashSet tagIds);
+    @Select(sql = "select ma.mepr_id as objectId, ma.mate_id as relatedId from metaproject_assignments ma where ma.mepr_id = any(?{1}) and ma.mate_id is not null", parameterBindings = {
+            LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public List<ObjectRelationRecord> getMaterialIds(LongSet tagIds);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagSampleTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagSampleTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..97281cd1911ee8470b5d688a2402e2e0f53229dd
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagSampleTranslator.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
+
+import java.util.List;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.common.ObjectRelationRecord;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.sample.ObjectToSamplesTranslator;
+
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import net.lemnik.eodsql.QueryTool;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class TagSampleTranslator extends ObjectToSamplesTranslator implements ITagSampleTranslator
+{
+
+    @Override
+    protected List<ObjectRelationRecord> loadRecords(LongOpenHashSet objectIds)
+    {
+        TagQuery query = QueryTool.getManagedQuery(TagQuery.class);
+        return query.getSampleIds(new LongOpenHashSet(objectIds));
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagTranslator.java
index e02aff46b699966e0034e3b4233cb2c852369fc5..c1c48ebec4b83a58f910d348defbb52c8b5b3652 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/entity/tag/TagTranslator.java
@@ -16,18 +16,17 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.entity.tag;
 
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
-
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import net.lemnik.eodsql.QueryTool;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
@@ -42,28 +41,31 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.TranslationResults
 public class TagTranslator extends AbstractCachingTranslator<Long, Tag, TagFetchOptions> implements ITagTranslator
 {
 
+    @Autowired
+    private ITagAuthorizationValidator authorizationValidator;
+
     @Autowired
     private ITagBaseTranslator baseTranslator;
 
     @Autowired
     private ITagOwnerTranslator ownerTranslator;
 
+    @Autowired
+    private ITagExperimentTranslator experimentTranslator;
+
+    @Autowired
+    private ITagSampleTranslator sampleTranslator;
+
+    @Autowired
+    private ITagDataSetTranslator dataSetTranslator;
+
+    @Autowired
+    private ITagMaterialTranslator materialTranslator;
+
     @Override
     protected Set<Long> shouldTranslate(TranslationContext context, Collection<Long> tagIds, TagFetchOptions fetchOptions)
     {
-        TagQuery query = QueryTool.getManagedQuery(TagQuery.class);
-        List<TagAuthorizationRecord> records = query.getAuthorizations(new LongOpenHashSet(tagIds));
-        Set<Long> result = new HashSet<Long>();
-
-        for (TagAuthorizationRecord record : records)
-        {
-            if (record.isPublic || record.owner.equals(context.getSession().tryGetPerson().getUserId()))
-            {
-                result.add(record.id);
-            }
-        }
-
-        return result;
+        return authorizationValidator.validate(context.getSession().tryGetPerson(), tagIds);
     }
 
     @Override
@@ -86,6 +88,26 @@ public class TagTranslator extends AbstractCachingTranslator<Long, Tag, TagFetch
             relations.put(ITagOwnerTranslator.class, ownerTranslator.translate(context, tagIds, fetchOptions.withOwner()));
         }
 
+        if (fetchOptions.hasExperiments())
+        {
+            relations.put(ITagExperimentTranslator.class, experimentTranslator.translate(context, tagIds, fetchOptions.withExperiments()));
+        }
+
+        if (fetchOptions.hasSamples())
+        {
+            relations.put(ITagSampleTranslator.class, sampleTranslator.translate(context, tagIds, fetchOptions.withSamples()));
+        }
+
+        if (fetchOptions.hasDataSets())
+        {
+            relations.put(ITagDataSetTranslator.class, dataSetTranslator.translate(context, tagIds, fetchOptions.withDataSets()));
+        }
+
+        if (fetchOptions.hasMaterials())
+        {
+            relations.put(ITagMaterialTranslator.class, materialTranslator.translate(context, tagIds, fetchOptions.withMaterials()));
+        }
+
         return relations;
     }
 
@@ -106,6 +128,30 @@ public class TagTranslator extends AbstractCachingTranslator<Long, Tag, TagFetch
             result.setOwner(relations.get(ITagOwnerTranslator.class, tagId));
             result.getFetchOptions().withOwnerUsing(fetchOptions.withOwner());
         }
+
+        if (fetchOptions.hasExperiments())
+        {
+            result.setExperiments((List<Experiment>) relations.get(ITagExperimentTranslator.class, tagId));
+            result.getFetchOptions().withExperimentsUsing(fetchOptions.withExperiments());
+        }
+
+        if (fetchOptions.hasSamples())
+        {
+            result.setSamples((List<Sample>) relations.get(ITagSampleTranslator.class, tagId));
+            result.getFetchOptions().withSamplesUsing(fetchOptions.withSamples());
+        }
+
+        if (fetchOptions.hasDataSets())
+        {
+            result.setDataSets((List<DataSet>) relations.get(ITagDataSetTranslator.class, tagId));
+            result.getFetchOptions().withDataSetsUsing(fetchOptions.withDataSets());
+        }
+
+        if (fetchOptions.hasMaterials())
+        {
+            result.setMaterials((List<Material>) relations.get(ITagMaterialTranslator.class, tagId));
+            result.getFetchOptions().withMaterialsUsing(fetchOptions.withMaterials());
+        }
     }
 
 }
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagCodeExecutorTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagIdentifierExecutorTest.java
similarity index 56%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagCodeExecutorTest.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagIdentifierExecutorTest.java
index d176f721edbbbdf5a6bb9297e22fd31c28c20d67..938da9a0d00cce5e91925bb3fadd8f73f91fa740 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagCodeExecutorTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/GetTagIdentifierExecutorTest.java
@@ -16,23 +16,22 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag;
 
-import junit.framework.Assert;
-
 import org.jmock.Expectations;
 import org.testng.annotations.Test;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagCode;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
-import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.UnauthorizedObjectAccessException;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.AbstractExecutorTest;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.GetTagCodeExecutor;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 
+import junit.framework.Assert;
+
 /**
  * @author pkupczyk
  */
-public class GetTagCodeExecutorTest extends AbstractExecutorTest
+public class GetTagIdentifierExecutorTest extends AbstractExecutorTest
 {
 
     @Test
@@ -49,11 +48,12 @@ public class GetTagCodeExecutorTest extends AbstractExecutorTest
                 }
             });
 
-        String code = execute(new TagPermId("/" + session.tryGetPerson().getUserId() + "/TEST_PERM_ID"));
-        Assert.assertEquals("TEST_PERM_ID", code);
+        MetaprojectIdentifier identifier = execute(new TagPermId("/" + session.tryGetPerson().getUserId() + "/TEST_PERM_ID"));
+        Assert.assertEquals("TEST_PERM_ID", identifier.getMetaprojectName());
+        Assert.assertEquals(session.tryGetPerson().getUserId(), identifier.getMetaprojectOwnerId());
     }
 
-    @Test(expectedExceptions = { UnauthorizedObjectAccessException.class }, expectedExceptionsMessageRegExp = ".*/OTHER_USER/TEST_PERM_ID.*")
+    @Test
     public void testWithPermIdForDifferentUser()
     {
         final Session session = createSession();
@@ -67,20 +67,34 @@ public class GetTagCodeExecutorTest extends AbstractExecutorTest
                 }
             });
 
-        execute(new TagPermId("/OTHER_USER/TEST_PERM_ID"));
+        MetaprojectIdentifier identifier = execute(new TagPermId("/OTHER_USER/TEST_PERM_ID"));
+        Assert.assertEquals("TEST_PERM_ID", identifier.getMetaprojectName());
+        Assert.assertEquals("OTHER_USER", identifier.getMetaprojectOwnerId());
     }
 
     @Test
     public void testWithNameId()
     {
-        String code = execute(new TagCode("TEST_NAME_ID"));
-        Assert.assertEquals("TEST_NAME_ID", code);
+        final Session session = createSession();
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(operationContext).getSession();
+                    will(returnValue(session));
+
+                }
+            });
+
+        MetaprojectIdentifier identifier = execute(new TagCode("TEST_NAME_ID"));
+        Assert.assertEquals("TEST_NAME_ID", identifier.getMetaprojectName());
+        Assert.assertEquals(session.tryGetPerson().getUserId(), identifier.getMetaprojectOwnerId());
     }
 
-    private String execute(ITagId tagId)
+    private MetaprojectIdentifier execute(ITagId tagId)
     {
-        GetTagCodeExecutor executor = new GetTagCodeExecutor();
-        return executor.getTagCode(operationContext, tagId);
+        GetTagIdentifierExecutor executor = new GetTagIdentifierExecutor();
+        return executor.getIdentifier(operationContext, tagId);
     }
 
 }
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutorTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutorTest.java
index 432872fccac3f3b3d429086e7cce4a793dc47ea8..ff8621be173a899c36ffa31247b098d92fa862fe 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutorTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/MapTagByIdExecutorTest.java
@@ -30,10 +30,12 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagCode;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.AbstractExecutorTest;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.IGetTagCodeExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.IGetTagIdentifierExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.MapTagByIdExecutor;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMetaprojectDAO;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 
 /**
@@ -44,12 +46,12 @@ public class MapTagByIdExecutorTest extends AbstractExecutorTest
 
     private IMetaprojectDAO metaprojectDao;
 
-    private IGetTagCodeExecutor getTagCodeExecutor;
+    private IGetTagIdentifierExecutor getTagIdentifierExecutor;
 
     @Override
     protected void init()
     {
-        getTagCodeExecutor = context.mock(IGetTagCodeExecutor.class);
+        getTagIdentifierExecutor = context.mock(IGetTagIdentifierExecutor.class);
         metaprojectDao = context.mock(IMetaprojectDAO.class);
     }
 
@@ -79,10 +81,18 @@ public class MapTagByIdExecutorTest extends AbstractExecutorTest
         final MetaprojectPE tag1 = new MetaprojectPE();
         tag1.setName("TEST_TAG_1");
         tag1.setOwner(session.tryGetPerson());
+
         final MetaprojectPE tag2 = new MetaprojectPE();
         tag2.setName("TEST_TAG_2");
         tag2.setOwner(session.tryGetPerson());
 
+        PersonPE otherUser = new PersonPE();
+        otherUser.setUserId("OTHER_USER");
+
+        final MetaprojectPE tag3 = new MetaprojectPE();
+        tag3.setName("TEST_TAG_3");
+        tag3.setOwner(otherUser);
+
         Collection<ITagId> tagIds = new LinkedList<ITagId>();
         tagIds.add(tagId1);
         tagIds.add(tagId2);
@@ -97,36 +107,37 @@ public class MapTagByIdExecutorTest extends AbstractExecutorTest
                     allowing(daoFactory).getMetaprojectDAO();
                     will(returnValue(metaprojectDao));
 
-                    one(getTagCodeExecutor).getTagCode(operationContext, tagId1);
-                    will(returnValue("TEST_TAG_1"));
+                    one(getTagIdentifierExecutor).getIdentifier(operationContext, tagId1);
+                    will(returnValue(new MetaprojectIdentifier(session.tryGetPerson().getUserId(), "TEST_TAG_1")));
 
-                    one(getTagCodeExecutor).getTagCode(operationContext, tagId2);
-                    will(returnValue("TEST_TAG_2"));
+                    one(getTagIdentifierExecutor).getIdentifier(operationContext, tagId2);
+                    will(returnValue(new MetaprojectIdentifier(session.tryGetPerson().getUserId(), "TEST_TAG_2")));
 
-                    one(getTagCodeExecutor).getTagCode(operationContext, tagId3);
-                    will(returnValue("TEST_TAG_3"));
+                    one(getTagIdentifierExecutor).getIdentifier(operationContext, tagId3);
+                    will(returnValue(new MetaprojectIdentifier("OTHER_USER", "TEST_TAG_3")));
 
-                    one(metaprojectDao).tryFindByOwnerAndName("TEST_PERSON", "TEST_TAG_1");
+                    one(metaprojectDao).tryFindByOwnerAndName(session.tryGetPerson().getUserId(), "TEST_TAG_1");
                     will(returnValue(tag1));
 
-                    one(metaprojectDao).tryFindByOwnerAndName("TEST_PERSON", "TEST_TAG_2");
+                    one(metaprojectDao).tryFindByOwnerAndName(session.tryGetPerson().getUserId(), "TEST_TAG_2");
                     will(returnValue(tag2));
 
-                    one(metaprojectDao).tryFindByOwnerAndName("TEST_PERSON", "TEST_TAG_3");
-                    will(returnValue(null));
+                    one(metaprojectDao).tryFindByOwnerAndName("OTHER_USER", "TEST_TAG_3");
+                    will(returnValue(tag3));
                 }
             });
 
         Map<ITagId, MetaprojectPE> map = execute(tagIds);
 
-        Assert.assertEquals(2, map.size());
+        Assert.assertEquals(3, map.size());
         Assert.assertEquals(tag1, map.get(tagId1));
         Assert.assertEquals(tag2, map.get(tagId2));
+        Assert.assertEquals(tag3, map.get(tagId3));
     }
 
     private Map<ITagId, MetaprojectPE> execute(Collection<? extends ITagId> tagIds)
     {
-        MapTagByIdExecutor executor = new MapTagByIdExecutor(daoFactory, getTagCodeExecutor);
+        MapTagByIdExecutor executor = new MapTagByIdExecutor(daoFactory, getTagIdentifierExecutor);
         return executor.map(operationContext, tagIds);
     }
 
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
index 650d15f0ba1582ef62089e5053d050bf049eaac7..6b5bfb6528195ec95c4c5f99366c7322bfcfb919 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
@@ -50,10 +50,19 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.create.AttachmentCrea
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IAttachmentsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IDataSetsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IMaterialsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModifierHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IOwnerHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IParentChildrenHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IProjectHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IProjectsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPropertiesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistratorHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISampleHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISamplesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISpaceHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ITagsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
@@ -160,110 +169,122 @@ public class AbstractTest extends SystemTestCase
             });
     }
 
-    protected void assertSpaceNotFetched(final ISpaceHolder entity)
+    protected void assertSpaceNotFetched(final ISpaceHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    entity.getSpace();
+                    holder.getSpace();
                 }
             });
     }
 
-    protected void assertProjectNotFetched(final Experiment experiment)
+    protected void assertProjectNotFetched(final IProjectHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    experiment.getProject();
+                    holder.getProject();
                 }
             });
     }
 
-    protected void assertProjectsNotFetched(final Space space)
+    protected void assertProjectsNotFetched(final IProjectsHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    space.getProjects();
+                    holder.getProjects();
                 }
             });
     }
 
-    protected void assertExperimentsNotFetched(final Project project)
+    protected void assertExperimentsNotFetched(final IExperimentsHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    project.getExperiments();
+                    holder.getExperiments();
                 }
             });
     }
 
-    protected void assertTagsNotFetched(final ITagsHolder entity)
+    protected void assertTagsNotFetched(final ITagsHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    entity.getTags();
+                    holder.getTags();
                 }
             });
     }
 
-    protected void assertExperimentNotFetched(final Sample sample)
+    protected void assertExperimentNotFetched(final IExperimentHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    sample.getExperiment();
+                    holder.getExperiment();
                 }
             });
     }
 
-    protected void assertExperimentNotFetched(final DataSet dataSet)
+    protected void assertSampleNotFetched(final ISampleHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    dataSet.getExperiment();
+                    holder.getSample();
                 }
             });
     }
 
-    protected void assertSampleNotFetched(final DataSet dataSet)
+    protected void assertSamplesNotFetched(final ISamplesHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    dataSet.getSample();
+                    holder.getSamples();
                 }
             });
     }
 
-    protected void assertSamplesNotFetched(final Space space)
+    protected void assertDataSetsNotFetched(final IDataSetsHolder holder)
     {
         assertNotFetched(new IDelegatedAction()
             {
                 @Override
                 public void execute()
                 {
-                    space.getSamples();
+                    holder.getDataSets();
+                }
+            });
+    }
+
+    protected void assertMaterialsNotFetched(final IMaterialsHolder holder)
+    {
+        assertNotFetched(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    holder.getMaterials();
                 }
             });
     }
@@ -364,6 +385,18 @@ public class AbstractTest extends SystemTestCase
             });
     }
 
+    protected void assertOwnerNotFetched(final IOwnerHolder holder)
+    {
+        assertNotFetched(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    holder.getOwner();
+                }
+            });
+    }
+
     protected void assertRegistratorNotFetched(final IRegistratorHolder entity)
     {
         assertNotFetched(new IDelegatedAction()
@@ -694,7 +727,7 @@ public class AbstractTest extends SystemTestCase
         throw new AssertionError("No property '" + code + "' found in " + codes);
     }
 
-    protected void assertOrder(List<PropertyAssignment> propertyAssignments, String...codes)
+    protected void assertOrder(List<PropertyAssignment> propertyAssignments, String... codes)
     {
         Set<String> codesSet = new LinkedHashSet<>(Arrays.asList(codes));
         List<String> propertyCodes = new ArrayList<>();
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/MapTagTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/MapTagTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4521dd0c857f25fb63bae7f36d28cede086a44c6
--- /dev/null
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/MapTagTest.java
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2014 ETH Zuerich, Scientific IT Services
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.systemtest.asapi.v3;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.id.MaterialPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagCode;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
+
+/**
+ * @author pkupczyk
+ */
+public class MapTagTest extends AbstractTest
+{
+
+    @Test
+    public void testMapByPermId()
+    {
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+
+        TagPermId permId1 = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+        TagPermId permId2 = new TagPermId(TEST_USER, "ANOTHER_TEST_METAPROJECTS");
+
+        Map<ITagId, Tag> map =
+                v3api.mapTags(sessionToken, Arrays.asList(permId1, permId2),
+                        new TagFetchOptions());
+
+        assertEquals(2, map.size());
+
+        Iterator<Tag> iter = map.values().iterator();
+        assertEquals(iter.next().getPermId(), permId1);
+        assertEquals(iter.next().getPermId(), permId2);
+
+        assertEquals(map.get(permId1).getPermId(), permId1);
+        assertEquals(map.get(permId2).getPermId(), permId2);
+
+        v3api.logout(sessionToken);
+    }
+
+    @Test
+    public void testMapByCode()
+    {
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+
+        TagCode code1 = new TagCode("TEST_METAPROJECTS");
+        TagCode code2 = new TagCode("ANOTHER_TEST_METAPROJECTS");
+
+        Map<ITagId, Tag> map =
+                v3api.mapTags(sessionToken, Arrays.asList(code1, code2),
+                        new TagFetchOptions());
+
+        assertEquals(2, map.size());
+
+        Iterator<Tag> iter = map.values().iterator();
+        assertEquals(iter.next().getCode(), code1.getCode());
+        assertEquals(iter.next().getCode(), code2.getCode());
+
+        assertEquals(map.get(code1).getCode(), code1.getCode());
+        assertEquals(map.get(code2).getCode(), code2.getCode());
+
+        v3api.logout(sessionToken);
+    }
+
+    @Test
+    public void testMapByPermIdCaseSensitivity()
+    {
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+
+        // user name is case sensitive, code is case insensitive
+        TagPermId permId1 = new TagPermId("teST", "TEST_METAPROJECTS");
+        TagPermId permId2 = new TagPermId("test", "TEST_METAPROJECTS");
+        TagPermId permId3 = new TagPermId("test", "ANOTHER_test_METAPROJECTS");
+
+        Map<ITagId, Tag> map =
+                v3api.mapTags(sessionToken, Arrays.asList(permId1, permId2, permId3),
+                        new TagFetchOptions());
+
+        assertEquals(2, map.size());
+
+        Iterator<Tag> iter = map.values().iterator();
+        assertEquals(iter.next().getPermId(), permId2);
+        assertEquals(iter.next().getPermId(), permId3);
+
+        assertEquals(map.get(permId2).getPermId(), permId2);
+        assertEquals(map.get(permId3).getPermId(), permId3);
+
+        v3api.logout(sessionToken);
+    }
+
+    @Test
+    public void testMapByCodeCaseSensitivity()
+    {
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+
+        // code is case insensitive
+        TagCode code1 = new TagCode("TEST_metaprojects");
+        TagCode code2 = new TagCode("ANOTHER_test_METAPROJECTS");
+
+        Map<ITagId, Tag> map =
+                v3api.mapTags(sessionToken, Arrays.asList(code1, code2),
+                        new TagFetchOptions());
+
+        assertEquals(2, map.size());
+
+        Iterator<Tag> iter = map.values().iterator();
+        assertEquals(iter.next().getCode(), code1.getCode());
+        assertEquals(iter.next().getCode(), code2.getCode());
+
+        assertEquals(map.get(code1).getCode(), code1.getCode());
+        assertEquals(map.get(code2).getCode(), code2.getCode());
+
+        v3api.logout(sessionToken);
+    }
+
+    @Test
+    public void testMapByIdsNonexistent()
+    {
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+
+        TagPermId permId1 = new TagPermId(TEST_USER, "IDONTEXIST");
+        TagPermId permId2 = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+        TagCode code = new TagCode("IDONTEXIST");
+
+        Map<ITagId, Tag> map =
+                v3api.mapTags(sessionToken,
+                        Arrays.asList(permId1, permId2, code),
+                        new TagFetchOptions());
+
+        assertEquals(1, map.size());
+
+        Iterator<Tag> iter = map.values().iterator();
+        assertEquals(iter.next().getPermId(), permId2);
+        assertEquals(map.get(permId2).getPermId(), permId2);
+
+        v3api.logout(sessionToken);
+    }
+
+    @Test
+    public void testMapByIdsDuplicated()
+    {
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+
+        TagPermId permId = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+        TagCode code = new TagCode("TEST_METAPROJECTS");
+
+        Map<ITagId, Tag> map =
+                v3api.mapTags(sessionToken, Arrays.asList(permId, code), new TagFetchOptions());
+
+        assertEquals(2, map.size());
+
+        assertEquals(map.get(permId).getPermId(), permId);
+        assertEquals(map.get(code).getCode(), code.getCode());
+
+        v3api.logout(sessionToken);
+    }
+
+    @Test
+    public void testMapByIdsUnauthorized()
+    {
+        TagPermId permId1 = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+        TagPermId permId2 = new TagPermId(TEST_POWER_USER_CISD, "TEST_METAPROJECTS");
+
+        List<? extends ITagId> ids = Arrays.asList(permId1, permId2);
+
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, ids, new TagFetchOptions());
+
+        assertEquals(map.size(), 1);
+        assertEquals(map.get(permId1).getPermId(), permId1);
+        assertEquals(map.get(permId2), null);
+
+        v3api.logout(sessionToken);
+
+        sessionToken = v3api.login(TEST_POWER_USER_CISD, PASSWORD);
+        map = v3api.mapTags(sessionToken, ids, new TagFetchOptions());
+
+        assertEquals(map.size(), 1);
+        assertEquals(map.get(permId2).getPermId(), permId2);
+        assertEquals(map.get(permId1), null);
+
+        v3api.logout(sessionToken);
+    }
+
+    @Test
+    public void testMapByIdsWithFetchOptionsEmpty()
+    {
+        TagPermId permId = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+
+        TagFetchOptions fetchOptions = new TagFetchOptions();
+
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, Arrays.asList(permId), fetchOptions);
+
+        Tag tag = map.get(permId);
+
+        assertEquals(tag.getPermId(), permId);
+        assertEquals(tag.getCode(), "TEST_METAPROJECTS");
+        assertEquals(tag.getDescription(), "Example metaproject no. 1");
+        assertTrue(tag.isPrivate());
+
+        assertOwnerNotFetched(tag);
+        assertExperimentsNotFetched(tag);
+        assertSamplesNotFetched(tag);
+        assertDataSetsNotFetched(tag);
+        assertMaterialsNotFetched(tag);
+    }
+
+    @Test
+    public void testMapByIdsWithOwner()
+    {
+        TagPermId permId = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+
+        TagFetchOptions fetchOptions = new TagFetchOptions();
+        fetchOptions.withOwner();
+
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, Arrays.asList(permId), fetchOptions);
+
+        Tag tag = map.get(permId);
+
+        assertEquals(tag.getPermId(), permId);
+        assertEquals(tag.getCode(), "TEST_METAPROJECTS");
+        assertEquals(tag.getDescription(), "Example metaproject no. 1");
+        assertTrue(tag.isPrivate());
+        assertEquals(tag.getOwner().getUserId(), TEST_USER);
+
+        assertExperimentsNotFetched(tag);
+        assertSamplesNotFetched(tag);
+        assertDataSetsNotFetched(tag);
+        assertMaterialsNotFetched(tag);
+    }
+
+    @Test
+    public void testMapByIdsWithExperiments()
+    {
+        TagPermId permId = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+
+        TagFetchOptions fetchOptions = new TagFetchOptions();
+        fetchOptions.withExperiments();
+
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, Arrays.asList(permId), fetchOptions);
+
+        Tag tag = map.get(permId);
+
+        assertEquals(tag.getPermId(), permId);
+        assertEquals(tag.getCode(), "TEST_METAPROJECTS");
+        assertEquals(tag.getDescription(), "Example metaproject no. 1");
+        assertTrue(tag.isPrivate());
+        assertExperimentIdentifiers(tag.getExperiments(), "/CISD/NEMO/EXP11", "/TEST-SPACE/TEST-PROJECT/EXP-SPACE-TEST");
+
+        assertOwnerNotFetched(tag);
+        assertSamplesNotFetched(tag);
+        assertDataSetsNotFetched(tag);
+        assertMaterialsNotFetched(tag);
+    }
+
+    @Test
+    public void testMapByIdsWithSamples()
+    {
+        TagPermId permId = new TagPermId(TEST_SPACE_USER, "TEST_METAPROJECTS");
+
+        TagFetchOptions fetchOptions = new TagFetchOptions();
+        fetchOptions.withSamples();
+
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, Arrays.asList(permId), fetchOptions);
+
+        Tag tag = map.get(permId);
+
+        assertEquals(tag.getPermId(), permId);
+        assertEquals(tag.getCode(), "TEST_METAPROJECTS");
+        assertEquals(tag.getDescription(), "Example metaproject no. 1");
+        assertTrue(tag.isPrivate());
+        assertSampleIdentifiers(tag.getSamples(), "/TEST-SPACE/FV-TEST", "/TEST-SPACE/EV-TEST");
+
+        assertOwnerNotFetched(tag);
+        assertExperimentsNotFetched(tag);
+        assertDataSetsNotFetched(tag);
+        assertMaterialsNotFetched(tag);
+    }
+
+    @Test
+    public void testMapByIdsWithDataSets()
+    {
+        TagPermId permId = new TagPermId(TEST_SPACE_USER, "TEST_METAPROJECTS");
+
+        TagFetchOptions fetchOptions = new TagFetchOptions();
+        fetchOptions.withDataSets();
+
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, Arrays.asList(permId), fetchOptions);
+
+        Tag tag = map.get(permId);
+
+        assertEquals(tag.getPermId(), permId);
+        assertEquals(tag.getCode(), "TEST_METAPROJECTS");
+        assertEquals(tag.getDescription(), "Example metaproject no. 1");
+        assertTrue(tag.isPrivate());
+        assertDataSetCodes(tag.getDataSets(), "20120619092259000-22", "20120628092259000-24");
+
+        assertOwnerNotFetched(tag);
+        assertExperimentsNotFetched(tag);
+        assertSamplesNotFetched(tag);
+        assertMaterialsNotFetched(tag);
+    }
+
+    @Test
+    public void testMapByIdsWithMaterials()
+    {
+        TagPermId permId = new TagPermId(TEST_USER, "TEST_METAPROJECTS");
+
+        TagFetchOptions fetchOptions = new TagFetchOptions();
+        fetchOptions.withMaterials();
+
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, Arrays.asList(permId), fetchOptions);
+
+        Tag tag = map.get(permId);
+
+        assertEquals(tag.getPermId(), permId);
+        assertEquals(tag.getCode(), "TEST_METAPROJECTS");
+        assertEquals(tag.getDescription(), "Example metaproject no. 1");
+        assertTrue(tag.isPrivate());
+        assertMaterialPermIds(tag.getMaterials(), new MaterialPermId("AD3", "VIRUS"));
+
+        assertOwnerNotFetched(tag);
+        assertExperimentsNotFetched(tag);
+        assertSamplesNotFetched(tag);
+        assertDataSetsNotFetched(tag);
+    }
+
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
index 97d03e4edf29936d76ec67647fb8468a1a9b3c4b..37b42082b88505820239b6f3acffbe9044938686 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
@@ -92,6 +92,9 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.update.SpaceUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyTermDeletionOptions;
@@ -173,6 +176,8 @@ public interface IApplicationServerApi extends IRpcService
     public Map<IVocabularyTermId, VocabularyTerm> mapVocabularyTerms(String sessionToken, List<? extends IVocabularyTermId> vocabularyTermIds,
             VocabularyTermFetchOptions fetchOptions);
 
+    public Map<ITagId, Tag> mapTags(String sessionToken, List<? extends ITagId> tagIds, TagFetchOptions fetchOptions);
+
     public SearchResult<Space> searchSpaces(String sessionToken, SpaceSearchCriteria searchCriteria, SpaceFetchOptions fetchOptions);
 
     public SearchResult<Project> searchProjects(String sessionToken, ProjectSearchCriteria searchCriteria, ProjectFetchOptions fetchOptions);
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IDataSetsHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IDataSetsHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..128abc7fd577aeb702af20ee67e3eb9526a343ff
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IDataSetsHolder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.IDataSetsHolder")
+public interface IDataSetsHolder
+{
+    List<DataSet> getDataSets();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IExperimentHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IExperimentHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0fa401d8aa9e551aa5744d976922f005ead9447
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IExperimentHolder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.IExperimentHolder")
+public interface IExperimentHolder
+{
+    Experiment getExperiment();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IExperimentsHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IExperimentsHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..c15f23fbc1c8f79691622b8314dfb3afa095f880
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IExperimentsHolder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.IExperimentsHolder")
+public interface IExperimentsHolder
+{
+    List<Experiment> getExperiments();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IMaterialsHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IMaterialsHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..72133aa441ab380a38b184118c39162e65ab6558
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IMaterialsHolder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.IMaterialsHolder")
+public interface IMaterialsHolder
+{
+    List<Material> getMaterials();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IOwnerHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IOwnerHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d7b2cba3c44cc353610121887eef788da6c4d10
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IOwnerHolder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.IOwnerHolder")
+public interface IOwnerHolder
+{
+    Person getOwner();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IProjectHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IProjectHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..f16fc5034e90820208cbb9b5e37ddf5eb1181e73
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IProjectHolder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.IProjectHolder")
+public interface IProjectHolder
+{
+    Project getProject();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IProjectsHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IProjectsHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..5103fafa1c8029a382ed2f05e397f08a2240d64b
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/IProjectsHolder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.IProjectsHolder")
+public interface IProjectsHolder
+{
+    List<Project> getProjects();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/ISampleHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/ISampleHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..de954bb389448925486c745b95745ae17bdad392
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/ISampleHolder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.ISampleHolder")
+public interface ISampleHolder
+{
+    Sample getSample();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/ISamplesHolder.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/ISamplesHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ac7569e5da18e0c0a58273e871c9859a67b88e6
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/interfaces/ISamplesHolder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.common.interfaces.ISamplesHolder")
+public interface ISamplesHolder
+{
+    List<Sample> getSamples();
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/search/AbstractCompositeSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/search/AbstractCompositeSearchCriteria.java
index ebbc83f11fd3c47252f6a4c38025a930be1fc431..155a6cc010538e958778bb9a18d92ce360afddf9 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/search/AbstractCompositeSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/common/search/AbstractCompositeSearchCriteria.java
@@ -16,7 +16,6 @@
 
 package ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/DataSet.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/DataSet.java
index beeae262e518fc26d008944f95ef75243d9c2009..a5b2efb27bd203658e06dc6fc2607e207b9a5f19 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/DataSet.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/DataSet.java
@@ -16,6 +16,7 @@
 package ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModificationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModifierHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IParentChildrenHolder;
@@ -23,6 +24,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPermIdHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPropertiesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistrationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistratorHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISampleHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ITagsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.LinkedData;
@@ -50,7 +52,7 @@ import java.util.Set;
  * Class automatically generated with DtoGenerator
  */
 @JsonObject("as.dto.dataset.DataSet")
-public class DataSet implements Serializable, ICodeHolder, IModificationDateHolder, IModifierHolder, IParentChildrenHolder<DataSet>, IPermIdHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ITagsHolder
+public class DataSet implements Serializable, ICodeHolder, IExperimentHolder, IModificationDateHolder, IModifierHolder, IParentChildrenHolder<DataSet>, IPermIdHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ISampleHolder, ITagsHolder
 {
     private static final long serialVersionUID = 1L;
 
@@ -281,6 +283,7 @@ public class DataSet implements Serializable, ICodeHolder, IModificationDateHold
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public Experiment getExperiment()
     {
         if (getFetchOptions() != null && getFetchOptions().hasExperiment())
@@ -301,6 +304,7 @@ public class DataSet implements Serializable, ICodeHolder, IModificationDateHold
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public Sample getSample()
     {
         if (getFetchOptions() != null && getFetchOptions().hasSample())
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/experiment/Experiment.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/experiment/Experiment.java
index c29f83c1e583fa496e275b60c724f9af0a07c60c..5f20e98e934879aa41fc0adfc6a307aff8833218 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/experiment/Experiment.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/experiment/Experiment.java
@@ -18,12 +18,15 @@ package ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.Attachment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IAttachmentsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IDataSetsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModificationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModifierHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPermIdHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IProjectHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPropertiesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistrationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistratorHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISamplesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ITagsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType;
@@ -50,7 +53,7 @@ import java.util.Set;
  * Class automatically generated with DtoGenerator
  */
 @JsonObject("as.dto.experiment.Experiment")
-public class Experiment implements Serializable, IAttachmentsHolder, ICodeHolder, IModificationDateHolder, IModifierHolder, IPermIdHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ITagsHolder
+public class Experiment implements Serializable, IAttachmentsHolder, ICodeHolder, IDataSetsHolder, IModificationDateHolder, IModifierHolder, IPermIdHolder, IProjectHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ISamplesHolder, ITagsHolder
 {
     private static final long serialVersionUID = 1L;
 
@@ -209,6 +212,7 @@ public class Experiment implements Serializable, IAttachmentsHolder, ICodeHolder
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public Project getProject()
     {
         if (getFetchOptions() != null && getFetchOptions().hasProject())
@@ -229,6 +233,7 @@ public class Experiment implements Serializable, IAttachmentsHolder, ICodeHolder
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public List<DataSet> getDataSets()
     {
         if (getFetchOptions() != null && getFetchOptions().hasDataSets())
@@ -249,6 +254,7 @@ public class Experiment implements Serializable, IAttachmentsHolder, ICodeHolder
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public List<Sample> getSamples()
     {
         if (getFetchOptions() != null && getFetchOptions().hasSamples())
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/project/Project.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/project/Project.java
index b275be13a2ce7b41a9b08bf6264b24d71aa500e5..8f8c97e9b6ed69c9727f1878a751b7df0db9ffcf 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/project/Project.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/project/Project.java
@@ -18,6 +18,7 @@ package ch.ethz.sis.openbis.generic.asapi.v3.dto.project;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.Attachment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IAttachmentsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModificationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModifierHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPermIdHolder;
@@ -43,7 +44,7 @@ import java.util.List;
  * Class automatically generated with DtoGenerator
  */
 @JsonObject("as.dto.project.Project")
-public class Project implements Serializable, IAttachmentsHolder, ICodeHolder, IModificationDateHolder, IModifierHolder, IPermIdHolder, IRegistrationDateHolder, IRegistratorHolder, ISpaceHolder
+public class Project implements Serializable, IAttachmentsHolder, ICodeHolder, IExperimentsHolder, IModificationDateHolder, IModifierHolder, IPermIdHolder, IRegistrationDateHolder, IRegistratorHolder, ISpaceHolder
 {
     private static final long serialVersionUID = 1L;
 
@@ -186,6 +187,7 @@ public class Project implements Serializable, IAttachmentsHolder, ICodeHolder, I
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public List<Experiment> getExperiments()
     {
         if (getFetchOptions() != null && getFetchOptions().hasExperiments())
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java
index 5d69344eabc401b70fdefc5b4592ff8f2d7d014d..bdbe4ef06fadb19d3374e17a55c6c401f1a55e86 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java
@@ -18,6 +18,8 @@ package ch.ethz.sis.openbis.generic.asapi.v3.dto.sample;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.Attachment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IAttachmentsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IDataSetsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModificationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModifierHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IParentChildrenHolder;
@@ -53,7 +55,7 @@ import java.util.Set;
  * Class automatically generated with DtoGenerator
  */
 @JsonObject("as.dto.sample.Sample")
-public class Sample implements Serializable, IAttachmentsHolder, ICodeHolder, IModificationDateHolder, IModifierHolder, IParentChildrenHolder<Sample>, IPermIdHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ISpaceHolder, ITagsHolder
+public class Sample implements Serializable, IAttachmentsHolder, ICodeHolder, IDataSetsHolder, IExperimentHolder, IModificationDateHolder, IModifierHolder, IParentChildrenHolder<Sample>, IPermIdHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ISpaceHolder, ITagsHolder
 {
     private static final long serialVersionUID = 1L;
 
@@ -245,6 +247,7 @@ public class Sample implements Serializable, IAttachmentsHolder, ICodeHolder, IM
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public Experiment getExperiment()
     {
         if (getFetchOptions() != null && getFetchOptions().hasExperiment())
@@ -389,6 +392,7 @@ public class Sample implements Serializable, IAttachmentsHolder, ICodeHolder, IM
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public List<DataSet> getDataSets()
     {
         if (getFetchOptions() != null && getFetchOptions().hasDataSets())
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/space/Space.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/space/Space.java
index 4a0d609de9f4d3bbf7576dd2c33bc3b7b6a95898..a0878562c488013d5bdf6cef6f2dddba6ce263a6 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/space/Space.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/space/Space.java
@@ -18,8 +18,10 @@ package ch.ethz.sis.openbis.generic.asapi.v3.dto.space;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModificationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPermIdHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IProjectsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistrationDateHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistratorHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISamplesHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
@@ -37,7 +39,7 @@ import java.util.List;
  * Class automatically generated with DtoGenerator
  */
 @JsonObject("as.dto.space.Space")
-public class Space implements Serializable, ICodeHolder, IModificationDateHolder, IPermIdHolder, IRegistrationDateHolder, IRegistratorHolder
+public class Space implements Serializable, ICodeHolder, IModificationDateHolder, IPermIdHolder, IProjectsHolder, IRegistrationDateHolder, IRegistratorHolder, ISamplesHolder
 {
     private static final long serialVersionUID = 1L;
 
@@ -173,6 +175,7 @@ public class Space implements Serializable, ICodeHolder, IModificationDateHolder
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public List<Sample> getSamples()
     {
         if (getFetchOptions() != null && getFetchOptions().hasSamples())
@@ -193,6 +196,7 @@ public class Space implements Serializable, ICodeHolder, IModificationDateHolder
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public List<Project> getProjects()
     {
         if (getFetchOptions() != null && getFetchOptions().hasProjects())
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/Tag.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/Tag.java
index 2ee1eb52c042f199b71925861557b9eb163e36f2..50a92a89b7a79f299922b29beb0238274b8a9101 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/Tag.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/Tag.java
@@ -16,9 +16,18 @@
 package ch.ethz.sis.openbis.generic.asapi.v3.dto.tag;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICodeHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IDataSetsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IExperimentsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IMaterialsHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IOwnerHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPermIdHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistrationDateHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISamplesHolder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.NotFetchedException;
@@ -27,12 +36,13 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.io.Serializable;
 import java.util.Date;
+import java.util.List;
 
 /*
  * Class automatically generated with DtoGenerator
  */
 @JsonObject("as.dto.tag.Tag")
-public class Tag implements Serializable, ICodeHolder, IPermIdHolder, IRegistrationDateHolder
+public class Tag implements Serializable, ICodeHolder, IDataSetsHolder, IExperimentsHolder, IMaterialsHolder, IOwnerHolder, IPermIdHolder, IRegistrationDateHolder, ISamplesHolder
 {
     private static final long serialVersionUID = 1L;
 
@@ -51,6 +61,18 @@ public class Tag implements Serializable, ICodeHolder, IPermIdHolder, IRegistrat
     @JsonProperty(value="private")
     private Boolean isPrivate;
 
+    @JsonProperty
+    private List<Experiment> experiments;
+
+    @JsonProperty
+    private List<Sample> samples;
+
+    @JsonProperty
+    private List<DataSet> dataSets;
+
+    @JsonProperty
+    private List<Material> materials;
+
     @JsonProperty
     private Date registrationDate;
 
@@ -124,6 +146,90 @@ public class Tag implements Serializable, ICodeHolder, IPermIdHolder, IRegistrat
         this.isPrivate = isPrivate;
     }
 
+    // Method automatically generated with DtoGenerator
+    @JsonIgnore
+    @Override
+    public List<Experiment> getExperiments()
+    {
+        if (getFetchOptions() != null && getFetchOptions().hasExperiments())
+        {
+            return experiments;
+        }
+        else
+        {
+            throw new NotFetchedException("Experiments have not been fetched.");
+        }
+    }
+
+    // Method automatically generated with DtoGenerator
+    public void setExperiments(List<Experiment> experiments)
+    {
+        this.experiments = experiments;
+    }
+
+    // Method automatically generated with DtoGenerator
+    @JsonIgnore
+    @Override
+    public List<Sample> getSamples()
+    {
+        if (getFetchOptions() != null && getFetchOptions().hasSamples())
+        {
+            return samples;
+        }
+        else
+        {
+            throw new NotFetchedException("Samples have not been fetched.");
+        }
+    }
+
+    // Method automatically generated with DtoGenerator
+    public void setSamples(List<Sample> samples)
+    {
+        this.samples = samples;
+    }
+
+    // Method automatically generated with DtoGenerator
+    @JsonIgnore
+    @Override
+    public List<DataSet> getDataSets()
+    {
+        if (getFetchOptions() != null && getFetchOptions().hasDataSets())
+        {
+            return dataSets;
+        }
+        else
+        {
+            throw new NotFetchedException("Data sets have not been fetched.");
+        }
+    }
+
+    // Method automatically generated with DtoGenerator
+    public void setDataSets(List<DataSet> dataSets)
+    {
+        this.dataSets = dataSets;
+    }
+
+    // Method automatically generated with DtoGenerator
+    @JsonIgnore
+    @Override
+    public List<Material> getMaterials()
+    {
+        if (getFetchOptions() != null && getFetchOptions().hasMaterials())
+        {
+            return materials;
+        }
+        else
+        {
+            throw new NotFetchedException("Materials have not been fetched.");
+        }
+    }
+
+    // Method automatically generated with DtoGenerator
+    public void setMaterials(List<Material> materials)
+    {
+        this.materials = materials;
+    }
+
     // Method automatically generated with DtoGenerator
     @JsonIgnore
     @Override
@@ -140,6 +246,7 @@ public class Tag implements Serializable, ICodeHolder, IPermIdHolder, IRegistrat
 
     // Method automatically generated with DtoGenerator
     @JsonIgnore
+    @Override
     public Person getOwner()
     {
         if (getFetchOptions() != null && getFetchOptions().hasOwner())
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/fetchoptions/TagFetchOptions.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/fetchoptions/TagFetchOptions.java
index 9c8eeb2250ad9287030543113285a4a623c26bc5..a1e0f7d39b1932ca25239617f18b373000af1f85 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/fetchoptions/TagFetchOptions.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/fetchoptions/TagFetchOptions.java
@@ -17,7 +17,11 @@ package ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.fetchoptions.FetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.fetchoptions.FetchOptionsToStringBuilder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.fetchoptions.MaterialFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.fetchoptions.PersonFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.fetchoptions.SampleFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -31,12 +35,112 @@ public class TagFetchOptions extends FetchOptions<Tag> implements Serializable
 {
     private static final long serialVersionUID = 1L;
 
+    @JsonProperty
+    private ExperimentFetchOptions experiments;
+
+    @JsonProperty
+    private SampleFetchOptions samples;
+
+    @JsonProperty
+    private DataSetFetchOptions dataSets;
+
+    @JsonProperty
+    private MaterialFetchOptions materials;
+
     @JsonProperty
     private PersonFetchOptions owner;
 
     @JsonProperty
     private TagSortOptions sort;
 
+    // Method automatically generated with DtoGenerator
+    public ExperimentFetchOptions withExperiments()
+    {
+        if (experiments == null)
+        {
+            experiments = new ExperimentFetchOptions();
+        }
+        return experiments;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public ExperimentFetchOptions withExperimentsUsing(ExperimentFetchOptions fetchOptions)
+    {
+        return experiments = fetchOptions;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public boolean hasExperiments()
+    {
+        return experiments != null;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public SampleFetchOptions withSamples()
+    {
+        if (samples == null)
+        {
+            samples = new SampleFetchOptions();
+        }
+        return samples;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public SampleFetchOptions withSamplesUsing(SampleFetchOptions fetchOptions)
+    {
+        return samples = fetchOptions;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public boolean hasSamples()
+    {
+        return samples != null;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public DataSetFetchOptions withDataSets()
+    {
+        if (dataSets == null)
+        {
+            dataSets = new DataSetFetchOptions();
+        }
+        return dataSets;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public DataSetFetchOptions withDataSetsUsing(DataSetFetchOptions fetchOptions)
+    {
+        return dataSets = fetchOptions;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public boolean hasDataSets()
+    {
+        return dataSets != null;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public MaterialFetchOptions withMaterials()
+    {
+        if (materials == null)
+        {
+            materials = new MaterialFetchOptions();
+        }
+        return materials;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public MaterialFetchOptions withMaterialsUsing(MaterialFetchOptions fetchOptions)
+    {
+        return materials = fetchOptions;
+    }
+
+    // Method automatically generated with DtoGenerator
+    public boolean hasMaterials()
+    {
+        return materials != null;
+    }
+
     // Method automatically generated with DtoGenerator
     public PersonFetchOptions withOwner()
     {
@@ -80,6 +184,10 @@ public class TagFetchOptions extends FetchOptions<Tag> implements Serializable
     protected FetchOptionsToStringBuilder getFetchOptionsStringBuilder()
     {
         FetchOptionsToStringBuilder f = new FetchOptionsToStringBuilder("Tag", this);
+        f.addFetchOption("Experiments", experiments);
+        f.addFetchOption("Samples", samples);
+        f.addFetchOption("DataSets", dataSets);
+        f.addFetchOption("Materials", materials);
         f.addFetchOption("Owner", owner);
         return f;
     }
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagCode.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagCode.java
index 36e19a6693610693d65ed617b6cad87eacc75601..fabe680c5311d8056b828c9b488a058e8fdfa495 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagCode.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagCode.java
@@ -39,8 +39,7 @@ public class TagCode implements ITagId, Serializable
      */
     public TagCode(String code)
     {
-        // case sensitive
-        setCode(code);
+        setCode(code.toUpperCase());
     }
 
     //
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagPermId.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagPermId.java
index 139b92b9559bb864bf883eb305e5d6d030bcf9f3..ee20c7a11284e5c01843ad5079024a626ac71ed0 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagPermId.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/id/TagPermId.java
@@ -36,8 +36,8 @@ public class TagPermId extends ObjectPermId implements ITagId
      */
     public TagPermId(String ownerId, String tagCode)
     {
-        // case sensitive
-        this("/" + ownerId + "/" + tagCode);
+        // case sensitive owner id, case insensitive code
+        this("/" + ownerId + "/" + tagCode.toUpperCase());
     }
 
     /**
diff --git a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
index ba7bf110576e237407f643d82ed59ce6f9cc9ef9..ef713ff42e7b7094f8a2df1f4989100022edee78 100644
--- a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
+++ b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
@@ -1098,3 +1098,18 @@ search Sample Types
 search Experiment Types
 search Data Set Types
 search Material Types
+get Materials
+has Materials
+I Data Sets Holder
+I Experiment Holder
+I Experiments Holder
+I Materials Holder
+I Owner Holder
+I Project Holder
+I Projects Holder
+I Sample Holder
+I Samples Holder
+map Tags
+set Materials
+with Materials
+with Materials Using