From 7d442e2290411e858a4be2818a17fe0be130b5f3 Mon Sep 17 00:00:00 2001
From: pkupczyk <pkupczyk>
Date: Thu, 16 Oct 2014 14:16:47 +0000
Subject: [PATCH] SSDM-942 : V3 AS API - authorization predicates

SVN: 32620
---
 .../server/api/v3/ApplicationServerApi.java   |  19 ++-
 .../ListExperimentCreationPredicate.java      |  89 ----------
 .../AbstractListObjectByIdExecutor.java       |  42 +++++
 .../common/AbstractMapObjectByIdExecutor.java |  51 ++++++
 .../common/IListObjectByIdExecutor.java       |  33 ++++
 .../common/IMapObjectByIdExecutor.java        |  33 ++++
 .../entity/MapEntityTypeByIdExecutor.java     |  30 +---
 .../experiment/CreateExperimentExecutor.java  |  12 +-
 .../IListExperimentByIdExecutor.java          |   9 +-
 .../IMapExperimentByIdExecutor.java           |   9 +-
 .../ListExperimentByIdExecutor.java           |  15 +-
 .../experiment/MapExperimentByIdExecutor.java |  51 ++----
 .../experiment/UpdateExperimentExecutor.java  |  10 ++
 .../project/IListProjectByIdExecutor.java     |  29 ++++
 .../project/IMapProjectByIdExecutor.java      |  29 ++++
 .../project/ListProjectByIdExecutor.java      |  53 ++++++
 .../project/MapProjectByIdExecutor.java       |  70 ++++++++
 .../project/TryGetProjectByIdExecutor.java    |  37 ++---
 ...stractSetSampleRelatedSamplesExecutor.java |  39 ++---
 ...actUpdateSampleRelatedSamplesExecutor.java |  68 ++++----
 .../executor/sample/CreateSampleExecutor.java | 146 ++++++----------
 .../sample/IListSampleByIdExecutor.java       |   9 +-
 .../sample/IMapSampleByIdExecutor.java        |  29 ++++
 .../sample/ISetSampleChildrenExecutor.java    |   2 +-
 .../sample/ISetSampleContainedExecutor.java   |   2 +-
 .../sample/ISetSampleContainerExecutor.java   |   2 +-
 .../sample/ISetSampleExperimentExecutor.java  |  33 ++++
 .../sample/ISetSampleParentsExecutor.java     |   2 +-
 .../sample/ISetSampleSpaceExecutor.java       |  33 ++++
 .../sample/ISetSampleTypeExecutor.java        |  33 ++++
 .../sample/IUpdateSampleChildrenExecutor.java |   2 +-
 .../IUpdateSampleContainedExecutor.java       |   2 +-
 .../IUpdateSampleContainerExecutor.java       |   2 +-
 .../sample/IUpdateSampleParentsExecutor.java  |   2 +-
 .../sample/ListSampleByIdExecutor.java        |  36 +---
 .../sample/MapSampleByIdExecutor.java         |  75 +++++++++
 .../sample/SetSampleChildrenExecutor.java     |  43 ++---
 .../sample/SetSampleContainedExecutor.java    |  27 +--
 .../sample/SetSampleContainerExecutor.java    |  33 ++--
 .../sample/SetSampleExperimentExecutor.java   |  87 ++++++++++
 .../sample/SetSampleParentsExecutor.java      |  44 ++---
 .../SetSampleRelatedSamplesExecutor.java      |  45 +++--
 .../sample/SetSampleSpaceExecutor.java        |  87 ++++++++++
 .../sample/SetSampleTypeExecutor.java         |  85 ++++++++++
 .../sample/UpdateSampleChildrenExecutor.java  |  75 +++++----
 .../sample/UpdateSampleContainedExecutor.java |  89 ++++++++--
 .../sample/UpdateSampleContainerExecutor.java |  43 ++---
 .../executor/sample/UpdateSampleExecutor.java |  10 ++
 .../UpdateSampleExperimentExecutor.java       |  12 ++
 .../sample/UpdateSampleParentsExecutor.java   |  75 +++++----
 .../UpdateSampleRelatedSamplesExecutor.java   |  38 ++---
 .../sample/UpdateSampleSpaceExecutor.java     |  12 ++
 .../space/IListSpaceByIdExecutor.java         |   9 +-
 .../executor/space/IMapSpaceByIdExecutor.java |   9 +-
 .../executor/space/ListSpaceByIdExecutor.java |  15 +-
 .../executor/space/MapSpaceByIdExecutor.java  |  49 ++----
 .../v3/helper/common/IListObjectById.java}    |  12 +-
 .../api/v3/helper/common/MapObjectById.java}  |  76 +++++----
 .../entity/ListEntityTypeByPermId.java}       |  22 +--
 .../experiment/ListExperimentByPermId.java}   |  25 ++-
 .../project/ListProjectByIdentifier.java      |  67 ++++++++
 .../helper/project/ListProjectByPermId.java   |  65 ++++++++
 .../sample/ListSampleByIdentifier.java}       |  39 +++--
 .../v3/helper/sample/ListSampleByPermId.java} |  25 ++-
 .../v3/helper/space/ListSpaceByPermId.java}   |  25 ++-
 .../EntityTypePermIdTranslator.java           |  35 ----
 .../entitytype/IEntityTypeIdTranslator.java   |  43 -----
 .../ExperimentIdentifierIdTranslator.java     |  35 ----
 .../ExperimentPermIdTranslator.java           |  35 ----
 .../experiment/IExperimentIdTranslator.java   |  48 ------
 .../id/sample/ISampleIdTranslator.java        |  48 ------
 .../sample/SampleIdentifierIdTranslator.java  |  35 ----
 .../id/sample/SamplePermIdTranslator.java     |  35 ----
 .../id/space/ISpaceIdTranslator.java          |  44 -----
 .../id/space/SpacePermIdTranslator.java       |  35 ----
 .../experiment/ExperimentValidator.java       |  46 -----
 .../api/v3/validator/entity/sample/.gitignore |   0
 .../ListerByExperimentTechIdId.java           |  66 --------
 .../id/sample/ListerBySampleTechIdId.java     |  66 --------
 .../server/dataaccess/IExperimentDAO.java     |  21 ++-
 .../server/dataaccess/IProjectDAO.java        |  11 ++
 .../server/dataaccess/db/ProjectDAO.java      |  29 ++++
 .../openbis/generic/shared/dto/SamplePE.java  |   3 +-
 .../MapExperimentByIdExecutorTest.java        |   5 +-
 .../project/MapProjectByIdExecutorTest.java   | 157 ++++++++++++++++++
 .../TryGetProjectByIdExecutorTest.java        |  75 ++-------
 .../api/v3/ExperimentCreateTest.java          |  15 +-
 .../api/v3/ExperimentUpdateTest.java          |  46 ++++-
 .../systemtest/api/v3/SampleCreateTest.java   | 157 +++++++++++++++++-
 .../systemtest/api/v3/SampleUpdateTest.java   | 147 +++++++++++++++-
 .../exceptions/ObjectNotFoundException.java   |  35 ++++
 91 files changed, 2198 insertions(+), 1455 deletions(-)
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/authorization/predicate/ListExperimentCreationPredicate.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractListObjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractMapObjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IListObjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IMapObjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IListProjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IMapProjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/ListProjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IMapSampleByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleExperimentExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleSpaceExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleTypeExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/MapSampleByIdExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleExperimentExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleSpaceExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleTypeExecutor.java
 rename openbis/source/java/ch/{systemsx/cisd/openbis/generic/server/business/search/id/IListerById.java => ethz/sis/openbis/generic/server/api/v3/helper/common/IListObjectById.java} (68%)
 rename openbis/source/java/ch/{systemsx/cisd/openbis/generic/server/business/search/id/ListerById.java => ethz/sis/openbis/generic/server/api/v3/helper/common/MapObjectById.java} (51%)
 rename openbis/source/java/ch/{systemsx/cisd/openbis/generic/server/business/search/id/entitytype/ListerByEntityTypePermIdId.java => ethz/sis/openbis/generic/server/api/v3/helper/entity/ListEntityTypeByPermId.java} (64%)
 rename openbis/source/java/ch/{systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentPermIdId.java => ethz/sis/openbis/generic/server/api/v3/helper/experiment/ListExperimentByPermId.java} (56%)
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByIdentifier.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByPermId.java
 rename openbis/source/java/ch/{systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleIdentifierId.java => ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByIdentifier.java} (81%)
 rename openbis/source/java/ch/{systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySamplePermIdId.java => ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByPermId.java} (58%)
 rename openbis/source/java/ch/{systemsx/cisd/openbis/generic/server/business/search/id/space/ListerBySpacePermIdId.java => ethz/sis/openbis/generic/server/api/v3/helper/space/ListSpaceByPermId.java} (59%)
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/EntityTypePermIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/IEntityTypeIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentIdentifierIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentPermIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/IExperimentIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/ISampleIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SampleIdentifierIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SamplePermIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/ISpaceIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/SpacePermIdTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/validator/entity/experiment/ExperimentValidator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/validator/entity/sample/.gitignore
 delete mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentTechIdId.java
 delete mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleTechIdId.java
 create mode 100644 openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutorTest.java
 create mode 100644 openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/exceptions/ObjectNotFoundException.java

diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java
index f9a0d185643..b4b206954d5 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java
@@ -16,8 +16,8 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3;
 
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 
 import javax.annotation.Resource;
@@ -26,7 +26,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-import ch.ethz.sis.openbis.generic.server.api.v3.authorization.predicate.ListExperimentCreationPredicate;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.OperationContext;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.ICreateExperimentExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IListExperimentByIdExecutor;
@@ -63,7 +62,6 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterio
 import ch.systemsx.cisd.openbis.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServer;
 import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
-import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.AuthorizationGuard;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.RolesAllowed;
 import ch.systemsx.cisd.openbis.generic.server.business.IPropertiesBatchManager;
 import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
