diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/IReindexObjectExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/IReindexObjectExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..e79b86cb1b089b906a40e30b19d603503cd3b1e5
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/IReindexObjectExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * 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.executor.common;
+
+import java.util.Collection;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder;
+
+/**
+ * @author pkupczyk
+ */
+public interface IReindexObjectExecutor
+{
+
+    <T extends IIdHolder> void reindex(IOperationContext context, Class<T> objectClass, Collection<T> objects);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/ReindexObjectExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/ReindexObjectExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd3310461097253845f3988d9ee21fa078f9af1c
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/ReindexObjectExecutor.java
@@ -0,0 +1,62 @@
+/*
+ * 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.executor.common;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+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.server.dataaccess.db.search.IFullTextIndexUpdateScheduler;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IndexUpdateOperation;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class ReindexObjectExecutor implements IReindexObjectExecutor
+{
+
+    @Autowired
+    private IDAOFactory daoFactory;
+
+    @Override
+    public <T extends IIdHolder> void reindex(IOperationContext context, Class<T> objectClass, Collection<T> objects)
+    {
+        IFullTextIndexUpdateScheduler indexUpdater = daoFactory.getPersistencyResources().getIndexUpdateScheduler();
+        List<Long> objectIds = new ArrayList<Long>();
+
+        for (IIdHolder object : objects)
+        {
+            if (object != null && object.getId() != null)
+            {
+                objectIds.add(object.getId());
+            }
+        }
+
+        if (false == objectIds.isEmpty())
+        {
+            indexUpdater.scheduleUpdate(IndexUpdateOperation.reindex(objectClass, objectIds));
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetChildrenExecutor.java
index ddab7ce48923845ec05362e90a6b1d51f6b0c961..1c2b8a7edc378bae7b7677d8bc2d2176bc8506fe 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetChildrenExecutor.java
@@ -16,19 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
 
-import java.util.Map;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 
 /**
  * @author pkupczyk
  */
-public interface ISetDataSetChildrenExecutor
+public interface ISetDataSetChildrenExecutor extends ISetEntityRelationsWithCacheExecutor<DataSetCreation, DataPE, IDataSetId, DataPE>
 {
 
-    void set(IOperationContext context, Map<DataSetCreation, DataPE> creationsMap, Map<IDataSetId, DataPE> relatedMap);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetComponentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetComponentsExecutor.java
index 21b3b6623f9d2031134e4d51298c3abadd894eaf..51cbde173ff2be2c829165749e8c10173bf34eeb 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetComponentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetComponentsExecutor.java
@@ -16,19 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
 
-import java.util.Map;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 
 /**
  * @author pkupczyk
  */
-public interface ISetDataSetComponentsExecutor
+public interface ISetDataSetComponentsExecutor extends ISetEntityRelationsWithCacheExecutor<DataSetCreation, DataPE, IDataSetId, DataPE>
 {
 
-    void set(IOperationContext context, Map<DataSetCreation, DataPE> creationsMap, Map<IDataSetId, DataPE> relatedMap);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetContainerExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetContainerExecutor.java
index 39ff7136927d0f7d8907d1ccf8f00ae1998276d8..2a74231d082acf7b4b037aa005dd2849f4ed2ad9 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetContainerExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetContainerExecutor.java
@@ -16,19 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
 
-import java.util.Map;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 
 /**
  * @author pkupczyk
  */
-public interface ISetDataSetContainerExecutor
+public interface ISetDataSetContainerExecutor extends ISetEntityRelationsWithCacheExecutor<DataSetCreation, DataPE, IDataSetId, DataPE>
 {
 
-    void set(IOperationContext context, Map<DataSetCreation, DataPE> creationsMap, Map<IDataSetId, DataPE> relatedMap);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetParentsExecutor.java
index c1422d3cba84befc6b28800565630a3aa49a62c9..579a2dcdf31c9a958e0668a95ea80d6177305038 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ISetDataSetParentsExecutor.java
@@ -16,19 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
 
-import java.util.Map;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 
 /**
  * @author pkupczyk
  */
-public interface ISetDataSetParentsExecutor
+public interface ISetDataSetParentsExecutor extends ISetEntityRelationsWithCacheExecutor<DataSetCreation, DataPE, IDataSetId, DataPE>
 {
 
-    void set(IOperationContext context, Map<DataSetCreation, DataPE> creationsMap, Map<IDataSetId, DataPE> relatedMap);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetChildrenExecutor.java
index ae5ca3121bc2bba5712dd2eef7b3712a060a0e7d..bb0753745ccd4b0713db05dd8f8b78f0eb843083 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetChildrenExecutor.java
@@ -31,7 +31,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
  * @author pkupczyk
  */
 @Component
-public class SetDataSetChildrenExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId> implements
+public class SetDataSetChildrenExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId, DataPE> implements
         ISetDataSetChildrenExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetComponentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetComponentsExecutor.java
index 846d08ecc4fa2ba2aec4a611eafdb0f10994142f..4bf2e385e0832cb3a706ce85231e10722a599a15 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetComponentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetComponentsExecutor.java
@@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
  * @author pkupczyk
  */
 @Component
-public class SetDataSetComponentsExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId> implements
+public class SetDataSetComponentsExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId, DataPE> implements
         ISetDataSetComponentsExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetContainerExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetContainerExecutor.java
index 48a16e6c72fb65e3d58a5aa0ce46d7639da3cf99..343f817bf9bdf314f89849c47025606f3126a444 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetContainerExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetContainerExecutor.java
@@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
  * @author pkupczyk
  */
 @Component
-public class SetDataSetContainerExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId> implements
+public class SetDataSetContainerExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId, DataPE> implements
         ISetDataSetContainerExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetParentsExecutor.java
index 067270a908d21d9990b44cf7dbf922927302a123..721d3c0fdc00d215b2858a739b00db8f5a5f7ce0 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetParentsExecutor.java
@@ -31,7 +31,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
  * @author pkupczyk
  */
 @Component
-public class SetDataSetParentsExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId> implements
+public class SetDataSetParentsExecutor extends AbstractSetEntityToManyRelationExecutor<DataSetCreation, DataPE, IDataSetId, DataPE> implements
         ISetDataSetParentsExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetRelatedDataSetsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetRelatedDataSetsExecutor.java
index 01677bc512fc6dba10f80a8fd420702acbc3998a..6f4d75d052dd98256e9a63dbcf6f7a8e9e8a5a33 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetRelatedDataSetsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/SetDataSetRelatedDataSetsExecutor.java
@@ -35,7 +35,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
  * @author pkupczyk
  */
 @Component
-public class SetDataSetRelatedDataSetsExecutor extends AbstractSetEntityMultipleRelationsExecutor<DataSetCreation, DataPE, IDataSetId> implements
+public class SetDataSetRelatedDataSetsExecutor extends AbstractSetEntityMultipleRelationsExecutor<DataSetCreation, DataPE, IDataSetId, DataPE>
+        implements
         ISetDataSetRelatedDataSetsExecutor
 {
 
@@ -55,7 +56,7 @@ public class SetDataSetRelatedDataSetsExecutor extends AbstractSetEntityMultiple
     private ISetDataSetChildrenExecutor setDataSetChildrenExecutor;
 
     @Override
-    protected void addRelatedIds(Set<IDataSetId> relatedIds, DataSetCreation creation)
+    protected void addRelatedIds(Set<IDataSetId> relatedIds, DataSetCreation creation, DataPE entity)
     {
         addRelatedIds(relatedIds, creation.getContainerIds());
         addRelatedIds(relatedIds, creation.getComponentIds());
@@ -63,6 +64,12 @@ public class SetDataSetRelatedDataSetsExecutor extends AbstractSetEntityMultiple
         addRelatedIds(relatedIds, creation.getChildIds());
     }
 
+    @Override
+    protected void addRelated(Map<IDataSetId, DataPE> relatedMap, DataSetCreation creation, DataPE entity)
+    {
+        addRelated(relatedMap, creation.getCreationId(), entity);
+    }
+
     @Override
     protected Map<IDataSetId, DataPE> map(IOperationContext context, List<IDataSetId> relatedIds)
     {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityMultipleRelationsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityMultipleRelationsExecutor.java
index ea126e9822e86f0f9a83abe9d18bc67168aded15..64c9b63864751fefab2f8ca11d81ba9e290229b3 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityMultipleRelationsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityMultipleRelationsExecutor.java
@@ -29,7 +29,6 @@ import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.CreationId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ICreationIdHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.ObjectNotFoundException;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.context.Progress;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
@@ -38,45 +37,41 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
  * @author pkupczyk
  */
 @Component
-public abstract class AbstractSetEntityMultipleRelationsExecutor<ENTITY_CREATION extends ICreationIdHolder, ENTITY_PE, ENTITY_ID extends IObjectId>
+public abstract class AbstractSetEntityMultipleRelationsExecutor<ENTITY_CREATION, ENTITY_PE, RELATED_ID extends IObjectId, RELATED_PE>
         implements ISetEntityRelationsExecutor<ENTITY_CREATION, ENTITY_PE>
 {
 
-    @SuppressWarnings("unchecked")
     @Override
     public void set(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> creationsMap)
     {
-        Map<IObjectId, ENTITY_PE> relatedMap = getRelatedMap(context, creationsMap);
+        Map<RELATED_ID, RELATED_PE> relatedMap = getRelatedMap(context, creationsMap);
 
-        set(context, creationsMap, (Map<ENTITY_ID, ENTITY_PE>) relatedMap);
+        set(context, creationsMap, relatedMap);
     }
 
-    private Map<IObjectId, ENTITY_PE> getRelatedMap(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> creationsMap)
+    private Map<RELATED_ID, RELATED_PE> getRelatedMap(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> creationsMap)
     {
         context.pushProgress(new Progress("load related entities"));
 
-        Set<ENTITY_ID> relatedIds = new HashSet<ENTITY_ID>();
-        for (ENTITY_CREATION creation : creationsMap.keySet())
+        Set<RELATED_ID> relatedIds = new HashSet<RELATED_ID>();
+        for (Entry<ENTITY_CREATION, ENTITY_PE> entry : creationsMap.entrySet())
         {
-            addRelatedIds(relatedIds, creation);
+            addRelatedIds(relatedIds, entry.getKey(), entry.getValue());
         }
 
-        Map<IObjectId, ENTITY_PE> relatedMap = new HashMap<IObjectId, ENTITY_PE>();
+        Map<RELATED_ID, RELATED_PE> relatedMap = new HashMap<RELATED_ID, RELATED_PE>();
 
         for (Entry<ENTITY_CREATION, ENTITY_PE> entry : creationsMap.entrySet())
         {
             ENTITY_CREATION creation = entry.getKey();
             ENTITY_PE entity = entry.getValue();
 
-            if (creation.getCreationId() != null)
-            {
-                relatedMap.put(creation.getCreationId(), entity);
-            }
+            addRelated(relatedMap, creation, entity);
         }
 
-        List<ENTITY_ID> toLoadIds = new LinkedList<ENTITY_ID>();
+        List<RELATED_ID> toLoadIds = new LinkedList<RELATED_ID>();
 
-        for (ENTITY_ID relatedId : relatedIds)
+        for (RELATED_ID relatedId : relatedIds)
         {
             if (relatedId instanceof CreationId)
             {
@@ -84,19 +79,18 @@ public abstract class AbstractSetEntityMultipleRelationsExecutor<ENTITY_CREATION
                 {
                     throw new ObjectNotFoundException(relatedId);
                 }
-            }
-            else
+            } else
             {
                 toLoadIds.add(relatedId);
             }
         }
 
-        Map<ENTITY_ID, ENTITY_PE> loadedMap = map(context, toLoadIds);
+        Map<RELATED_ID, RELATED_PE> loadedMap = map(context, toLoadIds);
         relatedMap.putAll(loadedMap);
 
-        for (ENTITY_ID relatedId : relatedIds)
+        for (RELATED_ID relatedId : relatedIds)
         {
-            ENTITY_PE related = relatedMap.get(relatedId);
+            RELATED_PE related = relatedMap.get(relatedId);
 
             if (related == null)
             {
@@ -111,7 +105,7 @@ public abstract class AbstractSetEntityMultipleRelationsExecutor<ENTITY_CREATION
         return relatedMap;
     }
 
-    protected void addRelatedIds(Set<ENTITY_ID> relatedIds, Collection<? extends ENTITY_ID> relatedIdsToAdd)
+    protected void addRelatedIds(Set<RELATED_ID> relatedIds, Collection<? extends RELATED_ID> relatedIdsToAdd)
     {
         if (relatedIdsToAdd != null)
         {
@@ -119,7 +113,7 @@ public abstract class AbstractSetEntityMultipleRelationsExecutor<ENTITY_CREATION
         }
     }
 
-    protected void addRelatedIds(Set<ENTITY_ID> relatedIds, ENTITY_ID relatedIdToAdd)
+    protected void addRelatedIds(Set<RELATED_ID> relatedIds, RELATED_ID relatedIdToAdd)
     {
         if (relatedIdToAdd != null)
         {
@@ -127,12 +121,22 @@ public abstract class AbstractSetEntityMultipleRelationsExecutor<ENTITY_CREATION
         }
     }
 
-    protected abstract void addRelatedIds(Set<ENTITY_ID> relatedIds, ENTITY_CREATION creation);
+    protected void addRelated(Map<RELATED_ID, RELATED_PE> relatedMap, RELATED_ID relatedId, RELATED_PE related)
+    {
+        if (relatedId != null && related != null)
+        {
+            relatedMap.put(relatedId, related);
+        }
+    }
+
+    protected abstract void addRelatedIds(Set<RELATED_ID> relatedIds, ENTITY_CREATION creation, ENTITY_PE entity);
+
+    protected abstract void addRelated(Map<RELATED_ID, RELATED_PE> relatedMap, ENTITY_CREATION creation, ENTITY_PE entity);
 
-    protected abstract Map<ENTITY_ID, ENTITY_PE> map(IOperationContext context, List<ENTITY_ID> relatedIds);
+    protected abstract Map<RELATED_ID, RELATED_PE> map(IOperationContext context, List<RELATED_ID> relatedIds);
 
-    protected abstract void check(IOperationContext context, ENTITY_ID relatedId, ENTITY_PE related);
+    protected abstract void check(IOperationContext context, RELATED_ID relatedId, RELATED_PE related);
 
-    protected abstract void set(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> creationsMap, Map<ENTITY_ID, ENTITY_PE> relatedMap);
+    protected abstract void set(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> creationsMap, Map<RELATED_ID, RELATED_PE> relatedMap);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityToManyRelationExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityToManyRelationExecutor.java
index f59f53879738c697030eb7c0cd4e674268ea4bbd..b371df0399d092f769c760a46627ec6e1c88b218 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityToManyRelationExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/AbstractSetEntityToManyRelationExecutor.java
@@ -29,24 +29,24 @@ import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 /**
  * @author pkupczyk
  */
-public abstract class AbstractSetEntityToManyRelationExecutor<ENTITY_CREATION, ENTITY_PE, ENTITY_ID>
+public abstract class AbstractSetEntityToManyRelationExecutor<ENTITY_CREATION, ENTITY_PE, RELATED_ID, RELATED_PE>
 {
 
     @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
     protected IRelationshipService relationshipService;
 
-    public void set(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> creationsMap, Map<ENTITY_ID, ENTITY_PE> relatedMap)
+    public void set(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> creationsMap, Map<RELATED_ID, RELATED_PE> relatedMap)
     {
         for (ENTITY_CREATION creation : creationsMap.keySet())
         {
             ENTITY_PE entity = creationsMap.get(creation);
-            Collection<? extends ENTITY_ID> relatedIds = getRelatedIds(context, creation);
+            Collection<? extends RELATED_ID> relatedIds = getRelatedIds(context, creation);
 
             if (relatedIds != null)
             {
-                Collection<ENTITY_PE> related = new LinkedList<ENTITY_PE>();
+                Collection<RELATED_PE> related = new LinkedList<RELATED_PE>();
 
-                for (ENTITY_ID relatedId : relatedIds)
+                for (RELATED_ID relatedId : relatedIds)
                 {
                     related.add(relatedMap.get(relatedId));
                 }
@@ -59,8 +59,8 @@ public abstract class AbstractSetEntityToManyRelationExecutor<ENTITY_CREATION, E
         }
     }
 
-    protected abstract Collection<? extends ENTITY_ID> getRelatedIds(IOperationContext context, ENTITY_CREATION creation);
+    protected abstract Collection<? extends RELATED_ID> getRelatedIds(IOperationContext context, ENTITY_CREATION creation);
 
-    protected abstract void setRelated(IOperationContext context, ENTITY_PE entity, Collection<ENTITY_PE> related);
+    protected abstract void setRelated(IOperationContext context, ENTITY_PE entity, Collection<RELATED_PE> related);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/ISetEntityRelationsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/ISetEntityRelationsWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..9eeb0032010b89657dd11b7a12acdac2c80c3042
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/entity/ISetEntityRelationsWithCacheExecutor.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.server.asapi.v3.executor.entity;
+
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetEntityRelationsWithCacheExecutor<ENTITY_CREATION, ENTITY_PE, RELATED_ID, RELATED_PE>
+{
+
+    public void set(IOperationContext context, Map<ENTITY_CREATION, ENTITY_PE> entitiesMap, Map<RELATED_ID, RELATED_PE> relatedMap);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleChildrenExecutor.java
index fcbd85a11760511b82806c846be89ddd4070ea3d..6a68945efedac6cba864aeeaf7c0590faea44f6d 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleChildrenExecutor.java
@@ -16,19 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.sample;
 
-import java.util.Map;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author pkupczyk
  */
-public interface ISetSampleChildrenExecutor
+public interface ISetSampleChildrenExecutor extends ISetEntityRelationsWithCacheExecutor<SampleCreation, SamplePE, ISampleId, SamplePE>
 {
 
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, SamplePE> sampleMap);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleComponentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleComponentsExecutor.java
index aeee846d986ef0a7b3e338950eb074176bb4b7d0..84a4f05e2db65630e84c3ad607b1d120473b4b11 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleComponentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleComponentsExecutor.java
@@ -16,19 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.sample;
 
-import java.util.Map;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author pkupczyk
  */
-public interface ISetSampleComponentsExecutor
+public interface ISetSampleComponentsExecutor extends ISetEntityRelationsWithCacheExecutor<SampleCreation, SamplePE, ISampleId, SamplePE>
 {
 
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, SamplePE> sampleMap);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleParentsExecutor.java
index 00976bb22148b26dde986ba3ad930b115eb9cac2..af14dfd15d13b02b71afbeefc101f22d3aa7e67d 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/ISetSampleParentsExecutor.java
@@ -16,19 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.sample;
 
-import java.util.Map;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
-import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author pkupczyk
  */
-public interface ISetSampleParentsExecutor
+public interface ISetSampleParentsExecutor extends ISetEntityRelationsWithCacheExecutor<SampleCreation, SamplePE, ISampleId, SamplePE>
 {
 
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, SamplePE> sampleMap);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleChildrenExecutor.java
index 8d65646b289bd501cd9f28037a335c43d93d9440..df144c9fb1346a4eb952f0e4f90d9a08d094cfba 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleChildrenExecutor.java
@@ -33,7 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
  * @author pkupczyk
  */
 @Component
-public class SetSampleChildrenExecutor extends AbstractSetEntityToManyRelationExecutor<SampleCreation, SamplePE, ISampleId> implements
+public class SetSampleChildrenExecutor extends AbstractSetEntityToManyRelationExecutor<SampleCreation, SamplePE, ISampleId, SamplePE> implements
         ISetSampleChildrenExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleComponentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleComponentsExecutor.java
index 90cb2766aaea6838d6a6599b0bf948169ce94012..ef810d2202d10fa48414b5604c197cc3c7d91f7d 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleComponentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleComponentsExecutor.java
@@ -31,7 +31,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
  * @author pkupczyk
  */
 @Component
-public class SetSampleComponentsExecutor extends AbstractSetEntityToManyRelationExecutor<SampleCreation, SamplePE, ISampleId> implements
+public class SetSampleComponentsExecutor extends AbstractSetEntityToManyRelationExecutor<SampleCreation, SamplePE, ISampleId, SamplePE> implements
         ISetSampleComponentsExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleParentsExecutor.java
index a05936e5c65ce168e0b2cd8f75a34b97e738ad6b..1a656f9d3e69697322efd3f6f152167e78fb5e7c 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleParentsExecutor.java
@@ -33,7 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
  * @author pkupczyk
  */
 @Component
-public class SetSampleParentsExecutor extends AbstractSetEntityToManyRelationExecutor<SampleCreation, SamplePE, ISampleId> implements
+public class SetSampleParentsExecutor extends AbstractSetEntityToManyRelationExecutor<SampleCreation, SamplePE, ISampleId, SamplePE> implements
         ISetSampleParentsExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleRelatedSamplesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleRelatedSamplesExecutor.java
index dcf2f735240ceafc6cf6735d8b4aa73850eef31e..3462a9e381603c50daea772bb13439476f7448e5 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleRelatedSamplesExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/SetSampleRelatedSamplesExecutor.java
@@ -35,7 +35,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
  * @author pkupczyk
  */
 @Component
-public class SetSampleRelatedSamplesExecutor extends AbstractSetEntityMultipleRelationsExecutor<SampleCreation, SamplePE, ISampleId> implements
+public class SetSampleRelatedSamplesExecutor extends AbstractSetEntityMultipleRelationsExecutor<SampleCreation, SamplePE, ISampleId, SamplePE>
+        implements
         ISetSampleRelatedSamplesExecutor
 {
 
@@ -55,7 +56,7 @@ public class SetSampleRelatedSamplesExecutor extends AbstractSetEntityMultipleRe
     private ISetSampleChildrenExecutor setSampleChildrenExecutor;
 
     @Override
-    protected void addRelatedIds(Set<ISampleId> relatedIds, SampleCreation creation)
+    protected void addRelatedIds(Set<ISampleId> relatedIds, SampleCreation creation, SamplePE entity)
     {
         addRelatedIds(relatedIds, creation.getContainerId());
         addRelatedIds(relatedIds, creation.getComponentIds());
@@ -63,6 +64,12 @@ public class SetSampleRelatedSamplesExecutor extends AbstractSetEntityMultipleRe
         addRelatedIds(relatedIds, creation.getChildIds());
     }
 
+    @Override
+    protected void addRelated(Map<ISampleId, SamplePE> relatedMap, SampleCreation creation, SamplePE entity)
+    {
+        addRelated(relatedMap, creation.getCreationId(), entity);
+    }
+
     @Override
     protected Map<ISampleId, SamplePE> map(IOperationContext context, List<ISampleId> relatedIds)
     {
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 e0d290fe0c9d77456c838129859c141536252b84..5d474142fd69642ca836618f4108dac7a10f8807 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
@@ -46,6 +46,15 @@ public class CreateTagExecutor extends AbstractCreateEntityExecutor<TagCreation,
     @Autowired
     private IDAOFactory daoFactory;
 
+    @Autowired
+    private ISetTagExperimentsExecutor setTagExperimentsExecutor;
+
+    @Autowired
+    private ISetTagSamplesExecutor setTagSamplesExecutor;
+
+    @Autowired
+    private ISetTagDataSetsExecutor setTagDataSetsExecutor;
+
     @Override
     protected List<MetaprojectPE> createEntities(IOperationContext context, Collection<TagCreation> creations)
     {
@@ -100,7 +109,9 @@ public class CreateTagExecutor extends AbstractCreateEntityExecutor<TagCreation,
     @Override
     protected void updateAll(IOperationContext context, Map<TagCreation, MetaprojectPE> entitiesMap)
     {
-        // nothing to do
+        setTagExperimentsExecutor.set(context, entitiesMap);
+        setTagSamplesExecutor.set(context, entitiesMap);
+        setTagDataSetsExecutor.set(context, entitiesMap);
     }
 
     @Override
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagDataSetsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagDataSetsExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..85d63b71a38f7ba45ef097115e252c5e58137b92
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagDataSetsExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.executor.tag;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsExecutor;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetTagDataSetsExecutor extends ISetEntityRelationsExecutor<TagCreation, MetaprojectPE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagDataSetsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagDataSetsWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..96d0e371d9f5c7df3489fbe982afc36e00d5ddad
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagDataSetsWithCacheExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * 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.executor.tag;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetTagDataSetsWithCacheExecutor
+        extends ISetEntityRelationsWithCacheExecutor<TagCreation, MetaprojectPE, IDataSetId, DataPE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagExperimentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagExperimentsExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9def06cbef74810debfaad79355e9d3b2806878
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagExperimentsExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.executor.tag;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsExecutor;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetTagExperimentsExecutor extends ISetEntityRelationsExecutor<TagCreation, MetaprojectPE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagExperimentsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagExperimentsWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..847662e92261905ba32203265aadedbe476d589b
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagExperimentsWithCacheExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * 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.executor.tag;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetTagExperimentsWithCacheExecutor
+        extends ISetEntityRelationsWithCacheExecutor<TagCreation, MetaprojectPE, IExperimentId, ExperimentPE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagSamplesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagSamplesExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..4885b4a0e844e7469668978c26e49b1255cfd3a7
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagSamplesExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.executor.tag;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsExecutor;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetTagSamplesExecutor extends ISetEntityRelationsExecutor<TagCreation, MetaprojectPE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagSamplesWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagSamplesWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5459df9f850f00bd97b783f622be25543206097
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/ISetTagSamplesWithCacheExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * 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.executor.tag;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ISetEntityRelationsWithCacheExecutor;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetTagSamplesWithCacheExecutor
+        extends ISetEntityRelationsWithCacheExecutor<TagCreation, MetaprojectPE, ISampleId, SamplePE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagDataSetsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagDataSetsExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ad7961affd420f77f447290a4c894d37f8d8a35
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagDataSetsExecutor.java
@@ -0,0 +1,84 @@
+/*
+ * 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.executor.tag;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.UnauthorizedObjectAccessException;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset.IMapDataSetByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.AbstractSetEntityMultipleRelationsExecutor;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.DataSetPEByExperimentOrSampleIdentifierValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetTagDataSetsExecutor extends AbstractSetEntityMultipleRelationsExecutor<TagCreation, MetaprojectPE, IDataSetId, DataPE>
+        implements ISetTagDataSetsExecutor
+{
+
+    @Autowired
+    private IMapDataSetByIdExecutor mapDataSetExecutor;
+
+    @Autowired
+    private ISetTagDataSetsWithCacheExecutor setTagDataSetsWithCacheExecutor;
+
+    @Override
+    protected void addRelatedIds(Set<IDataSetId> relatedIds, TagCreation creation, MetaprojectPE entity)
+    {
+        addRelatedIds(relatedIds, creation.getDataSetIds());
+    }
+
+    @Override
+    protected void addRelated(Map<IDataSetId, DataPE> relatedMap, TagCreation creation, MetaprojectPE entity)
+    {
+        // nothing to do here
+    }
+
+    @Override
+    protected Map<IDataSetId, DataPE> map(IOperationContext context, List<IDataSetId> relatedIds)
+    {
+        return mapDataSetExecutor.map(context, relatedIds);
+    }
+
+    @Override
+    protected void check(IOperationContext context, IDataSetId relatedId, DataPE related)
+    {
+        if (false == new DataSetPEByExperimentOrSampleIdentifierValidator().doValidation(context.getSession().tryGetPerson(), related))
+        {
+            throw new UnauthorizedObjectAccessException(relatedId);
+        }
+
+    }
+
+    @Override
+    protected void set(IOperationContext context, Map<TagCreation, MetaprojectPE> creationsMap, Map<IDataSetId, DataPE> relatedMap)
+    {
+        setTagDataSetsWithCacheExecutor.set(context, creationsMap, relatedMap);
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagDataSetsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagDataSetsWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a431e556f3cbc751c519add35efae7633e9fb7c
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagDataSetsWithCacheExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * 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.executor.tag;
+
+import java.util.Collection;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetTagDataSetsWithCacheExecutor extends SetTagEntitiesWithCacheExecutor<IDataSetId, DataPE>
+        implements ISetTagDataSetsWithCacheExecutor
+{
+
+    @Override
+    protected Class<DataPE> getRelatedClass()
+    {
+        return DataPE.class;
+    }
+
+    @Override
+    protected Collection<? extends IDataSetId> getRelatedIds(IOperationContext context, TagCreation creation)
+    {
+        return creation.getDataSetIds();
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagEntitiesWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagEntitiesWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c05dfef99fd016dad43828954883fff89099c3c
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagEntitiesWithCacheExecutor.java
@@ -0,0 +1,69 @@
+/*
+ * 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.executor.tag;
+
+import java.util.Collection;
+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.common.id.IObjectId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.IReindexObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.AbstractSetEntityToManyRelationExecutor;
+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;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public abstract class SetTagEntitiesWithCacheExecutor<RELATED_ID extends IObjectId, RELATED_PE extends IEntityWithMetaprojects>
+        extends AbstractSetEntityToManyRelationExecutor<TagCreation, MetaprojectPE, RELATED_ID, RELATED_PE>
+{
+
+    @Autowired
+    private IDAOFactory daoFactory;
+
+    @Autowired
+    private IReindexObjectExecutor reindexObjectExecutor;
+
+    protected abstract Class<RELATED_PE> getRelatedClass();
+
+    @Override
+    public void set(IOperationContext context, Map<TagCreation, MetaprojectPE> creationsMap, Map<RELATED_ID, RELATED_PE> relatedMap)
+    {
+        super.set(context, creationsMap, relatedMap);
+
+        daoFactory.getSessionFactory().getCurrentSession().flush();
+
+        reindexObjectExecutor.reindex(context, getRelatedClass(), relatedMap.values());
+    }
+
+    @Override
+    protected void setRelated(IOperationContext context, MetaprojectPE entity, Collection<RELATED_PE> related)
+    {
+        for (RELATED_PE aRelated : related)
+        {
+            aRelated.addMetaproject(entity);
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagExperimentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagExperimentsExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..de756c9498013ce9c3028ff8c64adb151f7e22ba
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagExperimentsExecutor.java
@@ -0,0 +1,83 @@
+/*
+ * 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.executor.tag;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.UnauthorizedObjectAccessException;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.AbstractSetEntityMultipleRelationsExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.experiment.IMapExperimentByIdExecutor;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentByIdentiferValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetTagExperimentsExecutor extends AbstractSetEntityMultipleRelationsExecutor<TagCreation, MetaprojectPE, IExperimentId, ExperimentPE>
+        implements ISetTagExperimentsExecutor
+{
+
+    @Autowired
+    private IMapExperimentByIdExecutor mapExperimentExecutor;
+
+    @Autowired
+    private ISetTagExperimentsWithCacheExecutor setTagExperimentsWithCacheExecutor;
+
+    @Override
+    protected void addRelatedIds(Set<IExperimentId> relatedIds, TagCreation creation, MetaprojectPE entity)
+    {
+        addRelatedIds(relatedIds, creation.getExperimentIds());
+    }
+
+    @Override
+    protected void addRelated(Map<IExperimentId, ExperimentPE> relatedMap, TagCreation creation, MetaprojectPE entity)
+    {
+        // nothing to do here
+    }
+
+    @Override
+    protected Map<IExperimentId, ExperimentPE> map(IOperationContext context, List<IExperimentId> relatedIds)
+    {
+        return mapExperimentExecutor.map(context, relatedIds);
+    }
+
+    @Override
+    protected void check(IOperationContext context, IExperimentId relatedId, ExperimentPE related)
+    {
+        if (false == new ExperimentByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), related))
+        {
+            throw new UnauthorizedObjectAccessException(relatedId);
+        }
+    }
+
+    @Override
+    protected void set(IOperationContext context, Map<TagCreation, MetaprojectPE> creationsMap, Map<IExperimentId, ExperimentPE> relatedMap)
+    {
+        setTagExperimentsWithCacheExecutor.set(context, creationsMap, relatedMap);
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagExperimentsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagExperimentsWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..20a763b243b7b430baa958ad005f18d4b3f45bbf
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagExperimentsWithCacheExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * 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.executor.tag;
+
+import java.util.Collection;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetTagExperimentsWithCacheExecutor extends SetTagEntitiesWithCacheExecutor<IExperimentId, ExperimentPE>
+        implements ISetTagExperimentsWithCacheExecutor
+{
+
+    @Override
+    protected Class<ExperimentPE> getRelatedClass()
+    {
+        return ExperimentPE.class;
+    }
+
+    @Override
+    protected Collection<? extends IExperimentId> getRelatedIds(IOperationContext context, TagCreation creation)
+    {
+        return creation.getExperimentIds();
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagSamplesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagSamplesExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4533130cef12d80fc8d470268a35edb5f2bddf0
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagSamplesExecutor.java
@@ -0,0 +1,83 @@
+/*
+ * 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.executor.tag;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.UnauthorizedObjectAccessException;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.AbstractSetEntityMultipleRelationsExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.sample.IMapSampleByIdExecutor;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SampleByIdentiferValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetTagSamplesExecutor extends AbstractSetEntityMultipleRelationsExecutor<TagCreation, MetaprojectPE, ISampleId, SamplePE>
+        implements ISetTagSamplesExecutor
+{
+
+    @Autowired
+    private IMapSampleByIdExecutor mapSampleExecutor;
+
+    @Autowired
+    private ISetTagSamplesWithCacheExecutor setTagSamplesWithCacheExecutor;
+
+    @Override
+    protected void addRelatedIds(Set<ISampleId> relatedIds, TagCreation creation, MetaprojectPE entity)
+    {
+        addRelatedIds(relatedIds, creation.getSampleIds());
+    }
+
+    @Override
+    protected void addRelated(Map<ISampleId, SamplePE> relatedMap, TagCreation creation, MetaprojectPE entity)
+    {
+        // nothing to do here
+    }
+
+    @Override
+    protected Map<ISampleId, SamplePE> map(IOperationContext context, List<ISampleId> relatedIds)
+    {
+        return mapSampleExecutor.map(context, relatedIds);
+    }
+
+    @Override
+    protected void check(IOperationContext context, ISampleId relatedId, SamplePE related)
+    {
+        if (false == new SampleByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), related))
+        {
+            throw new UnauthorizedObjectAccessException(relatedId);
+        }
+    }
+
+    @Override
+    protected void set(IOperationContext context, Map<TagCreation, MetaprojectPE> creationsMap, Map<ISampleId, SamplePE> relatedMap)
+    {
+        setTagSamplesWithCacheExecutor.set(context, creationsMap, relatedMap);
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagSamplesWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagSamplesWithCacheExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ffea2d97df178bc1efa56c62501f2d7e1d732775
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/SetTagSamplesWithCacheExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * 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.executor.tag;
+
+import java.util.Collection;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetTagSamplesWithCacheExecutor extends SetTagEntitiesWithCacheExecutor<ISampleId, SamplePE>
+        implements ISetTagSamplesWithCacheExecutor
+{
+
+    @Override
+    protected Class<SamplePE> getRelatedClass()
+    {
+        return SamplePE.class;
+    }
+
+    @Override
+    protected Collection<? extends ISampleId> getRelatedIds(IOperationContext context, TagCreation creation)
+    {
+        return creation.getSampleIds();
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagDataSetsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagDataSetsWithCacheExecutor.java
index ece5c87c35dbc7ab0dfb1e6d05822019a69df522..52fdce7a2bcbcf6a78d6f4e2b167d144a0b53310 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagDataSetsWithCacheExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagDataSetsWithCacheExecutor.java
@@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
  * @author pkupczyk
  */
 @Component
-public class UpdateTagDataSetsWithCacheExecutor extends UpdateTagEntitiesExecutor<IDataSetId, DataPE> implements IUpdateTagDataSetsWithCacheExecutor
+public class UpdateTagDataSetsWithCacheExecutor extends UpdateTagEntitiesWithCacheExecutor<IDataSetId, DataPE> implements IUpdateTagDataSetsWithCacheExecutor
 {
 
     @Override
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagEntitiesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagEntitiesWithCacheExecutor.java
similarity index 77%
rename from openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagEntitiesExecutor.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagEntitiesWithCacheExecutor.java
index 9d9d96aed04c9b837a2f64e027a1d094e22872b1..5a5680ce56388c65b40d86cdf4353cb9aefbd928 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagEntitiesExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagEntitiesWithCacheExecutor.java
@@ -25,10 +25,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.update.TagUpdate;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.IReindexObjectExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.AbstractUpdateEntityToManyRelationExecutor;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IFullTextIndexUpdateScheduler;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IndexUpdateOperation;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityWithMetaprojects;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
@@ -36,13 +35,16 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 /**
  * @author pkupczyk
  */
-public abstract class UpdateTagEntitiesExecutor<RELATED_ID, RELATED_PE extends IEntityWithMetaprojects>
+public abstract class UpdateTagEntitiesWithCacheExecutor<RELATED_ID, RELATED_PE extends IEntityWithMetaprojects>
         extends AbstractUpdateEntityToManyRelationExecutor<TagUpdate, MetaprojectPE, RELATED_ID, RELATED_PE>
 {
 
     @Autowired
     private IDAOFactory daoFactory;
 
+    @Autowired
+    private IReindexObjectExecutor reindexObjectExecutor;
+
     protected abstract Class<RELATED_PE> getRelatedClass();
 
     protected abstract RELATED_PE getCurrentlyRelated(MetaprojectAssignmentPE entity);
@@ -54,21 +56,7 @@ public abstract class UpdateTagEntitiesExecutor<RELATED_ID, RELATED_PE extends I
 
         daoFactory.getSessionFactory().getCurrentSession().flush();
 
-        IFullTextIndexUpdateScheduler indexUpdater = daoFactory.getPersistencyResources().getIndexUpdateScheduler();
-        List<Long> relatedIds = new ArrayList<Long>();
-
-        for (RELATED_PE related : relatedMap.values())
-        {
-            if (related != null)
-            {
-                relatedIds.add(related.getId());
-            }
-        }
-
-        if (false == relatedIds.isEmpty())
-        {
-            indexUpdater.scheduleUpdate(IndexUpdateOperation.reindex(getRelatedClass(), relatedIds));
-        }
+        reindexObjectExecutor.reindex(context, getRelatedClass(), relatedMap.values());
     }
 
     @Override
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagExperimentsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagExperimentsWithCacheExecutor.java
index 7bbed276a12af2055fa460e1c1c5b8f81c822037..ab7bb302cf442b76a63c0e555fd76de3f55ba082 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagExperimentsWithCacheExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagExperimentsWithCacheExecutor.java
@@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
  * @author pkupczyk
  */
 @Component
-public class UpdateTagExperimentsWithCacheExecutor extends UpdateTagEntitiesExecutor<IExperimentId, ExperimentPE>
+public class UpdateTagExperimentsWithCacheExecutor extends UpdateTagEntitiesWithCacheExecutor<IExperimentId, ExperimentPE>
         implements IUpdateTagExperimentsWithCacheExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagMaterialsWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagMaterialsWithCacheExecutor.java
index 8b9ff6f2a6c5e2ac4f6ec066dfd28f6d59440d1a..55eddd259f8ba56c6a4c0ad55167cb151cce8285 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagMaterialsWithCacheExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagMaterialsWithCacheExecutor.java
@@ -30,7 +30,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
  * @author pkupczyk
  */
 @Component
-public class UpdateTagMaterialsWithCacheExecutor extends UpdateTagEntitiesExecutor<IMaterialId, MaterialPE>
+public class UpdateTagMaterialsWithCacheExecutor extends UpdateTagEntitiesWithCacheExecutor<IMaterialId, MaterialPE>
         implements IUpdateTagMaterialsWithCacheExecutor
 {
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagSamplesWithCacheExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagSamplesWithCacheExecutor.java
index b10dddce7ddac68d108cd7bfece40b9f561b2fb6..78b1632a78b3ac4710cc5e4370a62de5a9fc03dc 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagSamplesWithCacheExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/tag/UpdateTagSamplesWithCacheExecutor.java
@@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
  * @author pkupczyk
  */
 @Component
-public class UpdateTagSamplesWithCacheExecutor extends UpdateTagEntitiesExecutor<ISampleId, SamplePE>
+public class UpdateTagSamplesWithCacheExecutor extends UpdateTagEntitiesWithCacheExecutor<ISampleId, SamplePE>
         implements IUpdateTagSamplesWithCacheExecutor
 {
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/tag/create/TagCreation.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/tag/create/TagCreation.js
index 51f55b8d5a78b281f4289516921295cd1fe162d7..687279feed967e5353eaea25ded9696cbc4f9bbf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/tag/create/TagCreation.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/tag/create/TagCreation.js
@@ -9,6 +9,10 @@ define([ "stjs" ], function(stjs) {
 		constructor.serialVersionUID = 1;
 		prototype.code = null;
 		prototype.description = null;
+		prototype.experimentIds = null;
+		prototype.sampleIds = null;
+		prototype.dataSetIds = null;
+		prototype.materialIds = null;
 
 		prototype.getCode = function() {
 			return this.code;
@@ -22,6 +26,47 @@ define([ "stjs" ], function(stjs) {
 		prototype.setDescription = function(description) {
 			this.description = description;
 		};
-	}, {});
+		prototype.getExperimentIds = function() {
+			return this.experimentIds;
+		};
+		prototype.setExperimentIds = function(experimentIds) {
+			this.experimentIds = experimentIds;
+		};
+		prototype.getSampleIds = function() {
+			return this.sampleIds;
+		};
+		prototype.setSampleIds = function(sampleIds) {
+			this.sampleIds = sampleIds;
+		};
+		prototype.getDataSetIds = function() {
+			return this.dataSetIds;
+		};
+		prototype.setDataSetIds = function(dataSetIds) {
+			this.dataSetIds = dataSetIds;
+		};
+		prototype.getMaterialIds = function() {
+			return this.materialIds;
+		};
+		prototype.setMaterialIds = function(materialIds) {
+			this.materialIds = materialIds;
+		};
+	}, {
+		experimentIds : {
+			name : "List",
+			arguments : [ "Object" ]
+		},
+		sampleIds : {
+			name : "List",
+			arguments : [ "Object" ]
+		},
+		dataSetIds : {
+			name : "List",
+			arguments : [ "Object" ]
+		},
+		materialIds : {
+			name : "List",
+			arguments : [ "Object" ]
+		}
+	});
 	return TagCreation;
 })
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateTagTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateTagTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..33b77f03c9e3076e39c00e925d3cca23b5917d93
--- /dev/null
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateTagTest.java
@@ -0,0 +1,227 @@
+/*
+ * 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.systemtest.asapi.v3;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentIdentifier;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdentifier;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+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.TagPermId;
+import ch.systemsx.cisd.common.action.IDelegatedAction;
+
+/**
+ * @author pkupczyk
+ */
+@Test(groups = { "before remote api" })
+public class CreateTagTest extends AbstractTest
+{
+
+    @Test
+    public void testCreateWithCodeNull()
+    {
+        assertUserFailureException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    TagCreation creation = new TagCreation();
+
+                    createTag(TEST_USER, PASSWORD, creation);
+                }
+            }, "Code cannot be empty");
+    }
+
+    @Test
+    public void testCreateWithCodeExisting()
+    {
+        assertUserFailureException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    TagCreation creation = new TagCreation();
+                    creation.setCode("TEST_METAPROJECTS");
+
+                    createTag(TEST_USER, PASSWORD, creation);
+                }
+            }, "Tag already exists in the database and needs to be unique");
+    }
+
+    @Test
+    public void testCreateWithCodeIncorrect()
+    {
+        assertUserFailureException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    TagCreation creation = new TagCreation();
+                    creation.setCode("i am incorrect");
+
+                    createTag(TEST_USER, PASSWORD, creation);
+                }
+            }, "Tag name cannot contain white spaces, commas, slashes or backslashes");
+    }
+
+    @Test
+    public void testCreateWithDescription()
+    {
+        TagCreation creation = new TagCreation();
+        creation.setCode("TEST_TAG");
+        creation.setDescription("test description");
+
+        Tag tag = createTag(TEST_USER, PASSWORD, creation);
+
+        assertEquals(tag.getDescription(), creation.getDescription());
+    }
+
+    @Test
+    public void testCreateWithExperiments()
+    {
+        final ExperimentIdentifier experimentId = new ExperimentIdentifier("/CISD/NEMO/EXP10");
+
+        TagCreation creation = new TagCreation();
+        creation.setCode("TEST_TAG");
+        creation.setExperimentIds(Arrays.asList(experimentId));
+
+        Tag tag = createTag(TEST_USER, PASSWORD, creation);
+
+        assertExperimentIdentifiers(tag.getExperiments(), experimentId.getIdentifier());
+    }
+
+    @Test
+    public void testCreateWithExperimentsUnauthorized()
+    {
+        final ExperimentIdentifier experimentId = new ExperimentIdentifier("/CISD/NEMO/EXP10");
+
+        assertUnauthorizedObjectAccessException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    TagCreation creation = new TagCreation();
+                    creation.setCode("TEST_TAG");
+                    creation.setExperimentIds(Arrays.asList(experimentId));
+
+                    createTag(TEST_SPACE_USER, PASSWORD, creation);
+                }
+            }, experimentId);
+    }
+
+    @Test
+    public void testCreateWithExperimentsNonexistent()
+    {
+        final ExperimentIdentifier experimentId = new ExperimentIdentifier("/CISD/NEMO/IDONTEXIST");
+
+        assertObjectNotFoundException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    TagCreation creation = new TagCreation();
+                    creation.setCode("TEST_TAG");
+                    creation.setExperimentIds(Arrays.asList(experimentId));
+
+                    createTag(TEST_USER, PASSWORD, creation);
+                }
+            }, experimentId);
+    }
+
+    @Test
+    public void testCreateWithSamples()
+    {
+        final SampleIdentifier sampleId = new SampleIdentifier("/CISD/CP-TEST-1");
+
+        TagCreation creation = new TagCreation();
+        creation.setCode("TEST_TAG");
+        creation.setSampleIds(Arrays.asList(sampleId));
+
+        Tag tag = createTag(TEST_USER, PASSWORD, creation);
+
+        assertSampleIdentifiers(tag.getSamples(), sampleId.getIdentifier());
+    }
+
+    @Test
+    public void testCreateWithSamplesUnauthorized()
+    {
+        final SampleIdentifier sampleId = new SampleIdentifier("/CISD/CP-TEST-1");
+
+        assertUnauthorizedObjectAccessException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    TagCreation creation = new TagCreation();
+                    creation.setCode("TEST_TAG");
+                    creation.setSampleIds(Arrays.asList(sampleId));
+
+                    createTag(TEST_SPACE_USER, PASSWORD, creation);
+                }
+            }, sampleId);
+    }
+
+    @Test
+    public void testCreateWithSamplesNonexistent()
+    {
+        final SampleIdentifier sampleId = new SampleIdentifier("/CISD/IDONTEXIST");
+
+        assertObjectNotFoundException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    TagCreation creation = new TagCreation();
+                    creation.setCode("TEST_TAG");
+                    creation.setSampleIds(Arrays.asList(sampleId));
+
+                    createTag(TEST_USER, PASSWORD, creation);
+                }
+            }, sampleId);
+    }
+
+    private Tag createTag(String user, String password, TagCreation creation)
+    {
+        String sessionToken = v3api.login(user, password);
+
+        List<TagPermId> ids = v3api.createTags(sessionToken, Arrays.asList(creation));
+
+        assertEquals(ids.size(), 1);
+
+        TagFetchOptions fetchOptions = new TagFetchOptions();
+        fetchOptions.withExperiments();
+        fetchOptions.withSamples();
+        fetchOptions.withDataSets();
+        fetchOptions.withMaterials();
+
+        Map<ITagId, Tag> map = v3api.mapTags(sessionToken, ids, fetchOptions);
+
+        assertEquals(map.size(), 1);
+
+        return map.get(ids.get(0));
+    }
+
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/create/TagCreation.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/create/TagCreation.java
index de34417a392e167a641c59fa6c8044c0bc56a81c..89b7fcc8a456765db28d966121d36473becc4c58 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/create/TagCreation.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/tag/create/TagCreation.java
@@ -17,7 +17,12 @@
 package ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create;
 
 import java.io.Serializable;