@@ -167,7 +165,6 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     { RoleWithHierarchy.SPACE_USER })
     @DatabaseCreateOrDeleteModification(value = ObjectKind.EXPERIMENT)
     public List<ExperimentPermId> createExperiments(String sessionToken,
-            @AuthorizationGuard(guardClass = ListExperimentCreationPredicate.class)
             List<ExperimentCreation> creations)
     {
         // REPLACES:
@@ -187,7 +184,11 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
 
     @Override
     @Transactional
-    public List<SamplePermId> createSamples(String sessionToken, List<SampleCreation> creations)
+    @RolesAllowed(
+    { RoleWithHierarchy.SPACE_USER })
+    @DatabaseCreateOrDeleteModification(value = ObjectKind.SAMPLE)
+    public List<SamplePermId> createSamples(String sessionToken,
+            List<SampleCreation> creations)
     {
         Session session = getSession(sessionToken);
         OperationContext context = new OperationContext(session);
@@ -265,7 +266,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
 
         List<ExperimentPE> experiments = listExperimentByIdExecutor.list(context, experimentIds);
 
-        return new LinkedList<Experiment>(
+        return new ArrayList<Experiment>(
                 new ExperimentTranslator(new TranslationContext(session), managedPropertyEvaluatorFactory, fetchOptions).translate(experiments));
     }
 
@@ -280,7 +281,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
 
         List<SamplePE> samples = listSampleByIdExecutor.list(context, sampleIds);
 
-        return new LinkedList<Sample>(
+        return new ArrayList<Sample>(
                 new SampleTranslator(new TranslationContext(session), managedPropertyEvaluatorFactory, fetchOptions).translate(samples));
     }
 
@@ -305,7 +306,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
 
         List<ExperimentPE> experiments = getDAOFactory().getExperimentDAO().listByIDs(experimentIds);
 
-        return new LinkedList<Experiment>(
+        return new ArrayList<Experiment>(
                 new ExperimentTranslator(new TranslationContext(session), managedPropertyEvaluatorFactory, fetchOptions).translate(experiments));
     }
 
@@ -329,7 +330,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
 
         List<SamplePE> samples = getDAOFactory().getSampleDAO().listByIDs(sampleIds);
 
-        return new LinkedList<Sample>(
+        return new ArrayList<Sample>(
                 new SampleTranslator(new TranslationContext(session), managedPropertyEvaluatorFactory, fetchOptions).translate(samples));
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/authorization/predicate/ListExperimentCreationPredicate.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/authorization/predicate/ListExperimentCreationPredicate.java
deleted file mode 100644
index 42dac1ad6b3..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/authorization/predicate/ListExperimentCreationPredicate.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package ch.ethz.sis.openbis.generic.server.api.v3.authorization.predicate;
-
-/*
- * Copyright 2014 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.
- */
-
-import java.util.List;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.OperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.TryGetProjectByIdExecutor;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentCreation;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
-import ch.systemsx.cisd.common.exceptions.Status;
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.openbis.generic.server.authorization.IAuthorizationDataProvider;
-import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
-import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.ShouldFlattenCollections;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ProjectPEPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
-
-/**
- * @author Jakub Straszewski
- * @author Franz-Josef Elmer
- */
-@ShouldFlattenCollections(value = false)
-public class ListExperimentCreationPredicate extends AbstractPredicate<List<ExperimentCreation>>
-{
-    private IAuthorizationDataProvider provider;
-
-    private ProjectPEPredicate projectPredicate;
-
-    public ListExperimentCreationPredicate()
-    {
-        projectPredicate = new ProjectPEPredicate();
-    }
-
-    @Override
-    public void init(IAuthorizationDataProvider dataProvider)
-    {
-        this.provider = dataProvider;
-        projectPredicate.init(provider);
-    }
-
-    @Override
-    public String getCandidateDescription()
-    {
-        return "experiment creation";
-    }
-
-    @Override
-    protected Status doEvaluation(PersonPE person, List<RoleWithIdentifier> allowedRoles,
-            List<ExperimentCreation> experimentCreations)
-    {
-
-        for (ExperimentCreation experimentCreation : experimentCreations)
-        {
-            IProjectId projectId = experimentCreation.getProjectId();
-            if (projectId == null)
-            {
-                throw new UserFailureException(
-                        "Unspecified project for experiment to registered with code '"
-                                + experimentCreation.getCode() + "'.");
-            }
-            ProjectPE project =
-                    new TryGetProjectByIdExecutor(provider.getDaoFactory().getProjectDAO()).tryGet(new OperationContext(null), projectId);
-            Status status = projectPredicate.evaluate(person, allowedRoles, project);
-            if (status.isError())
-            {
-                return status;
-            }
-        }
-        return Status.OK;
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractListObjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractListObjectByIdExecutor.java
new file mode 100644
index 00000000000..fdd475ea421
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractListObjectByIdExecutor.java
@@ -0,0 +1,42 @@
+/*
+ * 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.generic.server.api.v3.executor.common;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.IObjectId;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class AbstractListObjectByIdExecutor<ID extends IObjectId, OBJECT> implements IListObjectByIdExecutor<ID, OBJECT>
+{
+
+    @Override
+    public List<OBJECT> list(IOperationContext context, Collection<? extends ID> ids)
+    {
+        Map<ID, OBJECT> map = getMapExecutor().map(context, ids);
+        return new ArrayList<OBJECT>(map.values());
+    }
+
+    protected abstract IMapObjectByIdExecutor<ID, OBJECT> getMapExecutor();
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractMapObjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractMapObjectByIdExecutor.java
new file mode 100644
index 00000000000..582edf7da02
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/AbstractMapObjectByIdExecutor.java
@@ -0,0 +1,51 @@
+/*
+ * 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.generic.server.api.v3.executor.common;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.MapObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.IObjectId;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class AbstractMapObjectByIdExecutor<ID extends IObjectId, OBJECT> implements IMapObjectByIdExecutor<ID, OBJECT>
+{
+
+    @Override
+    public Map<ID, OBJECT> map(IOperationContext context, Collection<? extends ID> ids)
+    {
+        if (ids == null)
+        {
+            throw new IllegalArgumentException("Ids were null");
+        }
+        if (ids.isEmpty())
+        {
+            return Collections.emptyMap();
+        }
+        return new MapObjectById<ID, OBJECT>().map(createListers(context), ids);
+    }
+
+    protected abstract List<IListObjectById<? extends ID, OBJECT>> createListers(IOperationContext context);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IListObjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IListObjectByIdExecutor.java
new file mode 100644
index 00000000000..76d43077412
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IListObjectByIdExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.generic.server.api.v3.executor.common;
+
+import java.util.Collection;
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.IObjectId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IListObjectByIdExecutor<ID extends IObjectId, OBJECT>
+{
+
+    public List<OBJECT> list(IOperationContext context, Collection<? extends ID> ids);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IMapObjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IMapObjectByIdExecutor.java
new file mode 100644
index 00000000000..26aa2c63956
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/common/IMapObjectByIdExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.generic.server.api.v3.executor.common;
+
+import java.util.Collection;
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.IObjectId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapObjectByIdExecutor<ID extends IObjectId, OBJECT>
+{
+
+    public Map<ID, OBJECT> map(IOperationContext context, Collection<? extends ID> ids);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/entity/MapEntityTypeByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/entity/MapEntityTypeByIdExecutor.java
index 94d4b2b248b..1fb8c8418ae 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/entity/MapEntityTypeByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/entity/MapEntityTypeByIdExecutor.java
@@ -17,7 +17,6 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.entity;
 
 import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -26,12 +25,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.collection.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.id.entitytype.IEntityTypeIdTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.MapObjectById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.entity.ListEntityTypeByPermId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.IEntityTypeId;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.ListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.entitytype.ListerByEntityTypePermIdId;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
@@ -59,24 +56,11 @@ public class MapEntityTypeByIdExecutor implements IMapEntityTypeByIdExecutor
     @Override
     public Map<IEntityTypeId, EntityTypePE> map(IOperationContext context, EntityKind entityKind, Collection<? extends IEntityTypeId> entityTypeIds)
     {
-        List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.entitytype.IEntityTypeId> entityTypeIdsCore =
-                new ListTranslator().translate(entityTypeIds, new IEntityTypeIdTranslator());
+        List<IListObjectById<? extends IEntityTypeId, EntityTypePE>> listers =
+                new LinkedList<IListObjectById<? extends IEntityTypeId, EntityTypePE>>();
+        listers.add(new ListEntityTypeByPermId(daoFactory, entityKind));
 
-        @SuppressWarnings("rawtypes")
-        List<IListerById> listers = new LinkedList<IListerById>();
-        listers.add(new ListerByEntityTypePermIdId(daoFactory, entityKind));
-
-        List<EntityTypePE> list = new ListerById(listers).list(entityTypeIdsCore);
-        Map<IEntityTypeId, EntityTypePE> map = new LinkedHashMap<IEntityTypeId, EntityTypePE>();
-        int index = 0;
-
-        for (IEntityTypeId entityTypeId : entityTypeIds)
-        {
-            map.put(entityTypeId, list.get(index));
-            index++;
-        }
-
-        return map;
+        return new MapObjectById<IEntityTypeId, EntityTypePE>().map(listers, entityTypeIds);
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/CreateExperimentExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/CreateExperimentExecutor.java
index a12565f46b2..6312387aeae 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/CreateExperimentExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/CreateExperimentExecutor.java
@@ -31,10 +31,13 @@ import ch.ethz.sis.openbis.generic.server.api.v3.executor.tag.IAddTagToEntityExe
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentCreation;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.IEntityTypeId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ProjectByIdentiferValidator;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.util.RelationshipUtils;
 
@@ -114,7 +117,14 @@ public class CreateExperimentExecutor implements ICreateExperimentExecutor
 
         updateEntityPropertyExecutor.update(context, experiment, entityType, experimentCreation.getProperties());
 
-        experiment.setProject(getProjectByIdExecutor.get(context, experimentCreation.getProjectId()));
+        ProjectPE project = getProjectByIdExecutor.get(context, experimentCreation.getProjectId());
+
+        if (false == new ProjectByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), project))
+        {
+            throw new AuthorizationFailureException("Cannot access project " + experimentCreation.getProjectId());
+        }
+
+        experiment.setProject(project);
 
         String createdPermId = daoFactory.getPermIdDAO().createPermId();
         experiment.setPermId(createdPermId);
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IListExperimentByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IListExperimentByIdExecutor.java
index 6ac0499fd42..c1289dd2836 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IListExperimentByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IListExperimentByIdExecutor.java
@@ -16,19 +16,14 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment;
 
-import java.util.Collection;
-import java.util.List;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IListObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 
 /**
  * @author pkupczyk
  */
-public interface IListExperimentByIdExecutor
+public interface IListExperimentByIdExecutor extends IListObjectByIdExecutor<IExperimentId, ExperimentPE>
 {
 
-    public List<ExperimentPE> list(IOperationContext context, Collection<? extends IExperimentId> experimentIds);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IMapExperimentByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IMapExperimentByIdExecutor.java
index a24a1f54854..9cfcea6dcb8 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IMapExperimentByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/IMapExperimentByIdExecutor.java
@@ -16,19 +16,14 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment;
 
-import java.util.Collection;
-import java.util.Map;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 
 /**
  * @author pkupczyk
  */
-public interface IMapExperimentByIdExecutor
+public interface IMapExperimentByIdExecutor extends IMapObjectByIdExecutor<IExperimentId, ExperimentPE>
 {
 
-    public Map<IExperimentId, ExperimentPE> map(IOperationContext context, Collection<? extends IExperimentId> experimentIds);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/ListExperimentByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/ListExperimentByIdExecutor.java
index 91071f9ccbd..56c960d5051 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/ListExperimentByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/ListExperimentByIdExecutor.java
@@ -16,15 +16,11 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment;
 
-import java.util.ArrayList;
-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.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractListObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 
@@ -32,7 +28,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
  * @author pkupczyk
  */
 @Component
-public class ListExperimentByIdExecutor implements IListExperimentByIdExecutor
+public class ListExperimentByIdExecutor extends AbstractListObjectByIdExecutor<IExperimentId, ExperimentPE> implements IListExperimentByIdExecutor
 {
 
     @Autowired
@@ -49,10 +45,9 @@ public class ListExperimentByIdExecutor implements IListExperimentByIdExecutor
     }
 
     @Override
-    public List<ExperimentPE> list(IOperationContext context, Collection<? extends IExperimentId> experimentIds)
+    protected IMapObjectByIdExecutor<IExperimentId, ExperimentPE> getMapExecutor()
     {
-        Map<IExperimentId, ExperimentPE> map = mapExperimentByIdExecutor.map(context, experimentIds);
-        return new ArrayList<ExperimentPE>(map.values());
+        return mapExperimentByIdExecutor;
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutor.java
index 447feba1ac9..7e7e2e5e545 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutor.java
@@ -16,68 +16,53 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment;
 
-import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 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.server.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.collection.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.id.experiment.IExperimentIdTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.experiment.ListExperimentByPermId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.ListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.experiment.ListerByExperimentPermIdId;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.experiment.ListerByExperimentTechIdId;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 
 /**
  * @author pkupczyk
  */
 @Component
-public class MapExperimentByIdExecutor implements IMapExperimentByIdExecutor
+public class MapExperimentByIdExecutor extends AbstractMapObjectByIdExecutor<IExperimentId, ExperimentPE> implements IMapExperimentByIdExecutor
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
+    private IExperimentDAO experimentDAO;
 
     @SuppressWarnings("unused")
     private MapExperimentByIdExecutor()
     {
     }
 
-    public MapExperimentByIdExecutor(IDAOFactory daoFactory)
+    public MapExperimentByIdExecutor(IExperimentDAO experimentDAO)
     {
-        this.daoFactory = daoFactory;
+        this.experimentDAO = experimentDAO;
     }
 
     @Override
-    public Map<IExperimentId, ExperimentPE> map(IOperationContext context, Collection<? extends IExperimentId> experimentIds)
+    protected List<IListObjectById<? extends IExperimentId, ExperimentPE>> createListers(IOperationContext context)
     {
-        List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.IExperimentId> experimentIdsCore =
-                new ListTranslator().translate(experimentIds, new IExperimentIdTranslator());
-
-        @SuppressWarnings("rawtypes")
-        List<IListerById> listers = new LinkedList<IListerById>();
-        listers.add(new ListerByExperimentTechIdId(daoFactory));
-        listers.add(new ListerByExperimentPermIdId(daoFactory));
-
-        List<ExperimentPE> list = new ListerById(listers).list(experimentIdsCore);
-        Map<IExperimentId, ExperimentPE> map = new LinkedHashMap<IExperimentId, ExperimentPE>();
-        int index = 0;
-
-        for (IExperimentId experimentId : experimentIds)
-        {
-            map.put(experimentId, list.get(index));
-            index++;
-        }
+        List<IListObjectById<? extends IExperimentId, ExperimentPE>> listers =
+                new LinkedList<IListObjectById<? extends IExperimentId, ExperimentPE>>();
+        listers.add(new ListExperimentByPermId(experimentDAO));
+        return listers;
+    }
 
-        return map;
+    @Autowired
+    private void setDAOFactory(IDAOFactory daoFactory)
+    {
+        experimentDAO = daoFactory.getExperimentDAO();
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/UpdateExperimentExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/UpdateExperimentExecutor.java
index 355a52f3e89..058194026e4 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/UpdateExperimentExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/UpdateExperimentExecutor.java
@@ -35,6 +35,8 @@ import ch.ethz.sis.openbis.generic.server.api.v3.executor.property.IUpdateEntity
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.tag.IUpdateTagForEntityExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentByIdentiferValidator;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.util.RelationshipUtils;
@@ -110,6 +112,14 @@ public class UpdateExperimentExecutor implements IUpdateExperimentExecutor
 
         assert experimentIds.size() == experiments.size();
 
+        for (ExperimentPE experiment : experiments)
+        {
+            if (false == new ExperimentByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), experiment))
+            {
+                throw new AuthorizationFailureException("Cannot access experiment " + experiment.getIdentifier());
+            }
+        }
+
         Map<ExperimentUpdate, ExperimentPE> result = new HashMap<ExperimentUpdate, ExperimentPE>();
 
         Iterator<ExperimentUpdate> it1 = updates.iterator();
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IListProjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IListProjectByIdExecutor.java
new file mode 100644
index 00000000000..ac6ee7adfab
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IListProjectByIdExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014 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.api.v3.executor.project;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IListObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IListProjectByIdExecutor extends IListObjectByIdExecutor<IProjectId, ProjectPE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IMapProjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IMapProjectByIdExecutor.java
new file mode 100644
index 00000000000..6f50828b9c0
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IMapProjectByIdExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014 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.api.v3.executor.project;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapProjectByIdExecutor extends IMapObjectByIdExecutor<IProjectId, ProjectPE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/ListProjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/ListProjectByIdExecutor.java
new file mode 100644
index 00000000000..28d883b88b9
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/ListProjectByIdExecutor.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2014 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.api.v3.executor.project;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractListObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class ListProjectByIdExecutor extends AbstractListObjectByIdExecutor<IProjectId, ProjectPE> implements IListProjectByIdExecutor
+{
+
+    @Autowired
+    private IMapProjectByIdExecutor mapProjectByIdExecutor;
+
+    @SuppressWarnings("unused")
+    private ListProjectByIdExecutor()
+    {
+    }
+
+    public ListProjectByIdExecutor(IMapProjectByIdExecutor mapProjectByIdExecutor)
+    {
+        this.mapProjectByIdExecutor = mapProjectByIdExecutor;
+    }
+
+    @Override
+    protected IMapObjectByIdExecutor<IProjectId, ProjectPE> getMapExecutor()
+    {
+        return mapProjectByIdExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutor.java
new file mode 100644
index 00000000000..4e0a84a5092
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutor.java
@@ -0,0 +1,70 @@
+/*
+ * 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.generic.server.api.v3.executor.project;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.project.ListProjectByIdentifier;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.project.ListProjectByPermId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapProjectByIdExecutor extends AbstractMapObjectByIdExecutor<IProjectId, ProjectPE> implements IMapProjectByIdExecutor
+{
+
+    private IProjectDAO projectDAO;
+
+    @SuppressWarnings("unused")
+    private MapProjectByIdExecutor()
+    {
+    }
+
+    public MapProjectByIdExecutor(IProjectDAO projectDAO)
+    {
+        this.projectDAO = projectDAO;
+    }
+
+    @Override
+    protected List<IListObjectById<? extends IProjectId, ProjectPE>> createListers(IOperationContext context)
+    {
+        List<IListObjectById<? extends IProjectId, ProjectPE>> listers =
+                new LinkedList<IListObjectById<? extends IProjectId, ProjectPE>>();
+        listers.add(new ListProjectByIdentifier(projectDAO));
+        listers.add(new ListProjectByPermId(projectDAO));
+        return listers;
+    }
+
+    @Autowired
+    private void setDAOFactory(IDAOFactory daoFactory)
+    {
+        projectDAO = daoFactory.getProjectDAO();
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutor.java
index 31349b6b47e..d624801387c 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutor.java
@@ -16,18 +16,16 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.project;
 
+import java.util.Collections;
+import java.util.Map;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectIdentifier;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory;
 
 /**
  * @author pkupczyk
@@ -36,40 +34,29 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierF
 public class TryGetProjectByIdExecutor implements ITryGetProjectByIdExecutor
 {
 
-    private IProjectDAO projectDAO;
+    @Autowired
+    private IMapProjectByIdExecutor mapProjectByIdExecutor;
 
     @SuppressWarnings("unused")
     private TryGetProjectByIdExecutor()
     {
     }
 
-    public TryGetProjectByIdExecutor(IProjectDAO projectDAO)
+    public TryGetProjectByIdExecutor(IMapProjectByIdExecutor mapProjectByIdExecutor)
     {
-        this.projectDAO = projectDAO;
+        this.mapProjectByIdExecutor = mapProjectByIdExecutor;
     }
 
     @Override
     public ProjectPE tryGet(IOperationContext context, IProjectId projectId)
     {
-        if (projectId instanceof ProjectPermId)
-        {
-            ProjectPermId projectPermId = (ProjectPermId) projectId;
-            return projectDAO.tryGetByPermID(projectPermId.getPermId());
-        }
-        if (projectId instanceof ProjectIdentifier)
+        if (projectId == null)
         {
-            ProjectIdentifier projectIdentifier = (ProjectIdentifier) projectId;
-            ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier pid =
-                    ProjectIdentifierFactory.parse(projectIdentifier.getIdentifier());
-            return projectDAO.tryFindProject(pid.getSpaceCode(), pid.getProjectCode());
+            throw new UserFailureException("Unspecified project id.");
         }
-        throw new UnsupportedObjectIdException(projectId);
-    }
 
-    @Autowired
-    private void setDAOFactory(IDAOFactory daoFactory)
-    {
-        projectDAO = daoFactory.getProjectDAO();
+        Map<IProjectId, ProjectPE> projects = mapProjectByIdExecutor.map(context, Collections.singletonList(projectId));
+        return projects.get(projectId);
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractSetSampleRelatedSamplesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractSetSampleRelatedSamplesExecutor.java
index 51902b3fb00..71bc3306394 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractSetSampleRelatedSamplesExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractSetSampleRelatedSamplesExecutor.java
@@ -20,12 +20,9 @@ import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Map;
 
-import org.springframework.beans.factory.annotation.Autowired;
-
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -34,46 +31,32 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public abstract class AbstractSetSampleRelatedSamplesExecutor
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
-
-    protected AbstractSetSampleRelatedSamplesExecutor()
-    {
-    }
-
-    public AbstractSetSampleRelatedSamplesExecutor(IDAOFactory daoFactory)
-    {
-        this.daoFactory = daoFactory;
-    }
-
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, Long> techIdMap)
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, SamplePE> sampleMap)
     {
         for (SampleCreation creation : creationsMap.keySet())
         {
             SamplePE sample = creationsMap.get(creation);
-            Collection<? extends ISampleId> sampleIds = getRelatedSamplesIds(context, creation);
+            Collection<? extends ISampleId> relatedSampleIds = getRelatedSamplesIds(context, creation);
 
-            if (sampleIds != null)
+            if (relatedSampleIds != null)
             {
-                Collection<Long> sampleTechIds = new LinkedList<Long>();
+                Collection<SamplePE> relatedSamples = new LinkedList<SamplePE>();
 
-                for (ISampleId sampleId : sampleIds)
+                for (ISampleId relatedSampleId : relatedSampleIds)
                 {
-                    sampleTechIds.add(techIdMap.get(sampleId));
+                    relatedSamples.add(sampleMap.get(relatedSampleId));
                 }
 
-                setRelatedSamples(context, sample, sampleTechIds);
+                if (false == relatedSamples.isEmpty())
+                {
+                    setRelatedSamples(context, sample, relatedSamples);
+                }
             }
         }
     }
 
     protected abstract Collection<? extends ISampleId> getRelatedSamplesIds(IOperationContext context, SampleCreation creation);
 
-    protected abstract void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesTechIds);
-
-    public IDAOFactory getDaoFactory()
-    {
-        return daoFactory;
-    }
+    protected abstract void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<SamplePE> relatedSamples);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractUpdateSampleRelatedSamplesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractUpdateSampleRelatedSamplesExecutor.java
index 1e2bd7fd317..7f6be89010c 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractUpdateSampleRelatedSamplesExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/AbstractUpdateSampleRelatedSamplesExecutor.java
@@ -20,8 +20,6 @@ import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Map;
 
-import org.springframework.beans.factory.annotation.Autowired;
-
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue.ListUpdateAction;
@@ -30,7 +28,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue.List
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue.ListUpdateActionSet;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.ObjectNotFoundException;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -39,19 +37,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public abstract class AbstractUpdateSampleRelatedSamplesExecutor
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
-
-    protected AbstractUpdateSampleRelatedSamplesExecutor()
-    {
-    }
-
-    public AbstractUpdateSampleRelatedSamplesExecutor(IDAOFactory daoFactory)
-    {
-        this.daoFactory = daoFactory;
-    }
-
-    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, Long> techIdMap)
+    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, SamplePE> samplesMap)
     {
         for (SampleUpdate update : updateMap.keySet())
         {
@@ -63,22 +49,37 @@ public abstract class AbstractUpdateSampleRelatedSamplesExecutor
 
                 for (ListUpdateAction<? extends ISampleId> action : listUpdate.getActions())
                 {
-                    Collection<Long> relatedTechIds = new LinkedList<Long>();
+                    Collection<SamplePE> relatedSamples = new LinkedList<SamplePE>();
 
-                    for (ISampleId relatedId : action.getIds())
+                    if (action instanceof ListUpdateActionSet<?> || action instanceof ListUpdateActionAdd<?>)
                     {
-                        relatedTechIds.add(techIdMap.get(relatedId));
-                    }
-
-                    if (action instanceof ListUpdateActionSet<?>)
-                    {
-                        setRelatedSamples(context, sample, relatedTechIds);
-                    } else if (action instanceof ListUpdateActionAdd<?>)
-                    {
-                        addRelatedSamples(context, sample, relatedTechIds);
+                        for (ISampleId relatedId : action.getIds())
+                        {
+                            SamplePE relatedSample = samplesMap.get(relatedId);
+                            if (relatedSample == null)
+                            {
+                                throw new ObjectNotFoundException(relatedId);
+                            }
+                            relatedSamples.add(relatedSample);
+                        }
+                        if (action instanceof ListUpdateActionSet<?>)
+                        {
+                            setRelatedSamples(context, sample, relatedSamples);
+                        } else
+                        {
+                            addRelatedSamples(context, sample, relatedSamples);
+                        }
                     } else if (action instanceof ListUpdateActionRemove<?>)
                     {
-                        removeRelatedSamples(context, sample, relatedTechIds);
+                        for (ISampleId relatedId : action.getIds())
+                        {
+                            SamplePE relatedSample = samplesMap.get(relatedId);
+                            if (relatedSample != null)
+                            {
+                                relatedSamples.add(relatedSample);
+                            }
+                        }
+                        removeRelatedSamples(context, sample, relatedSamples);
                     }
                 }
             }
@@ -88,15 +89,10 @@ public abstract class AbstractUpdateSampleRelatedSamplesExecutor
 
     protected abstract ListUpdateValue<? extends ISampleId> getRelatedSamplesUpdate(IOperationContext context, SampleUpdate update);
 
-    protected abstract void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds);
+    protected abstract void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<SamplePE> relatedSamples);
 
-    protected abstract void addRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds);
+    protected abstract void addRelatedSamples(IOperationContext context, SamplePE sample, Collection<SamplePE> relatedSamples);
 
-    protected abstract void removeRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds);
-
-    public IDAOFactory getDaoFactory()
-    {
-        return daoFactory;
-    }
+    protected abstract void removeRelatedSamples(IOperationContext context, SamplePE sample, Collection<SamplePE> relatedSamples);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/CreateSampleExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/CreateSampleExecutor.java
index 3220c6b3096..c84fe0f29ac 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/CreateSampleExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/CreateSampleExecutor.java
@@ -16,37 +16,27 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 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.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.attachment.ICreateAttachmentExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IMapEntityTypeByIdExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IMapExperimentByIdExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.property.IUpdateEntityPropertyExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IMapSpaceByIdExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.tag.IAddTagToEntityExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.IEntityTypeId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SamplePermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.util.RelationshipUtils;
 
 /**
@@ -60,13 +50,13 @@ public class CreateSampleExecutor implements ICreateSampleExecutor
     private IDAOFactory daoFactory;
 
     @Autowired
-    private IMapEntityTypeByIdExecutor mapEntityTypeByIdExecutor;
+    private ISetSampleTypeExecutor setSampleTypeExecutor;
 
     @Autowired
-    private IMapSpaceByIdExecutor mapSpaceByIdExecutor;
+    private ISetSampleSpaceExecutor setSampleSpaceExecutor;
 
     @Autowired
-    private IMapExperimentByIdExecutor mapExperimentByIdExecutor;
+    private ISetSampleExperimentExecutor setSampleExperimentExecutor;
 
     @Autowired
     private ISetSampleRelatedSamplesExecutor setSampleRelatedSamplesExecutor;
@@ -88,16 +78,16 @@ public class CreateSampleExecutor implements ICreateSampleExecutor
     {
     }
 
-    public CreateSampleExecutor(IDAOFactory daoFactory, IMapEntityTypeByIdExecutor mapEntityTypeByIdExecutor,
-            IMapSpaceByIdExecutor mapSpaceByIdExecutor, IMapExperimentByIdExecutor mapExperimentByIdExecutor,
+    public CreateSampleExecutor(IDAOFactory daoFactory, ISetSampleTypeExecutor setSampleTypeExecutor,
+            ISetSampleSpaceExecutor setSampleSpaceExecutor, ISetSampleExperimentExecutor setSampleExperimentExecutor,
             ISetSampleRelatedSamplesExecutor setSampleRelatedSamplesExecutor, IUpdateEntityPropertyExecutor updateEntityPropertyExecutor,
             ICreateAttachmentExecutor createAttachmentExecutor, IAddTagToEntityExecutor addTagToEntityExecutor,
             IVerifySampleExecutor verifySampleExecutor)
     {
         this.daoFactory = daoFactory;
-        this.mapEntityTypeByIdExecutor = mapEntityTypeByIdExecutor;
-        this.mapSpaceByIdExecutor = mapSpaceByIdExecutor;
-        this.mapExperimentByIdExecutor = mapExperimentByIdExecutor;
+        this.setSampleTypeExecutor = setSampleTypeExecutor;
+        this.setSampleSpaceExecutor = setSampleSpaceExecutor;
+        this.setSampleExperimentExecutor = setSampleExperimentExecutor;
         this.setSampleRelatedSamplesExecutor = setSampleRelatedSamplesExecutor;
         this.updateEntityPropertyExecutor = updateEntityPropertyExecutor;
         this.createAttachmentExecutor = createAttachmentExecutor;
@@ -108,8 +98,9 @@ public class CreateSampleExecutor implements ICreateSampleExecutor
     @Override
     public List<SamplePermId> create(IOperationContext context, List<SampleCreation> creations)
     {
+        // TODO split this method
         List<SamplePermId> permIdsAll = new LinkedList<SamplePermId>();
-        HashMap<SampleCreation, SamplePE> samplesAll = new HashMap<SampleCreation, SamplePE>();
+        Map<SampleCreation, SamplePE> samplesAll = new LinkedHashMap<SampleCreation, SamplePE>();
 
         int batchSize = 1000;
         int batchStart = 0;
@@ -117,28 +108,34 @@ public class CreateSampleExecutor implements ICreateSampleExecutor
         while (batchStart < creations.size())
         {
             List<SampleCreation> creationsBatch = creations.subList(batchStart, Math.min(batchStart + batchSize, creations.size()));
-            List<SamplePE> samplesBatch = new LinkedList<SamplePE>();
+            Map<SampleCreation, SamplePE> batchMap = new LinkedHashMap<SampleCreation, SamplePE>();
 
             daoFactory.setBatchUpdateMode(true);
 
-            Map<IEntityTypeId, EntityTypePE> typeMap = getTypeMap(context, creationsBatch);
-            Map<ISpaceId, SpacePE> spaceMap = getSpaceMap(context, creationsBatch);
-            Map<IExperimentId, ExperimentPE> experimentMap = getExperimentMap(context, creationsBatch);
-
             for (SampleCreation creation : creationsBatch)
             {
                 context.pushContextDescription("register sample " + creation.getCode());
 
-                SamplePE sample = createSamplePE(context, creation, typeMap, spaceMap, experimentMap);
+                SamplePE sample = createSamplePE(context, creation);
 
                 permIdsAll.add(new SamplePermId(sample.getPermId()));
                 samplesAll.put(creation, sample);
-                samplesBatch.add(sample);
+                batchMap.put(creation, sample);
 
                 context.popContextDescription();
             }
 
-            daoFactory.getSampleDAO().createOrUpdateSamples(samplesBatch, context.getSession().tryGetPerson(), false);
+            setSampleSpaceExecutor.set(context, batchMap);
+            setSampleExperimentExecutor.set(context, batchMap);
+            setSampleTypeExecutor.set(context, batchMap);
+
+            for (Map.Entry<SampleCreation, SamplePE> batchEntry : batchMap.entrySet())
+            {
+                updateEntityPropertyExecutor.update(context, batchEntry.getValue(), batchEntry.getValue().getEntityType(), batchEntry.getKey()
+                        .getProperties());
+            }
+
+            daoFactory.getSampleDAO().createOrUpdateSamples(new ArrayList<SamplePE>(batchMap.values()), context.getSession().tryGetPerson(), false);
             daoFactory.setBatchUpdateMode(false);
 
             for (SampleCreation creation : creationsBatch)
@@ -154,53 +151,18 @@ public class CreateSampleExecutor implements ICreateSampleExecutor
             batchStart += batchSize;
         }
 
-        setSampleRelatedSamplesExecutor.set(context, samplesAll);
-        verifySamples(context, samplesAll.values());
-
-        return permIdsAll;
-    }
+        reloadSamples(samplesAll);
 
-    private Map<IEntityTypeId, EntityTypePE> getTypeMap(IOperationContext context, List<SampleCreation> creations)
-    {
-        Set<IEntityTypeId> ids = new HashSet<IEntityTypeId>();
-        for (SampleCreation creation : creations)
-        {
-            if (creation.getTypeId() != null)
-            {
-                ids.add(creation.getTypeId());
-            }
-        }
-        return mapEntityTypeByIdExecutor.map(context, EntityKind.SAMPLE, ids);
-    }
+        setSampleRelatedSamplesExecutor.set(context, samplesAll);
+        verifySampleExecutor.verify(context, samplesAll.values());
 
-    private Map<ISpaceId, SpacePE> getSpaceMap(IOperationContext context, List<SampleCreation> creations)
-    {
-        Set<ISpaceId> ids = new HashSet<ISpaceId>();
-        for (SampleCreation creation : creations)
-        {
-            if (creation.getSpaceId() != null)
-            {
-                ids.add(creation.getSpaceId());
-            }
-        }
-        return mapSpaceByIdExecutor.map(context, ids);
-    }
+        daoFactory.getSessionFactory().getCurrentSession().flush();
+        daoFactory.getSessionFactory().getCurrentSession().clear();
 
-    private Map<IExperimentId, ExperimentPE> getExperimentMap(IOperationContext context, List<SampleCreation> creations)
-    {
-        Set<IExperimentId> ids = new HashSet<IExperimentId>();
-        for (SampleCreation creation : creations)
-        {
-            if (creation.getExperimentId() != null)
-            {
-                ids.add(creation.getExperimentId());
-            }
-        }
-        return mapExperimentByIdExecutor.map(context, ids);
+        return permIdsAll;
     }
 
-    private SamplePE createSamplePE(IOperationContext context, SampleCreation sampleCreation, Map<IEntityTypeId, EntityTypePE> typeMap,
-            Map<ISpaceId, SpacePE> spaceMap, Map<IExperimentId, ExperimentPE> experimentMap)
+    private SamplePE createSamplePE(IOperationContext context, SampleCreation sampleCreation)
     {
         SamplePE sample = new SamplePE();
 
@@ -214,45 +176,35 @@ public class CreateSampleExecutor implements ICreateSampleExecutor
 
         String createdPermId = daoFactory.getPermIdDAO().createPermId();
         sample.setPermId(createdPermId);
+        sample.setRegistrator(context.getSession().tryGetPerson());
+        RelationshipUtils.updateModificationDateAndModifier(sample, context.getSession().tryGetPerson());
 
-        IEntityTypeId typeId = sampleCreation.getTypeId();
-        EntityTypePE entityType = typeMap.get(typeId);
-        sample.setSampleType((SampleTypePE) entityType);
+        return sample;
+    }
 
-        IExperimentId experimentId = sampleCreation.getExperimentId();
-        if (experimentId != null)
-        {
-            sample.setExperiment(experimentMap.get(experimentId));
-        }
+    private void reloadSamples(Map<SampleCreation, SamplePE> creationToSampleMap)
+    {
+        Collection<Long> ids = new HashSet<Long>();
 
-        ISpaceId spaceId = sampleCreation.getSpaceId();
-        if (spaceId != null)
+        for (SamplePE sample : creationToSampleMap.values())
         {
-            SpacePE space = spaceMap.get(spaceId);
-            sample.setSpace(space);
+            ids.add(sample.getId());
         }
 
-        updateEntityPropertyExecutor.update(context, sample, entityType, sampleCreation.getProperties());
-        sample.setRegistrator(context.getSession().tryGetPerson());
-        RelationshipUtils.updateModificationDateAndModifier(sample, context.getSession().tryGetPerson());
+        List<SamplePE> samples = daoFactory.getSampleDAO().listByIDs(ids);
 
-        return sample;
-    }
+        Map<Long, SamplePE> idToSampleMap = new HashMap<Long, SamplePE>();
 
-    private void verifySamples(IOperationContext context, Collection<SamplePE> samples)
-    {
-        Set<Long> techIds = new HashSet<Long>();
         for (SamplePE sample : samples)
         {
-            techIds.add(sample.getId());
+            idToSampleMap.put(sample.getId(), sample);
         }
 
-        daoFactory.getSessionFactory().getCurrentSession().flush();
-        daoFactory.getSessionFactory().getCurrentSession().clear();
-
-        Collection<SamplePE> freshSamples = daoFactory.getSampleDAO().listByIDs(techIds);
+        for (Map.Entry<SampleCreation, SamplePE> entry : creationToSampleMap.entrySet())
+        {
+            entry.setValue(idToSampleMap.get(entry.getValue().getId()));
+        }
 
-        verifySampleExecutor.verify(context, freshSamples);
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IListSampleByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IListSampleByIdExecutor.java
index cc02c18b202..72ae7222bb7 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IListSampleByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IListSampleByIdExecutor.java
@@ -16,19 +16,14 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
-import java.util.Collection;
-import java.util.List;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IListObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author pkupczyk
  */
-public interface IListSampleByIdExecutor
+public interface IListSampleByIdExecutor extends IListObjectByIdExecutor<ISampleId, SamplePE>
 {
 
-    public List<SamplePE> list(IOperationContext context, Collection<? extends ISampleId> sampleIds);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IMapSampleByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IMapSampleByIdExecutor.java
new file mode 100644
index 00000000000..617de604058
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IMapSampleByIdExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapSampleByIdExecutor extends IMapObjectByIdExecutor<ISampleId, SamplePE>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleChildrenExecutor.java
index 71a0ffebe1e..b274a242dfc 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleChildrenExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface ISetSampleChildrenExecutor
 {
 
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, Long> techIdMap);
+    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/api/v3/executor/sample/ISetSampleContainedExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleContainedExecutor.java
index 58713cd4803..6da84732aa1 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleContainedExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleContainedExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface ISetSampleContainedExecutor
 {
 
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, Long> techIdMap);
+    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/api/v3/executor/sample/ISetSampleContainerExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleContainerExecutor.java
index 97e74506f95..ea7de4bae7c 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleContainerExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleContainerExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface ISetSampleContainerExecutor
 {
 
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, Long> techIdMap);
+    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/api/v3/executor/sample/ISetSampleExperimentExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleExperimentExecutor.java
new file mode 100644
index 00000000000..a0e32ca0a64
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleExperimentExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetSampleExperimentExecutor
+{
+
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleParentsExecutor.java
index c0e457b94ac..32b8b3e483d 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleParentsExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface ISetSampleParentsExecutor
 {
 
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, Long> techIdMap);
+    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/api/v3/executor/sample/ISetSampleSpaceExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleSpaceExecutor.java
new file mode 100644
index 00000000000..9f12fa6976d
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleSpaceExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetSampleSpaceExecutor
+{
+
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleTypeExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleTypeExecutor.java
new file mode 100644
index 00000000000..0fd492f847f
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ISetSampleTypeExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISetSampleTypeExecutor
+{
+
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleChildrenExecutor.java
index 59264477583..345e832c94a 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleChildrenExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface IUpdateSampleChildrenExecutor
 {
 
-    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, Long> techIdMap);
+    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, SamplePE> sampleMap);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainedExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainedExecutor.java
index 2cac239d099..77818e909f9 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainedExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainedExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface IUpdateSampleContainedExecutor
 {
 
-    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, Long> techIdMap);
+    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, SamplePE> sampleMap);
 
 }
\ No newline at end of file
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainerExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainerExecutor.java
index 4335d25893a..56c119272d4 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainerExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleContainerExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface IUpdateSampleContainerExecutor
 {
 
-    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, Long> techIdMap);
+    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, SamplePE> sampleMap);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleParentsExecutor.java
index dd6574b6af6..88f3fcec9eb 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/IUpdateSampleParentsExecutor.java
@@ -29,6 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public interface IUpdateSampleParentsExecutor
 {
 
-    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, Long> techIdMap);
+    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, SamplePE> sampleMap);
 
 }
\ No newline at end of file
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleByIdExecutor.java
index 15677f34daa..0d6535e100b 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/ListSampleByIdExecutor.java
@@ -16,58 +16,38 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
-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.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.collection.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.id.sample.ISampleIdTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractListObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.ListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.sample.ListerBySampleIdentifierId;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.sample.ListerBySamplePermIdId;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.sample.ListerBySampleTechIdId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author pkupczyk
  */
 @Component
-public class ListSampleByIdExecutor implements IListSampleByIdExecutor
+public class ListSampleByIdExecutor extends AbstractListObjectByIdExecutor<ISampleId, SamplePE> implements IListSampleByIdExecutor
 {
 
     @Autowired
-    private IDAOFactory daoFactory;
+    private IMapSampleByIdExecutor mapSampleByIdExecutor;
 
     @SuppressWarnings("unused")
     private ListSampleByIdExecutor()
     {
     }
 
-    public ListSampleByIdExecutor(IDAOFactory daoFactory)
+    public ListSampleByIdExecutor(IMapSampleByIdExecutor mapSampleByIdExecutor)
     {
-        this.daoFactory = daoFactory;
+        this.mapSampleByIdExecutor = mapSampleByIdExecutor;
     }
 
     @Override
-    public List<SamplePE> list(IOperationContext context, Collection<? extends ISampleId> sampleIds)
+    protected IMapObjectByIdExecutor<ISampleId, SamplePE> getMapExecutor()
     {
-        List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.ISampleId> sampleIdsCore =
-                new ListTranslator().translate(sampleIds, new ISampleIdTranslator());
-
-        @SuppressWarnings("rawtypes")
-        List<IListerById> listers = new ArrayList<IListerById>();
-        listers.add(new ListerBySamplePermIdId(daoFactory));
-        listers.add(new ListerBySampleTechIdId(daoFactory));
-        listers.add(new ListerBySampleIdentifierId(daoFactory, context.getSession().tryGetPerson().getHomeSpace()));
-
-        return new ListerById(listers).list(sampleIdsCore);
+        return mapSampleByIdExecutor;
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/MapSampleByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/MapSampleByIdExecutor.java
new file mode 100644
index 00000000000..e9eb72dd69e
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/MapSampleByIdExecutor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.sample.ListSampleByIdentifier;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.sample.ListSampleByPermId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapSampleByIdExecutor extends AbstractMapObjectByIdExecutor<ISampleId, SamplePE> implements IMapSampleByIdExecutor
+{
+
+    private ISpaceDAO spaceDAO;
+
+    private ISampleDAO sampleDAO;
+
+    @SuppressWarnings("unused")
+    private MapSampleByIdExecutor()
+    {
+    }
+
+    public MapSampleByIdExecutor(ISpaceDAO spaceDAO, ISampleDAO sampleDAO)
+    {
+        this.spaceDAO = spaceDAO;
+        this.sampleDAO = sampleDAO;
+    }
+
+    @Override
+    protected List<IListObjectById<? extends ISampleId, SamplePE>> createListers(IOperationContext context)
+    {
+        List<IListObjectById<? extends ISampleId, SamplePE>> listers =
+                new LinkedList<IListObjectById<? extends ISampleId, SamplePE>>();
+        listers.add(new ListSampleByPermId(sampleDAO));
+        listers.add(new ListSampleByIdentifier(spaceDAO, sampleDAO, context.getSession().tryGetHomeGroup()));
+        return listers;
+    }
+
+    @Autowired
+    private void setDAOFactory(IDAOFactory daoFactory)
+    {
+        spaceDAO = daoFactory.getSpaceDAO();
+        sampleDAO = daoFactory.getSampleDAO();
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleChildrenExecutor.java
index 85d8cdce47e..7aa4a125a65 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleChildrenExecutor.java
@@ -17,15 +17,18 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Resource;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.relationship.IGetParentChildRelationshipIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -35,19 +38,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class SetSampleChildrenExecutor extends AbstractSetSampleRelatedSamplesExecutor implements ISetSampleChildrenExecutor
 {
 
-    @Autowired
-    private IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor;
-
-    @SuppressWarnings("unused")
-    private SetSampleChildrenExecutor()
-    {
-    }
-
-    public SetSampleChildrenExecutor(IDAOFactory daoFactory, IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor)
-    {
-        super(daoFactory);
-        this.getParentChildRelationshipIdExecutor = getParentChildRelationshipIdExecutor;
-    }
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
 
     @Override
     protected Collection<? extends ISampleId> getRelatedSamplesIds(IOperationContext context, SampleCreation creation)
@@ -56,11 +48,22 @@ public class SetSampleChildrenExecutor extends AbstractSetSampleRelatedSamplesEx
     }
 
     @Override
-    protected void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesTechIds)
+    protected void setRelatedSamples(IOperationContext context, SamplePE parent, Collection<SamplePE> children)
     {
-        getDaoFactory().getSampleDAO().setSampleRelationshipChildren(sample.getId(), relatedSamplesTechIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
+        Set<SamplePE> existingChildren = new HashSet<SamplePE>(parent.getChildren());
+
+        context.pushContextDescription("set children for sample " + parent.getCode());
+
+        for (SamplePE child : children)
+        {
+            if (false == existingChildren.contains(child))
+            {
+                relationshipService.addParentToSample(context.getSession(), child, parent);
+                existingChildren.add(child);
+            }
+        }
+
+        context.popContextDescription();
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainedExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainedExecutor.java
index 6273c1b558c..27c8dc60547 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainedExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainedExecutor.java
@@ -18,12 +18,15 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Collection;
 
+import javax.annotation.Resource;
+
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -33,15 +36,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class SetSampleContainedExecutor extends AbstractSetSampleRelatedSamplesExecutor implements ISetSampleContainedExecutor
 {
 
-    @SuppressWarnings("unused")
-    private SetSampleContainedExecutor()
-    {
-    }
-
-    public SetSampleContainedExecutor(IDAOFactory daoFactory)
-    {
-        super(daoFactory);
-    }
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
 
     @Override
     protected Collection<? extends ISampleId> getRelatedSamplesIds(IOperationContext context, SampleCreation creation)
@@ -50,9 +46,16 @@ public class SetSampleContainedExecutor extends AbstractSetSampleRelatedSamplesE
     }
 
     @Override
-    protected void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesTechIds)
+    protected void setRelatedSamples(IOperationContext context, SamplePE container, Collection<SamplePE> contained)
     {
-        getDaoFactory().getSampleDAO().setSampleContained(sample.getId(), relatedSamplesTechIds);
+        context.pushContextDescription("set contained for sample " + container.getCode());
+
+        for (SamplePE aContained : contained)
+        {
+            relationshipService.assignSampleToContainer(context.getSession(), aContained, container);
+        }
+
+        context.popContextDescription();
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainerExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainerExecutor.java
index 9660e759cd5..78d674b4ab8 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainerExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleContainerExecutor.java
@@ -18,14 +18,15 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Map;
 
-import org.springframework.beans.factory.annotation.Autowired;
+import javax.annotation.Resource;
+
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -35,33 +36,25 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class SetSampleContainerExecutor implements ISetSampleContainerExecutor
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
-
-    @SuppressWarnings("unused")
-    private SetSampleContainerExecutor()
-    {
-    }
-
-    public SetSampleContainerExecutor(IDAOFactory daoFactory)
-    {
-        this.daoFactory = daoFactory;
-    }
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
 
     @Override
-    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, Long> techIdMap)
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap, Map<ISampleId, SamplePE> sampleMap)
     {
-        ISampleDAO sampleDAO = daoFactory.getSampleDAO();
-
         for (SampleCreation creation : creationsMap.keySet())
         {
+            context.pushContextDescription("set container for sample " + creation.getCode());
+
             SamplePE sample = creationsMap.get(creation);
             ISampleId containerId = creation.getContainerId();
             if (containerId != null)
             {
-                Long containerTechId = techIdMap.get(containerId);
-                sampleDAO.setSampleContainer(sample.getId(), containerTechId);
+                SamplePE container = sampleMap.get(containerId);
+                relationshipService.assignSampleToContainer(context.getSession(), sample, container);
             }
+
+            context.popContextDescription();
         }
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleExperimentExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleExperimentExecutor.java
new file mode 100644
index 00000000000..33a3070b427
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleExperimentExecutor.java
@@ -0,0 +1,87 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import java.util.LinkedList;
+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.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IMapExperimentByIdExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.ObjectNotFoundException;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+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.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetSampleExperimentExecutor implements ISetSampleExperimentExecutor
+{
+
+    @Autowired
+    private IMapExperimentByIdExecutor mapExperimentByIdExecutor;
+
+    @Override
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap)
+    {
+        List<IExperimentId> experimentIds = new LinkedList<IExperimentId>();
+
+        for (SampleCreation creation : creationsMap.keySet())
+        {
+            if (creation.getExperimentId() != null)
+            {
+                experimentIds.add(creation.getExperimentId());
+            }
+        }
+
+        Map<IExperimentId, ExperimentPE> experimentMap = mapExperimentByIdExecutor.map(context, experimentIds);
+
+        for (Map.Entry<SampleCreation, SamplePE> creationEntry : creationsMap.entrySet())
+        {
+            SampleCreation creation = creationEntry.getKey();
+            SamplePE sample = creationEntry.getValue();
+
+            context.pushContextDescription("set experiment for sample " + creation.getCode());
+
+            if (creation.getExperimentId() != null)
+            {
+                ExperimentPE experiment = experimentMap.get(creation.getExperimentId());
+                if (experiment == null)
+                {
+                    throw new ObjectNotFoundException(creation.getExperimentId());
+                }
+
+                if (false == new ExperimentByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), experiment))
+                {
+                    throw new AuthorizationFailureException("Cannot access experiment " + creation.getExperimentId());
+                }
+
+                sample.setExperiment(experiment);
+            }
+
+            context.popContextDescription();
+        }
+    }
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleParentsExecutor.java
index c086f643af5..b6d01fe5230 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleParentsExecutor.java
@@ -17,15 +17,18 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Resource;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.relationship.IGetParentChildRelationshipIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -35,19 +38,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class SetSampleParentsExecutor extends AbstractSetSampleRelatedSamplesExecutor implements ISetSampleParentsExecutor
 {
 
-    @Autowired
-    private IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor;
-
-    @SuppressWarnings("unused")
-    private SetSampleParentsExecutor()
-    {
-    }
-
-    public SetSampleParentsExecutor(IDAOFactory daoFactory, IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor)
-    {
-        super(daoFactory);
-        this.getParentChildRelationshipIdExecutor = getParentChildRelationshipIdExecutor;
-    }
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
 
     @Override
     protected Collection<? extends ISampleId> getRelatedSamplesIds(IOperationContext context, SampleCreation creation)
@@ -56,11 +48,21 @@ public class SetSampleParentsExecutor extends AbstractSetSampleRelatedSamplesExe
     }
 
     @Override
-    protected void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesTechIds)
+    protected void setRelatedSamples(IOperationContext context, SamplePE child, Collection<SamplePE> parents)
     {
-        getDaoFactory().getSampleDAO().setSampleRelationshipParents(sample.getId(), relatedSamplesTechIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
-    }
+        Set<SamplePE> existingParents = new HashSet<SamplePE>(child.getParents());
+
+        context.pushContextDescription("set parents for sample " + child.getCode());
 
+        for (SamplePE parent : parents)
+        {
+            if (false == existingParents.contains(parent))
+            {
+                relationshipService.addParentToSample(context.getSession(), child, parent);
+                existingParents.add(parent);
+            }
+        }
+
+        context.popContextDescription();
+    }
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleRelatedSamplesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleRelatedSamplesExecutor.java
index d567c9e0e8a..a4b43a11438 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleRelatedSamplesExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleRelatedSamplesExecutor.java
@@ -19,7 +19,6 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -33,6 +32,7 @@ import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.CreationId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.ObjectNotFoundException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
@@ -44,7 +44,7 @@ public class SetSampleRelatedSamplesExecutor implements ISetSampleRelatedSamples
 {
 
     @Autowired
-    private IListSampleTechIdByIdExecutor listSampleTechIdByIdExecutor;
+    private IMapSampleByIdExecutor mapSampleByIdExecutor;
 
     @Autowired
     private ISetSampleContainerExecutor setSampleContainerExecutor;
@@ -63,11 +63,11 @@ public class SetSampleRelatedSamplesExecutor implements ISetSampleRelatedSamples
     {
     }
 
-    public SetSampleRelatedSamplesExecutor(IListSampleTechIdByIdExecutor listSampleTechIdByIdExecutor,
+    public SetSampleRelatedSamplesExecutor(IMapSampleByIdExecutor mapSampleByIdExecutor,
             ISetSampleContainerExecutor setSampleContainerExecutor, ISetSampleContainedExecutor setSampleContainedExecutor,
             ISetSampleParentsExecutor setSampleParentsExecutor, ISetSampleChildrenExecutor setSampleChildrenExecutor)
     {
-        this.listSampleTechIdByIdExecutor = listSampleTechIdByIdExecutor;
+        this.mapSampleByIdExecutor = mapSampleByIdExecutor;
         this.setSampleContainerExecutor = setSampleContainerExecutor;
         this.setSampleContainedExecutor = setSampleContainedExecutor;
         this.setSampleParentsExecutor = setSampleParentsExecutor;
@@ -77,7 +77,7 @@ public class SetSampleRelatedSamplesExecutor implements ISetSampleRelatedSamples
     @Override
     public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap)
     {
-        Map<ISampleId, Long> relatedSamplesMap = getRelatedSamplesMap(context, creationsMap);
+        Map<ISampleId, SamplePE> relatedSamplesMap = getRelatedSamplesMap(context, creationsMap);
 
         setSampleContainerExecutor.set(context, creationsMap, relatedSamplesMap);
         setSampleContainedExecutor.set(context, creationsMap, relatedSamplesMap);
@@ -85,12 +85,12 @@ public class SetSampleRelatedSamplesExecutor implements ISetSampleRelatedSamples
         setSampleChildrenExecutor.set(context, creationsMap, relatedSamplesMap);
     }
 
-    private Map<ISampleId, Long> getRelatedSamplesMap(IOperationContext context, Map<SampleCreation, SamplePE> createdSamples)
+    private Map<ISampleId, SamplePE> getRelatedSamplesMap(IOperationContext context, Map<SampleCreation, SamplePE> createdSamples)
     {
-        context.pushContextDescription("register samples - verify relationships");
+        context.pushContextDescription("load related samples");
 
-        Collection<ISampleId> relatedSamples = getRelatedSamplesIds(createdSamples.keySet());
-        HashMap<ISampleId, Long> sampleIdToTechIdMap = new HashMap<ISampleId, Long>();
+        Collection<ISampleId> relatedSamplesIds = getRelatedSamplesIds(createdSamples.keySet());
+        HashMap<ISampleId, SamplePE> relatedSamplesMap = new HashMap<ISampleId, SamplePE>();
 
         for (Entry<SampleCreation, SamplePE> entry : createdSamples.entrySet())
         {
@@ -99,41 +99,40 @@ public class SetSampleRelatedSamplesExecutor implements ISetSampleRelatedSamples
 
             if (sampleCreation.getCreationId() != null)
             {
-                sampleIdToTechIdMap.put(sampleCreation.getCreationId(), sample.getId());
+                relatedSamplesMap.put(sampleCreation.getCreationId(), sample);
             }
         }
 
-        List<ISampleId> knownSampleIds = new LinkedList<ISampleId>();
+        List<ISampleId> samplesToLoadIds = new LinkedList<ISampleId>();
 
-        for (ISampleId relatedSample : relatedSamples)
+        for (ISampleId relatedSample : relatedSamplesIds)
         {
             if (relatedSample instanceof CreationId)
             {
-                if (false == sampleIdToTechIdMap.containsKey(relatedSample))
+                if (false == relatedSamplesMap.containsKey(relatedSample))
                 {
                     throw new UserFailureException("Unknown sample creation id: " + relatedSample);
                 }
             }
             else
             {
-                knownSampleIds.add(relatedSample);
+                samplesToLoadIds.add(relatedSample);
             }
         }
-        Collection<Long> techIds = listSampleTechIdByIdExecutor.list(context, knownSampleIds);
+        Map<ISampleId, SamplePE> loadedSamplesMap = mapSampleByIdExecutor.map(context, samplesToLoadIds);
+        relatedSamplesMap.putAll(loadedSamplesMap);
 
-        assert knownSampleIds.size() == techIds.size();
-
-        Iterator<ISampleId> it1 = knownSampleIds.iterator();
-        Iterator<Long> it2 = techIds.iterator();
-
-        while (it1.hasNext())
+        for (ISampleId relatedSampleId : relatedSamplesIds)
         {
-            sampleIdToTechIdMap.put(it1.next(), it2.next());
+            if (false == relatedSamplesMap.containsKey(relatedSampleId))
+            {
+                throw new ObjectNotFoundException(relatedSampleId);
+            }
         }
 
         context.popContextDescription();
 
-        return sampleIdToTechIdMap;
+        return relatedSamplesMap;
     }
 
     private Set<ISampleId> getRelatedSamplesIds(Collection<SampleCreation> sampleCreations)
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleSpaceExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleSpaceExecutor.java
new file mode 100644
index 00000000000..5da74234aa1
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleSpaceExecutor.java
@@ -0,0 +1,87 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import java.util.LinkedList;
+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.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IMapSpaceByIdExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.ObjectNotFoundException;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SimpleSpaceValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetSampleSpaceExecutor implements ISetSampleSpaceExecutor
+{
+
+    @Autowired
+    private IMapSpaceByIdExecutor mapSpaceByIdExecutor;
+
+    @Override
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap)
+    {
+        List<ISpaceId> spaceIds = new LinkedList<ISpaceId>();
+
+        for (SampleCreation creation : creationsMap.keySet())
+        {
+            if (creation.getSpaceId() != null)
+            {
+                spaceIds.add(creation.getSpaceId());
+            }
+        }
+
+        Map<ISpaceId, SpacePE> spaceMap = mapSpaceByIdExecutor.map(context, spaceIds);
+
+        for (Map.Entry<SampleCreation, SamplePE> creationEntry : creationsMap.entrySet())
+        {
+            SampleCreation creation = creationEntry.getKey();
+            SamplePE sample = creationEntry.getValue();
+
+            context.pushContextDescription("set space for sample " + creation.getCode());
+
+            if (creation.getSpaceId() != null)
+            {
+                SpacePE space = spaceMap.get(creation.getSpaceId());
+                if (space == null)
+                {
+                    throw new ObjectNotFoundException(creation.getSpaceId());
+                }
+
+                if (false == new SimpleSpaceValidator().doValidation(context.getSession().tryGetPerson(), space))
+                {
+                    throw new AuthorizationFailureException("Cannot access space " + creation.getSpaceId());
+                }
+
+                sample.setSpace(space);
+            }
+
+            context.popContextDescription();
+        }
+    }
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleTypeExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleTypeExecutor.java
new file mode 100644
index 00000000000..1efccea22df
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/SetSampleTypeExecutor.java
@@ -0,0 +1,85 @@
+/*
+ * 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.generic.server.api.v3.executor.sample;
+
+import java.util.LinkedList;
+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.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IMapEntityTypeByIdExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.IEntityTypeId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.ObjectNotFoundException;
+import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SetSampleTypeExecutor implements ISetSampleTypeExecutor
+{
+
+    @Autowired
+    private IMapEntityTypeByIdExecutor mapEntityTypeByIdExecutor;
+
+    @Override
+    public void set(IOperationContext context, Map<SampleCreation, SamplePE> creationsMap)
+    {
+        List<IEntityTypeId> typeIds = new LinkedList<IEntityTypeId>();
+
+        for (SampleCreation creation : creationsMap.keySet())
+        {
+            if (creation.getTypeId() != null)
+            {
+                typeIds.add(creation.getTypeId());
+            }
+        }
+
+        Map<IEntityTypeId, EntityTypePE> typeMap = mapEntityTypeByIdExecutor.map(context, EntityKind.SAMPLE, typeIds);
+
+        for (Map.Entry<SampleCreation, SamplePE> creationEntry : creationsMap.entrySet())
+        {
+            SampleCreation creation = creationEntry.getKey();
+            SamplePE sample = creationEntry.getValue();
+
+            context.pushContextDescription("set type for sample " + creation.getCode());
+
+            if (creation.getTypeId() == null)
+            {
+                throw new UserFailureException("No type for sample provided");
+            } else
+            {
+                EntityTypePE type = typeMap.get(creation.getTypeId());
+                if (type == null)
+                {
+                    throw new ObjectNotFoundException(creation.getTypeId());
+                }
+                sample.setSampleType((SampleTypePE) type);
+            }
+
+            context.popContextDescription();
+        }
+    }
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleChildrenExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleChildrenExecutor.java
index a011fe971a4..54cdc8198fd 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleChildrenExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleChildrenExecutor.java
@@ -17,16 +17,19 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Resource;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.relationship.IGetParentChildRelationshipIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -36,19 +39,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class UpdateSampleChildrenExecutor extends AbstractUpdateSampleRelatedSamplesExecutor implements IUpdateSampleChildrenExecutor
 {
 
-    @Autowired
-    private IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor;
-
-    @SuppressWarnings("unused")
-    private UpdateSampleChildrenExecutor()
-    {
-    }
-
-    public UpdateSampleChildrenExecutor(IDAOFactory daoFactory, IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor)
-    {
-        super(daoFactory);
-        this.getParentChildRelationshipIdExecutor = getParentChildRelationshipIdExecutor;
-    }
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
 
     @Override
     protected ListUpdateValue<? extends ISampleId> getRelatedSamplesUpdate(IOperationContext context, SampleUpdate update)
@@ -57,27 +49,54 @@ public class UpdateSampleChildrenExecutor extends AbstractUpdateSampleRelatedSam
     }
 
     @Override
-    protected void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    protected void setRelatedSamples(IOperationContext context, SamplePE parent, Collection<SamplePE> children)
     {
-        getDaoFactory().getSampleDAO().setSampleRelationshipChildren(sample.getId(), relatedSamplesIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
+        Set<SamplePE> existingChildren = new HashSet<SamplePE>(parent.getChildren());
+        Set<SamplePE> newChildren = new HashSet<SamplePE>(children);
+
+        for (SamplePE anExistingChild : existingChildren)
+        {
+            if (false == newChildren.contains(anExistingChild))
+            {
+                relationshipService.removeParentFromSample(context.getSession(), anExistingChild, parent);
+            }
+        }
+
+        for (SamplePE aNewChild : newChildren)
+        {
+            if (false == existingChildren.contains(aNewChild))
+            {
+                relationshipService.addParentToSample(context.getSession(), aNewChild, parent);
+            }
+        }
     }
 
     @Override
-    protected void addRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    protected void addRelatedSamples(IOperationContext context, SamplePE parent, Collection<SamplePE> children)
     {
-        getDaoFactory().getSampleDAO().addSampleRelationshipChildren(sample.getId(), relatedSamplesIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
+        Set<SamplePE> existingChildren = new HashSet<SamplePE>(parent.getChildren());
+
+        for (SamplePE aChild : children)
+        {
+            if (false == existingChildren.contains(aChild))
+            {
+                relationshipService.addParentToSample(context.getSession(), aChild, parent);
+            }
+        }
     }
 
     @Override
-    protected void removeRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    protected void removeRelatedSamples(IOperationContext context, SamplePE parent, Collection<SamplePE> children)
     {
-        getDaoFactory().getSampleDAO().removeSampleRelationshipChildren(sample.getId(), relatedSamplesIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
+        Set<SamplePE> existingChildren = new HashSet<SamplePE>(parent.getChildren());
+
+        for (SamplePE aChild : children)
+        {
+            if (existingChildren.contains(aChild))
+            {
+                relationshipService.removeParentFromSample(context.getSession(), aChild, parent);
+            }
+        }
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainedExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainedExecutor.java
index 7222cd60ab7..ab187ac72aa 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainedExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainedExecutor.java
@@ -16,7 +16,12 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Resource;
 
 import org.springframework.stereotype.Component;
 
@@ -24,7 +29,8 @@ import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -34,38 +40,91 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class UpdateSampleContainedExecutor extends AbstractUpdateSampleRelatedSamplesExecutor implements IUpdateSampleContainedExecutor
 {
 
-    @SuppressWarnings("unused")
-    private UpdateSampleContainedExecutor()
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
+
+    @Override
+    protected ListUpdateValue<? extends ISampleId> getRelatedSamplesUpdate(IOperationContext context, SampleUpdate update)
     {
+        return update.getContainedIds();
     }
 
-    public UpdateSampleContainedExecutor(IDAOFactory daoFactory)
+    @Override
+    protected void setRelatedSamples(IOperationContext context, SamplePE container, Collection<SamplePE> contained)
     {
-        super(daoFactory);
+        Set<SamplePE> existingContained = new HashSet<SamplePE>(container.getContained());
+        Set<SamplePE> newContained = new HashSet<SamplePE>(contained);
+
+        for (SamplePE anExistingContained : existingContained)
+        {
+            if (false == newContained.contains(existingContained))
+            {
+                removeFromContainer(relationshipService, context, anExistingContained, container);
+            }
+        }
+
+        for (SamplePE aNewContained : newContained)
+        {
+            if (false == existingContained.contains(aNewContained))
+            {
+                assignToContainer(relationshipService, context, aNewContained, container);
+            }
+        }
     }
 
     @Override
-    protected ListUpdateValue<? extends ISampleId> getRelatedSamplesUpdate(IOperationContext context, SampleUpdate update)
+    protected void addRelatedSamples(IOperationContext context, SamplePE container, Collection<SamplePE> contained)
     {
-        return update.getContainedIds();
+        for (SamplePE aContained : contained)
+        {
+            assignToContainer(relationshipService, context, aContained, container);
+        }
     }
 
     @Override
-    protected void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    protected void removeRelatedSamples(IOperationContext context, SamplePE container, Collection<SamplePE> contained)
     {
-        getDaoFactory().getSampleDAO().setSampleContained(sample.getId(), relatedSamplesIds);
+        for (SamplePE aContained : contained)
+        {
+            removeFromContainer(relationshipService, context, aContained, container);
+        }
     }
 
-    @Override
-    protected void addRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    static void assignToContainer(IRelationshipService service, IOperationContext context, SamplePE sample, SamplePE container)
     {
-        getDaoFactory().getSampleDAO().addSampleContained(sample.getId(), relatedSamplesIds);
+        SamplePE previousContainer = sample.getContainer();
+
+        if (previousContainer != null)
+        {
+            if (previousContainer.equals(container))
+            {
+                // nothing to do
+                return;
+            } else
+            {
+                removeFromContainer(service, context, sample, previousContainer);
+            }
+        }
+
+        Set<SamplePE> contained = new HashSet<SamplePE>(container.getContained());
+        contained.add(sample);
+        container.setContained(new ArrayList<SamplePE>(contained));
+
+        service.assignSampleToContainer(context.getSession(), sample, container);
     }
 
-    @Override
-    protected void removeRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    static void removeFromContainer(IRelationshipService service, IOperationContext context, SamplePE sample, SamplePE container)
     {
-        getDaoFactory().getSampleDAO().removeSampleContained(sample.getId(), relatedSamplesIds);
+        SamplePE previousContainer = sample.getContainer();
+
+        if (previousContainer != null && previousContainer.equals(container))
+        {
+            Set<SamplePE> contained = new HashSet<SamplePE>(container.getContained());
+            contained.remove(sample);
+            container.setContained(new ArrayList<SamplePE>(contained));
+
+            service.removeSampleFromContainer(context.getSession(), sample);
+        }
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainerExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainerExecutor.java
index 3dcf79e6368..fedbbc1a0d8 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainerExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleContainerExecutor.java
@@ -18,15 +18,17 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Map;
 
-import org.springframework.beans.factory.annotation.Autowired;
+import javax.annotation.Resource;
+
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.FieldUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.ObjectNotFoundException;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -36,24 +38,12 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class UpdateSampleContainerExecutor implements IUpdateSampleContainerExecutor
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
-
-    @SuppressWarnings("unused")
-    private UpdateSampleContainerExecutor()
-    {
-    }
-
-    public UpdateSampleContainerExecutor(IDAOFactory daoFactory)
-    {
-        this.daoFactory = daoFactory;
-    }
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
 
     @Override
-    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, Long> techIdMap)
+    public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap, Map<ISampleId, SamplePE> samplesMap)
     {
-        ISampleDAO sampleDAO = daoFactory.getSampleDAO();
-
         for (SampleUpdate update : updateMap.keySet())
         {
             SamplePE sample = updateMap.get(update);
@@ -61,8 +51,21 @@ public class UpdateSampleContainerExecutor implements IUpdateSampleContainerExec
 
             if (containerUpdate != null && containerUpdate.isModified())
             {
-                Long containerTechId = techIdMap.get(containerUpdate.getValue());
-                sampleDAO.setSampleContainer(sample.getId(), containerTechId);
+                if (containerUpdate.getValue() == null)
+                {
+                    if (sample.getContainer() != null)
+                    {
+                        UpdateSampleContainedExecutor.removeFromContainer(relationshipService, context, sample, sample.getContainer());
+                    }
+                } else
+                {
+                    SamplePE container = samplesMap.get(containerUpdate.getValue());
+                    if (container == null)
+                    {
+                        throw new ObjectNotFoundException(containerUpdate.getValue());
+                    }
+                    UpdateSampleContainedExecutor.assignToContainer(relationshipService, context, sample, container);
+                }
             }
         }
     }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExecutor.java
index 8b4f8d2c137..2dafdcdc337 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExecutor.java
@@ -35,6 +35,8 @@ import ch.ethz.sis.openbis.generic.server.api.v3.executor.property.IUpdateEntity
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.tag.IUpdateTagForEntityExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SampleByIdentiferValidator;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.util.RelationshipUtils;
@@ -121,6 +123,14 @@ public class UpdateSampleExecutor implements IUpdateSampleExecutor
 
         assert sampleIds.size() == samples.size();
 
+        for (SamplePE sample : samples)
+        {
+            if (false == new SampleByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), sample))
+            {
+                throw new AuthorizationFailureException("Cannot access sample " + sample.getIdentifier());
+            }
+        }
+
         Map<SampleUpdate, SamplePE> result = new HashMap<SampleUpdate, SamplePE>();
 
         Iterator<SampleUpdate> it1 = updates.iterator();
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExperimentExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExperimentExecutor.java
index 66ffd719435..6ddc179fc0f 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExperimentExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleExperimentExecutor.java
@@ -23,6 +23,8 @@ import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IGetExperimentByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.FieldUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentByIdentiferValidator;
 import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
@@ -60,6 +62,7 @@ public class UpdateSampleExperimentExecutor implements IUpdateSampleExperimentEx
             {
                 if (sample.getExperiment() != null)
                 {
+                    checkExperiment(context, sample.getExperiment());
                     relationshipService.unassignSampleFromExperiment(context.getSession(), sample);
                 }
             }
@@ -68,10 +71,19 @@ public class UpdateSampleExperimentExecutor implements IUpdateSampleExperimentEx
                 ExperimentPE experiment = getExperimentByIdExecutor.get(context, update.getValue());
                 if (false == experiment.equals(sample.getExperiment()))
                 {
+                    checkExperiment(context, experiment);
                     relationshipService.assignSampleToExperiment(context.getSession(), sample, experiment);
                 }
             }
         }
     }
 
+    private void checkExperiment(IOperationContext context, ExperimentPE experiment)
+    {
+        if (false == new ExperimentByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), experiment))
+        {
+            throw new AuthorizationFailureException("Cannot access experiment " + experiment.getIdentifier());
+        }
+    }
+
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleParentsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleParentsExecutor.java
index 676b2911193..e3f7175125c 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleParentsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleParentsExecutor.java
@@ -17,16 +17,19 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Resource;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.relationship.IGetParentChildRelationshipIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
@@ -36,19 +39,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 public class UpdateSampleParentsExecutor extends AbstractUpdateSampleRelatedSamplesExecutor implements IUpdateSampleParentsExecutor
 {
 
-    @Autowired
-    private IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor;
-
-    @SuppressWarnings("unused")
-    private UpdateSampleParentsExecutor()
-    {
-    }
-
-    public UpdateSampleParentsExecutor(IDAOFactory daoFactory, IGetParentChildRelationshipIdExecutor getParentChildRelationshipIdExecutor)
-    {
-        super(daoFactory);
-        this.getParentChildRelationshipIdExecutor = getParentChildRelationshipIdExecutor;
-    }
+    @Resource(name = ComponentNames.RELATIONSHIP_SERVICE)
+    private IRelationshipService relationshipService;
 
     @Override
     protected ListUpdateValue<? extends ISampleId> getRelatedSamplesUpdate(IOperationContext context, SampleUpdate update)
@@ -57,27 +49,54 @@ public class UpdateSampleParentsExecutor extends AbstractUpdateSampleRelatedSamp
     }
 
     @Override
-    protected void setRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    protected void setRelatedSamples(IOperationContext context, SamplePE child, Collection<SamplePE> parents)
     {
-        getDaoFactory().getSampleDAO().setSampleRelationshipParents(sample.getId(), relatedSamplesIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
+        Set<SamplePE> existingParents = new HashSet<SamplePE>(child.getParents());
+        Set<SamplePE> newParents = new HashSet<SamplePE>(parents);
+
+        for (SamplePE anExistingParent : existingParents)
+        {
+            if (false == newParents.contains(anExistingParent))
+            {
+                relationshipService.removeParentFromSample(context.getSession(), child, anExistingParent);
+            }
+        }
+
+        for (SamplePE aNewParent : newParents)
+        {
+            if (false == existingParents.contains(aNewParent))
+            {
+                relationshipService.addParentToSample(context.getSession(), child, aNewParent);
+            }
+        }
     }
 
     @Override
-    protected void addRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    protected void addRelatedSamples(IOperationContext context, SamplePE child, Collection<SamplePE> parents)
     {
-        getDaoFactory().getSampleDAO().addSampleRelationshipParents(sample.getId(), relatedSamplesIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
+        Set<SamplePE> existingParents = new HashSet<SamplePE>(child.getParents());
+
+        for (SamplePE aParent : parents)
+        {
+            if (false == existingParents.contains(aParent))
+            {
+                relationshipService.addParentToSample(context.getSession(), child, aParent);
+            }
+        }
     }
 
     @Override
-    protected void removeRelatedSamples(IOperationContext context, SamplePE sample, Collection<Long> relatedSamplesIds)
+    protected void removeRelatedSamples(IOperationContext context, SamplePE child, Collection<SamplePE> parents)
     {
-        getDaoFactory().getSampleDAO().removeSampleRelationshipParents(sample.getId(), relatedSamplesIds,
-                getParentChildRelationshipIdExecutor.get(context),
-                context.getSession().tryGetPerson());
+        Set<SamplePE> existingParents = new HashSet<SamplePE>(child.getParents());
+
+        for (SamplePE aParent : parents)
+        {
+            if (existingParents.contains(aParent))
+            {
+                relationshipService.removeParentFromSample(context.getSession(), child, aParent);
+            }
+        }
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleRelatedSamplesExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleRelatedSamplesExecutor.java
index d57df7f2ab8..a6e8c0f4923 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleRelatedSamplesExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleRelatedSamplesExecutor.java
@@ -17,9 +17,7 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.sample;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
@@ -41,7 +39,7 @@ public class UpdateSampleRelatedSamplesExecutor implements IUpdateSampleRelatedS
 {
 
     @Autowired
-    private IListSampleTechIdByIdExecutor listSampleTechIdByIdExecutor;
+    private IMapSampleByIdExecutor mapSampleByIdExecutor;
 
     @Autowired
     private IUpdateSampleContainerExecutor updateSampleContainerExecutor;
@@ -60,11 +58,11 @@ public class UpdateSampleRelatedSamplesExecutor implements IUpdateSampleRelatedS
     {
     }
 
-    public UpdateSampleRelatedSamplesExecutor(IListSampleTechIdByIdExecutor listSampleTechIdByIdExecutor,
+    public UpdateSampleRelatedSamplesExecutor(IMapSampleByIdExecutor mapSampleByIdExecutor,
             IUpdateSampleContainerExecutor updateSampleContainerExecutor, IUpdateSampleContainedExecutor updateSampleContainedExecutor,
             IUpdateSampleParentsExecutor updateSampleParentsExecutor, IUpdateSampleChildrenExecutor updateSampleChildrenExecutor)
     {
-        this.listSampleTechIdByIdExecutor = listSampleTechIdByIdExecutor;
+        this.mapSampleByIdExecutor = mapSampleByIdExecutor;
         this.updateSampleContainerExecutor = updateSampleContainerExecutor;
         this.updateSampleContainedExecutor = updateSampleContainedExecutor;
         this.updateSampleParentsExecutor = updateSampleParentsExecutor;
@@ -74,35 +72,23 @@ public class UpdateSampleRelatedSamplesExecutor implements IUpdateSampleRelatedS
     @Override
     public void update(IOperationContext context, Map<SampleUpdate, SamplePE> updateMap)
     {
-        Map<ISampleId, Long> techIdMap = getRelatedSamplesMap(context, updateMap.keySet());
-        updateSampleContainerExecutor.update(context, updateMap, techIdMap);
-        updateSampleContainedExecutor.update(context, updateMap, techIdMap);
-        updateSampleParentsExecutor.update(context, updateMap, techIdMap);
-        updateSampleChildrenExecutor.update(context, updateMap, techIdMap);
+        Map<ISampleId, SamplePE> samplesMap = getRelatedSamplesMap(context, updateMap.keySet());
+        updateSampleContainerExecutor.update(context, updateMap, samplesMap);
+        updateSampleContainedExecutor.update(context, updateMap, samplesMap);
+        updateSampleParentsExecutor.update(context, updateMap, samplesMap);
+        updateSampleChildrenExecutor.update(context, updateMap, samplesMap);
     }
 
-    private HashMap<ISampleId, Long> getRelatedSamplesMap(IOperationContext context, Collection<SampleUpdate> updates)
+    private Map<ISampleId, SamplePE> getRelatedSamplesMap(IOperationContext context, Collection<SampleUpdate> updates)
     {
         context.pushContextDescription("update samples - verify related entities exist");
 
-        Collection<ISampleId> relatedSamples = getRelatedSamplesIds(updates);
-        HashMap<ISampleId, Long> sampleIdToTechIdMap = new HashMap<ISampleId, Long>();
-
-        Collection<Long> techIds = listSampleTechIdByIdExecutor.list(context, relatedSamples);
-
-        assert relatedSamples.size() == techIds.size();
-
-        Iterator<ISampleId> it1 = relatedSamples.iterator();
-        Iterator<Long> it2 = techIds.iterator();
-
-        while (it1.hasNext())
-        {
-            sampleIdToTechIdMap.put(it1.next(), it2.next());
-        }
+        Collection<ISampleId> relatedSamplesIds = getRelatedSamplesIds(updates);
+        Map<ISampleId, SamplePE> relatedSamplesMap = mapSampleByIdExecutor.map(context, relatedSamplesIds);
 
         context.popContextDescription();
 
-        return sampleIdToTechIdMap;
+        return relatedSamplesMap;
     }
 
     private Set<ISampleId> getRelatedSamplesIds(Collection<SampleUpdate> updates)
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleSpaceExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleSpaceExecutor.java
index 5989cc61741..0d95bcc3963 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleSpaceExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/sample/UpdateSampleSpaceExecutor.java
@@ -23,6 +23,8 @@ import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IGetSpaceByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.FieldUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SimpleSpaceValidator;
 import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
@@ -60,12 +62,14 @@ public class UpdateSampleSpaceExecutor implements IUpdateSampleSpaceExecutor
             {
                 if (sample.getSpace() != null)
                 {
+                    checkSpace(context, sample.getSpace());
                     relationshipService.shareSample(context.getSession(), sample);
                 }
             }
             else
             {
                 SpacePE space = getSpaceByIdExecutor.get(context, update.getValue());
+                checkSpace(context, space);
 
                 if (sample.getSpace() == null)
                 {
@@ -78,4 +82,12 @@ public class UpdateSampleSpaceExecutor implements IUpdateSampleSpaceExecutor
         }
     }
 
+    private void checkSpace(IOperationContext context, SpacePE space)
+    {
+        if (false == new SimpleSpaceValidator().doValidation(context.getSession().tryGetPerson(), space))
+        {
+            throw new AuthorizationFailureException("Cannot access space " + space.getCode());
+        }
+    }
+
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IListSpaceByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IListSpaceByIdExecutor.java
index 2f0ae3f6461..0df20a394fa 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IListSpaceByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IListSpaceByIdExecutor.java
@@ -16,19 +16,14 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.space;
 
-import java.util.Collection;
-import java.util.List;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IListObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
 /**
  * @author pkupczyk
  */
-public interface IListSpaceByIdExecutor
+public interface IListSpaceByIdExecutor extends IListObjectByIdExecutor<ISpaceId, SpacePE>
 {
 
-    public List<SpacePE> list(IOperationContext context, Collection<? extends ISpaceId> spaceIds);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IMapSpaceByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IMapSpaceByIdExecutor.java
index 0b6072a140a..63af0686733 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IMapSpaceByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/IMapSpaceByIdExecutor.java
@@ -16,19 +16,14 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.space;
 
-import java.util.Collection;
-import java.util.Map;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
 /**
  * @author pkupczyk
  */
-public interface IMapSpaceByIdExecutor
+public interface IMapSpaceByIdExecutor extends IMapObjectByIdExecutor<ISpaceId, SpacePE>
 {
 
-    public Map<ISpaceId, SpacePE> map(IOperationContext context, Collection<? extends ISpaceId> spaceIds);
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/ListSpaceByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/ListSpaceByIdExecutor.java
index 44eb78d7fd6..297c21cbec2 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/ListSpaceByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/ListSpaceByIdExecutor.java
@@ -16,15 +16,11 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.space;
 
-import java.util.ArrayList;
-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.server.api.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractListObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
@@ -32,7 +28,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
  * @author pkupczyk
  */
 @Component
-public class ListSpaceByIdExecutor implements IListSpaceByIdExecutor
+public class ListSpaceByIdExecutor extends AbstractListObjectByIdExecutor<ISpaceId, SpacePE> implements IListSpaceByIdExecutor
 {
 
     @Autowired
@@ -49,10 +45,9 @@ public class ListSpaceByIdExecutor implements IListSpaceByIdExecutor
     }
 
     @Override
-    public List<SpacePE> list(IOperationContext context, Collection<? extends ISpaceId> spaceIds)
+    protected IMapObjectByIdExecutor<ISpaceId, SpacePE> getMapExecutor()
     {
-        Map<ISpaceId, SpacePE> map = mapSpaceByIdExecutor.map(context, spaceIds);
-        return new ArrayList<SpacePE>(map.values());
+        return mapSpaceByIdExecutor;
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/MapSpaceByIdExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/MapSpaceByIdExecutor.java
index 6d375101c52..12df18578a2 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/MapSpaceByIdExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/space/MapSpaceByIdExecutor.java
@@ -16,66 +16,53 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.space;
 
-import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 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.server.api.v3.executor.IOperationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.collection.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.id.space.ISpaceIdTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.AbstractMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.space.ListSpaceByPermId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.ListerById;
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.space.ListerBySpacePermIdId;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
 /**
  * @author pkupczyk
  */
 @Component
-public class MapSpaceByIdExecutor implements IMapSpaceByIdExecutor
+public class MapSpaceByIdExecutor extends AbstractMapObjectByIdExecutor<ISpaceId, SpacePE> implements IMapSpaceByIdExecutor
 {
 
-    @Autowired
-    private IDAOFactory daoFactory;
+    private ISpaceDAO spaceDAO;
 
     @SuppressWarnings("unused")
     private MapSpaceByIdExecutor()
     {
     }
 
-    public MapSpaceByIdExecutor(IDAOFactory daoFactory)
+    public MapSpaceByIdExecutor(ISpaceDAO spaceDAO)
     {
-        this.daoFactory = daoFactory;
+        this.spaceDAO = spaceDAO;
     }
 
     @Override
-    public Map<ISpaceId, SpacePE> map(IOperationContext context, Collection<? extends ISpaceId> spaceIds)
+    protected List<IListObjectById<? extends ISpaceId, SpacePE>> createListers(IOperationContext context)
     {
-        List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.space.ISpaceId> spaceIdsCore =
-                new ListTranslator().translate(spaceIds, new ISpaceIdTranslator());
-
-        @SuppressWarnings("rawtypes")
-        List<IListerById> listers = new LinkedList<IListerById>();
-        listers.add(new ListerBySpacePermIdId(daoFactory));
-
-        List<SpacePE> list = new ListerById(listers).list(spaceIdsCore);
-        Map<ISpaceId, SpacePE> map = new LinkedHashMap<ISpaceId, SpacePE>();
-        int index = 0;
-
-        for (ISpaceId spaceId : spaceIds)
-        {
-            map.put(spaceId, list.get(index));
-            index++;
-        }
+        List<IListObjectById<? extends ISpaceId, SpacePE>> listers =
+                new LinkedList<IListObjectById<? extends ISpaceId, SpacePE>>();
+        listers.add(new ListSpaceByPermId(spaceDAO));
+        return listers;
+    }
 
-        return map;
+    @Autowired
+    private void setDAOFactory(IDAOFactory daoFactory)
+    {
+        spaceDAO = daoFactory.getSpaceDAO();
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/IListerById.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/common/IListObjectById.java
similarity index 68%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/IListerById.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/common/IListObjectById.java
index 984c74cff54..dd628a61dc3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/IListerById.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/common/IListObjectById.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 ETH Zuerich, CISD
+ * 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.
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.server.business.search.id;
+package ch.ethz.sis.openbis.generic.server.api.v3.helper.common;
 
 import java.util.List;
 
 /**
  * @author pkupczyk
  */
-public interface IListerById<I, O>
+public interface IListObjectById<ID, OBJECT>
 {
 
-    public Class<I> getIdClass();
+    public Class<ID> getIdClass();
 
-    public I createId(O object);
+    public ID createId(OBJECT entity);
 
-    public List<O> listByIds(List<I> ids);
+    public List<OBJECT> listByIds(List<ID> ids);
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/ListerById.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/common/MapObjectById.java
similarity index 51%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/ListerById.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/common/MapObjectById.java
index 411c1ff996a..8ba3cc25da0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/ListerById.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/common/MapObjectById.java
@@ -14,33 +14,25 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.server.business.search.id;
+package ch.ethz.sis.openbis.generic.server.api.v3.helper.common;
 
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
-import ch.systemsx.cisd.common.collection.CollectionUtils;
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.IObjectId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
 
 /**
  * @author pkupczyk
  */
 @SuppressWarnings({ "rawtypes", "unchecked" })
-public class ListerById
+public class MapObjectById<ID, OBJECT>
 {
 
-    private List<IListerById> listers;
-
-    public ListerById(List<IListerById> listers)
-    {
-        this.listers = listers;
-    }
-
     private Map<Class, List> groupIdsByClass(Collection ids)
     {
         Map<Class, List> idClassToIdListMap =
@@ -48,11 +40,16 @@ public class ListerById
 
         for (Object id : ids)
         {
-            List<Object> idList = idClassToIdListMap.get(id.getClass());
+            if (id == null)
+            {
+                continue;
+            }
+
+            List idList = idClassToIdListMap.get(id.getClass());
 
             if (idList == null)
             {
-                idList = new LinkedList<Object>();
+                idList = new LinkedList<ID>();
                 idClassToIdListMap.put(id.getClass(), idList);
             }
 
@@ -61,44 +58,59 @@ public class ListerById
         return idClassToIdListMap;
     }
 
-    private Map<Object, Object> listByIds(Map<Class, List> idClassToIdListMap)
+    private Map mapByIds(List<IListObjectById<? extends ID, OBJECT>> listers, Map<Class, List> idClassToIdListMap)
     {
-        final Map<Object, Object> idToObject = new HashMap<Object, Object>();
-
-        final Set unmatchedIds = new HashSet();
+        final Map idToObject = new HashMap();
 
         for (Class idClass : idClassToIdListMap.keySet())
         {
             List idList = idClassToIdListMap.get(idClass);
+            IListObjectById listerForIdClass = null;
 
-            for (IListerById lister : listers)
+            for (IListObjectById lister : listers)
             {
                 if (lister.getIdClass().equals(idClass))
                 {
-                    HashSet idSet = new HashSet(idList);
+                    listerForIdClass = lister;
+                }
+            }
 
-                    List objects = lister.listByIds(idList);
+            if (listerForIdClass == null)
+            {
+                throw new UnsupportedObjectIdException((IObjectId) idList.iterator().next());
+            } else
+            {
+                List objects = listerForIdClass.listByIds(idList);
+                if (objects != null)
+                {
                     for (Object object : objects)
                     {
-                        Object createId = lister.createId(object);
+                        Object createId = listerForIdClass.createId(object);
                         idToObject.put(createId, object);
-                        idSet.remove(createId);
                     }
-                    unmatchedIds.addAll(idSet);
                 }
             }
         }
-        if (unmatchedIds.isEmpty() == false)
-        {
-            throw new UserFailureException("Unknown ids " + CollectionUtils.abbreviate(unmatchedIds, 200));
-        }
+
         return idToObject;
     }
 
-    public <T> List<T> list(Collection ids)
+    public Map<ID, OBJECT> map(List<IListObjectById<? extends ID, OBJECT>> listers, Collection<? extends ID> ids)
     {
         Map<Class, List> idClassToIdListMap = groupIdsByClass(ids);
-        Map<Object, Object> idToObjectMap = listByIds(idClassToIdListMap);
-        return CollectionUtils.map(ids, idToObjectMap);
+        Map idToObjectMap = mapByIds(listers, idClassToIdListMap);
+        Map orderedMap = new LinkedHashMap();
+
+        for (ID id : ids)
+        {
+            Object object = idToObjectMap.get(id);
+            if (object != null)
+            {
+                orderedMap.put(id, object);
+            }
+        }
+
+        return orderedMap;
     }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/entitytype/ListerByEntityTypePermIdId.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/entity/ListEntityTypeByPermId.java
similarity index 64%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/entitytype/ListerByEntityTypePermIdId.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/entity/ListEntityTypeByPermId.java
index 6bb26478615..9a18acaec2a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/entitytype/ListerByEntityTypePermIdId.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/entity/ListEntityTypeByPermId.java
@@ -14,49 +14,49 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.server.business.search.id.entitytype;
+package ch.ethz.sis.openbis.generic.server.api.v3.helper.entity;
 
 import java.util.LinkedList;
 import java.util.List;
 
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePermId;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.entitytype.EntityTypePermIdId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 
 /**
  * @author pkupczyk
  */
-public class ListerByEntityTypePermIdId implements IListerById<EntityTypePermIdId, EntityTypePE>
+public class ListEntityTypeByPermId implements IListObjectById<EntityTypePermId, EntityTypePE>
 {
 
     private IEntityTypeDAO entityTypeDAO;
 
-    public ListerByEntityTypePermIdId(IDAOFactory daoFactory, EntityKind entityKind)
+    public ListEntityTypeByPermId(IDAOFactory daoFactory, EntityKind entityKind)
     {
         this.entityTypeDAO = daoFactory.getEntityTypeDAO(entityKind);
     }
 
     @Override
-    public Class<EntityTypePermIdId> getIdClass()
+    public Class<EntityTypePermId> getIdClass()
     {
-        return EntityTypePermIdId.class;
+        return EntityTypePermId.class;
     }
 
     @Override
-    public EntityTypePermIdId createId(EntityTypePE entityType)
+    public EntityTypePermId createId(EntityTypePE entityType)
     {
-        return new EntityTypePermIdId(entityType.getCode());
+        return new EntityTypePermId(entityType.getCode());
     }
 
     @Override
-    public List<EntityTypePE> listByIds(List<EntityTypePermIdId> ids)
+    public List<EntityTypePE> listByIds(List<EntityTypePermId> ids)
     {
         List<String> permIds = new LinkedList<String>();
 
-        for (EntityTypePermIdId id : ids)
+        for (EntityTypePermId id : ids)
         {
             permIds.add(id.getPermId());
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentPermIdId.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/experiment/ListExperimentByPermId.java
similarity index 56%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentPermIdId.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/experiment/ListExperimentByPermId.java
index 7e6213f8d07..3879590d418 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentPermIdId.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/experiment/ListExperimentByPermId.java
@@ -14,48 +14,47 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.server.business.search.id.experiment;
+package ch.ethz.sis.openbis.generic.server.api.v3.helper.experiment;
 
 import java.util.LinkedList;
 import java.util.List;
 
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentPermIdId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 
 /**
  * @author pkupczyk
  */
-public class ListerByExperimentPermIdId implements IListerById<ExperimentPermIdId, ExperimentPE>
+public class ListExperimentByPermId implements IListObjectById<ExperimentPermId, ExperimentPE>
 {
 
     private IExperimentDAO experimentDAO;
 
-    public ListerByExperimentPermIdId(IDAOFactory daoFactory)
+    public ListExperimentByPermId(IExperimentDAO experimentDAO)
     {
-        this.experimentDAO = daoFactory.getExperimentDAO();
+        this.experimentDAO = experimentDAO;
     }
 
     @Override
-    public Class<ExperimentPermIdId> getIdClass()
+    public Class<ExperimentPermId> getIdClass()
     {
-        return ExperimentPermIdId.class;
+        return ExperimentPermId.class;
     }
 
     @Override
-    public ExperimentPermIdId createId(ExperimentPE experiment)
+    public ExperimentPermId createId(ExperimentPE experiment)
     {
-        return new ExperimentPermIdId(experiment.getPermId());
+        return new ExperimentPermId(experiment.getPermId());
     }
 
     @Override
-    public List<ExperimentPE> listByIds(List<ExperimentPermIdId> ids)
+    public List<ExperimentPE> listByIds(List<ExperimentPermId> ids)
     {
         List<String> permIds = new LinkedList<String>();
 
-        for (ExperimentPermIdId id : ids)
+        for (ExperimentPermId id : ids)
         {
             permIds.add(id.getPermId());
         }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByIdentifier.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByIdentifier.java
new file mode 100644
index 00000000000..48b330470b5
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByIdentifier.java
@@ -0,0 +1,67 @@
+/*
+ * 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.generic.server.api.v3.helper.project;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectIdentifier;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory;
+
+/**
+ * @author pkupczyk
+ */
+public class ListProjectByIdentifier implements IListObjectById<ProjectIdentifier, ProjectPE>
+{
+
+    private IProjectDAO projectDAO;
+
+    public ListProjectByIdentifier(IProjectDAO projectDAO)
+    {
+        this.projectDAO = projectDAO;
+    }
+
+    @Override
+    public Class<ProjectIdentifier> getIdClass()
+    {
+        return ProjectIdentifier.class;
+    }
+
+    @Override
+    public ProjectIdentifier createId(ProjectPE project)
+    {
+        return new ProjectIdentifier(project.getIdentifier());
+    }
+
+    @Override
+    public List<ProjectPE> listByIds(List<ProjectIdentifier> ids)
+    {
+        List<ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier> identifiers =
+                new LinkedList<ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier>();
+
+        for (ProjectIdentifier id : ids)
+        {
+            identifiers.add(ProjectIdentifierFactory.parse(id.getIdentifier()));
+        }
+
+        return projectDAO.tryFindProjects(identifiers);
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByPermId.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByPermId.java
new file mode 100644
index 00000000000..41d853fdf5f
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/project/ListProjectByPermId.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 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.api.v3.helper.project;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+public class ListProjectByPermId implements IListObjectById<ProjectPermId, ProjectPE>
+{
+
+    private IProjectDAO projectDAO;
+
+    public ListProjectByPermId(IProjectDAO projectDAO)
+    {
+        this.projectDAO = projectDAO;
+    }
+
+    @Override
+    public Class<ProjectPermId> getIdClass()
+    {
+        return ProjectPermId.class;
+    }
+
+    @Override
+    public ProjectPermId createId(ProjectPE project)
+    {
+        return new ProjectPermId(project.getPermId());
+    }
+
+    @Override
+    public List<ProjectPE> listByIds(List<ProjectPermId> ids)
+    {
+        List<String> permIds = new LinkedList<String>();
+
+        for (ProjectPermId id : ids)
+        {
+            permIds.add(id.getPermId());
+        }
+
+        return projectDAO.listByPermID(permIds);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleIdentifierId.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByIdentifier.java
similarity index 81%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleIdentifierId.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByIdentifier.java
index c87599280f7..d2419e79d44 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleIdentifierId.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByIdentifier.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.server.business.search.id.sample;
+package ch.ethz.sis.openbis.generic.server.api.v3.helper.sample;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -23,14 +23,12 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SampleIdentifierId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 
@@ -38,41 +36,41 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
  * @author Franz-Josef Elmer
  */
 // TODO: neds unit tests
-public class ListerBySampleIdentifierId implements IListerById<SampleIdentifierId, SamplePE>
+public class ListSampleByIdentifier implements IListObjectById<SampleIdentifier, SamplePE>
 {
 
-    private ISampleDAO sampleDAO;
-
     private ISpaceDAO spaceDAO;
 
+    private ISampleDAO sampleDAO;
+
     private SpacePE homeSpaceOrNull;
 
-    public ListerBySampleIdentifierId(IDAOFactory daoFactory, SpacePE homeSpaceOrNull)
+    public ListSampleByIdentifier(ISpaceDAO spaceDAO, ISampleDAO sampleDAO, SpacePE homeSpaceOrNull)
     {
-        this.spaceDAO = daoFactory.getSpaceDAO();
-        this.sampleDAO = daoFactory.getSampleDAO();
+        this.spaceDAO = spaceDAO;
+        this.sampleDAO = sampleDAO;
         this.homeSpaceOrNull = homeSpaceOrNull;
     }
 
     @Override
-    public Class<SampleIdentifierId> getIdClass()
+    public Class<SampleIdentifier> getIdClass()
     {
-        return SampleIdentifierId.class;
+        return SampleIdentifier.class;
     }
 
     @Override
-    public SampleIdentifierId createId(SamplePE sample)
+    public SampleIdentifier createId(SamplePE sample)
     {
-        return new SampleIdentifierId(sample.getIdentifier());
+        return new SampleIdentifier(sample.getIdentifier());
     }
 
     @Override
-    public List<SamplePE> listByIds(List<SampleIdentifierId> ids)
+    public List<SamplePE> listByIds(List<SampleIdentifier> ids)
     {
-        Map<Key, List<String>> sampleCodesBySpaceAndContainer = new HashMap<ListerBySampleIdentifierId.Key, List<String>>();
-        for (SampleIdentifierId id : ids)
+        Map<Key, List<String>> sampleCodesBySpaceAndContainer = new HashMap<ListSampleByIdentifier.Key, List<String>>();
+        for (SampleIdentifier id : ids)
         {
-            SampleIdentifier sid = SampleIdentifierFactory.parse(id.getIdentifier());
+            ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier sid = SampleIdentifierFactory.parse(id.getIdentifier());
             if (sid.isDatabaseInstanceLevel())
             {
                 addToMap(sampleCodesBySpaceAndContainer, null, sid);
@@ -116,7 +114,8 @@ public class ListerBySampleIdentifierId implements IListerById<SampleIdentifierI
         return result;
     }
 
-    private void addToMap(Map<Key, List<String>> sampleCodesBySpaceAndContainer, SpacePE space, SampleIdentifier sampleIdentifier)
+    private void addToMap(Map<Key, List<String>> sampleCodesBySpaceAndContainer, SpacePE space,
+            ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier sampleIdentifier)
     {
         Key key = new Key(space, sampleIdentifier.tryGetContainerCode());
         List<String> list = sampleCodesBySpaceAndContainer.get(key);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySamplePermIdId.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByPermId.java
similarity index 58%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySamplePermIdId.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByPermId.java
index 478e6186928..3465a85b474 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySamplePermIdId.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/sample/ListSampleByPermId.java
@@ -14,48 +14,47 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.server.business.search.id.sample;
+package ch.ethz.sis.openbis.generic.server.api.v3.helper.sample;
 
 import java.util.LinkedList;
 import java.util.List;
 
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SamplePermId;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SamplePermIdId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author pkupczyk
  */
-public class ListerBySamplePermIdId implements IListerById<SamplePermIdId, SamplePE>
+public class ListSampleByPermId implements IListObjectById<SamplePermId, SamplePE>
 {
 
     private ISampleDAO sampleDAO;
 
-    public ListerBySamplePermIdId(IDAOFactory daoFactory)
+    public ListSampleByPermId(ISampleDAO sampleDAO)
     {
-        this.sampleDAO = daoFactory.getSampleDAO();
+        this.sampleDAO = sampleDAO;
     }
 
     @Override
-    public Class<SamplePermIdId> getIdClass()
+    public Class<SamplePermId> getIdClass()
     {
-        return SamplePermIdId.class;
+        return SamplePermId.class;
     }
 
     @Override
-    public SamplePermIdId createId(SamplePE sample)
+    public SamplePermId createId(SamplePE sample)
     {
-        return new SamplePermIdId(sample.getPermId());
+        return new SamplePermId(sample.getPermId());
     }
 
     @Override
-    public List<SamplePE> listByIds(List<SamplePermIdId> ids)
+    public List<SamplePE> listByIds(List<SamplePermId> ids)
     {
         List<String> permIds = new LinkedList<String>();
 
-        for (SamplePermIdId id : ids)
+        for (SamplePermId id : ids)
         {
             permIds.add(id.getPermId());
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/space/ListerBySpacePermIdId.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/space/ListSpaceByPermId.java
similarity index 59%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/space/ListerBySpacePermIdId.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/space/ListSpaceByPermId.java
index c406e07bb9b..d4531e3edc3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/space/ListerBySpacePermIdId.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/helper/space/ListSpaceByPermId.java
@@ -14,48 +14,47 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.server.business.search.id.space;
+package ch.ethz.sis.openbis.generic.server.api.v3.helper.space;
 
 import java.util.LinkedList;
 import java.util.List;
 
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.ethz.sis.openbis.generic.server.api.v3.helper.common.IListObjectById;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.space.SpacePermIdId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
 /**
  * @author pkupczyk
  */
-public class ListerBySpacePermIdId implements IListerById<SpacePermIdId, SpacePE>
+public class ListSpaceByPermId implements IListObjectById<SpacePermId, SpacePE>
 {
 
     private ISpaceDAO spaceDAO;
 
-    public ListerBySpacePermIdId(IDAOFactory daoFactory)
+    public ListSpaceByPermId(ISpaceDAO spaceDAO)
     {
-        this.spaceDAO = daoFactory.getSpaceDAO();
+        this.spaceDAO = spaceDAO;
     }
 
     @Override
-    public Class<SpacePermIdId> getIdClass()
+    public Class<SpacePermId> getIdClass()
     {
-        return SpacePermIdId.class;
+        return SpacePermId.class;
     }
 
     @Override
-    public SpacePermIdId createId(SpacePE space)
+    public SpacePermId createId(SpacePE space)
     {
-        return new SpacePermIdId(space.getCode());
+        return new SpacePermId(space.getCode());
     }
 
     @Override
-    public List<SpacePE> listByIds(List<SpacePermIdId> ids)
+    public List<SpacePE> listByIds(List<SpacePermId> ids)
     {
         List<String> permIds = new LinkedList<String>();
 
-        for (SpacePermIdId id : ids)
+        for (SpacePermId id : ids)
         {
             permIds.add(id.getPermId());
         }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/EntityTypePermIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/EntityTypePermIdTranslator.java
deleted file mode 100644
index 667b1d96a25..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/EntityTypePermIdTranslator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.entitytype;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePermId;
-
-/**
- * @author pkupczyk
- */
-public class EntityTypePermIdTranslator extends
-        AbstractTranslator<EntityTypePermId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.entitytype.EntityTypePermIdId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.entitytype.EntityTypePermIdId doTranslate(EntityTypePermId id)
-    {
-        return new ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.entitytype.EntityTypePermIdId(id.getPermId());
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/IEntityTypeIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/IEntityTypeIdTranslator.java
deleted file mode 100644
index e8496fdbd64..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/entitytype/IEntityTypeIdTranslator.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.entitytype;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.IEntityTypeId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
-
-/**
- * @author pkupczyk
- */
-public class IEntityTypeIdTranslator extends
-        AbstractTranslator<IEntityTypeId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.entitytype.IEntityTypeId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.entitytype.IEntityTypeId doTranslate(IEntityTypeId id)
-    {
-        if (id instanceof EntityTypePermId)
-        {
-            return new EntityTypePermIdTranslator().translate((EntityTypePermId) id);
-        } else
-        {
-            throw new UnsupportedObjectIdException(id);
-        }
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentIdentifierIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentIdentifierIdTranslator.java
deleted file mode 100644
index 908d09a8343..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentIdentifierIdTranslator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.experiment;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentIdentifier;
-
-/**
- * @author pkupczyk
- */
-public class ExperimentIdentifierIdTranslator extends
-        AbstractTranslator<ExperimentIdentifier, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentIdentifierId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentIdentifierId doTranslate(ExperimentIdentifier id)
-    {
-        return new ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentIdentifierId(id.getIdentifier());
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentPermIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentPermIdTranslator.java
deleted file mode 100644
index 392927a720d..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/ExperimentPermIdTranslator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.experiment;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
-
-/**
- * @author pkupczyk
- */
-public class ExperimentPermIdTranslator extends
-        AbstractTranslator<ExperimentPermId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentPermIdId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentPermIdId doTranslate(ExperimentPermId id)
-    {
-        return new ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentPermIdId(id.getPermId());
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/IExperimentIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/IExperimentIdTranslator.java
deleted file mode 100644
index 0820261ab30..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/experiment/IExperimentIdTranslator.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.experiment;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentIdentifier;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
-
-/**
- * @author pkupczyk
- */
-public class IExperimentIdTranslator extends
-        AbstractTranslator<IExperimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.IExperimentId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.IExperimentId doTranslate(
-            IExperimentId id)
-    {
-        if (id instanceof ExperimentPermId)
-        {
-            return new ExperimentPermIdTranslator().translate((ExperimentPermId) id);
-        } else if (id instanceof ExperimentIdentifier)
-        {
-            return new ExperimentIdentifierIdTranslator().translate((ExperimentIdentifier) id);
-        } else
-        {
-            throw new UnsupportedObjectIdException(id);
-        }
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/ISampleIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/ISampleIdTranslator.java
deleted file mode 100644
index 57472b974b7..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/ISampleIdTranslator.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.sample;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SamplePermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SampleIdentifier;
-import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
-
-/**
- * @author pkupczyk
- */
-public class ISampleIdTranslator extends
-        AbstractTranslator<ISampleId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.ISampleId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.ISampleId doTranslate(
-            ISampleId id)
-    {
-        if (id instanceof SamplePermId)
-        {
-            return new SamplePermIdTranslator().translate((SamplePermId) id);
-        } else if (id instanceof SampleIdentifier)
-        {
-            return new SampleIdentifierIdTranslator().translate((SampleIdentifier) id);
-        } else
-        {
-            throw new UnsupportedObjectIdException(id);
-        }
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SampleIdentifierIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SampleIdentifierIdTranslator.java
deleted file mode 100644
index 6c67eab9d8e..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SampleIdentifierIdTranslator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.sample;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SampleIdentifier;
-
-/**
- * @author pkupczyk
- */
-public class SampleIdentifierIdTranslator extends
-        AbstractTranslator<SampleIdentifier, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SampleIdentifierId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SampleIdentifierId doTranslate(SampleIdentifier id)
-    {
-        return new ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SampleIdentifierId(id.getIdentifier());
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SamplePermIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SamplePermIdTranslator.java
deleted file mode 100644
index 674aaf48ba6..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/sample/SamplePermIdTranslator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.sample;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SamplePermId;
-
-/**
- * @author pkupczyk
- */
-public class SamplePermIdTranslator extends
-        AbstractTranslator<SamplePermId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SamplePermIdId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SamplePermIdId doTranslate(SamplePermId id)
-    {
-        return new ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SamplePermIdId(id.getPermId());
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/ISpaceIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/ISpaceIdTranslator.java
deleted file mode 100644
index ea431e4f56a..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/ISpaceIdTranslator.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.space;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
-
-/**
- * @author pkupczyk
- */
-public class ISpaceIdTranslator extends
-        AbstractTranslator<ISpaceId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.space.ISpaceId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.space.ISpaceId doTranslate(
-            ISpaceId id)
-    {
-        if (id instanceof SpacePermId)
-        {
-            return new SpacePermIdTranslator().translate((SpacePermId) id);
-        } else
-        {
-            throw new UnsupportedObjectIdException(id);
-        }
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/SpacePermIdTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/SpacePermIdTranslator.java
deleted file mode 100644
index d5e55ab91fd..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/id/space/SpacePermIdTranslator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.translator.id.space;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
-
-/**
- * @author pkupczyk
- */
-public class SpacePermIdTranslator extends
-        AbstractTranslator<SpacePermId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.space.SpacePermIdId>
-{
-
-    @Override
-    protected ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.space.SpacePermIdId doTranslate(SpacePermId id)
-    {
-        return new ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.space.SpacePermIdId(id.getPermId());
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/validator/entity/experiment/ExperimentValidator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/validator/entity/experiment/ExperimentValidator.java
deleted file mode 100644
index 728c5c451ba..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/validator/entity/experiment/ExperimentValidator.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2013 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.api.v3.validator.entity.experiment;
-
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.AbstractValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentByIdentiferValidator;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder;
-import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
-
-/**
- * @author pkupczyk
- */
-public class ExperimentValidator extends AbstractValidator<Experiment>
-{
-
-    private ExperimentByIdentiferValidator validator = new ExperimentByIdentiferValidator();
-
-    @Override
-    public boolean doValidation(final PersonPE person, final Experiment experiment)
-    {
-        return validator.doValidation(person, new IIdentifierHolder()
-            {
-                @Override
-                public String getIdentifier()
-                {
-                    return experiment.getIdentifier().getIdentifier();
-                }
-            });
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/validator/entity/sample/.gitignore b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/validator/entity/sample/.gitignore
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentTechIdId.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentTechIdId.java
deleted file mode 100644
index 7fe3bc8c8fb..00000000000
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/experiment/ListerByExperimentTechIdId.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2013 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.systemsx.cisd.openbis.generic.server.business.search.id.experiment;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.experiment.ExperimentTechIdId;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
-
-/**
- * @author pkupczyk
- */
-public class ListerByExperimentTechIdId implements IListerById<ExperimentTechIdId, ExperimentPE>
-{
-
-    private IExperimentDAO experimentDAO;
-
-    public ListerByExperimentTechIdId(IDAOFactory daoFactory)
-    {
-        this.experimentDAO = daoFactory.getExperimentDAO();
-    }
-
-    @Override
-    public Class<ExperimentTechIdId> getIdClass()
-    {
-        return ExperimentTechIdId.class;
-    }
-
-    @Override
-    public ExperimentTechIdId createId(ExperimentPE experiment)
-    {
-        return new ExperimentTechIdId(experiment.getId());
-    }
-
-    @Override
-    public List<ExperimentPE> listByIds(List<ExperimentTechIdId> ids)
-    {
-        List<Long> techIds = new LinkedList<Long>();
-
-        for (ExperimentTechIdId id : ids)
-        {
-            techIds.add(id.getTechId());
-        }
-
-        return experimentDAO.listByIDs(techIds);
-    }
-
-}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleTechIdId.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleTechIdId.java
deleted file mode 100644
index f1ec0c54bb7..00000000000
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/id/sample/ListerBySampleTechIdId.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2013 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.systemsx.cisd.openbis.generic.server.business.search.id.sample;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import ch.systemsx.cisd.openbis.generic.server.business.search.id.IListerById;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.sample.SampleTechIdId;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
-
-/**
- * @author pkupczyk
- */
-public class ListerBySampleTechIdId implements IListerById<SampleTechIdId, SamplePE>
-{
-
-    private ISampleDAO sampleDAO;
-
-    public ListerBySampleTechIdId(IDAOFactory daoFactory)
-    {
-        this.sampleDAO = daoFactory.getSampleDAO();
-    }
-
-    @Override
-    public Class<SampleTechIdId> getIdClass()
-    {
-        return SampleTechIdId.class;
-    }
-
-    @Override
-    public SampleTechIdId createId(SamplePE sample)
-    {
-        return new SampleTechIdId(sample.getId());
-    }
-
-    @Override
-    public List<SamplePE> listByIds(List<SampleTechIdId> ids)
-    {
-        List<Long> techIds = new LinkedList<Long>();
-
-        for (SampleTechIdId id : ids)
-        {
-            techIds.add(id.getTechId());
-        }
-
-        return sampleDAO.listByIDs(techIds);
-    }
-
-}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExperimentDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExperimentDAO.java
index 2341a183ab9..23db41cb42b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExperimentDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExperimentDAO.java
@@ -54,16 +54,16 @@ public interface IExperimentDAO extends IGenericDAO<ExperimentPE>
             throws DataAccessException;
 
     /**
-     * Lists experiments of specified type, project and space. All criteria are optional. If no
-     * criteria is specified all experiments are returned. Fetches also properties.
+     * Lists experiments of specified type, project and space. All criteria are optional. If no criteria is specified all experiments are returned.
+     * Fetches also properties.
      */
     public List<ExperimentPE> listExperimentsWithProperties(
             final ExperimentTypePE experimentTypeOrNull, final ProjectPE projectOrNull,
             final SpacePE spaceOrNull) throws DataAccessException;
 
     /**
-     * Lists experiments of specified type, project and space. All criteria are optional. If no
-     * criteria is specified all experiments are returned. Fetches also properties.
+     * Lists experiments of specified type, project and space. All criteria are optional. If no criteria is specified all experiments are returned.
+     * Fetches also properties.
      */
     public List<ExperimentPE> listExperimentsWithProperties(
             final ExperimentTypePE experimentTypeOrNull, final List<ProjectPE> projectsOrNull,
@@ -81,8 +81,8 @@ public interface IExperimentDAO extends IGenericDAO<ExperimentPE>
     public ExperimentPE tryFindByCodeAndProject(ProjectPE project, String experimentCode);
 
     /**
-     * Lists experiments (with minimal additional information) belonging to the given
-     * <code>project</code> and having a property with the specified value.
+     * Lists experiments (with minimal additional information) belonging to the given <code>project</code> and having a property with the specified
+     * value.
      */
     public List<ExperimentPE> listExperimentsByProjectAndProperty(final String propertyCode,
             final String propertyValue, final ProjectPE project) throws DataAccessException;
@@ -99,13 +99,18 @@ public interface IExperimentDAO extends IGenericDAO<ExperimentPE>
     public List<String> getSampleCodes(ExperimentPE experiment);
 
     /**
-     * Try to obtain the experiment for the given <var>permId</var>. Returns <code>null</code>, if
-     * no experiment with the given perm id exists.
+     * Try to obtain the experiment for the given <var>permId</var>. Returns <code>null</code>, if no experiment with the given perm id exists.
      */
     public ExperimentPE tryGetByPermID(String permId);
 
+    /**
+     * List experiments by perm ids.
+     */
     public List<ExperimentPE> listByPermID(Collection<String> permId);
 
+    /**
+     * List experiments by ids.
+     */
     public List<ExperimentPE> listByIDs(Collection<Long> ids);
 
     /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IProjectDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IProjectDAO.java
index eccc6445312..255f21b5bf6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IProjectDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IProjectDAO.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.server.dataaccess;
 
+import java.util.Collection;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
@@ -41,6 +42,16 @@ public interface IProjectDAO extends IGenericDAO<ProjectPE>
      */
     public List<ProjectPE> listProjects(SpacePE space);
 
+    /**
+     * Lists projects by ids.
+     */
+    public List<ProjectPE> listByIDs(Collection<Long> ids);
+
+    /**
+     * Lists projects by perm ids.
+     */
+    public List<ProjectPE> listByPermID(Collection<String> permIds);
+
     /**
      * Returns project for given perm id or null if such a project does not exist.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ProjectDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ProjectDAO.java
index 8d8dd19b646..0b432f01fea 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ProjectDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ProjectDAO.java
@@ -16,6 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -135,6 +137,33 @@ public class ProjectDAO extends AbstractGenericEntityDAO<ProjectPE> implements I
         return matchingProjects;
     }
 
+    @Override
+    public List<ProjectPE> listByPermID(Collection<String> values)
+    {
+        return listByIDsOfName("permId", values);
+    }
+
+    @Override
+    public List<ProjectPE> listByIDs(Collection<Long> values)
+    {
+        return listByIDsOfName("id", values);
+    }
+
+    private List<ProjectPE> listByIDsOfName(String idName, Collection<?> values)
+    {
+        if (values == null || values.isEmpty())
+        {
+            return new ArrayList<ProjectPE>();
+        }
+        final List<ProjectPE> list =
+                DAOUtils.listByCollection(getHibernateTemplate(), ProjectPE.class, idName, values);
+        if (operationLog.isDebugEnabled())
+        {
+            operationLog.debug(String.format("%d projects(s) have been found.", list.size()));
+        }
+        return list;
+    }
+
     @Override
     public void createProject(ProjectPE project, PersonPE modifier)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java
index 899fd31ec71..261b2e81def 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java
@@ -811,8 +811,7 @@ public class SamplePE extends AttachmentHolderPE implements IIdAndCodeHolder, Co
         return contained;
     }
 
-    @SuppressWarnings("unused")
-    private void setContained(List<SamplePE> contained)
+    public void setContained(List<SamplePE> contained)
     {
         this.contained = contained;
     }
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutorTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutorTest.java
index fed01f37867..81ffba2879f 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutorTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/experiment/MapExperimentByIdExecutorTest.java
@@ -67,9 +67,6 @@ public class MapExperimentByIdExecutorTest extends AbstractExecutorTest
         context.checking(new Expectations()
             {
                 {
-                    allowing(daoFactory).getExperimentDAO();
-                    will(returnValue(experimentDao));
-
                     one(experimentDao).listByPermID(Arrays.asList(permId1.getPermId(), permId2.getPermId(), permId3.getPermId()));
                     will(returnValue(Arrays.asList(experiment2, experiment1, experiment3)));
                 }
@@ -85,7 +82,7 @@ public class MapExperimentByIdExecutorTest extends AbstractExecutorTest
 
     private Map<IExperimentId, ExperimentPE> execute(IExperimentId... experimentIds)
     {
-        MapExperimentByIdExecutor executor = new MapExperimentByIdExecutor(daoFactory);
+        MapExperimentByIdExecutor executor = new MapExperimentByIdExecutor(experimentDao);
         return executor.map(operationContext, Arrays.asList(experimentIds));
     }
 }
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutorTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutorTest.java
new file mode 100644
index 00000000000..445916d0662
--- /dev/null
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/MapProjectByIdExecutorTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2014 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.api.v3.executor.project;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.AbstractExecutorTest;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectIdentifier;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
+
+/**
+ * @author pkupczyk
+ */
+public class MapProjectByIdExecutorTest extends AbstractExecutorTest
+{
+
+    private IProjectDAO projectDao;
+
+    @Override
+    protected void init()
+    {
+        projectDao = context.mock(IProjectDAO.class);
+    }
+
+    @Test
+    public void testGetByPermId()
+    {
+        final ProjectPE project = new ProjectPE();
+        project.setId(123L);
+        project.setPermId("TEST_PERM_ID");
+        final ProjectPermId permId = new ProjectPermId(project.getPermId());
+
+        context.checking(new Expectations()
+            {
+                {
+                    one(projectDao).listByPermID(Collections.singletonList(project.getPermId()));
+                    will(returnValue(Collections.singletonList(project)));
+                }
+            });
+
+        Map<IProjectId, ProjectPE> result = execute(permId);
+        Assert.assertEquals(1, result.size());
+        Assert.assertEquals(Long.valueOf(123L), result.get(permId).getId());
+    }
+
+    @Test
+    public void testGetByPermIdNonexistent()
+    {
+        final ProjectPermId permId = new ProjectPermId("NONEXISTENT_PROJECT");
+
+        context.checking(new Expectations()
+            {
+                {
+                    one(projectDao).listByPermID(Collections.singletonList(permId.getPermId()));
+                    will(returnValue(null));
+                }
+            });
+
+        Map<IProjectId, ProjectPE> result = execute(permId);
+        Assert.assertNotNull(result);
+        Assert.assertEquals(0, result.size());
+    }
+
+    @Test
+    public void testGetByIdentifier()
+    {
+        final SpacePE space = new SpacePE();
+        space.setCode("TEST_SPACE");
+
+        final ProjectPE project = new ProjectPE();
+        project.setId(123L);
+        project.setCode("TEST_PROJECT");
+        project.setSpace(space);
+
+        final ProjectIdentifier identifier = new ProjectIdentifier("/" + space.getCode() + "/" + project.getCode());
+
+        context.checking(new Expectations()
+            {
+                {
+                    one(projectDao).tryFindProjects(
+                            Collections.singletonList(new ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier(space.getCode(),
+                                    project.getCode())));
+                    will(returnValue(Collections.singletonList(project)));
+                }
+            });
+
+        Map<IProjectId, ProjectPE> result = execute(identifier);
+        Assert.assertEquals(1, result.size());
+        Assert.assertEquals(Long.valueOf(123L), result.get(identifier).getId());
+    }
+
+    @Test
+    public void testGetByIdentifierNonexistent()
+    {
+        final String spaceCode = "TEST_SPACE";
+        final String projectCode = "NONEXISTENT_PROJECT";
+        final ProjectIdentifier identifier = new ProjectIdentifier("/" + spaceCode + "/" + projectCode);
+
+        context.checking(new Expectations()
+            {
+                {
+                    one(projectDao).tryFindProjects(
+                            Collections.singletonList(new ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier(spaceCode,
+                                    projectCode)));
+                    will(returnValue(Collections.emptyList()));
+                }
+            });
+
+        Map<IProjectId, ProjectPE> result = execute(identifier);
+        Assert.assertNotNull(result);
+        Assert.assertEquals(0, result.size());
+    }
+
+    @Test(expectedExceptions = { UnsupportedObjectIdException.class })
+    public void testGetByUnknownId()
+    {
+        final IProjectId unknownId = new IProjectId()
+            {
+
+                private static final long serialVersionUID = 1L;
+
+            };
+        execute(unknownId);
+    }
+
+    private Map<IProjectId, ProjectPE> execute(IProjectId... projectIds)
+    {
+        IMapProjectByIdExecutor executor = new MapProjectByIdExecutor(projectDao);
+        return executor.map(operationContext, Arrays.asList(projectIds));
+    }
+}
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutorTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutorTest.java
index 5ca31ad800a..2c35c8d705b 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutorTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/TryGetProjectByIdExecutorTest.java
@@ -16,18 +16,16 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.executor.project;
 
+import java.util.Collections;
+
 import junit.framework.Assert;
 
 import org.jmock.Expectations;
 import org.testng.annotations.Test;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.AbstractExecutorTest;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.TryGetProjectByIdExecutor;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectIdentifier;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.exceptions.UnsupportedObjectIdException;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 
 /**
@@ -36,16 +34,16 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 public class TryGetProjectByIdExecutorTest extends AbstractExecutorTest
 {
 
-    private IProjectDAO projectDao;
+    private IMapProjectByIdExecutor mapExecutor;
 
     @Override
     protected void init()
     {
-        projectDao = context.mock(IProjectDAO.class);
+        mapExecutor = context.mock(IMapProjectByIdExecutor.class);
     }
 
     @Test
-    public void testGetByPermId()
+    public void testGetExisting()
     {
         final ProjectPermId permId = new ProjectPermId("TEST_PERM_ID");
         final ProjectPE project = new ProjectPE();
@@ -54,8 +52,8 @@ public class TryGetProjectByIdExecutorTest extends AbstractExecutorTest
         context.checking(new Expectations()
             {
                 {
-                    one(projectDao).tryGetByPermID(permId.getPermId());
-                    will(returnValue(project));
+                    one(mapExecutor).map(operationContext, Collections.singletonList(permId));
+                    will(returnValue(Collections.singletonMap(permId, project)));
                 }
             });
 
@@ -64,15 +62,15 @@ public class TryGetProjectByIdExecutorTest extends AbstractExecutorTest
     }
 
     @Test
-    public void testGetByPermIdNonexistent()
+    public void testGetNonexistent()
     {
         final ProjectPermId permId = new ProjectPermId("NONEXISTENT_PROJECT");
 
         context.checking(new Expectations()
             {
                 {
-                    one(projectDao).tryGetByPermID("NONEXISTENT_PROJECT");
-                    will(returnValue(null));
+                    one(mapExecutor).map(operationContext, Collections.singletonList(permId));
+                    will(returnValue(Collections.emptyMap()));
                 }
             });
 
@@ -80,60 +78,9 @@ public class TryGetProjectByIdExecutorTest extends AbstractExecutorTest
         Assert.assertNull(result);
     }
 
-    @Test
-    public void testGetByIdentifier()
-    {
-        final ProjectIdentifier identifier = new ProjectIdentifier("/TEST_SPACE/TEST_PROJECT");
-        final ProjectPE project = new ProjectPE();
-        project.setId(123L);
-
-        context.checking(new Expectations()
-            {
-                {
-                    one(projectDao).tryFindProject("TEST_SPACE", "TEST_PROJECT");
-                    will(returnValue(project));
-                }
-            });
-
-        ProjectPE result = execute(identifier);
-        Assert.assertEquals(Long.valueOf(123L), result.getId());
-    }
-
-    @Test
-    public void testGetByIdentifierNonexistent()
-    {
-        final ProjectIdentifier identifier = new ProjectIdentifier("/TEST_SPACE/NONEXISTENT_PROJECT");
-
-        context.checking(new Expectations()
-            {
-                {
-                    one(projectDao).tryFindProject("TEST_SPACE", "NONEXISTENT_PROJECT");
-                    will(returnValue(null));
-                }
-            });
-
-        ProjectPE result = execute(identifier);
-        Assert.assertNull(result);
-    }
-
-    @Test(expectedExceptions = { UnsupportedObjectIdException.class })
-    public void testGetByUnknownId()
-    {
-        final IProjectId unknownId = new IProjectId()
-            {
-
-                private static final long serialVersionUID = 1L;
-
-            };
-        final ProjectPE project = new ProjectPE();
-        project.setId(123L);
-
-        execute(unknownId);
-    }
-
     private ProjectPE execute(IProjectId projectId)
     {
-        TryGetProjectByIdExecutor executor = new TryGetProjectByIdExecutor(projectDao);
+        TryGetProjectByIdExecutor executor = new TryGetProjectByIdExecutor(mapExecutor);
         return executor.tryGet(operationContext, projectId);
     }
 }
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentCreateTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentCreateTest.java
index 15443aae166..af6458be30d 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentCreateTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentCreateTest.java
@@ -40,7 +40,8 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectIdentifie
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.ITagId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagPermId;
-import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.test.AssertionUtil;
 
 /**
  * @author pkupczyk
@@ -48,8 +49,8 @@ import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 public class ExperimentCreateTest extends AbstractExperimentTest
 {
 
-    @Test(expectedExceptions = AuthorizationFailureException.class)
-    public void testCreateExperimentWithFailedAuthorization()
+    @Test
+    public void testCreateExperimentWithUnauthorizedProject()
     {
         String sessionToken = v3api.login(TEST_POWER_USER_CISD, PASSWORD);
 
@@ -58,7 +59,13 @@ public class ExperimentCreateTest extends AbstractExperimentTest
         experiment.setTypeId(new EntityTypePermId("SIRNA_HCS"));
         experiment.setProjectId(new ProjectIdentifier("/TESTGROUP/TESTPROJ"));
 
-        v3api.createExperiments(sessionToken, Arrays.asList(experiment));
+        try
+        {
+            v3api.createExperiments(sessionToken, Arrays.asList(experiment));
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+        }
     }
 
     @Test
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentUpdateTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentUpdateTest.java
index c4a52205f0f..760f1ca8fa7 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentUpdateTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/ExperimentUpdateTest.java
@@ -17,6 +17,7 @@
 package ch.ethz.sis.openbis.systemtest.api.v3;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
 
 import java.util.Arrays;
 import java.util.List;
@@ -31,6 +32,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePer
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectIdentifier;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagNameId;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.test.AssertionUtil;
 
 /**
@@ -66,10 +68,48 @@ public class ExperimentUpdateTest extends AbstractExperimentTest
         Experiment experiment = experiments.get(0);
         assertEquals(experiment.getIdentifier().getIdentifier(), "/CISD/NOE/TEST_EXPERIMENT");
     }
-    
+
+    @Test
+    public void testUpdateExperimentWithUnauthorizedExperiment()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        ExperimentUpdate update = new ExperimentUpdate();
+        update.setExperimentId(new ExperimentPermId("200811050951882-1028"));
+
+        try
+        {
+            v3api.updateExperiments(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure: Cannot access experiment /CISD/NEMO/EXP1", e.getMessage());
+        }
+    }
+
     @Test
-    public void samplesAreUpdatedWhenNewProjectOfExperimentIsInAnotherSpace() {
-        
+    public void testUpdateExperimentWithUnauthorizedProject()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        ExperimentUpdate update = new ExperimentUpdate();
+        update.setExperimentId(new ExperimentPermId("200902091255058-1037"));
+        update.setProjectId(new ProjectIdentifier("/CISD/NEMO"));
+
+        try
+        {
+            v3api.updateExperiments(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+        }
+    }
+
+    @Test
+    public void samplesAreUpdatedWhenNewProjectOfExperimentIsInAnotherSpace()
+    {
+
     }
 
     @Test
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleCreateTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleCreateTest.java
index 5d87bd1857d..ba48fce1f2b 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleCreateTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleCreateTest.java
@@ -38,6 +38,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.tag.Tag;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.CreationId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePermId;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SampleIdentifier;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.SamplePermId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
@@ -393,8 +394,8 @@ public class SampleCreateTest extends AbstractSampleTest
     {
         String sessionToken = v3api.login(TEST_USER, PASSWORD);
 
-        SampleCreation sc1 = createSimpleSample("SAMPLE_1");
-        SampleCreation sc2 = createSimpleSample("SAMPLE_2");
+        SampleCreation sc1 = sampleCreation("SAMPLE_1");
+        SampleCreation sc2 = sampleCreation("SAMPLE_2");
 
         sc2.setContainerId(new SampleIdentifier("/CISD/SAMPLE_1"));
 
@@ -418,8 +419,8 @@ public class SampleCreateTest extends AbstractSampleTest
     {
         String sessionToken = v3api.login(TEST_USER, PASSWORD);
 
-        SampleCreation sc1 = createSimpleSample("SAMPLE_1");
-        SampleCreation sc2 = createSimpleSample("SAMPLE_2");
+        SampleCreation sc1 = sampleCreation("SAMPLE_1");
+        SampleCreation sc2 = sampleCreation("SAMPLE_2");
 
         sc2.setContainerId(sc1.getCreationId());
 
@@ -443,9 +444,9 @@ public class SampleCreateTest extends AbstractSampleTest
     {
         String sessionToken = v3api.login(TEST_USER, PASSWORD);
 
-        SampleCreation sample1 = createSimpleSample("SAMPLE_1");
-        SampleCreation sample2 = createSimpleSample("SAMPLE_2");
-        SampleCreation sample3 = createSimpleSample("SAMPLE_3");
+        SampleCreation sample1 = sampleCreation("SAMPLE_1");
+        SampleCreation sample2 = sampleCreation("SAMPLE_2");
+        SampleCreation sample3 = sampleCreation("SAMPLE_3");
 
         sample2.setContainerId(sample1.getCreationId());
         sample3.setContainerId(sample2.getCreationId());
@@ -465,7 +466,7 @@ public class SampleCreateTest extends AbstractSampleTest
     public void testCreateSampleWithoutCode()
     {
         String sessionToken = v3api.login(TEST_USER, PASSWORD);
-        SampleCreation sample = createSimpleSample(null);
+        SampleCreation sample = sampleCreation(null);
         try
         {
             v3api.createSamples(sessionToken, Arrays.asList(sample));
@@ -476,7 +477,126 @@ public class SampleCreateTest extends AbstractSampleTest
         }
     }
 
-    private SampleCreation createSimpleSample(String code)
+    @Test
+    public void testCreateSampleWithUnauthorizedSpace()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleCreation creation = new SampleCreation();
+        creation.setCode("UNAUTHORIZED_SPACE");
+        creation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+        creation.setSpaceId(new SpacePermId("CISD"));
+
+        try
+        {
+            v3api.createSamples(sessionToken, Collections.singletonList(creation));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+            AssertionUtil.assertContains("set space for sample UNAUTHORIZED_SPACE", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreateSampleWithUnauthorizedExperiment()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleCreation creation = new SampleCreation();
+        creation.setCode("UNAUTHORIZED_EXPERIMENT");
+        creation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+        creation.setSpaceId(new SpacePermId("TEST-SPACE"));
+        creation.setExperimentId(new ExperimentPermId("200811050951882-1028"));
+
+        try
+        {
+            v3api.createSamples(sessionToken, Collections.singletonList(creation));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+            AssertionUtil.assertContains("set experiment for sample UNAUTHORIZED_EXPERIMENT", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreateSampleWithUnauthorizedParent()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleCreation creation = sampleCreation("TEST-SPACE", "UNAUTHORIZED_PARENT");
+        creation.setParentIds(Collections.singletonList(createCisdSample("PARENT_SAMPLE")));
+
+        try
+        {
+            v3api.createSamples(sessionToken, Collections.singletonList(creation));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+            AssertionUtil.assertContains("set parents for sample UNAUTHORIZED_PARENT", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreateSampleWithUnauthorizedChild()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleCreation creation = sampleCreation("TEST-SPACE", "UNAUTHORIZED_CHILD");
+        creation.setChildIds(Collections.singletonList(createCisdSample("CHILD_SAMPLE")));
+
+        try
+        {
+            v3api.createSamples(sessionToken, Collections.singletonList(creation));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+            AssertionUtil.assertContains("set children for sample UNAUTHORIZED_CHILD", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreateSampleWithUnauthorizedContainer()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleCreation creation = sampleCreation("TEST-SPACE", "UNAUTHORIZED_CONTAINER");
+        creation.setContainerId(createCisdSample("CONTAINER_SAMPLE"));
+
+        try
+        {
+            v3api.createSamples(sessionToken, Collections.singletonList(creation));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+            AssertionUtil.assertContains("set container for sample UNAUTHORIZED_CONTAINER", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreateSampleWithUnauthorizedContained()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleCreation creation = sampleCreation("TEST-SPACE", "UNAUTHORIZED_CONTAINED");
+        creation.setContainedIds(Collections.singletonList(createCisdSample("CONTAINED_SAMPLE")));
+
+        try
+        {
+            v3api.createSamples(sessionToken, Collections.singletonList(creation));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+            AssertionUtil.assertContains("set contained for sample UNAUTHORIZED_CONTAINED", e.getMessage());
+        }
+    }
+
+    private SampleCreation sampleCreation(String code)
     {
         SampleCreation sampleParent = new SampleCreation();
         sampleParent.setCode(code);
@@ -486,4 +606,23 @@ public class SampleCreateTest extends AbstractSampleTest
         return sampleParent;
     }
 
+    private SampleCreation sampleCreation(String spaceCode, String code)
+    {
+        SampleCreation sampleParent = new SampleCreation();
+        sampleParent.setCode(code);
+        sampleParent.setTypeId(new EntityTypePermId("CELL_PLATE"));
+        sampleParent.setSpaceId(new SpacePermId(spaceCode));
+        sampleParent.setCreationId(new CreationId("creation " + code));
+        return sampleParent;
+    }
+
+    private SamplePermId createCisdSample(String code)
+    {
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        SampleCreation creation = sampleCreation("CISD", code);
+        List<SamplePermId> ids = v3api.createSamples(sessionToken, Collections.singletonList(creation));
+        v3api.logout(sessionToken);
+        return ids.get(0);
+    }
+
 }
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleUpdateTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleUpdateTest.java
index 874310207f3..1414317d1d6 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleUpdateTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SampleUpdateTest.java
@@ -19,6 +19,7 @@ package ch.ethz.sis.openbis.systemtest.api.v3;
 import static ch.systemsx.cisd.common.test.AssertionUtil.assertCollectionContainsOnly;
 import static ch.systemsx.cisd.common.test.AssertionUtil.assertCollectionSize;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -564,9 +565,10 @@ public class SampleUpdateTest extends AbstractSampleTest
         assertIdentifier(sample2, "/CISD/SAMPLE_2_WITH_TAGS");
         assertTags(sample2.getTags(), "TEST_TAG_2", "TEST_TAG_3");
     }
-    
+
     @Test
-    public void updateSampleRemoveSpace() {
+    public void updateSampleRemoveSpace()
+    {
         String sessionToken = v3api.login(TEST_USER, PASSWORD);
 
         SampleCreation creation = new SampleCreation();
@@ -597,9 +599,10 @@ public class SampleUpdateTest extends AbstractSampleTest
         assertEquals(sample.getExperiment(), null);
         assertIdentifier(sample, "/SAMPLE");
     }
-    
+
     @Test
-    public void updateSharedSampleSetSpace() {
+    public void updateSharedSampleSetSpace()
+    {
         String sessionToken = v3api.login(TEST_USER, PASSWORD);
 
         SampleCreation creation = new SampleCreation();
@@ -627,7 +630,139 @@ public class SampleUpdateTest extends AbstractSampleTest
         assertEquals(sample.getSpace().getCode(), "TEST-SPACE");
         assertEquals(sample.getExperiment().getIdentifier().getIdentifier(), "/TEST-SPACE/TEST-PROJECT/EXP-SPACE-TEST");
         assertIdentifier(sample, "/TEST-SPACE/SAMPLE");
-        
+
     }
-    
+
+    @Test
+    public void testUpdateSampleWithUnauthorizedSample()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleUpdate update = new SampleUpdate();
+        update.setSampleId(new SamplePermId("200902091219327-1025"));
+
+        try
+        {
+            v3api.updateSamples(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure: Cannot access sample /CISD/CP-TEST-1", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUpdateSampleWithUnauthorizedSpace()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleUpdate update = new SampleUpdate();
+        update.setSampleId(new SamplePermId("200902091250077-1060"));
+        update.setSpaceId(new SpacePermId("CISD"));
+
+        try
+        {
+            v3api.updateSamples(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure: Cannot access space CISD", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUpdateSampleWithUnauthorizedExperiment()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleUpdate update = new SampleUpdate();
+        update.setSampleId(new SamplePermId("200902091250077-1060"));
+        update.setExperimentId(new ExperimentPermId("200811050951882-1028"));
+
+        try
+        {
+            v3api.updateSamples(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure: Cannot access experiment /CISD/NEMO/EXP1", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUpdateSampleWithUnauthorizedContainer()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleUpdate update = new SampleUpdate();
+        update.setSampleId(new SamplePermId("200902091250077-1060"));
+        update.setContainerId(new SamplePermId("200902091219327-1025"));
+
+        try
+        {
+            v3api.updateSamples(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUpdateSampleWithUnauthorizedContained()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleUpdate update = new SampleUpdate();
+        update.setSampleId(new SamplePermId("200902091250077-1060"));
+        update.getContainedIds().add(new SamplePermId("200902091219327-1025"));
+
+        try
+        {
+            v3api.updateSamples(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUpdateSampleWithUnauthorizedParent()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleUpdate update = new SampleUpdate();
+        update.setSampleId(new SamplePermId("200902091250077-1060"));
+        update.getParentIds().add(new SamplePermId("200902091219327-1025"));
+
+        try
+        {
+            v3api.updateSamples(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUpdateSampleWithUnauthorizedChild()
+    {
+        String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD);
+
+        SampleUpdate update = new SampleUpdate();
+        update.setSampleId(new SamplePermId("200902091250077-1060"));
+        update.getChildIds().add(new SamplePermId("200902091219327-1025"));
+
+        try
+        {
+            v3api.updateSamples(sessionToken, Arrays.asList(update));
+            fail("Expected user failure exception");
+        } catch (UserFailureException e)
+        {
+            AssertionUtil.assertContains("Authorization failure", e.getMessage());
+        }
+    }
+
 }
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/exceptions/ObjectNotFoundException.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/exceptions/ObjectNotFoundException.java
new file mode 100644
index 00000000000..93753fc65ff
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/exceptions/ObjectNotFoundException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.generic.shared.api.v3.exceptions;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.IObjectId;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+
+/**
+ * @author pkupczyk
+ */
+public class ObjectNotFoundException extends UserFailureException
+{
+
+    private static final long serialVersionUID = 1L;
+
+    public ObjectNotFoundException(IObjectId id)
+    {
+        super("Object with id [" + id + "]  has not been found.");
+    }
+
+}
-- 
GitLab