+import java.util.List;
 
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.id.IMaterialId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
 /**
@@ -32,6 +37,14 @@ public class TagCreation implements Serializable
 
     private String description;
 
+    private List<? extends IExperimentId> experimentIds;
+
+    private List<? extends ISampleId> sampleIds;
+
+    private List<? extends IDataSetId> dataSetIds;
+
+    private List<? extends IMaterialId> materialIds;
+
     public String getCode()
     {
         return code;
@@ -52,4 +65,44 @@ public class TagCreation implements Serializable
         this.description = description;
     }
 
+    public List<? extends IExperimentId> getExperimentIds()
+    {
+        return experimentIds;
+    }
+
+    public void setExperimentIds(List<? extends IExperimentId> experimentIds)
+    {
+        this.experimentIds = experimentIds;
+    }
+
+    public List<? extends ISampleId> getSampleIds()
+    {
+        return sampleIds;
+    }
+
+    public void setSampleIds(List<? extends ISampleId> sampleIds)
+    {
+        this.sampleIds = sampleIds;
+    }
+
+    public List<? extends IDataSetId> getDataSetIds()
+    {
+        return dataSetIds;
+    }
+
+    public void setDataSetIds(List<? extends IDataSetId> dataSetIds)
+    {
+        this.dataSetIds = dataSetIds;
+    }
+
+    public List<? extends IMaterialId> getMaterialIds()
+    {
+        return materialIds;
+    }
+
+    public void setMaterialIds(List<? extends IMaterialId> materialIds)
+    {
+        this.materialIds = materialIds;
+    }
+
 }
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 4e56f69d79438b6d917696a87923e8aec253db17..0b05d31cc93d1e5853f70d641e6b2ea088618fff 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
@@ -1126,4 +1126,8 @@ set Tag Id
 Tag Update
 update Tags
 create Tags
-Tag Creation
\ No newline at end of file
+Tag Creation
+set DataSet Ids
+set Experiment Ids
+set Material Ids
+set Sample Ids
\ No newline at end of file